diff src/aci2/aci/cmh_satr.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/cmh_satr.c	Mon Sep 26 00:29:36 2016 +0000
@@ -0,0 +1,1850 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GSM-PS (6147)
+|  Modul   :  CMH_SATR
++----------------------------------------------------------------------------- 
+|  Copyright 2002 Texas Instruments Berlin, AG 
+|                 All rights reserved. 
+| 
+|                 This file is confidential and a trade secret of Texas 
+|                 Instruments Berlin, AG 
+|                 The receipt of or possession of this file does not convey 
+|                 any rights to reproduce or disclose its contents or to 
+|                 manufacture, use, or sell anything it may describe, in 
+|                 whole, or in part, without the specific written consent of 
+|                 Texas Instruments Berlin, AG. 
++----------------------------------------------------------------------------- 
+|  Purpose :  This module defines the functions which are responsible
+|             for the responses of the protocol stack adapter for
+|             the SIM application toolkit.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifdef SIM_TOOLKIT
+
+#ifndef CMH_SATR_C
+#define CMH_SATR_C
+#endif
+
+#include "aci_all.h"
+/*==== INCLUDES ===================================================*/
+#include "aci_cmh.h"
+#include "aci_mem.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_sat.h"
+#include "psa_sim.h" /* for simShrdPrm declaration */
+#include "psa_sms.h"
+#include "psa_util.h"
+#include "cmh.h"
+#include "cmh_cc.h"
+#include "cmh_sat.h"
+#include "cmh_sms.h"
+#include "aoc.h"
+
+#include "phb.h"
+#include "cmh_phb.h"
+#include "l4_tim.h"
+/*==== CONSTANTS ==================================================*/
+
+
+/*==== TYPES ======================================================*/
+
+
+/*==== EXPORT =====================================================*/
+
+
+/*==== VARIABLES ==================================================*/
+
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++--------------------------------------------------------------------+
+| PROJECT :                     MODULE  : CMH_SATR                   |
+| STATE   : code                ROUTINE : cmhSAT_ModifyScaPdu        |
++--------------------------------------------------------------------+
+
+  PURPOSE : modifies the SCA in a SUBMIT PDU
+
+*/
+LOCAL void cmhSAT_ModifyScaPdu( T_sms_sdu *sms_sdu,
+                          UBYTE  *sca_buf,
+                          UBYTE sca_len )
+{
+  UBYTE old_sca_len;
+  UBYTE *rest;
+  USHORT rest_len;
+  UBYTE *old_sdu;
+  UBYTE old_sdu_len;
+
+  ACI_MALLOC(old_sdu, SIM_PDU_LEN);
+  old_sdu_len = sms_sdu->l_buf/8;
+  memcpy ( old_sdu, sms_sdu->buf, old_sdu_len );
+
+  old_sca_len = *old_sdu+1;
+  rest = old_sdu + old_sca_len;
+  rest_len = old_sdu_len - old_sca_len;
+
+  /* copy new SCA */
+  memcpy(sms_sdu->buf, sca_buf, sca_len);
+
+  /* copy the rest of the PDU */
+  memcpy(sms_sdu->buf+sca_len, rest, rest_len);
+
+  /* set the length */
+  sms_sdu->l_buf = (sca_len+rest_len) * 8;
+
+  ACI_MFREE(old_sdu);
+}
+
+
+/*
++--------------------------------------------------------------------+
+| PROJECT :                     MODULE  : CMH_SATR                   |
+| STATE   : code                ROUTINE : cmhSAT_ModifyDaPdu         |
++--------------------------------------------------------------------+
+
+  PURPOSE : modifies the destination address in a SUBMIT PDU
+
+*/
+LOCAL void cmhSAT_ModifyDaPdu( T_sms_sdu *sms_sdu,
+                         UBYTE  *da_buf,
+                         UBYTE da_len )
+{
+  UBYTE old_sca_len;
+  UBYTE old_da_len;
+  UBYTE *rest;
+  USHORT rest_len;
+  UBYTE *old_sdu;
+  UBYTE *new_sdu;
+  UBYTE old_sdu_len;
+
+  ACI_MALLOC(old_sdu, SIM_PDU_LEN);
+  old_sdu_len = sms_sdu->l_buf/8;
+  memcpy ( old_sdu, sms_sdu->buf, old_sdu_len );
+
+  new_sdu = sms_sdu->buf;
+
+  old_sca_len = *old_sdu+1;
+  old_da_len  = (*(old_sdu + old_sca_len + 2)+1)/2 + 2;
+  rest = old_sdu + old_sca_len + 2 + old_da_len;
+  rest_len = old_sdu_len - old_sca_len - 2 - old_da_len;
+
+  /* copy old sca, fo, mr */
+  memcpy(new_sdu, old_sdu, old_sca_len+2);
+  new_sdu += old_sca_len+2;
+
+  /* copy the new DA */
+  memcpy(new_sdu, da_buf, da_len);
+  new_sdu += da_len;
+
+  /* copy the rest of the PDU */
+  memcpy(new_sdu, rest, rest_len);
+
+  /* set the length */
+  sms_sdu->l_buf = (old_sca_len+2+da_len+rest_len) * 8;
+
+  ACI_MFREE(old_sdu);
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_STKCmdCnf             |
++-------------------------------------------------------------------+
+
+  PURPOSE : STK command confirmation
+
+*/
+
+GLOBAL SHORT cmhSAT_STKCmdCnf ( void )
+{
+
+  TRACE_FUNCTION ("cmhSAT_STKCmdCnf()");
+
+/*
+ *-------------------------------------------------------------------
+ * check for command context
+ *-------------------------------------------------------------------
+ */
+  switch( satEntStat.curCmd )
+  {
+    case( AT_CMD_SATE ):
+     /*
+      *----------------------------------------------------------------
+      * process event for %SATE command
+      *----------------------------------------------------------------
+      */
+      satEntStat.curCmd = AT_CMD_NONE;
+
+      TRACE_EVENT_P1("SAT reponse with SIM cause: %d", satShrdPrm.stkError);
+      
+      switch (satShrdPrm.stkError)
+      {
+        case SIM_NO_ERROR:
+          R_AT( RAT_SATE, satEntStat.entOwn )
+            ( satShrdPrm.stkCmdLen>>3, satShrdPrm.stkCmd );
+
+          R_AT( RAT_OK, satEntStat.entOwn )
+            ( AT_CMD_SATE );
+          break;
+
+        case SIM_CAUSE_SAT_BUSY:
+          R_AT( RAT_CME, satEntStat.entOwn )
+            ( AT_CMD_SATE, CME_ERR_SimSatBusy );
+          break;
+
+        case SIM_CAUSE_PUK1_BLOCKED:
+          R_AT( RAT_CME, satEntStat.entOwn )
+            ( AT_CMD_SATE, CME_ERR_SimFail );
+          break;
+
+        default:
+          R_AT( RAT_CME, satEntStat.entOwn )
+            ( AT_CMD_SATE, CME_ERR_Unknown );
+          break;
+      }
+      break;
+  }
+
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_STKCmdInd             |
++-------------------------------------------------------------------+
+
+  PURPOSE : STK command indication
+
+*/
+
+GLOBAL SHORT cmhSAT_STKCmdInd ( void )
+{
+  SHORT idx;                 /* holds list index */
+
+  TRACE_FUNCTION ("cmhSAT_STKCmdInd()");
+
+/*
+ *----------------------------------------------------------------
+ * send unsolicited result
+ *----------------------------------------------------------------
+ */
+
+  for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+  {
+    R_AT( RAT_SATI, idx )
+      ( satShrdPrm.stkCmdLen>>3, satShrdPrm.stkCmd );
+  }
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_Cust1StkCmdInd             |
++-------------------------------------------------------------------+
+
+  PURPOSE : Used for Sending the Origianl STK command indication to a Cust1 MMI,
+                   when performing Setup Call, Send SS, Send USSD or Send SMS
+*/
+
+GLOBAL SHORT cmhSAT_Cust1StkCmdInd ( void )
+{
+  SHORT idx;                 /* holds list index */
+
+  TRACE_FUNCTION ("cmhSAT_Cust1StkCmdInd()");
+
+  if (satShrdPrm.cust1StkCmd != (void *)0)
+  {
+      /*
+       *----------------------------------------------------------------
+       * send %SATI the MMI with the Stk Cmd
+       *----------------------------------------------------------------
+       */
+       
+        for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+        {
+          R_AT( RAT_SATI, idx )
+            ( satShrdPrm.cust1StkCmdLen >>3, satShrdPrm.cust1StkCmd);
+        }
+
+        ACI_MFREE(satShrdPrm.cust1StkCmd);
+
+        satShrdPrm.cust1StkCmd = (void *)0;
+        satShrdPrm.cust1StkCmdLen = 0;
+  }
+
+  return 0;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_STKUsrNtfy            |
++-------------------------------------------------------------------+
+
+  PURPOSE : STK user notification
+
+*/
+
+GLOBAL SHORT cmhSAT_STKUsrNtfy ( void )
+{
+  SHORT idx;                 /* holds list index */
+
+  T_ACI_SATN_CNTRL_TYPE cntrl_type = SATN_CNTRL_BY_SIM_Not_Present;
+
+  TRACE_FUNCTION ("cmhSAT_STKUsrNtfy()");
+
+/*
+ *----------------------------------------------------------------
+ * determine user notification
+ *----------------------------------------------------------------
+ */
+  switch( satShrdPrm.ntfy )
+  {
+    case( USR_NTF_CC_SIM ):
+
+      if (simShrdPrm.overall_cust_mode EQ CUST_MODE_BEHAVIOUR_1)
+      {
+          switch (satShrdPrm.SIMCCParm.ccAct)
+          {
+                case CC_ACT_CAL:
+                    cntrl_type = SATN_CNTRL_BY_SIM_CALL;
+                    break ;
+
+                case CC_ACT_SS:
+                    cntrl_type = SATN_CNTRL_BY_SIM_SS;
+                    break ;
+
+                case CC_ACT_USSD:
+                    cntrl_type = SATN_CNTRL_BY_SIM_USSD;
+                    break ;
+
+                case SMC_ACT_MO:
+                    cntrl_type = SATN_CNTRL_BY_SIM_SMS;
+                    break ;
+
+                 default:
+                    cntrl_type = SATN_CNTRL_BY_SIM_Not_Present;
+          }
+      }
+
+      if(psa_IsVldOwnId(satShrdPrm.owner) AND
+         satShrdPrm.owner NEQ NO_VLD_OWN      )
+      {
+        R_AT( RAT_SATN, satShrdPrm.owner )
+          ( satShrdPrm.stkCmdLen>>3, satShrdPrm.stkCmd, cntrl_type );
+        break;
+      }
+      /* otherwise continue, no break */
+      /*lint -fallthrough*/
+    default:
+
+      for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+      {
+        if( idx NEQ satShrdPrm.run_at_id )
+        {
+          /* don't notify SAT itself over run at channel */
+          R_AT( RAT_SATN, idx )
+          ( satShrdPrm.stkCmdLen>>3, satShrdPrm.stkCmd, cntrl_type );
+        }
+      }
+  }
+
+  return 0;
+}
+
+LOCAL void send_error_to_user( BOOL  ownNotSAT,
+                               UBYTE command,
+                               UBYTE result,
+                               UBYTE additional_result,
+                               UBYTE *resId,
+                               BOOL  satopc )
+{
+  T_ACI_SAT_TERM_RESP resp_data;
+
+  psaSAT_InitTrmResp( &resp_data );
+
+  if( ownNotSAT )
+  {
+    /* setup initiated by user */
+    R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+      ( command, CME_ERR_NotPresent );
+    /* log result */
+    cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, command,
+                  -1, -1, CME_ERR_NotPresent );
+    return;
+  }
+
+  /* setup initiated by SAT */
+  /* send SAT response */
+  resp_data.add_content = additional_result;
+
+  /* if source was open channel command */
+#ifdef FF_SAT_E  
+  if(satopc)
+  {
+    if( satShrdPrm.opchStat EQ OPCH_CCSIM_REQ )
+    {
+       cmhSAT_OpChnFailed( result, &resp_data );
+       return;
+    }
+  }
+#endif /* FF_SAT_E */
+
+  if( resId NEQ NULL )
+  { 
+    resp_data.resCC = resId;
+  }
+  psaSAT_SendTrmResp( result, &resp_data );
+}
+
+/* return TRUE if key sequence accepted, FALSE otherwise */
+LOCAL BOOL sim_control_send_ss( T_CLPTY_PRM *ss_clpty, 
+                                UBYTE       command, 
+                                BOOL        ownNotSAT, 
+                                UBYTE       *resCC )
+{
+  T_ACI_RETURN      retVal;             /* holds return value */
+  T_ACI_D_CLIR_OVRD dummy2;             /* dummy value */
+  T_ACI_D_TOC       dummy1;             /* dummy value */
+
+  /* check for busy SS condition */
+  if( psaSS_stbFindActSrv( NO_ENTRY ) NEQ NO_ENTRY )
+  {
+    /* NOTE: shouldn't that be:
+    send_error_to_user( ownNotSAT, RSLT_CC_SIM_PRM, ADD_ME_SS_BUSY, resCC, FALSE);
+    or send_error_to_user( ownNotSAT, RSLT_CC_SIM_PRM, RSLT_ME_CAP, resCC, FALSE);
+    ??*/
+    send_error_to_user( ownNotSAT, command, RSLT_ME_UNAB_PROC, ADD_ME_SS_BUSY, resCC, FALSE);
+    return FALSE;
+  }
+
+  /* send SS control string */
+  retVal = cmhCC_chkKeySeq ( satShrdPrm.SIMCCParm.owner,
+                             ss_clpty,
+                             &dummy1,
+                             &dummy2,
+                             CC_SIM_NO );
+  if( retVal NEQ AT_EXCT )
+  {
+    /* string is not SS: terminate with error */
+    send_error_to_user( ownNotSAT, command, RSLT_CC_SIM_PRM, RSLT_ME_CAP, resCC, FALSE);
+    return(FALSE);
+  }
+  else
+  {
+#ifdef FF_SAT_E
+    if(!ownNotSAT AND satShrdPrm.opchStat EQ OPCH_CCSIM_REQ )
+    {
+      return( FALSE );
+    }
+#endif /* FF_SAT_E */     
+    return(TRUE);
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_ResCalCntrlBySIM      |
++-------------------------------------------------------------------+
+
+  PURPOSE : Handle SIM call control result. Return TRUE if primitive
+            is needed for building a terminal response.
+
+*/
+LOCAL BOOL cmhSAT_result_sim_cc_ss( SHORT cId,
+                                    UBYTE *resId, 
+                                    T_ccr_allw *ccr )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+  T_ACI_SAT_TERM_RESP resp_data;
+  BOOL  ownNotSAT = (satShrdPrm.SIMCCParm.owner NEQ OWN_SAT);  /* flags that the owner is not SAT */
+  UBYTE cmdBuf;                         /* buffer command */
+
+  TRACE_FUNCTION("cmhSAT_result_sim_cc_ss()");
+
+  psaSAT_InitTrmResp( &resp_data );
+  
+#ifdef FF_SAT_E 
+  /* check for a pending OPEN CHANNEL command */
+  if (ctb->calStat EQ CS_SAT_CSD_REQ)
+  {
+    /* free ctb entry */
+    psaCC_FreeCtbNtry (cId);
+
+    /* respond with "error, Interaction with CC by SIM, perm problem" */
+    resp_data.add_content = ADD_CC_REQ_CHNG;
+    resp_data.chnStat = TRUE;
+
+    cmhSAT_OpChnFailed( RSLT_CC_SIM_PRM, &resp_data );
+
+    return( FALSE );
+  }
+#endif /* FF_SAT_E */ 
+
+  cmdBuf = ctb->curCmd;
+  psaCC_FreeCtbNtry (cId);
+
+  cmhCC_init_cldPty( &satPndSetup.clpty );
+
+  utl_BCD2DialStr( ccr->ss_string.ss_ctrl_string,
+                   satPndSetup.clpty.num,
+                   (UBYTE)MINIMUM(ccr->ss_string.c_ss_ctrl_string,
+                                  MAX_DIAL_LEN-1));
+
+  satPndSetup.clpty.ton = ccr->ss_string.noa;
+  satPndSetup.clpty.npi = ccr->ss_string.npi;
+
+  if( sim_control_send_ss( &satPndSetup.clpty, cmdBuf, ownNotSAT, resId ) )
+    return( !ownNotSAT );
+  return( FALSE );  /* primitive not needed anymore */
+}
+
+LOCAL void cmhSAT_result_sim_cc_address( SHORT cId, T_ccr_allw *ccr )
+{
+  TRACE_FUNCTION("cmhSAT_result_sim_cc_address()");
+
+  /* adjust called address */
+  cmhSAT_fillSetupPrm ( cId,
+                        &ccr->addr,
+                        ((ccr->v_subaddr)?&ccr->subaddr:NULL));
+#ifdef FF_SAT_E  
+  if( psaCC_ctb(cId)->calStat NEQ CS_SAT_CSD_REQ )
+#endif /* FF_SAT_E */
+  {
+    /* new call table entry set default bearer capabilities */
+    cmhSAT_fillSetupBC ( cId, BEARER_SERV_SPEECH, BEARER_SERV_NOT_PRES );
+  }
+
+  /* adjust bearer capabilities */
+  if( ccr->v_cap_cnf_parms )
+  {
+    /* CCP not supported yet */
+  /*
+    satShrdPrm.ntfy          = USR_NTF_SETUP_CAL;
+    satShrdPrm.capParm.cId   = cId;
+    satShrdPrm.capParm.cntxt = CTX_SAT_SETUP;
+    satShrdPrm.capParm.CCres = *resId;
+
+    if( psaCC_BCapDecode( BCRI_SAT, ccr->cap_cnf_parms.l_cap_cnf_parms>>3,
+                          ccr->cap_cnf_parms.b_cap_cnf_parms ) < 0 )
+    {
+      psaSAT_SendTrmResp( RSLT_ME_CAP, 0, NULL, NULL, NULL );
+      psaCC_FreeCtbNtry (cId);
+      return( FALSE );
+    }
+    else
+    {
+      return( *resId EQ CCR_ALLW_WITH_MDFY );
+    }
+  */
+  }
+}
+
+LOCAL BOOL cmhSAT_result_sim_cc_ussd( SHORT cId,
+                                      UBYTE *resId, 
+                                      T_ccr_allw *ccr  )
+{
+  T_ACI_SAT_TERM_RESP resp_data;
+  BOOL                ownNotSAT = (satShrdPrm.SIMCCParm.owner NEQ OWN_SAT);  /* flags that the owner is not SAT */
+  UBYTE               cmdBuf;                         /* buffer command */
+  UBYTE               len = 0;
+  T_ACI_RETURN        retVal;
+  T_ACI_D_TOC         dummy1;
+  T_ACI_D_CLIR_OVRD   dummy2;
+
+  TRACE_FUNCTION("cmhSAT_result_sim_cc_ussd()");
+
+  psaSAT_InitTrmResp( &resp_data );
+
+  /* check for busy SS condition */
+  if( psaSS_stbFindActSrv( NO_ENTRY ) NEQ NO_ENTRY )
+  {
+    /* respond with "error, ME currently unable to process command" */
+    resp_data.add_content = ADD_ME_SS_BUSY;
+    resp_data.resCC       = resId;
+    psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
+    return( FALSE );
+  }
+
+  /* call adr to be modified with USSD string*/
+  cmdBuf = psaCC_ctb(cId)->curCmd;
+  psaCC_FreeCtbNtry (cId);
+
+  if( utl_getAlphabetCb( (UBYTE) ccr->ussd_string.dcs) EQ 0 ) /* 7bit alphabet */
+  {
+     len=utl_cvt7To8( ccr->ussd_string.ussd_str,
+                      ccr->ussd_string.c_ussd_str,
+                      (UBYTE*)&satPndSetup.clpty.num, 0);
+     satPndSetup.clpty.num[len]=0x00;
+  }
+  else
+  {
+     memcpy( satPndSetup.clpty.num, ccr->ussd_string.ussd_str,
+             ccr->ussd_string.c_ussd_str );
+     satPndSetup.clpty.num[ccr->ussd_string.c_ussd_str]=0x00;
+  }
+
+  retVal = cmhCC_chkKeySeq ( satShrdPrm.SIMCCParm.owner,
+                             &satPndSetup.clpty, 
+                             &dummy1, &dummy2,
+                             CC_SIM_NO );
+
+  if( retVal EQ AT_EXCT )
+  {
+    return( !ownNotSAT );
+  }
+
+  if( ownNotSAT )
+  {
+    R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+        ( cmdBuf, CME_ERR_NotPresent );
+
+    /* log result */
+    cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, cmdBuf,
+                  -1, -1, CME_ERR_NotPresent );
+  }
+  /* setup initiated by SAT */
+  else
+  {
+    /* send SAT response */
+    resp_data.resCC = resId;
+    psaSAT_SendTrmResp( RSLT_ME_CAP, &resp_data );
+  }
+
+  return( FALSE );  /* primitive not needed anymore */
+}
+
+
+GLOBAL BOOL cmhSAT_ResCalCntrlBySIM( UBYTE* resId, void *ccRes )
+{
+  UBYTE cmdBuf;                         /* buffer command */
+  SHORT cId = satShrdPrm.SIMCCParm.cId; /* holds setup call id */
+  SHORT actId;                          /* holds active call id */
+  T_ccr_allw * ccr;                     /* points to CC result */
+  BOOL  ownNotSAT;                      /* flags that the owner is not SAT */
+  UBYTE idx;                            /* holds index */
+  T_ACI_SAT_TERM_RESP resp_data;
+
+#if defined SMI OR defined MFW
+  T_ACI_CLOG     cmdLog;      /* holds logging info */
+  CHAR           cmdlog_num_buf[MAX_CC_CALLED_NUMBER];  /* buffer where number is written for cmdLog */
+  USHORT         length;                       /* length of number */
+#endif
+
+  TRACE_FUNCTION("cmhSAT_ResCalCntrlBySIM()");
+
+  psaSAT_InitTrmResp( &resp_data );
+
+  ccr = (T_ccr_allw*)ccRes;
+
+  /* check if queued event download */
+  if (satShrdPrm.event.c_queued)
+  {
+    cmhSAT_EventDwn( -1, -1, -1);
+  }
+
+  satShrdPrm.SIMCCParm.busy = FALSE;
+
+  if (!psaCC_ctbIsValid (cId))
+  {
+    TRACE_ERROR ("Call table entry disappeared");
+    return FALSE;
+  }
+
+  ownNotSAT = satShrdPrm.SIMCCParm.owner NEQ OWN_SAT;
+
+  /*
+  ** If this is a Cust1 MMI and The originator was a STK Cmd
+  */
+  if ((simShrdPrm.overall_cust_mode EQ (UBYTE)CUST_MODE_BEHAVIOUR_1) AND
+      (ownNotSAT == FALSE))
+  {
+    /*
+    ** Customised behaviour for the Cust1 MMI
+    */
+    if (*resId == CCR_NOT_ALLW)
+    {
+        /* Call Setup not allowed */
+          send_error_to_user( ownNotSAT, psaCC_ctb(cId)->curCmd, 
+                            RSLT_CC_SIM_PRM, ADD_CC_NOT_ALLWD, 
+                            NULL, TRUE);
+    }
+    else
+    {
+        /*
+        ** This was a SAT initiated call. For the Cust1 the ACI does not yet have any
+        ** actions to perform, other than the CC By SIM which has been done. So :
+        ** Send the Original STK Cmd to the MMI in a %SATI for the MMI to process.
+        **
+        ** The second action will cause the MMI to request the approriate Call Setup, SS
+        ** or USSD Request and the required Call Table entry will then be re-created.
+        */
+        cmhSAT_Cust1StkCmdInd();
+    }
+  
+    /* Free the Call Table Entry
+    ** The SATI indication (if sent) will cause the MMI to request the approriate Call Setup, SS
+    ** or USSD Request and the required Call Table entry will then be re-created.
+    */
+    psaCC_FreeCtbNtry (cId);
+
+    return( FALSE );  /* primitive not needed anymore */
+  }
+
+  /* determine result id */
+  switch( *resId )
+  {
+    case( CCR_NOT_ALLW ):
+      /* call setup not allowed */
+      send_error_to_user( ownNotSAT, psaCC_ctb(cId)->curCmd, 
+                          RSLT_CC_SIM_PRM, ADD_CC_NOT_ALLWD, 
+                          NULL, TRUE);
+
+      /* memory for number has also been allocated in case of SAT setup call !! */
+      psaCC_FreeCtbNtry (cId);
+      return( FALSE );  /* primitive not needed anymore */
+
+    case( CCR_ALLW_WITH_MDFY ):
+      /* call setup allowed with modification */
+      if( ccr->v_ss_string )
+      {
+        /* if setup was converted into a SS control string */
+        return(cmhSAT_result_sim_cc_ss( cId, resId, ccr ));
+      }
+      else if( ccr->v_addr )
+      {
+        /* Replace call parameters for this cId with the ones provided by SIM */
+        cmhSAT_result_sim_cc_address( cId, ccr );
+      }
+      else if (ccr->v_ussd_string)
+      {
+        /* if setup was converted into a USSD control string */
+        return(cmhSAT_result_sim_cc_ussd( cId, resId, ccr ));
+      }
+      else
+      {} /* do not change cId parameters */
+      break;
+
+    case( CCR_ALLW_NO_MDFY ):
+      /* call setup allowed no modification */
+      /* use parameters already linked to cId */
+      break;
+  }
+
+  /* perform call setup initiated by user */
+  if( ownNotSAT )
+  {
+    /* check for an active call */
+    actId = psaCC_ctbFindCall( NO_VLD_OWN, CS_ACT, NO_VLD_CT );
+
+    if( actId NEQ NO_ENTRY )
+    {
+      /* put active on hold if possible */
+      if( psaCC_ctb(actId)->prio EQ PRIO_NORM_CALL AND
+          cmhCC_getcalltype(actId) EQ VOICE_CALL )
+      {
+        cmhCC_HoldCall(actId, psaCC_ctb(cId)->curSrc, AT_CMD_D);
+      }
+      /* reject call setup: already data or emergency call on going */
+      else
+      {
+        cmdBuf = psaCC_ctb(cId)->curCmd;
+        psaCC_FreeCtbNtry (cId);
+
+        R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+          ( cmdBuf, CME_ERR_NotPresent );
+
+        /* log result */
+        cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, cmdBuf,
+                      -1, -1, CME_ERR_NotPresent );
+
+        return( FALSE );  /* primitive not needed anymore */
+      }
+    }
+
+    /* finally set up call */
+    cmhCC_flagCall( cId,
+                    &(cmhPrm[psaCC_ctb(cId)->calOwn].ccCmdPrm.mltyCncFlg));
+
+    psaCC_NewCall (cId);
+
+
+#if defined SMI OR defined MFW
+    /* log command */
+    cmdLog.atCmd                = AT_CMD_D;
+    cmdLog.cmdType              = CLOG_TYPE_Set;
+    cmdLog.retCode              = AT_EXCT;
+    cmdLog.cId                  = cId+1;
+    cmdLog.sId                  = ACI_NumParmNotPresent;
+    cmdLog.cmdPrm.sD.srcId      = psaCC_ctb(cId)->curSrc;
+
+    cmdLog.cmdPrm.sD.number     = cmdlog_num_buf;
+
+    /* 
+     * For this block wrong code is generated by target compiler 1.22e
+     * Use psaCC_ctb() to simplify pointer expression.
+     */
+#if 0
+    if(ccShrdPrm.ctb[cId]->cldPty.c_called_num < MAX_CC_CALLED_NUMBER)
+    {
+      length = ccShrdPrm.ctb[cId]->cldPty.c_called_num;
+    }
+    else
+      length = MAX_CC_CALLED_NUMBER;
+
+    utl_BCD2String( cmdLog.cmdPrm.sD.number,
+                   (UBYTE *) ccShrdPrm.ctb[cId]->cldPty.called_num, 
+                   length);
+#else
+    if(psaCC_ctb(cId)->cldPty.c_called_num < MAX_CC_CALLED_NUMBER)
+    {
+      length = psaCC_ctb(cId)->cldPty.c_called_num;
+    }
+    else
+      length = MAX_CC_CALLED_NUMBER;
+
+    utl_BCD2String (cmdLog.cmdPrm.sD.number,
+                    psaCC_ctb(cId)->cldPty.called_num, 
+                    length);
+#endif /* else, #if 0 */
+
+    cmdLog.cmdPrm.sD.clirOvrd   = D_CLIR_OVRD_Default; /* ??? */
+    cmdLog.cmdPrm.sD.cugCtrl    = D_CUG_CTRL_NotPresent; /* ??? */
+    cmdLog.cmdPrm.sD.callType   = psaCC_ctb(cId)->calType;
+#ifdef SIM_TOOLKIT
+    cmdLog.cmdPrm.sD.simCallCtrl= D_SIMCC_ACTIVE;
+#endif  /* SIM tOOLKIT */
+    rAT_PercentCLOG( &cmdLog );
+#endif  /* SMI or MFW */
+    return( FALSE );
+  }
+  /* perform call setup initiated by SAT */
+  else /* Must be normal behaviour, otherwise it would have been trapped earlier in the function */
+  {
+  
+#ifdef FF_SAT_E
+   /* if source was open channel command */
+   if( satShrdPrm.opchStat EQ OPCH_CCSIM_REQ )
+   {
+      if(*resId EQ CCR_ALLW_WITH_MDFY) 
+        satShrdPrm.opchCCMdfy = TRUE;
+
+      cmhSAT_OpChnAlert( cId );
+      return( FALSE );
+   }
+#endif /* FF_SAT_E */
+
+   /* alert user if command details are supported */
+    if( cmhSAT_ChckCmdDet() )
+    {
+     /* check aoc condition */
+      if ((psaCC_ctb(cId)->prio EQ PRIO_NORM_CALL) AND
+          (aoc_check_moc() EQ FALSE))
+        /*
+         * check ACM exceeds ACMmax
+         * for non-emergency calls
+         */
+      {
+        resp_data.add_content = ADD_NO_CAUSE;
+        resp_data.resCC = (*resId EQ CCR_ALLW_WITH_MDFY)? resId: NULL;
+
+
+        psaSAT_SendTrmResp(RSLT_ME_UNAB_PROC, &resp_data);
+        psaCC_FreeCtbNtry (cId);
+        return( FALSE );
+      }
+
+      for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+      {
+
+#ifdef FF_SAT_E 
+         T_ACI_SATA_ADD addPrm;
+
+         addPrm.chnType = SATA_CT_VOICE;
+         addPrm.chnEst  = SATA_EST_IM;
+
+         R_AT( RAT_SATA, idx )( cId+1, satShrdPrm.dur, &addPrm );
+#else          
+         R_AT( RAT_SATA, idx )( cId+1, satShrdPrm.dur );         
+#endif /* FF_SAT_E */         
+      }
+
+      satShrdPrm.ntfy = USR_NTF_SETUP_CAL;
+    }
+    return( FALSE );
+  }
+}
+
+LOCAL BOOL sim_control_setup_call( T_ccr_allw *ccr, BOOL ownNotSAT )
+{
+  SHORT cId = satShrdPrm.SIMCCParm.cId; /* holds setup call id */
+  UBYTE idx;                            /* holds index */
+#ifdef FF_SAT_E  
+  T_ACI_SATA_ADD addPrm;
+#endif /* FF_SAT_E */
+  cId = psaCC_ctbNewEntry();
+
+  if( cId EQ NO_ENTRY )
+  {
+    send_error_to_user( ownNotSAT, AT_CMD_D, RSLT_ME_UNAB_PROC, ADD_NO_CAUSE, NULL, FALSE);
+    return( FALSE );  /* primitive not needed anymore */
+  }
+
+  /* fill in setup parameter for called address */
+  cmhSAT_fillSetupPrm ( cId,
+                        ((ccr->v_addr)?&ccr->addr:NULL),
+                        ((ccr->v_subaddr)?&ccr->subaddr:NULL));
+  /* new call table entry set default bearer capabilities */
+  cmhSAT_fillSetupBC ( cId, BEARER_SERV_SPEECH, BEARER_SERV_NOT_PRES );
+
+  /* check aoc condition */
+  if ((psaCC_ctb(cId)->prio EQ PRIO_NORM_CALL) AND
+      (aoc_check_moc() EQ FALSE))
+    /* check ACM exceeds ACMmax for non-emergency calls */
+  {
+    send_error_to_user( ownNotSAT, AT_CMD_D, RSLT_ME_UNAB_PROC, ADD_NO_CAUSE, NULL, FALSE);
+    psaCC_FreeCtbNtry (cId);
+    return( FALSE );
+  }
+
+  if( ccr->v_cap_cnf_parms )
+  {
+    /* check bearer caps, ctb not allocated */
+  }
+
+  /* declare call table entry as used and the owner and status
+     of the call */
+  psaCC_ctb(cId)->calOwn     = satShrdPrm.SIMCCParm.owner;
+  psaCC_ctb(cId)->calStat    = CS_SAT_REQ;
+  psaCC_ctb(cId)->curCmd     = AT_CMD_D;
+  psaCC_ctb(cId)->curSrc     = satShrdPrm.SIMCCParm.owner;
+
+  if( !ownNotSAT ) psaCC_ctb(cId)->SATinv = TRUE;
+
+  /* alert user */
+  if( ownNotSAT )
+  {
+#ifdef FF_SAT_E  
+    addPrm.chnType = SATA_CT_VOICE;
+    addPrm.chnEst  = SATA_EST_IM;
+
+    R_AT( RAT_SATA, satShrdPrm.SIMCCParm.owner )
+      ( cId+1, satShrdPrm.dur, &addPrm );
+#else
+    R_AT( RAT_SATA, satShrdPrm.SIMCCParm.owner )
+      ( cId+1, satShrdPrm.dur);
+#endif /* FF_SAT_E */ 
+
+    R_AT( RAT_OK, satShrdPrm.SIMCCParm.owner )
+      ( AT_CMD_D );
+    /* log result */
+    cmh_logRslt ( satShrdPrm.SIMCCParm.owner,
+                  RAT_OK, AT_CMD_D, -1, -1, -1 );
+  }
+   /* setup initiated by SAT */
+  else
+  {
+    for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+    {
+#ifdef FF_SAT_E  
+      addPrm.chnType = SATA_CT_VOICE;
+      addPrm.chnEst  = SATA_EST_IM;
+      R_AT( RAT_SATA, idx )
+        ( cId+1, satShrdPrm.dur, &addPrm );
+#else 
+      R_AT( RAT_SATA, idx )
+        ( cId+1, satShrdPrm.dur);
+#endif /* FF_SAT_E */
+    }
+  }
+  return( !ownNotSAT );
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_ResSSCntrlBySIM       |
++-------------------------------------------------------------------+
+
+  PURPOSE : Handle SIM SS control result. Return TRUE if primitive
+            is needed for building a terminal response.
+
+*/
+
+GLOBAL BOOL cmhSAT_ResSSCntrlBySIM( UBYTE* resId, void *ccRes )
+{
+  SHORT cId = satShrdPrm.SIMCCParm.cId; /* holds setup call id */
+  T_ccr_allw * ccr;                     /* points to CC result */
+  BOOL  ownNotSAT;                      /* flags that the owner is not SAT */
+
+  TRACE_FUNCTION("cmhSAT_ResSSCntrlBySIM()");
+  
+  ccr = (T_ccr_allw*)ccRes;
+
+  /* check if queued event download */
+  if (satShrdPrm.event.c_queued)
+  {
+    cmhSAT_EventDwn( -1, -1, -1);
+  }
+
+  satShrdPrm.SIMCCParm.busy = FALSE;
+
+  ownNotSAT = satShrdPrm.SIMCCParm.owner NEQ OWN_SAT;
+
+  /*
+  ** If this is a Cust1 MMI and The originator was a STK Cmd
+  */
+  if ((simShrdPrm.overall_cust_mode EQ (UBYTE)CUST_MODE_BEHAVIOUR_1) AND
+      (ownNotSAT == FALSE))
+  {
+      /*
+      ** Customised behaviour for the Cust1 MMI
+      */
+      if (*resId == CCR_NOT_ALLW)
+      {
+          send_error_to_user( ownNotSAT,
+                                             AT_CMD_D,
+                                             RSLT_CC_SIM_PRM,
+                                             ADD_CC_NOT_ALLWD,
+                                             NULL, FALSE);
+      }
+      else
+      {
+          /*
+          ** This was a SAT initiated Request. For the Cust1 the ACI does not yet have any
+          ** actions to perform, other than the CC By SIM which has been done. So :
+          ** Send the Original STK Cmd to the MMI in a %SATI for the MMI to process.
+          **
+          ** The second action will cause the MMI to request the approriate Call Setup, SS
+          ** or USSD Request and the required Call Table entry will then be re-created.
+          */
+          cmhSAT_Cust1StkCmdInd();
+      }
+    
+      /* Free the Call Table Entry
+      ** The SATI indication (if sent) will cause the MMI to request the approriate Call Setup, SS
+      ** or USSD Request and the required Call Table entry will then be re-created.
+      */
+      if (psaCC_ctbIsValid (cId))
+      {
+        psaCC_retMOCTi(psaCC_ctb(cId)->ti);
+        psaCC_chngCalTypCnt(cId, -1);
+        psaCC_FreeCtbNtry (cId);
+      }
+      return( FALSE );  /* primitive not needed anymore */
+  }
+
+
+/* determine result id */
+  switch( *resId )
+  {
+    case( CCR_NOT_ALLW ): /* SS not allowed */
+    {
+      send_error_to_user( ownNotSAT, AT_CMD_D, RSLT_CC_SIM_PRM, ADD_CC_NOT_ALLWD, NULL, FALSE);
+      if (ownNotSAT EQ FALSE)
+      {
+        /* clear call ID */
+        if (psaCC_ctbIsValid (cId))
+        {
+          psaCC_retMOCTi(psaCC_ctb(cId)->ti);
+          psaCC_chngCalTypCnt(cId, -1);
+          psaCC_FreeCtbNtry (cId);
+        }
+      }
+      return( FALSE );  /* primitive not needed anymore */
+    }
+    case( CCR_ALLW_WITH_MDFY ): /* SS allowed with modification */
+    {
+      if( ccr->v_addr )
+      {
+        /* if SS control string was converted into a call setup */
+        return(sim_control_setup_call( ccr, ownNotSAT ));
+      }
+      else if( ccr->v_ss_string )
+      {
+        /* if SS control string was changed by sim control */
+
+        /* adjust SS control string */
+        cmhCC_init_cldPty( &satPndSetup.clpty ); /* erase previous ss string */
+
+        utl_BCD2DialStr( ccr->ss_string.ss_ctrl_string,
+                         satPndSetup.clpty.num,
+                         (UBYTE)MINIMUM(ccr->ss_string.c_ss_ctrl_string,
+                                        MAX_DIAL_LEN-1));
+        satPndSetup.clpty.ton = ccr->ss_string.noa;
+        satPndSetup.clpty.npi = ccr->ss_string.npi;
+
+        sim_control_send_ss( &satPndSetup.clpty, AT_CMD_D, ownNotSAT, NULL );
+        return(FALSE);
+      }
+      else  /* if no optionnal field, then assume no modification see 11.14 ?9.1.6 */
+        sim_control_send_ss( &satPndSetup.clpty, AT_CMD_D, ownNotSAT, NULL );
+        return(FALSE);
+    }
+    /* SS allowed no modification */
+    default:
+      TRACE_ERROR ("Unknown resID in cmhSAT_ResSSCntrlBySIM!");
+      /*lint -fallthrough*/
+    case( CCR_ALLW_NO_MDFY ):
+      sim_control_send_ss( &satPndSetup.clpty, AT_CMD_D, ownNotSAT, NULL );
+      return( FALSE );  /* primitive not needed anymore */
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_ResUSSDCntrlBySIM     |
++-------------------------------------------------------------------+
+
+  PURPOSE : Handle SIM USSD control result. Return TRUE if primitive
+            is needed for building a terminal response.
+
+*/
+
+GLOBAL BOOL cmhSAT_ResUSSDCntrlBySIM( UBYTE* resId, void *ccRes )
+{
+  T_ACI_RETURN retVal;                  /* holds return value */
+  T_ccr_allw * ccr;                     /* points to CC result */
+  UBYTE idx;                            /* holds index */
+  BOOL  ownNotSAT;                      /* flags that the owner is not SAT */
+  SHORT sId;
+  T_ACI_SAT_TERM_RESP resp_data;
+#ifdef FF_SAT_E 
+  T_ACI_SATA_ADD addPrm;
+#endif
+  UBYTE *ussdString;
+  UBYTE ussdLen;
+  UBYTE src_len;
+
+
+
+  TRACE_FUNCTION ("cmhSAT_ResUSSDCntrlBySIM()");
+
+  psaSAT_InitTrmResp( &resp_data );
+
+  ccr = (T_ccr_allw*)ccRes;
+
+  /* check if queued event download */
+  if (satShrdPrm.event.c_queued)
+  {
+    cmhSAT_EventDwn( -1, -1, -1);
+  }
+
+  satShrdPrm.SIMCCParm.busy = FALSE;
+
+  ownNotSAT = satShrdPrm.SIMCCParm.owner NEQ OWN_SAT;
+
+  /*
+  ** If this is a Cust1 MMI and The originator was a STK Cmd
+  */
+  if ((simShrdPrm.overall_cust_mode EQ (UBYTE)CUST_MODE_BEHAVIOUR_1) AND
+      (ownNotSAT == FALSE))
+  {
+      /*
+      ** Customised behaviour for the Cust1 MMI
+      */
+      if (*resId == CCR_NOT_ALLW)
+      {
+          /* send SAT response */
+          resp_data.add_content = ADD_CC_NOT_ALLWD;
+          psaSAT_SendTrmResp( RSLT_CC_SIM_PRM, &resp_data );
+      }
+      else
+      {
+          /*
+          ** This was a SAT initiated Request. For the Cust1 the ACI does not yet have any
+          ** actions to perform, other than the CC By SIM which has been done. So :
+          ** Send the Original STK Cmd to the MMI in a %SATI for the MMI to process.
+          */
+          cmhSAT_Cust1StkCmdInd();
+      }
+
+      return( FALSE );  /* primitive not needed anymore */
+  }
+
+/*
+ *----------------------------------------------------------------
+ * determine result id
+ *----------------------------------------------------------------
+ */
+  switch( *resId )
+  {
+    /*
+     *------------------------------------------------------------
+     * SS not allowed
+     *------------------------------------------------------------
+     */
+    case( CCR_NOT_ALLW ):
+
+       /* setup initiated by user */
+      if( ownNotSAT )
+      {
+        R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+          ( AT_CMD_D, CME_ERR_NotPresent );
+        /* log result */
+        cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, AT_CMD_D,
+                      -1, -1, CME_ERR_NotPresent );
+      }
+       /* setup initiated by SAT */
+      else
+      {
+        /* send SAT response */
+        resp_data.add_content = ADD_CC_NOT_ALLWD;
+        psaSAT_SendTrmResp( RSLT_CC_SIM_PRM, &resp_data );
+      }
+      return( FALSE );  /* primitive not needed anymore */
+
+    /*
+     *------------------------------------------------------------
+     * USSD allowed with modification
+     *------------------------------------------------------------
+     */
+    case( CCR_ALLW_WITH_MDFY ):
+
+      /* if USSD control string was converted into a call setup */
+      if( ccr->v_addr )
+      {
+        SHORT cId = psaCC_ctbNewEntry();
+
+        if( cId EQ NO_ENTRY )
+        {
+          /* 
+           * We got no free slot in the call table
+           */
+          if( ownNotSAT )
+          {
+            R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+              ( AT_CMD_D, CME_ERR_NotPresent );
+            /* log result */
+            cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, AT_CMD_D,
+                          -1, -1, CME_ERR_NotPresent );
+          }
+           /* setup initiated by SAT */
+          else
+          {
+            /* send SAT response */
+            resp_data.add_content = ADD_NO_CAUSE;
+            psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
+          }
+          return( FALSE );  /* primitive not needed anymore */
+        }
+
+        /*
+         * We have successfully allocated a slot in the call table
+         */
+
+        /* fill in setup parameter for called address */
+        cmhSAT_fillSetupPrm ( cId,
+                              ((ccr->v_addr)?&ccr->addr:NULL),
+                              ((ccr->v_subaddr)?&ccr->subaddr:NULL));
+        /* new call table entry set default bearer capabilities */
+        cmhSAT_fillSetupBC ( cId, BEARER_SERV_SPEECH, BEARER_SERV_NOT_PRES );
+
+       /* check aoc condition */
+        if ((psaCC_ctb(cId)->prio EQ PRIO_NORM_CALL) AND
+            (aoc_check_moc() EQ FALSE))
+          /*
+           * check ACM exceeds ACMmax
+           * for non-emergency calls
+           */
+        {
+          if( ownNotSAT )
+          {
+            R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+              ( AT_CMD_D, CME_ERR_NotPresent );
+            /* log result */
+            cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, AT_CMD_D,
+                          -1, -1, CME_ERR_NotPresent );
+          }
+           /* setup initiated by SAT */
+          else
+          {
+            resp_data.add_content = ADD_NO_CAUSE;
+            psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
+          }
+          psaCC_FreeCtbNtry (cId);
+          return( FALSE );
+        }
+
+        if( ccr->v_cap_cnf_parms )
+        {
+          /* check bearer caps, ctb not allocated */
+        }
+
+
+        /* declare call table entry as used and the owner and status
+           of the call */
+        psaCC_ctb(cId)->calOwn     = satShrdPrm.SIMCCParm.owner;
+        psaCC_ctb(cId)->calStat    = CS_SAT_REQ;
+        psaCC_ctb(cId)->curCmd     = AT_CMD_D;
+        psaCC_ctb(cId)->curSrc     = satShrdPrm.SIMCCParm.owner;
+
+        if( !ownNotSAT )
+          psaCC_ctb(cId)->SATinv = TRUE;
+
+        /* alert user */
+        if( ownNotSAT )
+        {
+
+#ifdef FF_SAT_E
+          addPrm.chnType = SATA_CT_VOICE;
+          addPrm.chnEst  = SATA_EST_IM;
+
+          R_AT( RAT_SATA, satShrdPrm.SIMCCParm.owner )
+            ( cId+1, satShrdPrm.dur, &addPrm );
+#else
+          R_AT( RAT_SATA, satShrdPrm.SIMCCParm.owner )
+            ( cId+1, satShrdPrm.dur);
+#endif /* FF_SAT_E */
+
+          R_AT( RAT_OK, satShrdPrm.SIMCCParm.owner )
+            ( AT_CMD_D );
+          /* log result */
+          cmh_logRslt ( satShrdPrm.SIMCCParm.owner,
+                        RAT_OK, AT_CMD_D, -1, -1, -1 );
+        }
+         /* setup initiated by SAT */
+        else
+        {
+          for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+          {
+#ifdef FF_SAT_E
+            addPrm.chnType = SATA_CT_VOICE;
+            addPrm.chnEst  = SATA_EST_IM;
+
+            R_AT( RAT_SATA, idx )
+              ( cId+1, satShrdPrm.dur, &addPrm );
+#else             
+            R_AT( RAT_SATA, idx )
+              ( cId+1, satShrdPrm.dur);
+#endif 
+          }
+        }
+
+        return( !ownNotSAT );
+      }
+
+      /* --- no break, continue with next case --- */
+      /*lint -fallthrough*/
+
+    /*
+     *------------------------------------------------------------
+     * USSD allowed no modification
+     *------------------------------------------------------------
+     */
+    default:
+      TRACE_ERROR ("unknown resID in cmhSAT_ResUSSDCntrlBySIM");
+      /*lint -fallthrough*/
+    case( CCR_ALLW_NO_MDFY ):
+
+      /* check for busy SS condition */
+      if( psaSS_stbFindActSrv( NO_ENTRY ) NEQ NO_ENTRY )
+      {
+        /* respond with "error, ME currently unable to process command" */
+        resp_data.add_content = ADD_ME_USSD_BUSY;
+        psaSAT_SendTrmResp( RSLT_ME_UNAB_PROC, &resp_data );
+        return( FALSE );
+      }
+
+      /* adjust SS control string */
+      if( ccr->v_ussd_string )
+      {
+        memcpy( &(satPndSetup.ussd_str),
+                &ccr->ussd_string,
+                sizeof(T_ussd_string));
+      }
+
+      /********************************************************************************/
+      /*
+       *-------------------------------------------------------------------
+       * check if there is a USSD request pending
+       *-------------------------------------------------------------------
+       */
+      sId = psaSS_stbFindUssdReq();
+
+      if( sId EQ NO_ENTRY )
+      {
+        /* check if there is another service in progress */
+        if( psaSS_stbFindActSrv( sId ) NEQ NO_ENTRY )
+        {
+          ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_ParallelUSSD );
+          return( AT_FAIL );
+        }
+
+        /* get new service table entry */
+        sId = psaSS_stbNewEntry();
+        if( sId EQ NO_ENTRY )
+        {
+          ACI_ERR_DESC( ACI_ERR_CLASS_Ext, EXT_ERR_SrvTabFull );
+          return( AT_FAIL );
+        }
+
+        CCD_START;
+
+        MALLOC(ussdString, MAX_USSD_STRING);
+
+        /* set data coding scheme */
+        /* patch !!!!! CLB 11/12/01      */
+        if( (UBYTE)satPndSetup.ussd_str.dcs EQ 0x40 )
+        {
+          /* 0x40 means basically default alphabet...
+          yet some asian networks dont seem to accept it (although using it
+          in their own STK !!!) */
+          satPndSetup.ussd_str.dcs = 0x0F;
+        }
+        /*********************************/
+       if( utl_getAlphabetCb( (UBYTE)satPndSetup.ussd_str.dcs ) EQ 0 ) /* 7bit alphabet */
+       {
+         src_len = (UBYTE)MINIMUM( MAX_USSD_STRING, satPndSetup.ussd_str.c_ussd_str); 
+         ussdLen = utl_cvt8To7( satPndSetup.ussd_str.ussd_str,
+                             src_len,
+                             ussdString, 0 );
+         /* According to spec 23.038 section 6.1.2.3 for USSD packing, for bytes end with
+          * (8*n)-1 i.e where n is 1,2,3....i.e byte 7, 15, 23 ... to be padded 
+          * with carriage return <CR>(0xD) 
+          */
+         if ((src_len+1)%8 EQ 0)
+         {
+           ussdString[ussdLen-1] |= (0xD << 1);
+         }
+       }
+       else
+       {
+         ussdLen = satPndSetup.ussd_str.c_ussd_str;
+         memcpy(ussdString, satPndSetup.ussd_str.ussd_str, MAX_USSD_STRING);
+       }
+       psaSS_asmProcUSSDReq( (UBYTE)satPndSetup.ussd_str.dcs /*dcs*/,
+                              ussdString,
+                              ussdLen);
+       MFREE(ussdString);
+
+        /* start new transaction */
+        ssShrdPrm.stb[sId].ntryUsdFlg = TRUE;
+
+        if (ownNotSAT)   
+        {
+            ssShrdPrm.stb[sId].curCmd = AT_CMD_CUSD;
+            ssShrdPrm.stb[sId].srvOwn = satShrdPrm.SIMCCParm.owner;
+        }
+        else
+        {
+            ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+            ssShrdPrm.stb[sId].srvOwn = OWN_SAT;
+            satShrdPrm.SentUSSDid     = sId;
+        }
+        psaSS_NewTrns(sId);
+
+        if (ownNotSAT)
+        {
+          R_AT( RAT_OK, satShrdPrm.SIMCCParm.owner )
+                  ( AT_CMD_CUSD);
+
+          cmh_logRslt ( satShrdPrm.SIMCCParm.owner,
+                        RAT_OK, AT_CMD_CUSD, -1, -1, -1 );
+        }
+
+        CCD_END;
+
+        retVal = AT_EXCT;
+      }
+      else
+      {
+        CCD_START;
+
+        psaSS_asmCnfUSSDReq( (UBYTE)satPndSetup.ussd_str.dcs,
+                             satPndSetup.ussd_str.ussd_str,
+                             satPndSetup.ussd_str.c_ussd_str );
+
+        ssShrdPrm.stb[sId].ussdReqFlg = FALSE;
+
+        /* continue existing transaction */
+        psaSS_CntTrns(sId);
+
+        CCD_END;
+
+        retVal = AT_CMPL;
+      }
+    /**********************************************************************************/
+
+      if( retVal EQ AT_EXCT )
+        return( FALSE );  /* primitive not needed anymore */
+
+      if( ownNotSAT )
+      {
+        R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+              ( AT_CMD_D, CME_ERR_NotPresent );
+        /* log result */
+        cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, AT_CMD_D,
+                      -1, -1, CME_ERR_NotPresent );
+      }
+      /* setup initiated by SAT */
+      else
+      {
+        /* send SAT response */
+        resp_data.resCC = resId;
+        psaSAT_SendTrmResp( RSLT_ME_CAP, &resp_data );
+      }
+
+      return( FALSE );  /* primitive not needed anymore */
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SATR                     |
+|                            ROUTINE : cmhSAT_ResSMCntrlBySIM       |
++-------------------------------------------------------------------+
+
+  PURPOSE : Handle SIM SM  control result. Return TRUE if primitive
+            is needed for building a terminal response.
+
+*/
+
+GLOBAL BOOL cmhSAT_ResSMCntrlBySIM( UBYTE* resId, void *smcRes )
+{
+  BOOL  ownNotSAT;                      /* flags that the owner is not SAT */
+  T_smcr_allw *smcr;                    /* points to SM result */
+  T_ACI_CMGF_MOD mode;
+  UBYTE sca_buf[MAX_SMS_ADDR_DIG/2 + 2];
+  UBYTE da_buf[MAX_SMS_ADDR_DIG/2 + 2];
+  UBYTE sca_len = 0;
+  UBYTE da_len = 0;
+  T_ACI_SAT_TERM_RESP resp_data;
+  UBYTE srcId = smsShrdPrm.smsEntStat.entOwn;
+
+  TRACE_FUNCTION ("cmhSAT_ResSMCntrlBySIM()");
+
+
+  psaSAT_InitTrmResp( &resp_data );
+
+  smcr = (T_smcr_allw*)smcRes;
+
+  /* check if queued event download */
+  if (satShrdPrm.event.c_queued)
+  {
+    cmhSAT_EventDwn( -1, -1, -1);
+  }
+
+  satShrdPrm.SIMCCParm.busy = FALSE;
+
+  ownNotSAT = satShrdPrm.SIMCCParm.owner NEQ OWN_SAT;
+
+  /*
+  ** If this is a Cust1 MMI and The originator was a STK Cmd
+  */
+  if ((simShrdPrm.overall_cust_mode EQ (UBYTE)CUST_MODE_BEHAVIOUR_1) AND
+      (ownNotSAT == FALSE))
+  {
+      /*
+      ** Customised behaviour for the Cust1 MMI
+      */
+      if (*resId == CCR_NOT_ALLW)
+      {
+            /* send SAT response */
+            resp_data.add_content = ADD_CC_NOT_ALLWD;
+            psaSAT_SendTrmResp( RSLT_CC_SIM_PRM, &resp_data );
+      }
+      else
+      {
+          /*
+          ** This was a SAT initiated Request. For the Cust1 the ACI does not yet have any
+          ** actions to perform, other than the CC By SIM which has been done. So :
+          ** Send the Original STK Cmd to the MMI in a %SATI for the MMI to process.
+          **
+          ** The second action will cause the MMI to request the approriate Call Setup, SS
+          ** or USSD Request and the required Call Table entry will then be re-created.
+          */
+          cmhSAT_Cust1StkCmdInd();
+      }
+    
+      if ( (sat_mnsms_submit_req->rec_num EQ  SMS_RECORD_NOT_EXIST) OR
+           (sat_mnsms_submit_req->modify  NEQ SMS_MODIFY_NON) )
+      {
+        if (smsShrdPrm.tpdu.tp_submit NEQ NULL)
+        {
+          ACI_MFREE(smsShrdPrm.tpdu.tp_submit);
+          smsShrdPrm.tpdu.tp_submit = NULL;
+        }
+      }
+      PFREE( sat_mnsms_submit_req );
+
+      /*
+      ** Ensure that the SMS parameters are reset, so that the SMS Entity is freed to
+      ** process the command later.
+      */
+      smsShrdPrm.smsEntStat.curCmd = AT_CMD_NONE;
+      smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = CMD_SRC_NONE;
+
+      return( FALSE );  /* primitive not needed anymore */
+  }
+
+  if (smsShrdPrm.smsEntStat.curCmd EQ AT_CMD_CMSS)
+  {
+    mode = CMGF_MOD_Txt;
+  }
+#if defined MFW OR defined FF_MMI_RIV OR defined _CONC_TESTING_
+  else if (smsShrdPrm.smsEntStat.entOwn EQ CMD_SRC_LCL)
+  {
+    mode = CMGF_MOD_Txt; /* since text mode (AT+CMGF=1) is never set in MMI */
+  }
+#endif
+  else if (ownNotSAT EQ FALSE)
+  {
+    mode = CMGF_MOD_Pdu;
+  }
+  else
+  {
+    /*
+     * request current mode
+     */
+    qAT_PlusCMGF(srcId, &mode);
+  }
+
+/*
+ *----------------------------------------------------------------
+ * determine result id
+ *----------------------------------------------------------------
+ */
+  switch( *resId )
+  {
+    /*
+     *------------------------------------------------------------
+     * send message not allowed
+     *------------------------------------------------------------
+     */
+    case( CCR_NOT_ALLW ):
+       /* setup initiated by user */
+      if( ownNotSAT )
+      {
+        R_AT( RAT_CME, satShrdPrm.SIMCCParm.owner )
+          ( smsShrdPrm.smsEntStat.curCmd, CME_ERR_NotPresent );
+        /* log result */
+        cmh_logRslt ( satShrdPrm.SIMCCParm.owner, RAT_CME, smsShrdPrm.smsEntStat.curCmd,
+                      -1, -1, CME_ERR_NotPresent );
+
+        smsShrdPrm.smsEntStat.curCmd = AT_CMD_NONE;
+        smsShrdPrm.smsEntStat.entOwn = smsShrdPrm.owner = OWN_NONE;
+      }
+       /* setup initiated by SAT */
+      else
+      {
+        /* send SAT response */
+        resp_data.add_content = ADD_CC_NOT_ALLWD;
+        psaSAT_SendTrmResp( RSLT_CC_SIM_PRM, &resp_data );
+      }
+
+      if ( (sat_mnsms_submit_req->rec_num EQ  SMS_RECORD_NOT_EXIST) OR
+           (sat_mnsms_submit_req->modify  NEQ SMS_MODIFY_NON) )
+      {
+        if (smsShrdPrm.tpdu.tp_submit NEQ NULL)
+        {
+          ACI_MFREE(smsShrdPrm.tpdu.tp_submit);
+          smsShrdPrm.tpdu.tp_submit = NULL;
+        }
+      }
+      PFREE( sat_mnsms_submit_req );
+      return( FALSE );  /* primitive not needed anymore */
+
+
+    case( CCR_ALLW_WITH_MDFY ):
+      if ( smcr->v_sm_addr )
+      {
+        /*
+         * RP Service Center Address
+         */
+
+        sat_mnsms_submit_req->modify |= SMS_MODIFY_SCA;
+
+        if (mode EQ CMGF_MOD_Pdu)
+        {
+          /* PDU mode */
+          sca_len = CodeRPAddress( sca_buf,
+                                    smcr->sm_addr.c_bcdDigit,
+                                    smcr->sm_addr.noa,
+                                    smcr->sm_addr.npi,
+                                    smcr->sm_addr.bcdDigit );
+
+          cmhSAT_ModifyScaPdu( &sat_mnsms_submit_req->sms_sdu,
+                               sca_buf,
+                               sca_len );
+        }
+        else
+        {
+          /* Text mode */
+          smsShrdPrm.tpdu.sc_addr.v_ton = 1;
+          smsShrdPrm.tpdu.sc_addr.ton = smcr->sm_addr.noa;
+          smsShrdPrm.tpdu.sc_addr.v_npi = 1;
+          smsShrdPrm.tpdu.sc_addr.npi = smcr->sm_addr.npi;
+          smsShrdPrm.tpdu.sc_addr.c_num = smcr->sm_addr.c_bcdDigit;
+          memcpy(smsShrdPrm.tpdu.sc_addr.num, smcr->sm_addr.bcdDigit,
+                 smcr->sm_addr.c_bcdDigit);
+        }
+      }
+
+      if ( smcr->v_sm_addr_2)
+      {
+        /*
+         * TP Destination Address
+         */
+
+        sat_mnsms_submit_req->modify |= SMS_MODIFY_TPOA;
+
+        if (mode EQ CMGF_MOD_Pdu)
+        {
+          /* PDU  mode */
+          da_len = CodeTPAddress( da_buf,
+                                   smcr->sm_addr_2.c_bcdDigit,
+                                   smcr->sm_addr_2.noa,
+                                   smcr->sm_addr_2.npi,
+                                   smcr->sm_addr_2.bcdDigit );
+
+          cmhSAT_ModifyDaPdu( &sat_mnsms_submit_req->sms_sdu,
+                              da_buf,
+                              da_len );
+        }
+        else
+        {
+          /* Text mode */
+          smsShrdPrm.tpdu.tp_submit->tp_da.ton    = smcr->sm_addr_2.noa;
+          smsShrdPrm.tpdu.tp_submit->tp_da.npi    = smcr->sm_addr_2.npi;
+          smsShrdPrm.tpdu.tp_submit->tp_da.c_num  = smcr->sm_addr_2.c_bcdDigit;
+          smsShrdPrm.tpdu.tp_submit->tp_da.digits = smcr->sm_addr_2.c_bcdDigit;
+          memcpy(smsShrdPrm.tpdu.tp_submit->tp_da.num, smcr->sm_addr_2.bcdDigit,
+                 smcr->sm_addr_2.c_bcdDigit);
+        }
+      }
+      /* no break needed !!!! */
+      /*lint -fallthrough*/
+    case( CCR_ALLW_NO_MDFY ):
+      if( sat_mnsms_submit_req )
+      {
+        if (mode EQ CMGF_MOD_Txt) /* Text mode */
+        {
+          /* code sm here */
+          cmhSMS_codeMsg (&sat_mnsms_submit_req->sms_sdu,
+                          SMS_VT_SUBMIT,
+                          &smsShrdPrm.tpdu.sc_addr,
+                          SMS_SUBMIT,
+                          (UBYTE*)smsShrdPrm.tpdu.tp_submit);
+
+          if (smsShrdPrm.tpdu.tp_submit NEQ NULL)
+          {
+            ACI_MFREE(smsShrdPrm.tpdu.tp_submit);
+            smsShrdPrm.tpdu.tp_submit = NULL;
+          }
+        }
+
+        PSENDX (SMS, sat_mnsms_submit_req);
+      }
+      else
+        TRACE_EVENT("error provoked by SAT");
+      break;
+
+    default:
+      if ( (sat_mnsms_submit_req->rec_num EQ SMS_RECORD_NOT_EXIST) OR
+           (sat_mnsms_submit_req->modify NEQ SMS_MODIFY_NON) )
+      {
+        if (smsShrdPrm.tpdu.tp_submit NEQ NULL)
+        {
+          ACI_MFREE(smsShrdPrm.tpdu.tp_submit);
+          smsShrdPrm.tpdu.tp_submit = NULL;
+        }
+      }
+      TRACE_EVENT("wrong type of result received from SIM");
+      PFREE( sat_mnsms_submit_req );
+      return( FALSE );  /* primitive not needed anymore */
+  }
+
+return FALSE;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH                          |
+|                            ROUTINE : cmhCC_SatDTMFsent            |
++-------------------------------------------------------------------+
+
+  PURPOSE : confirmation for sent SAT DTMF
+*/
+GLOBAL void cmhCC_SatDTMFsent ( SHORT cId )
+{
+  T_CC_CALL_TBL *ctb = ccShrdPrm.ctb[cId];
+  T_ACI_SAT_TERM_RESP resp_data;
+static UBYTE          dtmf_separator_count = 0;
+
+  TRACE_FUNCTION ("cmhCC_SatDTMFsent()");
+
+  psaSAT_InitTrmResp( &resp_data );
+
+  /*
+   * Use ctb here because TI compiler 1.22e may have a problem otherwise here.
+   * See cmhCC_SndDiscRsn() for the details.
+   */  
+  if (GET_CAUSE_VALUE(ctb->nrmCs) NEQ NOT_PRESENT_8BIT AND
+      ctb->nrmCs                  NEQ MNCC_CAUSE_DTMF_START_SUCCESS)
+  {
+    TRACE_EVENT_P1("network reported error when sending DTMF: %d", ctb->nrmCs);
+    
+    psaSAT_SendTrmResp( RSLT_NTW_UNAB_PROC, &resp_data );
+    dtmf_separator_count = 0;
+    return;
+  }
+
+  if(is_digit_dtmf_separator(ccShrdPrm.dtmf.dig[ccShrdPrm.dtmf.cur]))
+  {
+    if (dtmf_separator_count EQ 0)
+    {
+      dtmf_separator_count = 1;
+      if(ctb->dtmfCmd NEQ AT_CMD_VTS)  /* this is only valid within a number to dial */
+       {
+         /* p within a number string: this is a 3 seconds pause */
+          TRACE_EVENT("DTMF pause requested: 3 seconds");
+#if defined (NEW_FRAME)
+          TIMERSTART( TDTMF_VALUE, ACI_TDTMF );
+#else
+          TIMERSTART( TDTMF_VALUE, t_dtmf_handle );
+#endif
+          ccShrdPrm.dtmf.cur++;  /* skip the DTMF seperator */
+
+          return;
+       }
+      ccShrdPrm.dtmf.cur++;  /* skip the DTMF seperator */
+    }
+  }
+  else
+  {
+    dtmf_separator_count = 0;
+  }
+
+  if (ccShrdPrm.dtmf.cur < ccShrdPrm.dtmf.cnt)
+  {
+    cmhSAT_sendDTMF ( NULL );
+  }
+  else      /* whole DTMF string has been sent */
+  {
+    ccShrdPrm.dtmf.cId = NO_ENTRY;               /* Reset cId after sending the whole DTMF string */
+    ctb->dtmfCmd = AT_CMD_NONE;
+    ctb->dtmfSrc = CMD_SRC_NONE;
+    psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );
+    dtmf_separator_count = 0;
+  }
+}
+
+#endif /* #ifdef SIM_TOOLKIT */
+/*==== EOF ========================================================*/