diff src/g23m-aci/aci/cmh_ssr.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-aci/aci/cmh_ssr.c	Sun Jul 15 04:40:46 2018 +0000
@@ -0,0 +1,2908 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GSM-PS (6147)
+|  Modul   :  CMH_SSR
++----------------------------------------------------------------------------- 
+|  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
+|             supplementary service.
++----------------------------------------------------------------------------- 
+*/ 
+
+#ifndef CMH_SSR_C
+#define CMH_SSR_C
+#endif
+
+#include "aci_all.h"
+/*==== INCLUDES ===================================================*/
+#include "aci_cmh.h"
+#include "ati_cmd.h"
+#include "aci_cmd.h"
+#include "aci_mem.h"
+
+#ifdef FAX_AND_DATA
+#include "aci_fd.h"
+#endif    /* of #ifdef FAX_AND_DATA */
+
+#include "ksd.h"
+#include "aci.h"
+#include "psa.h"
+#include "psa_ss.h"
+#include "psa_util.h"
+#include "cmh.h"
+#include "cmh_ss.h"
+
+#include "psa_cc.h"
+#ifdef SIM_TOOLKIT
+#include "psa_sat.h"
+#endif /* SIM_TOOLKIT */
+
+#include "cmh_cc.h"
+
+#ifdef FF_CPHS
+#include "cphs.h"
+#endif /* FF_CPHS */
+
+/*==== CONSTANTS ==================================================*/
+/*==== TYPES ======================================================*/
+
+/*==== EXPORT =====================================================*/
+
+/*==== PROTOTYPES =====================================================*/
+/* Implements Measure 217 */
+LOCAL void cmhSS_SSActDeact (SHORT sId, 
+                             UBYTE opCd, 
+                             T_ssInfo *ssInfo);
+/* Implements Measure 215 */
+LOCAL void cmhSS_SSRegistrated_Erased (SHORT sId,
+                                       UBYTE opCd, 
+                                       T_ssInfo *ssInfo);
+/* Implements Measure 209, 210, 214 */
+LOCAL void cmhSS_ksdCBCF_Res (SHORT sId,
+                              T_ACI_KSIR  *ksStat,
+                              T_ACI_KSD_CMD ksdCmd);
+/* Implements Measure 76 */
+LOCAL T_ACI_USSD_DATA* cmhSS_prepareUSSDRes(T_ussdArg *ussdArg, SHORT *dcs);
+/* Used in Measure 217 */
+LOCAL void cmhSS_processKSDCF (SHORT sId, UBYTE opCd, T_ssInfo *ssInfo);
+/*==== VARIABLES ==================================================*/
+EXTERN T_PCEER causeMod;
+EXTERN SHORT causeCeer;
+
+#define CF_LST_SIZE (sizeof(T_CF_FEAT)*MAX_CF_FEAT_NR)
+#define CB_LST_SIZE (sizeof(T_CB_INFO)*MAX_CB_INFO_NR)
+#define CW_LST_SIZE (sizeof(T_Cx_BSG) *MAX_CW_BSG_NR)
+#define CC_LST_SIZE (sizeof(T_CC_FEAT)*MAX_CC_FEAT_NR)
+
+#define MAX_LST_BUF (MAXIMUM(MAXIMUM(MAXIMUM(CF_LST_SIZE,CB_LST_SIZE),\
+                                     CW_LST_SIZE),\
+                             CC_LST_SIZE))
+
+LOCAL ULONG ssLstBuf[MAX_LST_BUF/sizeof(ULONG)];
+EXTERN T_ACI_CUSCFG_PARAMS cuscfgParams;
+EXTERN SHORT Ext_USSD_Res_Pending_sId;
+EXTERN T_CUSDR_EXT_USSD_RES Ext_USSD_Res_Pending;
+
+/*==== FUNCTIONS ==================================================*/
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSResultFailure        |
++-------------------------------------------------------------------+
+
+  PURPOSE : A result was received, that is corrupt.
+
+*/
+
+/* Check whether KSD returned with an error: TRUE if error, FALSE otherwise */
+LOCAL BOOL check_ksd_error( T_OWN srcId, SHORT sId, T_ACI_KSIR * ksStat )
+{
+  UBYTE err = KSD_NO_ERROR;
+
+  /* Check if this is a response generated by an error */
+  switch ( ksStat -> ksdCmd )
+  {
+    case( KSD_CMD_CF ):
+      err = ksStat->ir.rKSCF.ssErr;
+      break;
+    case( KSD_CMD_CW ):
+      err = ksStat->ir.rKSCW.ssErr;
+      break;
+    case( KSD_CMD_CB ):
+      err = ksStat->ir.rKSCB.ssErr;
+      break;
+    case( KSD_CMD_CL ):
+      err = ksStat->ir.rKSCL.ssErr;
+      break;
+    case( KSD_CMD_PWD ):
+      err = ksStat->ir.rKSPW.ssErr;
+      break;
+    case( KSD_CMD_USSD ):
+      err = ksStat->ir.rKSUS.ssErr;
+      break;
+
+  }
+  if( err NEQ KSD_NO_ERROR AND
+      srcId NEQ ((T_OWN)CMD_SRC_LCL) )  /* MFW has its own implementation regarding errors in KSD */
+  {
+    TRACE_EVENT_P1( "SS error. Code error: %d", err);
+
+    return(TRUE);
+  }
+  return(FALSE);
+}
+
+GLOBAL void cmhSS_SSResultFailure( SHORT sId )
+{
+  T_ACI_KSIR ksStat;      /* holds KS status */
+  T_OWN      owner   = ssShrdPrm.stb[sId].srvOwn;
+  T_ACI_AT_CMD      cmdBuf  = ssShrdPrm.stb[sId].curCmd;
+
+  TRACE_FUNCTION ("cmhSS_SSResultFailure()");
+
+  switch( cmdBuf )
+  {
+    case( AT_CMD_NONE ): break;
+      /*lint -e{408} */ 
+    case( KSD_CMD_CF ):
+      /*lint -e{408} */
+    case( KSD_CMD_CW ):
+      /*lint -e{408} */
+    case( KSD_CMD_CB ):
+      /*lint -e{408} */
+    case( KSD_CMD_CL ):
+      /*lint -e{408} */
+    case( KSD_CMD_PWD ):
+      /*lint -e{408} */     
+    case( KSD_CMD_USSD ):
+      
+
+      memset( &ksStat, 0, sizeof(ksStat));
+
+      cmhSS_ksdBuildErrRslt( sId, &ksStat, KSD_NO_ERROR );
+
+      if(!check_ksd_error( owner, sId, &ksStat ))
+      {
+          /*
+          ** CQ12314 : NDH : 23/9/2003
+          ** Added srcID field to ksStat to enable called entity to determine the originator of the command
+          ** and take appropriate action.  (eg to Activate Call Forwarding Icon)
+          */
+          ksStat.srcId = (T_ACI_CMD_SRC)owner;
+        
+        #if defined (MFW)
+          if (ksStat.srcId NEQ CMD_SRC_LCL)
+          {
+            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
+          }
+        #endif
+        
+        R_AT( RAT_KSIR, (T_ACI_CMD_SRC)owner )
+          ( &ksStat );
+      }
+
+      /* NO BREAK HERE... Continue... */
+      
+       /*lint -fallthrough */       
+    default:
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      if (owner > ((T_OWN)CMD_SRC_NONE) AND owner < OWN_SRC_MAX) /* Just to remove LINT warning */
+      {
+        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;
+      }
+
+      R_AT( RAT_CME, (T_ACI_CMD_SRC)owner )
+        ((T_ACI_AT_CMD)cmdBuf, CME_ERR_NotPresent );
+      cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_CME,(T_ACI_AT_CMD)cmdBuf, -1, 
+	  	                   BS_SPEED_NotPresent, CME_ERR_NotPresent );
+  }
+
+  /* set service table entry to unused */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_CLIP_Interrogated      |
++-------------------------------------------------------------------+
+
+  PURPOSE : Interrogation result is available.
+
+*/
+
+/* process result for +CLIP command */
+LOCAL void cmhSS_CLIP_Interrogated( T_OWN owner, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_CLIP_STAT clip_status;
+  
+  TRACE_FUNCTION ("cmhSS_CLIP_Interrogated()");
+
+  if( ! irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    clip_status = CLIP_STAT_Unknown;    /* if no status is present */
+  }
+  else if( irgtSS->interrogateSSRes.ssStatus & SSS_P )
+  {
+    clip_status = CLIP_STAT_Prov;       /* if service is provisioned */
+  }
+  else
+  {
+    clip_status = CLIP_STAT_NotProv;    /* else service is not provisioned */
+  }
+
+  R_AT( RAT_CLIP, (T_ACI_CMD_SRC)owner )
+    ( clip_status, NULL, NULL, MNCC_PRES_NOT_PRES, NULL, NULL, NULL );
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSInterrogated         |
++-------------------------------------------------------------------+
+
+  PURPOSE : Interrogation result is available.
+  Process result for +CDIP command
+*/
+LOCAL void cmhSS_CDIP_Interrogated( T_OWN owner, T_INTERROGATE_SS_RES *irgtSS )
+{
+   TRACE_FUNCTION ("cmhSS_CDIP_Interrogated()");
+
+ /* Following code of part is not using so it is commented but might be used in future 
+   *  so it is not removed -Rachna 
+   */ 
+
+  /* 
+    *  T_ACI_CDIP_STAT CDIP_status;
+    * 
+    * TRACE_FUNCTION ("cmhSS_CDIP_Interrogated()");
+    *
+    *if( ! irgtSS->interrogateSSRes.v_ssStatus )
+    *{
+    *CDIP_status = CDIP_STAT_Unknown;    / * if no status is present * /
+    *}
+    *else if( irgtSS->interrogateSSRes.ssStatus & SSS_P )
+    *{
+    *CDIP_status = CDIP_STAT_Prov;       / * if service is provisioned * /	
+    *}
+    *else
+    *{
+    *CDIP_status = CDIP_STAT_NotProv;    / * else service is not provisioned * /
+    *}
+    */
+   R_AT( RAT_CDIP, (T_ACI_CMD_SRC)owner )
+    ( NULL, NULL, NULL, NULL );
+
+}
+
+/* process result for +CLIR command */
+LOCAL void cmhSS_CLIR_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_CC_CMD_PRM    *pCCCmdPrm;   /* points to CC command parameters */
+  T_ACI_CLIR_STAT clir_status;
+  T_OWN           owner;
+
+  TRACE_FUNCTION ("cmhSS_CLIR_Interrogated()");
+
+  owner = ssShrdPrm.stb[sId].srvOwn;
+  pCCCmdPrm = &cmhPrm[owner].ccCmdPrm;
+
+  if( irgtSS->interrogateSSRes.v_ssStatus )   /* if status is present */
+  {
+    if( irgtSS->interrogateSSRes.ssStatus & SSS_P )     /* if service is provisioned */
+    {
+      clir_status = CLIR_STAT_Permanent;
+    }
+    else                                                /* else service is not provisioned */
+    {
+      clir_status = CLIR_STAT_NotProv;
+    }
+  }
+  else if( ! irgtSS->interrogateSSRes.v_cliRestrictionInfo          OR
+           ! irgtSS->interrogateSSRes.cliRestrictionInfo.v_ssStatus )    /* if no status is present */
+  {
+    clir_status = CLIR_STAT_Unknown;
+  }
+  else if( irgtSS->interrogateSSRes.cliRestrictionInfo.ssStatus & SSS_P )  /* if service is provisioned */
+  {
+    /* check the restriction info */
+    if( irgtSS->interrogateSSRes.cliRestrictionInfo.v_cliRestrictionOption )
+    {
+      switch( irgtSS->
+                interrogateSSRes.cliRestrictionInfo.cliRestrictionOption )
+      {
+      case( CLIR_OPT_PERMANENT ):
+        clir_status = CLIR_STAT_Permanent;
+        break;
+        
+      case( CLIR_OPT_TEMPORARY ):
+        clir_status = CLIR_STAT_RestrictTemp;
+        break;
+        
+      case( CLIR_OPT_ALLOWED ):
+        clir_status = CLIR_STAT_AllowTemp;
+        break;
+        
+      default:
+        clir_status = CLIR_STAT_Unknown;
+      }
+    }
+    /* else no restriction info present */
+    else
+    {
+      clir_status = CLIR_STAT_Unknown;
+    }
+  }
+  else                                                                     /* else service is not provisioned */
+  {
+    clir_status = CLIR_STAT_NotProv;
+  }
+
+  /* sends indication to user */
+  R_AT( RAT_CLIR, (T_ACI_CMD_SRC)owner )
+        ( pCCCmdPrm -> CLIRmode, clir_status );
+}
+
+
+/* process result for +COLP command */
+LOCAL void cmhSS_COLP_Interrogated( T_OWN owner, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_COLP_STAT colp_status;
+  
+  TRACE_FUNCTION ("cmhSS_COLP_Interrogated()");
+
+  if( ! irgtSS->interrogateSSRes.v_ssStatus )             /* if no status is present */
+  {
+    colp_status = COLP_STAT_Unknown;
+  }
+  else if( irgtSS->interrogateSSRes.ssStatus & SSS_P )    /* if service is provisioned */
+  {
+    colp_status = COLP_STAT_Prov;
+  }
+  else                                                    /* else service is not provisioned */
+  {
+    colp_status = COLP_STAT_NotProv;
+  }
+
+  R_AT( RAT_COLP,(T_ACI_CMD_SRC)owner )
+    ( colp_status, NULL, NULL, NULL, NULL, NULL );
+}
+
+/* process result for +COLR command */
+LOCAL void cmhSS_COLR_Interrogated( T_OWN owner, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_COLR_STAT colr_status;
+  
+  TRACE_FUNCTION ("cmhSS_COLR_Interrogated()");
+
+  if( ! irgtSS->interrogateSSRes.v_ssStatus )             /* if no status is present */
+  {
+    colr_status = COLR_STAT_Unknown;
+  }
+  else if( irgtSS->interrogateSSRes.ssStatus & SSS_P )    /* if service is provisioned */
+  {
+    colr_status = COLR_STAT_Prov;
+  }
+  else                                                    /* else service is not provisioned */
+  {
+    colr_status = COLR_STAT_NotProv;
+  }
+
+  R_AT( RAT_COLR, (T_ACI_CMD_SRC)owner )
+    ( colr_status );
+}
+
+
+LOCAL void cmhSS_CLCK_CCWA_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS, T_ACI_AT_CMD cmdBuf )
+{
+  T_ACI_CLSSTAT   srvStat;     /* holds service status */
+  USHORT          queried_classes = ssShrdPrm.stb[sId].ClassType; /* classes queried by the user */
+  T_OWN           owner           = ssShrdPrm.stb[sId].srvOwn;
+  
+  srvStat.status     = STATUS_NotPresent; /* Lint */
+  srvStat.class_type = CLASS_NotPresent;  /* Lint */
+
+  srvStat.class_type = CLASS_NotPresent;
+
+/* if status is present, service is provisioned but not active for
+  any basic service type ref.GSM 04.83/1.6/Ver.5.0.0 and
+  ref.GSM 04.88/1.5/Ver.5.0.0 */
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    srvStat.status = (irgtSS->interrogateSSRes.ssStatus & SSS_A)? 
+              STATUS_Active : STATUS_NotActive;
+    if ( cmdBuf EQ AT_CMD_CLCK )
+      srvStat.class_type = CLASS_VceDatFaxSms;
+    else
+      srvStat.class_type = CLASS_VceDatFax;
+  }
+  
+  /* if BS group list is present, the service is active for the
+  containing BS/TS ref.GSM 04.83/1.6/Ver.5.0.0 and
+  ref.GSM 04.88/1.5/Ver.5.0.0 */
+  else if( irgtSS->interrogateSSRes.v_basicServiceGroupList )
+  {
+    /* no basic services present */
+    if( irgtSS->interrogateSSRes.basicServiceGroupList.c_basicServiceGroupList_value EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO BASIC SERVICES IN BASIC SERVICE LIST");
+    }
+    
+    /* basic service list present */
+    else
+    {
+      srvStat.status = STATUS_Active;
+      srvStat.class_type =
+        cmhSS_GetClassLst( &irgtSS->interrogateSSRes.basicServiceGroupList );
+
+      TRACE_EVENT_P1("srvStat.class_type: %d",srvStat.class_type);
+    }
+  }
+
+  /* filter answer before sending message */
+  /* addition here because class values follow recommendation where each
+  class is bit represented */
+
+  TRACE_EVENT_P1("userClass: %d", queried_classes);
+
+  if( (srvStat.class_type & queried_classes) EQ 0 )
+  {
+    /* means classes queried by user are not active !! */
+    srvStat.status = STATUS_NotActive;
+    srvStat.class_type = (T_ACI_CLASS)queried_classes;
+  }
+  else
+  {
+    srvStat.class_type = (T_ACI_CLASS)(srvStat.class_type &((T_ACI_CLASS)queried_classes));
+  }
+
+  switch( cmdBuf)
+  {
+  case( AT_CMD_CCWA ):
+    R_AT( RAT_CCWA, (T_ACI_CMD_SRC)owner )
+      ( &srvStat, NULL, NULL, MNCC_PRES_NOT_PRES, CLASS_NotPresent, NULL );
+    break;
+    
+  case( AT_CMD_CLCK ):
+    R_AT( RAT_CLCK, (T_ACI_CMD_SRC)owner )
+      ( &srvStat );
+    break;
+  }
+}
+
+/* process result for +CLCK command */
+LOCAL void cmhSS_CLCK_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  TRACE_FUNCTION ("cmhSS_CLCK_Interrogated()");
+
+  cmhSS_CLCK_CCWA_Interrogated( sId, irgtSS, AT_CMD_CLCK );
+}
+
+/* process result for +CCWA command */
+LOCAL void cmhSS_CCWA_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  TRACE_FUNCTION ("cmhSS_CCWA_Interrogated()");
+
+  cmhSS_CLCK_CCWA_Interrogated( sId, irgtSS, AT_CMD_CCWA );
+}
+
+/* process result for +CCFC command */
+LOCAL void cmhSS_CCFC_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_CCFC_SET  ccfcStat;    /* holds CCFC service status */
+  UBYTE           idx;         /* holds list index */
+  UBYTE           active_class_list = 0; /* list of active classes */
+  USHORT          queried_classes = ssShrdPrm.stb[sId].ClassType; /* classes queried by the user */
+  T_OWN           owner           = ssShrdPrm.stb[sId].srvOwn;
+
+  TRACE_FUNCTION ("cmhSS_CCFC_Interrogated()");
+
+  /* if status is present, service is provisioned but not active for
+  any basic service type ref.GSM 04.82/x.6/Ver.5.0.0 */
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    ccfcStat.clsstat.status = (irgtSS->interrogateSSRes.ssStatus & SSS_A)?
+           STATUS_Active:STATUS_NotActive;
+    ccfcStat.number[0]  = 0x0;
+    ccfcStat.type.npi   = NPI_NotPresent;
+    ccfcStat.type.ton   = TON_NotPresent;
+    ccfcStat.subaddr[0] = 0x0;
+    ccfcStat.satype.tos = TOS_NotPresent;
+    ccfcStat.satype.oe  = OE_NotPresent;
+    ccfcStat.time       = ACI_NumParmNotPresent;
+
+    ccfcStat.clsstat.class_type = (T_ACI_CLASS)(CLASS_VceDatFax & ((T_ACI_CLASS)queried_classes));
+
+    R_AT( RAT_CCFC, (T_ACI_CMD_SRC)owner )
+      ( &ccfcStat );
+
+    return;
+
+  }
+  
+  /* if forwarding feature list is present, decode the forwarding
+  information */
+  else if( irgtSS->interrogateSSRes.v_forwardingFeatureList )
+  {
+    /* no forwarding features present */
+    if( irgtSS->interrogateSSRes.forwardingFeatureList.c_ff EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO BASIC SERVICES IN BASIC SERVICE LIST");
+    }
+    
+    /* fowarding feature list present */
+    else
+    {
+      for( idx=0;
+      idx < irgtSS->interrogateSSRes.forwardingFeatureList.c_ff;
+      idx++ )
+      {
+        ccfcStat.clsstat.class_type =
+            cmhSS_GetClass( &irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+                              basicService );
+
+        if( !irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].v_ssStatus )
+        {
+          ccfcStat.clsstat.status  = STATUS_NotPresent;
+        }
+        else if( irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].ssStatus
+          & SSS_A )
+        {
+          ccfcStat.clsstat.status  = STATUS_Active;
+        }
+        else
+        {
+          ccfcStat.clsstat.status  = STATUS_NotActive;
+        }
+        
+        if( irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+          v_forwardedToNumber AND
+          irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+          forwardedToNumber.c_bcdDigit )
+        {
+          utl_BCD2DialStr
+            (irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+            forwardedToNumber.bcdDigit,
+            ccfcStat.number,
+            irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+            forwardedToNumber.c_bcdDigit);
+          
+          ccfcStat.type.npi = (T_ACI_TOA_NPI)irgtSS->interrogateSSRes.forwardingFeatureList.
+            ff[idx].forwardedToNumber.npi;
+          ccfcStat.type.ton = (T_ACI_TOA_TON)irgtSS->interrogateSSRes.forwardingFeatureList.
+            ff[idx].forwardedToNumber.noa;
+        }
+        else
+        {
+          ccfcStat.number[0]  = 0x0;
+          ccfcStat.type.npi   = NPI_NotPresent;
+          ccfcStat.type.ton   = TON_NotPresent;
+        }
+        
+        if( irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+          v_forwardedToSubaddress AND
+          irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+          forwardedToSubaddress.c_subadr_str)
+        {
+          utl_BCD2DialStr
+            (irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+            forwardedToSubaddress.subadr_str,
+            ccfcStat.subaddr,
+            irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+            forwardedToSubaddress.c_subadr_str);
+          
+          ccfcStat.satype.tos = (T_ACI_TOS_TOS)irgtSS->interrogateSSRes.
+            forwardingFeatureList.ff[idx].
+            forwardedToSubaddress.tos;
+          ccfcStat.satype.oe  = (T_ACI_TOS_OE)irgtSS->interrogateSSRes.
+            forwardingFeatureList.ff[idx].
+            forwardedToSubaddress.oei;
+        }
+        else
+        {
+          ccfcStat.subaddr[0] = 0x0;
+          ccfcStat.satype.tos = TOS_NotPresent;
+          ccfcStat.satype.oe  = OE_NotPresent;
+        }
+        
+        if( irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+          v_noReplyConditionTime)
+          ccfcStat.time = irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
+          noReplyConditionTime;
+        else
+          ccfcStat.time = ACI_NumParmNotPresent;
+
+        TRACE_EVENT_P1("network class: %d", ccfcStat.clsstat.class_type);
+        TRACE_EVENT_P1("userClass: %d", queried_classes);
+        TRACE_EVENT_P1("status: %d", ccfcStat.clsstat.status);
+        
+        if( ccfcStat.clsstat.status EQ STATUS_Active )
+        {
+          active_class_list += ccfcStat.clsstat.class_type;
+          
+          if( (ccfcStat.clsstat.class_type & queried_classes) NEQ 0 )
+          /* filter what the user has queried */
+          {
+            R_AT( RAT_CCFC,(T_ACI_CMD_SRC)owner )
+              ( &ccfcStat );
+          }
+        }
+      }
+
+      if( (active_class_list EQ 0)   /* means there are no active classes */
+        OR
+          ((active_class_list & queried_classes) EQ 0) /* means user querried unactive classes */ )
+      {
+        ccfcStat.clsstat.class_type = (T_ACI_CLASS)(CLASS_VceDatFax & (T_ACI_CLASS)queried_classes);
+        ccfcStat.clsstat.status  = STATUS_NotActive;
+
+        R_AT( RAT_CCFC, (T_ACI_CMD_SRC)owner )
+          ( &ccfcStat );
+      }
+    }
+  }
+}
+
+/* process result for %CCBS command */
+LOCAL void cmhSS_CCBS_Interrogated( T_OWN owner, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_CCBS_STAT ccbsStat;    /* holds CCBS service status */
+  UBYTE           idx;         /* holds list index */
+  T_ACI_CCBS_SET  ccbsSet;     /* holds CCBS service status */
+
+  TRACE_FUNCTION ("cmhSS_CCBS_Interrogated()");
+
+  /* if present, decode the CCBS information */
+  if( irgtSS->interrogateSSRes.v_cliRestrictionInfo )
+  {
+    if( !irgtSS->interrogateSSRes.cliRestrictionInfo.v_ssStatus )
+      ccbsStat = CCBS_STAT_NotPresent;
+    else
+    {
+      if(!(irgtSS->interrogateSSRes.cliRestrictionInfo.ssStatus
+        & SSS_P))
+        ccbsStat  = CCBS_STAT_NotProvisioned;
+      else if( irgtSS->interrogateSSRes.cliRestrictionInfo.ssStatus
+        & SSS_A )
+        ccbsStat = CCBS_STAT_Active;
+      else
+        ccbsStat  = CCBS_STAT_Provisioned;
+    }
+    
+    /* no CCBS features present */
+    if( irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.c_ccbsf EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO FEATURES IN CCBS FEATURE LIST");
+      
+      cmhrat_ccbs( (UBYTE)owner, CCBS_IND_IrgtResult, ccbsStat, NULL );
+    }
+    
+    /* CCBS feature list present */
+    else
+    {
+      ccbsStat = CCBS_STAT_Active;
+      
+      for( idx=0;
+      idx < irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.c_ccbsf;
+      idx++ )
+      {
+        if( irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+          v_b_subscriberNumber AND
+          irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+          b_subscriberNumber.c_bcdDigit )
+        {
+          utl_BCD2DialStr
+            (irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+            b_subscriberNumber.bcdDigit,
+            ccbsSet.number,
+            irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+            b_subscriberNumber.c_bcdDigit);
+          
+          ccbsSet.type.npi = (T_ACI_TOA_NPI)irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
+            ccbsf[idx].b_subscriberNumber.npi;
+          ccbsSet.type.ton = (T_ACI_TOA_TON)irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
+            ccbsf[idx].b_subscriberNumber.noa;
+        }
+        else
+        {
+          ccbsSet.number[0]  = 0x0;
+          ccbsSet.type.npi   = NPI_NotPresent;
+          ccbsSet.type.ton   = TON_NotPresent;
+        }
+        
+        if( irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+          v_b_subscriberSubaddress AND
+          irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+          b_subscriberSubaddress.c_subadr_str )
+        {
+          utl_BCD2DialStr
+            (irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].b_subscriberSubaddress.subadr_str,
+            ccbsSet.subaddr,
+            irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].b_subscriberSubaddress.c_subadr_str);
+          
+          ccbsSet.satype.tos = (T_ACI_TOS_TOS)irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
+            ccbsf[idx].b_subscriberSubaddress.tos;
+          ccbsSet.satype.oe  = (T_ACI_TOS_OE)irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
+            ccbsf[idx].b_subscriberSubaddress.oei;
+        }
+        else
+        {
+          ccbsSet.subaddr[0] = 0x0;
+          ccbsSet.satype.tos = TOS_NotPresent;
+          ccbsSet.satype.oe  = OE_NotPresent;
+        }
+        
+        if( irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+          v_ccbsIndex )
+          ccbsSet.idx = irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
+          ccbsf[idx].ccbsIndex;
+        else
+          ccbsSet.idx = ACI_NumParmNotPresent;
+        
+        if( irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].
+          v_basicServiceGroup )
+          ccbsSet.class_type =
+          cmhSS_GetClass( (T_basicService*)&irgtSS->interrogateSSRes.cliRestrictionInfo.
+          ccbsFeatureList.ccbsf[idx].basicServiceGroup );
+        else
+          ccbsSet.class_type = CLASS_NotPresent;
+        
+        ccbsSet.alrtPtn = ALPT_NotPresent;
+        
+        cmhrat_ccbs( (UBYTE)owner, CCBS_IND_IrgtResult, ccbsStat, &ccbsSet );
+      }
+    }
+  }
+}
+
+/* process result for KSD CF command */
+LOCAL void cmhSS_KSDCF_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_KSIR      ksStat;      /* holds KS status */
+  T_CF_FEAT      *cfFeat;      /* points to CF feature list element */
+
+
+  TRACE_FUNCTION ("cmhSS_KSDCF_Interrogated()");
+
+  cfFeat = (T_CF_FEAT *)ssLstBuf;
+  memset( &ksStat, 0, sizeof(ksStat));
+  
+  ksStat.ksdCmd = KSD_CMD_CF;
+  ksStat.ir.rKSCF.opCd  = KSD_OP_IRGT;
+  ksStat.ir.rKSCF.ssCd  = ssShrdPrm.stb[sId].ssCode;
+  ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;
+  
+  /* if status is present, service is provisioned but not active for
+  any basic service type ref.GSM 04.82/x.6/Ver.5.0.0 */
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    ksStat.ir.rKSCF.c_cfFeatLst = 1;
+    ksStat.ir.rKSCF.cfFeatLst   = cfFeat;
+    
+    cfFeat->ssSt = irgtSS->interrogateSSRes.ssStatus;
+    cfFeat->bsTp = KSD_BS_TP_None;
+    cfFeat->bsCd = KSD_BS_TeleBearerUnknown;
+    
+    cfFeat->npi    = 0xFF;
+    cfFeat->ton    = 0xFF;
+    cfFeat->tos    = 0xFF;
+    cfFeat->oe     = 0xFF;
+    cfFeat->time   = 0xFF;
+  }
+  
+  /* if forwarding number present, copy the number parameters */
+  else if( irgtSS->interrogateSSRes.v_forwardedToNumber )
+  {
+    ksStat.ir.rKSCF.c_cfFeatLst = 1;
+    ksStat.ir.rKSCF.cfFeatLst   = cfFeat;
+    
+    cfFeat->ssSt = KSD_ST_NOT_VALID;
+    cfFeat->bsTp = KSD_BS_TP_None;
+    cfFeat->bsCd = KSD_BS_TeleBearerUnknown;
+    
+    if( irgtSS->interrogateSSRes.forwardedToNumber.c_bcdDigit )
+    {
+      utl_BCD2DialStr
+        (irgtSS->interrogateSSRes.forwardedToNumber.bcdDigit,
+        (char*)cfFeat->num,
+        irgtSS->interrogateSSRes.forwardedToNumber.c_bcdDigit);
+      
+      cfFeat->npi = irgtSS->interrogateSSRes.forwardedToNumber.npi;
+      cfFeat->ton = irgtSS->interrogateSSRes.forwardedToNumber.noa;
+    }
+    else
+    {
+      cfFeat->npi = 0xFF;
+      cfFeat->ton = 0xFF;
+    }
+    
+    cfFeat->tos  = 0xFF;
+    cfFeat->oe   = 0xFF;
+    cfFeat->time = 0xFF;
+  }
+  
+  /* if forwarding feature list is present, decode the forwarding
+  information */
+  else if( irgtSS->interrogateSSRes.v_forwardingFeatureList )
+  {
+    /* no forwarding features present */
+    if( irgtSS->interrogateSSRes.forwardingFeatureList.c_ff EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO BASIC SERVICES IN BASIC SERVICE LIST");
+    }
+    
+    /* fowarding feature list present */
+    else
+    {
+      ksStat.ir.rKSCF.cfFeatLst   = cfFeat;
+      
+      ksStat.ir.rKSCF.c_cfFeatLst =
+        cmhSS_ksdFillFwdFeatList( &irgtSS->interrogateSSRes.forwardingFeatureList,
+        cfFeat );
+    }
+  }
+  /* Implements Measure 209, 210, 214 */
+   cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_NONE); 
+}
+
+/* process result for KSD CB command */
+LOCAL void cmhSS_KSDCB_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_CB_INFO     * cbInfo;      /* points to CB information element */
+  T_ACI_KSIR      ksStat;      /* holds KS status */
+  UBYTE           lstSpce;     /* holds list space */
+  UBYTE           idx;         /* holds list index */
+
+  TRACE_FUNCTION ("cmhSS_KSDCB_Interrogated()");
+
+  cbInfo = (T_CB_INFO *)ssLstBuf;
+  memset( &ksStat, 0, sizeof(ksStat));
+  
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+  
+  ksStat.ksdCmd = KSD_CMD_CB;
+  ksStat.ir.rKSCB.opCd  = KSD_OP_IRGT;
+  ksStat.ir.rKSCB.ssCd  = ssShrdPrm.stb[sId].ssCode;
+  ksStat.ir.rKSCB.ssErr = KSD_NO_ERROR;
+  
+  /* if status is present, service is provisioned but not active for
+  any basic service type ref.GSM 04.83/1.6/Ver.5.0.0 and
+  ref.GSM 04.88/1.5/Ver.5.0.0 */
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    ksStat.ir.rKSCB.c_cbInfoLst = 1;
+    ksStat.ir.rKSCB.cbInfoLst   = cbInfo;
+    cbInfo->ssSt = irgtSS->interrogateSSRes.ssStatus;
+    cbInfo->bsTp = KSD_BS_TP_None;
+    cbInfo->bsCd = KSD_BS_TeleBearerUnknown;
+  }
+  
+  /* if BS group list is present, the service is active for the
+  containing BS/TS ref.GSM 04.83/1.6/Ver.5.0.0 and
+  ref.GSM 04.88/1.5/Ver.5.0.0 */
+  else if( irgtSS->interrogateSSRes.v_basicServiceGroupList )
+  {
+    /* no basic services present */
+    if( irgtSS->interrogateSSRes.basicServiceGroupList.c_basicServiceGroupList_value EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO BASIC SERVICES IN BASIC SERVICE LIST");
+    }
+    
+    /* basic service list present */
+    else
+    {
+      TRACE_EVENT("Basic service list is present: Status is SET for these services");
+      
+      ksStat.ir.rKSCB.cbInfoLst = cbInfo;
+      
+      lstSpce = MAX_CB_INFO_NR;
+      
+      for( idx=0;
+      idx < irgtSS->interrogateSSRes.basicServiceGroupList.c_basicServiceGroupList_value
+                   AND lstSpce;
+      idx++ )
+      {
+        if (irgtSS->interrogateSSRes.basicServiceGroupList.
+                   basicServiceGroupList_value[idx].v_teleservice)
+        {
+          cbInfo->bsCd = irgtSS->interrogateSSRes.basicServiceGroupList.
+                basicServiceGroupList_value[idx].teleservice;
+          cbInfo->bsTp = KSD_BS_TP_Tele; 
+          cbInfo->ssSt = KSD_ST_A;
+          cbInfo++;
+          lstSpce--;
+        }
+        if (irgtSS->interrogateSSRes.basicServiceGroupList.
+                   basicServiceGroupList_value[idx].v_bearerService)
+        {
+          cbInfo->bsCd = irgtSS->interrogateSSRes.basicServiceGroupList.
+                 basicServiceGroupList_value[idx].bearerService;
+          cbInfo->bsTp = KSD_BS_TP_Bearer;
+          cbInfo->ssSt = KSD_ST_A;
+          cbInfo++;
+          lstSpce--;
+        }
+      }
+      
+      ksStat.ir.rKSCB.c_cbInfoLst = MAX_CB_INFO_NR - lstSpce;
+    }
+  }
+  /* Implements Measure 209, 210, 214 */
+   cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_NONE); 
+}
+
+/* process result for KSD CW command */
+LOCAL void cmhSS_KSDCW_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_KSIR      ksStat;      /* holds KS status */
+  T_Cx_BSG      * cxBSG;       /* points to Cx basic service group element */
+  TRACE_FUNCTION ("cmhSS_KSDCW_Interrogated()");
+
+  cxBSG = (T_Cx_BSG *)ssLstBuf;
+  memset( &ksStat, 0, sizeof(ksStat));
+  
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+  
+  ksStat.ksdCmd = KSD_CMD_CW;
+  ksStat.ir.rKSCW.opCd  = KSD_OP_IRGT;
+  ksStat.ir.rKSCW.ssCd  = ssShrdPrm.stb[sId].ssCode;
+  ksStat.ir.rKSCW.ssErr = KSD_NO_ERROR;
+
+  ksStat.ir.rKSCW.ssSt = KSD_ST_NOT_VALID;
+  
+  /* if status is present, service is provisioned but not active for
+  any basic service type ref.GSM 04.83/1.6/Ver.5.0.0 and
+  ref.GSM 04.88/1.5/Ver.5.0.0 */
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    ksStat.ir.rKSCW.ssSt = irgtSS->interrogateSSRes.ssStatus;
+    ksStat.ir.rKSCW.c_cwBSGLst = 1;
+    ksStat.ir.rKSCW.cwBSGLst   = cxBSG;
+    cxBSG->bsTp = KSD_BS_TP_None;
+    cxBSG->bsCd = KSD_BS_TeleBearerUnknown;
+  }
+  
+  /* if BS group list is present, the service is active for the
+  containing BS/TS ref.GSM 04.83/1.6/Ver.5.0.0 and
+  ref.GSM 04.88/1.5/Ver.5.0.0 */
+  else if( irgtSS->interrogateSSRes.v_basicServiceGroupList )
+  {
+    /* no basic services present */
+    if( irgtSS->interrogateSSRes.basicServiceGroupList.c_basicServiceGroupList_value EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO BASIC SERVICES IN BASIC SERVICE LIST");
+    }
+    
+    /* basic service list present */
+    else
+    {
+      ksStat.ir.rKSCW.ssSt = KSD_ST_A;
+      ksStat.ir.rKSCW.cwBSGLst = cxBSG;
+      
+      ksStat.ir.rKSCW.c_cwBSGLst =
+        cmhSS_ksdFillBSGList ( &irgtSS->interrogateSSRes.basicServiceGroupList,
+        cxBSG );
+    }
+  }
+  /* Implements Measure 209, 210, 214 */
+   cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_NONE); 
+}
+
+/* process result for KSD CL command */
+LOCAL void cmhSS_KSDCL_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_KSIR      ksStat;      /* holds KS status */
+  T_CC_CMD_PRM    *pCCCmdPrm;   /* points to CC command parameters */
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+  TRACE_FUNCTION ("cmhSS_KSDCL_Interrogated()");
+
+  pCCCmdPrm = &cmhPrm[owner].ccCmdPrm;
+
+  ksStat.ir.rKSCL.mode = pCCCmdPrm -> CLIRmode;
+  
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+  
+  ksStat.ksdCmd = KSD_CMD_CL;
+  ksStat.ir.rKSCL.opCd  = KSD_OP_IRGT;
+  ksStat.ir.rKSCL.ssCd  = ssShrdPrm.stb[sId].ssCode;
+  ksStat.ir.rKSCL.ssErr = KSD_NO_ERROR;
+  
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    ksStat.ir.rKSCL.ssSt = irgtSS->interrogateSSRes.ssStatus;
+  }
+  
+  if( irgtSS->interrogateSSRes.v_cliRestrictionInfo )
+  {
+    ksStat.ir.rKSCL.ssSt =
+      (irgtSS->interrogateSSRes.cliRestrictionInfo.v_ssStatus)?
+      irgtSS->interrogateSSRes.cliRestrictionInfo.ssStatus:
+    (U8)KSD_ST_NOT_VALID;
+    
+    ksStat.ir.rKSCL.clirOpt =
+      (irgtSS->interrogateSSRes.cliRestrictionInfo.v_cliRestrictionOption)?
+      irgtSS->interrogateSSRes.cliRestrictionInfo.cliRestrictionOption:
+    (U8)KSD_CO_NOT_VALID;
+  }
+  /* Implements Measure 209, 210, 214 */
+   cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_NONE); 
+}
+
+/* process result for KSD CCBS command */
+LOCAL void cmhSS_KSDCCBS_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_KSIR      ksStat;      /* holds KS status */
+  T_CC_FEAT     * ccFeat;      /* points to CC feature list element */
+  TRACE_FUNCTION ("cmhSS_KSDCCBS_Interrogated()");
+
+  ccFeat = (T_CC_FEAT *)ssLstBuf;
+  memset( &ksStat, 0, sizeof(ksStat));
+  
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+  
+  ksStat.ksdCmd = KSD_CMD_CCBS;
+  ksStat.ir.rKSCF.opCd  = KSD_OP_IRGT;
+  ksStat.ir.rKSCF.ssCd  = ssShrdPrm.stb[sId].ssCode;
+  ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;
+  
+  /* if present, decode the CCBS information */
+  if( irgtSS->interrogateSSRes.v_cliRestrictionInfo )
+  {
+    ksStat.ir.rKSCL.ssSt =
+      (irgtSS->interrogateSSRes.cliRestrictionInfo.v_ssStatus)?
+      irgtSS->interrogateSSRes.cliRestrictionInfo.ssStatus:
+    (U8)KSD_ST_NOT_VALID;
+    
+    /* no CCBS features present */
+    if( irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.c_ccbsf EQ 0 )
+    {
+      TRACE_EVENT("UNEXP: NO FEATURES IN CCBS FEATURE LIST");
+    }
+    
+    /* CCBS feature list present */
+    else
+    {
+      ksStat.ir.rKSCC.ccFeatLst   = ccFeat;
+      
+      ksStat.ir.rKSCC.c_ccFeatLst =
+        cmhSS_ksdFillCCBSFeatList( &irgtSS->interrogateSSRes.cliRestrictionInfo.
+        ccbsFeatureList,
+        ccFeat );
+    }
+  }
+   /* Implements Measure 209, 210, 214 */
+   cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_NONE);
+}
+
+LOCAL void cmhSS_CNAP_Interrogated( T_OWN owner, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_ACI_CNAP_STATUS status = CNAP_SERVICE_STATUS_UNKNOWN;
+  
+  TRACE_FUNCTION ("cmhSS_CNAP_Interrogated()");
+
+  if( irgtSS->interrogateSSRes.v_ssStatus )
+  {
+    TRACE_EVENT("service status information present");
+    status = (irgtSS->interrogateSSRes.ssStatus & SSS_P)? CNAP_SERVICE_PROVISIONED : CNAP_SERVICE_NOT_PROVISIONED;
+  }
+
+  R_AT( RAT_CNAP, (T_ACI_CMD_SRC)owner )
+      ( NULL, status );
+}
+  
+GLOBAL void cmhSS_SSInterrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS )
+{
+  T_SS_CMD_PRM  *pSSCmdPrm;   /* points to SS command parameters */
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+  USHORT          cmdBuf = ssShrdPrm.stb[sId].curCmd;
+
+  TRACE_FUNCTION ("cmhSS_SSInterrogated()");
+
+  pSSCmdPrm = &cmhPrm[owner].ssCmdPrm;
+
+  /* check for command context */
+  switch( cmdBuf )
+  {
+    case( AT_CMD_CLIP ):
+      cmhSS_CLIP_Interrogated( owner, irgtSS );
+      break;
+
+    case( AT_CMD_CDIP ):
+      cmhSS_CDIP_Interrogated( owner, irgtSS );
+      break;
+
+    case( AT_CMD_CLIR ):
+      cmhSS_CLIR_Interrogated( sId, irgtSS );
+      break;
+
+    case( AT_CMD_COLP ):
+      cmhSS_COLP_Interrogated( owner, irgtSS );
+      break;
+
+    case( AT_CMD_COLR ):
+      cmhSS_COLR_Interrogated( owner, irgtSS );
+      break;
+
+    case( AT_CMD_CCWA ):
+      /* if the service is not provisioned by the network, an error component was received.
+         This is not handled here, see cmhSS_ErrorReturn() */
+      cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)); 
+      cmhSS_CCWA_Interrogated( sId, irgtSS );
+      break;
+    
+    case( AT_CMD_CLCK ):
+      /* if the service is not provisioned by the network, an error component was received.
+         This is not handled here, see cmhSS_ErrorReturn() */
+      cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)); 
+      cmhSS_CLCK_Interrogated( sId, irgtSS );
+      break;
+
+    case( AT_CMD_CCFC ):
+      cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)); 
+      /* if the service is not provisioned by the network, an error component was received.
+         This is not handled here, see cmhSS_ErrorReturn() */
+      cmhSS_CCFC_Interrogated( sId, irgtSS );
+      break;
+
+    case( AT_CMD_CCBS ):
+      cmhSS_CCBS_Interrogated( owner, irgtSS );
+      break;
+   
+    /* process result for KSD CF command */
+    case( KSD_CMD_CF ):
+      cmhSS_KSDCF_Interrogated( sId, irgtSS );
+      break;
+
+    case( KSD_CMD_CB ):
+      cmhSS_KSDCB_Interrogated( sId, irgtSS );
+      break;
+
+    case( KSD_CMD_CW ):
+      cmhSS_KSDCW_Interrogated( sId, irgtSS );
+      break;
+
+    case( KSD_CMD_CL ):
+      cmhSS_KSDCL_Interrogated( sId, irgtSS );
+      break;
+
+    case( KSD_CMD_CCBS ):
+      cmhSS_KSDCCBS_Interrogated( sId, irgtSS );
+      break;
+
+    case( AT_CMD_CNAP ):
+      cmhSS_CNAP_Interrogated( owner, irgtSS );
+      break;
+  }
+
+  /* set service table entry to unused */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+
+  R_AT( RAT_OK, (T_ACI_CMD_SRC)owner )
+    ( (T_ACI_AT_CMD)cmdBuf );
+  cmh_logRslt( (T_ACI_CMD_SRC)owner, RAT_OK,(T_ACI_AT_CMD)cmdBuf, -1, 
+  	                  BS_SPEED_NotPresent,CME_ERR_NotPresent );
+
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSRegistered           |
++-------------------------------------------------------------------+
+
+  PURPOSE : SS registration result is available.
+
+*/
+
+GLOBAL void cmhSS_SSRegistrated( SHORT sId,
+                                 T_REGISTER_SS_RES *regSS )
+{
+  /* Implements Measure 215 */
+  TRACE_FUNCTION ("cmhSS_SSRegistrated()");
+  cmhSS_SSRegistrated_Erased( sId, KSD_OP_REG, &regSS->ssInfo );
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSErased               |
++-------------------------------------------------------------------+
+
+  PURPOSE : SS erasure result is available.
+
+*/
+
+GLOBAL void cmhSS_SSErased( SHORT sId,
+                            T_ERASE_SS_RES *ersSS )
+{
+  /* Implements Measure 215 */
+
+  TRACE_FUNCTION ("cmhSS_SSErased()");
+  cmhSS_SSRegistrated_Erased( sId, KSD_OP_ERS, &ersSS->ssInfo );
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSActivated            |
++-------------------------------------------------------------------+
+
+  PURPOSE : SS erasure result is available.
+
+*/
+
+GLOBAL void cmhSS_SSActivated( SHORT sId,
+                               T_ACTIVATE_SS_RES *actSS )
+{
+  /* Implements Measure 217 */
+  TRACE_FUNCTION ("cmhSS_SSActivated()");
+  cmhSS_SSActDeact( sId, KSD_OP_ACT, &actSS->ssInfo );        
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSDeactivated          |
++-------------------------------------------------------------------+
+
+  PURPOSE : SS erasure result is available.
+
+*/
+
+GLOBAL void cmhSS_SSDeactivated( SHORT sId,
+                                 T_DEACTIVATE_SS_RES *deactSS )
+{
+  /* Implements Measure 217 */
+
+  TRACE_FUNCTION ("cmhSS_SSDeactivated()");
+  cmhSS_SSActDeact( sId, KSD_OP_DEACT, &deactSS->ssInfo );
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_getPassword            |
++-------------------------------------------------------------------+
+
+  PURPOSE : get password guidance.
+
+*/
+
+GLOBAL void cmhSS_getPassword( SHORT sId,
+                               T_GET_PWD_INV *getPWD )
+{
+  T_SS_CMD_PRM *pSSCmdPrm;   /* points to SS command parameters */
+  T_OWN        owner  = ssShrdPrm.stb[sId].srvOwn;
+  USHORT        cmdBuf = ssShrdPrm.stb[sId].curCmd; 
+
+  TRACE_FUNCTION ("cmhSS_getPassword()");
+
+  if(owner EQ OWN_SRC_SAT)
+  {
+    TRACE_EVENT("Owner SAT");
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * check for mandatory info
+ *-------------------------------------------------------------------
+ */
+  if( ! getPWD -> v_guidanceInfo  )
+  {
+    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+    R_AT( RAT_CME, (T_ACI_CMD_SRC)owner )
+      ( (T_ACI_AT_CMD)cmdBuf, CME_ERR_NotPresent );
+    cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_CME, (T_ACI_AT_CMD)cmdBuf, -1, 
+		           BS_SPEED_NotPresent, CME_ERR_NotPresent );
+    return;
+  }
+/*
+ *-------------------------------------------------------------------
+ * check for command context
+ *-------------------------------------------------------------------
+ */
+  switch( cmdBuf )
+  {
+   /*
+    *----------------------------------------------------------------
+    * process result for +CPWD and +CLCK and KSD PWD and KSD CB command
+    *----------------------------------------------------------------
+    */
+    case( AT_CMD_CPWD ):
+    case( AT_CMD_CLCK ):
+    case( KSD_CMD_PWD ):
+    case( KSD_CMD_CB  ):
+
+      if (owner > ((T_OWN)CMD_SRC_NONE)) /* Just to remove LINT warning */
+      {
+        pSSCmdPrm = &cmhPrm[owner].ssCmdPrm;
+      
+
+        switch( getPWD -> guidanceInfo )
+        {
+          case( GUI_ENTER_PW ):
+/* Implements Measure#32: Row 1151 */
+            if(strcmp((CHAR*)pSSCmdPrm->CXXXpwd, ffff_str) EQ 0)
+            {
+              /* remember sId to answer with password */
+  #ifdef SIM_TOOLKIT            
+              satShrdPrm.sId_pwd_requested = sId;
+  #endif /* SIM_TOOLKIT */
+
+              /* Password never given before ask for it */
+              R_AT( RAT_CME, (T_ACI_CMD_SRC)owner )
+                ( AT_CMD_CPWD, CME_ERR_WrongPasswd );
+              cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_CME, AT_CMD_CPWD, -1,
+			  	                 BS_SPEED_NotPresent, CME_ERR_WrongPasswd );
+              return;
+            }
+            else
+            {
+              psaSS_asmVerifyPWD( pSSCmdPrm -> CXXXpwd );
+              psaSS_CntTrns(sId);
+            }
+            break;
+
+          case( GUI_ENTER_NEW_PW ):
+
+            psaSS_asmVerifyPWD( pSSCmdPrm -> CXXXnewPwd );
+            psaSS_CntTrns(sId);
+            break;
+
+          case( GUI_ENTER_NEW_PW_AGAIN ):
+
+            psaSS_asmVerifyPWD( pSSCmdPrm -> CXXXnewPwd2 );
+            psaSS_CntTrns(sId);
+            break;
+
+          case( GUI_BAD_PW_RETRY ):
+          case( GUI_BAD_PW_FORM ):
+
+            ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+            ssShrdPrm.stb[sId].curCmd     = AT_CMD_NONE;
+
+            R_AT( RAT_CME, (T_ACI_CMD_SRC)owner )
+              ( AT_CMD_CPWD, CME_ERR_WrongPasswd );
+            cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_CME, AT_CMD_CPWD,
+				        -1, BS_SPEED_NotPresent, CME_ERR_WrongPasswd );
+
+           /* end of transaction */
+            psaSS_asmEmptyRslt();
+            psaSS_EndTrns(sId);
+
+            ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+        }
+        break;
+      }
+  }
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSPWDRegistrated       |
++-------------------------------------------------------------------+
+
+  PURPOSE : Password registration result is available.
+
+*/
+
+GLOBAL void cmhSS_SSPWDRegistrated( SHORT sId,
+                                    T_REGISTER_PWD_RES *regPWD )
+{
+  T_ACI_KSIR     ksStat;      /* holds KS status */
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+
+  TRACE_FUNCTION ("cmhSS_SSPWDRegistrated()");
+
+/*
+ *-------------------------------------------------------------------
+ * check for command context
+ *-------------------------------------------------------------------
+ */
+  switch( ssShrdPrm.stb[sId].curCmd )
+  {
+   /*
+    *----------------------------------------------------------------
+    * process result for +CPWD  command
+    *----------------------------------------------------------------
+    */
+    case( AT_CMD_CPWD ):
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      /* terminate command */
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)owner )
+        ( AT_CMD_CPWD );
+      cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_OK, AT_CMD_CPWD, 
+	  	                   -1,BS_SPEED_NotPresent,CME_ERR_NotPresent );
+      break;
+
+   /*
+    *----------------------------------------------------------------
+    * process result for KSD PWD command
+    *----------------------------------------------------------------
+    */
+    /*lint -e{408}*/ 
+    case( KSD_CMD_PWD ):
+
+      memset( &ksStat, 0, sizeof(ksStat));
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      ksStat.ksdCmd = KSD_CMD_PWD;
+      ksStat.ir.rKSPW.opCd  = KSD_OP_REG;
+      ksStat.ir.rKSPW.ssCd  = ssShrdPrm.stb[sId].ssCode;
+      ksStat.ir.rKSPW.ssErr = KSD_NO_ERROR;
+
+      if( regPWD->v_newPassword )
+      {
+        memcpy( ksStat.ir.rKSPW.newPwd, regPWD->newPassword.digit,
+                MAX_PWD_NUM );
+      }
+      /* Implements Measure 209, 210, 214 */
+      cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_PWD); 
+
+      break;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * set service table entry to unused
+ *-------------------------------------------------------------------
+ */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_CCNtryErased           |
++-------------------------------------------------------------------+
+
+  PURPOSE : CC entry erased.
+
+*/
+
+GLOBAL void cmhSS_CCNtryErased( SHORT sId,
+                                T_ERASE_CC_ENTRY_RES *ersCCNtry )
+{
+/*  T_ACI_KSIR     ksStat; */     /* holds KS status */
+  T_OWN owner = ssShrdPrm.stb[sId].srvOwn;
+
+  TRACE_FUNCTION ("cmhSS_CCNtryErased()");
+
+/*
+ *-------------------------------------------------------------------
+ * check for command context
+ *-------------------------------------------------------------------
+ */
+  switch( ssShrdPrm.stb[sId].curCmd & 0xFFFF )
+  {
+   /* process result for %CCBS  command */
+     case( AT_CMD_CCBS ):
+      /* terminate command */
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)owner )
+        ( AT_CMD_CCBS );
+      cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_OK, AT_CMD_CCBS, 
+	  	               -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );
+      break;
+
+   /* process result for KSD CCBS command */
+    case( (T_ACI_AT_CMD)KSD_CMD_CCBS ):
+
+      /*  Should be removed...
+      CLB: why should any status notification be sent to user ???
+      SS has just been erased !! 
+      05 Feb 2002
+      
+      memset( &ksStat, 0, sizeof(ksStat));
+
+      ksStat.ksdCmd = KSD_CMD_CCBS;
+      ksStat.ir.rKSCC.opCd  = KSD_OP_ERS;
+      ksStat.ir.rKSCC.ssCd  = KSD_SS_NONE;
+      ksStat.ir.rKSCC.ssSt  = KSD_ST_NOT_VALID;
+      ksStat.ir.rKSCC.ssErr = KSD_NO_ERROR;
+
+      ksStat.ir.rKSCC.c_ccFeatLst = 0;
+      ksStat.ir.rKSCC.ccFeatLst   = NULL;
+
+      if( ersCCNtry -> eraseCCEntryRes.v_ssCode )
+      {
+        ksStat.ir.rKSCC.ssCd  = ersCCNtry -> eraseCCEntryRes.ssCode;
+      }
+
+      if( ersCCNtry -> eraseCCEntryRes.v_ssStatus )
+      {
+        ksStat.ir.rKSCC.ssSt  = ersCCNtry -> eraseCCEntryRes.ssStatus;
+      }
+
+      R_AT( RAT_KSIR, owner )
+        ( &ksStat );*/
+
+      /* terminate command */
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)owner )
+        ( KSD_CMD_CCBS );
+      cmh_logRslt ((T_ACI_CMD_SRC)owner, RAT_OK, (T_ACI_AT_CMD)KSD_CMD_CCBS, 
+	  	                                            -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );
+      break;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * set service table entry to unused
+ *-------------------------------------------------------------------
+ */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_USSDNotify             |
++-------------------------------------------------------------------+
+
+  PURPOSE : Network initiated USSD notification received.
+
+*/
+
+GLOBAL void cmhSS_USSDNotify( SHORT sId,
+                              T_USSD_NOTIFY_INV *ussdNtfy )
+{
+  UBYTE           idx;
+  SHORT           dcs   = ACI_NumParmNotPresent;
+
+  T_ACI_USSD_DATA *ussd = NULL;
+
+  TRACE_FUNCTION ("cmhSS_USSDNotify()");
+
+/*
+ *-------------------------------------------------------------------
+ * check for another service in progress
+ *-------------------------------------------------------------------
+ */
+  if( psaSS_stbFindActSrv( sId ) NEQ NO_ENTRY )
+  {
+    psaSS_asmErrorRslt( sId, ERR_USSD_BUSY );
+
+    psaSS_EndTrns(sId);
+
+    ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+
+    return;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * send unsolicited result code
+ *-------------------------------------------------------------------
+ */
+//TISH, patch for OMAPS00122402
+//start
+//  if( ussdNtfy -> v_ussdArg )
+  if( ussdNtfy -> v_ussdArg && ussdNtfy -> ussdArg.ussdString.l_ussdString>>3)
+//end
+  {
+    /* Implements Measure 76 */
+    ussd = cmhSS_prepareUSSDRes(&ussdNtfy -> ussdArg, &dcs);
+    for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+    {
+      R_AT( RAT_CUSD, (T_ACI_CMD_SRC)idx )
+        ( CUSD_MOD_NoActReq, ussd, dcs );
+    }
+
+    if (ussd NEQ NULL)
+    {
+      MFREE(ussd);
+    }
+  }
+
+  ssShrdPrm.stb[sId].ussd_operation = TRUE;
+  
+/*
+ *-------------------------------------------------------------------
+ * confirm USSD notify receiption with empty result if Extended USSD Response feature is not enabled. 
+ *-------------------------------------------------------------------
+ */
+  if(cuscfgParams.Ext_USSD_Response EQ CUSCFG_STAT_Disabled)
+  {
+  //TISH, patch for OMAPS00122402
+  //start
+  	if ((UBYTE)(ussdNtfy -> ussdArg.ussdString.l_ussdString>>3) EQ 0)
+  		{
+			  ssShrdPrm.stb[sId].failType = SSF_SS_ERR;
+			  ssShrdPrm.stb[sId].errCd    = ERR_UNKNOWN_ALPHA;
+			  ssShrdPrm.cmpType = CT_RET_ERR;  	
+			  psaSS_CntTrns(sId);
+  			return;
+  		}
+//end	
+    psaSS_asmEmptyRslt();
+
+    psaSS_CntTrns(sId);
+
+  }
+  else
+  {
+    Ext_USSD_Res_Pending = CUSDR_EXT_USSD_RES_Notify;
+    Ext_USSD_Res_Pending_sId = sId;
+  }
+  
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_USSDRequest            |
++-------------------------------------------------------------------+
+
+  PURPOSE : Network initiated USSD request received.
+
+*/
+
+GLOBAL void cmhSS_USSDRequest( SHORT sId,
+                               T_USSD_REQ_INV *ussdReq )
+{
+  UBYTE           idx;
+  SHORT           dcs   = ACI_NumParmNotPresent;
+  T_ACI_USSD_DATA *ussd = NULL;
+  T_ACI_KSIR      ksStat;
+
+  TRACE_FUNCTION ("cmhSS_USSDRequest()");
+
+  /* check for another service in progress */
+  if( psaSS_stbFindActSrv( sId ) NEQ NO_ENTRY )
+  {
+    psaSS_asmErrorRslt( sId, ERR_USSD_BUSY );
+
+    psaSS_EndTrns(sId);
+
+    ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+    return;
+  }
+
+  /* send unsolicited result code */
+  if( ussdReq -> v_ussdArg )
+  {
+    /* Implements Measure 76 */
+    ussd = cmhSS_prepareUSSDRes(&ussdReq -> ussdArg, &dcs);
+    if(ssShrdPrm.stb[sId].curCmd EQ AT_CMD_CUSD )
+    {
+      R_AT( RAT_CUSD, (T_ACI_CMD_SRC)ssShrdPrm.stb[sId].srvOwn )
+        ( CUSD_MOD_YesActReq, ussd, dcs );
+    }
+    else if (ssShrdPrm.stb[sId].curCmd EQ ((T_ACI_AT_CMD)KSD_CMD_USSD))
+    {
+      ksStat.ksdCmd        = KSD_CMD_USSD;
+      ksStat.ir.rKSUS.mode = CUSD_MOD_YesActReq;
+      ksStat.ir.rKSUS.ussd = ussd->data;
+      ksStat.ir.rKSUS.len  = ussd->len;
+      ksStat.ir.rKSUS.dcs  = dcs;
+      ksStat.ir.rKSUS.ssErr = KSD_NO_ERROR;
+
+      R_AT( RAT_KSIR, (T_ACI_CMD_SRC)ssShrdPrm.stb[sId].srvOwn )
+          ( &ksStat );     
+    }
+    else
+    {
+      for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+      {
+        R_AT( RAT_CUSD, (T_ACI_CMD_SRC)idx )
+          ( CUSD_MOD_YesActReq, ussd, dcs );
+      }
+    }
+      
+    if(ussd NEQ NULL)
+    {
+      MFREE(ussd);
+    }
+    ssShrdPrm.stb[sId].ussdReqFlg = TRUE;
+  }
+
+  ssShrdPrm.stb[sId].ussd_operation = TRUE;
+
+  if(cuscfgParams.Ext_USSD_Response NEQ CUSCFG_STAT_Disabled)
+  {
+    Ext_USSD_Res_Pending = CUSDR_EXT_USSD_RES_Request;
+    Ext_USSD_Res_Pending_sId = sId;
+  }
+  
+  /* check command context */
+  if(ssShrdPrm.stb[sId].curCmd EQ AT_CMD_CUSD )
+  {
+    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+  }
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_USSDReqProcessed       |
++-------------------------------------------------------------------+
+
+  PURPOSE : USSD request was processed.
+
+*/
+
+/* TRUE returned means operation has been processed by SAT:
+function os to return immediatly */
+LOCAL BOOL cmhss_sat_ussd_reqprocessed( SHORT sId,
+                                        T_PROCESS_USSD_REQ_RES *prcUSSDReq )
+{
+#ifdef SIM_TOOLKIT
+  BOOL            retvalue = FALSE;
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+  T_ACI_AT_CMD           cmdBuf = ssShrdPrm.stb[sId].curCmd;
+
+  T_text     USSD_resp;
+  T_ACI_SAT_TERM_RESP resp_data;
+
+  /* ACI-SPR-16433: temporaly used to hold incoming USSD string */ 
+  UBYTE           additionalData[MAX_USSD_LEN];
+  UBYTE           additionalDataLen = 0; /* max 183 Byte, see MAX_USSD_LEN */ 
+  USHORT          index = 0;
+  UBYTE           ussdAddLen = 0;
+  
+  psaSAT_InitTrmResp( &resp_data );
+
+  TRACE_FUNCTION ("cmhss_sat_ussd_reqprocessed()");
+
+  if( (cmdBuf NEQ AT_CMD_NONE) AND ( (owner NEQ OWN_SRC_SAT) OR      
+      ((T_ACI_KSD_CMD)cmdBuf NEQ KSD_CMD_USSD) ) )
+
+  {
+    TRACE_EVENT_P1("cmhss_sat_ussd_reqprocessed(): ssShrdPrm.stb[sId].curCmd NEQ AT_CMD_NONE --> %d", 
+                    ssShrdPrm.stb[sId].curCmd);
+    retvalue = FALSE;
+  }
+  else if ( satShrdPrm.USSDterm )        /* response to a user defined termination */
+  {
+    psaSAT_SendTrmResp( RSLT_USER_TERM_SS, &resp_data );
+    satShrdPrm.USSDterm = FALSE; /* reinitialize */
+    retvalue = TRUE;
+  }
+  /* ACI-SPR-16433: USSD session might been started as SS command and KSD 
+                    identified an USSD key sequence */
+  else if ( sId EQ satShrdPrm.SentUSSDid AND 
+          ( (satShrdPrm.cmdDet.cmdType EQ SAT_CMD_SEND_USSD) OR 
+            (satShrdPrm.cmdDet.cmdType EQ SAT_CMD_SEND_SS  )    ))
+  {
+    /* Terminal response to SEND USSD when no error */
+    
+    if( prcUSSDReq -> v_ussdRes )
+    {
+      if ( prcUSSDReq -> ussdRes.v_ussdString )
+      {
+        USSD_resp.c_text_str = prcUSSDReq -> ussdRes.ussdString.l_ussdString>>3;
+
+        memcpy( &(USSD_resp.text_str),
+                &(prcUSSDReq -> ussdRes.ussdString.b_ussdString),
+                USSD_resp.c_text_str);
+      }
+      else
+        USSD_resp.c_text_str = 0;
+
+      if ( prcUSSDReq -> ussdRes.v_ussdDataCodingScheme )
+      {
+        /*
+          ACI: OMAPS00060422
+
+          According to the 11.14 the USSD string Data Coding Scheme
+          is coded as for Cell Broadcast defined in TS 23.038.
+          So, we store the USSD Data Coding Scheme when we receive from SIM
+          as a CBS Data coding Scheme.
+
+          But, while seding the TERMINAL RESPONSE to the SIM we send the string
+          as Text String. According to the 11.14 for Text String Data Coding
+          Scheme is coded as for SMS Data Coding Scheme defined in 23.038
+        */
+
+        /*
+          If we receive the DCS in USSD String from SIM as F0 (CBS DCS value:
+          Means 7-Bit Default, with No Message Class.
+
+          But, in the Text string while sending TERMINAL RESPONSE the DCS value
+          we have to change according to the 11.14 Specification. So, in Text
+          String the the DCS value of CBS will become 00(SMS DCS for text
+          String which Means 7-Bit Default, with No Message Class.)
+
+        */
+
+        if ( prcUSSDReq -> ussdRes.ussdDataCodingScheme EQ 0xF0 )
+        {
+          /* This is a special case. The CBS DCS for F0 (Special case 7-bit 
+             default GSM alphabet with No Message class) we can send SMS 
+             value as 0x00. The CBS DCS for F1 (Special case 8-bit with No
+             Message class) we can send SMS value as 0x01 as the if bit 4 
+             is ZERO then message class has no meaning.
+          */
+          USSD_resp.dcs = prcUSSDReq -> ussdRes.ussdDataCodingScheme & 0x0f;
+        }
+        else if ( prcUSSDReq -> ussdRes.ussdDataCodingScheme >= 0x40 AND
+                  prcUSSDReq -> ussdRes.ussdDataCodingScheme <= 0x7F )
+        {
+          /* Below are the mapping between CBS DCS -> SMS DCS values. 
+             For any values of CBS from 40 - 7F we can send SMS DCS as 00 - 3F
+          */
+          USSD_resp.dcs = prcUSSDReq -> ussdRes.ussdDataCodingScheme & 0x3f;
+        }
+        else if ( prcUSSDReq -> ussdRes.ussdDataCodingScheme >= 0xF1 AND
+                  prcUSSDReq -> ussdRes.ussdDataCodingScheme <= 0xF4 )
+        {
+          /* For CBS DCS 0xF1..0xF4 SMS DCS is sent as other than above we can
+             send as it is */
+          USSD_resp.dcs = prcUSSDReq -> ussdRes.ussdDataCodingScheme;
+        }
+        else
+        {
+          /* For any values for CBS DCS other than above we can send as it is */
+          TRACE_EVENT_P1("Possible problem in converting CBS to SMS DCS: %d", prcUSSDReq -> ussdRes.ussdDataCodingScheme);
+          USSD_resp.dcs = prcUSSDReq -> ussdRes.ussdDataCodingScheme;
+        }
+      }
+
+      resp_data.text = &USSD_resp;
+
+      /* ACI-SPR-16344: Prepare additional data for terminal response 
+         as requested in GSM 11.14 section 12.12.1 */
+      if ( satShrdPrm.cmdDet.cmdType EQ SAT_CMD_SEND_SS )
+      {
+        /* calculate length */
+        if ( prcUSSDReq->ussdRes.v_ussdString )
+        {
+          ussdAddLen = prcUSSDReq->ussdRes.ussdString.l_ussdString>>3;
+        }
+        /* also consider the first byte */ 
+        additionalDataLen = ussdAddLen + 8;
+
+        /* START: reconstruct the operation component received */
+        /* copy msg_type */
+        additionalData[index++] = prcUSSDReq->msg_type;
+        /* set sequence tag */
+        additionalData[index++] = 0x30; /* sequence tag */
+        /* length might be in one or 2 bytes representation (see GSM5_TLV) 
+           (-2) because the first two bytes are not counted */
+        if( (additionalDataLen-2) <= 0x7F ) 
+        {
+          additionalData[index++] = additionalDataLen-2;
+        }
+        else
+        {
+          additionalData[index++] = 0x81; /* prefix */ 
+          additionalData[index++] = additionalDataLen-2;          
+        }
+        /* set dcs tag and dcs length and dcs */
+        additionalData[index++] = 0x04; /* dcs tag */
+        additionalData[index++] = 0x01; /* dcs length (always 1) */
+        if ( prcUSSDReq->ussdRes.v_ussdDataCodingScheme )
+        {
+          additionalData[index++] = prcUSSDReq->ussdRes.ussdDataCodingScheme;
+        }
+        else 
+        {
+          TRACE_EVENT("cmhss_sat_ussd_req processed: DCS undef assuming 0x00");
+          additionalData[index++] = 0x00; /* default value */
+        }
+        /* set ussd tag, length and string */
+        additionalData[index++] = 0x04;  /* ussd tag */
+        /* length might be one or 2 bytes (see GSM5_TLV) */
+        if( (additionalDataLen-2) <= 0x7F ) 
+        {
+          additionalData[index++] = ussdAddLen;
+        }
+        else
+        {
+          additionalData[index++] = 0x81; /* prefix */
+          additionalData[index++] = ussdAddLen;
+        }
+        /* copy ussd string */
+        if ( prcUSSDReq->ussdRes.v_ussdString ) 
+        {
+          memcpy(additionalData+index, 
+                 &(prcUSSDReq -> ussdRes.ussdString.b_ussdString),
+                 ussdAddLen);
+        }
+        /* copy additional data to terminal response */        
+        resp_data.add = additionalData;
+        resp_data.addLen = additionalDataLen;        
+      }
+      /* End of ACI-SPR-16344: Prepare additional data for terminal response */
+      
+      psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );
+
+      satShrdPrm.SentUSSDid = NO_ENTRY; /* reinitialize */
+
+      retvalue = TRUE;
+    }
+  }
+  return retvalue; 
+#else /* SIM_TOOLKIT */
+  return FALSE;
+#endif /* SIM_TOOLKIT */
+}
+
+
+GLOBAL void cmhSS_USSDReqProcessed( SHORT sId,
+                                    T_PROCESS_USSD_REQ_RES *prcUSSDReq )
+{
+  SHORT           dcs = ACI_NumParmNotPresent;
+  T_ACI_KSIR      ksStat;   /* holds KS status */
+  T_ACI_USSD_DATA *ussd;
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+  BOOL            end_of_process;
+
+  TRACE_FUNCTION ("cmhSS_USSDReqProcessed()");
+
+  /* Check whether this is a SAT action */
+  end_of_process = cmhss_sat_ussd_reqprocessed( sId, prcUSSDReq );
+  if(end_of_process)
+  {
+    /* set service table entry to unused */
+    ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+    return;
+  }
+  
+  /* check command context */
+  switch( ssShrdPrm.stb[sId].curCmd )
+  {
+    case( AT_CMD_NONE ):
+    case( AT_CMD_CUSD ):
+
+      /* send unsolicited result code */
+      if( prcUSSDReq -> v_ussdRes )
+      {
+        if( prcUSSDReq -> ussdRes.v_ussdDataCodingScheme )
+          dcs = prcUSSDReq -> ussdRes.ussdDataCodingScheme;
+
+        if( prcUSSDReq -> ussdRes.v_ussdString )
+        {
+          MALLOC(ussd, sizeof(T_ACI_USSD_DATA));
+
+          /* SDU offset is assumed to be zero for ussd string */
+          ussd->len = prcUSSDReq -> ussdRes.ussdString.l_ussdString>>3;
+          /* Implements Measure 25 */
+          /* This function is more correct than utl_getAlphabetCb as it takes care 
+             of reserved codings */
+          if( cmh_getAlphabetCb( (UBYTE)dcs ) EQ 0 ) /* 7bit alphabet */
+          {
+            ussd->len = utl_cvt7To8( prcUSSDReq -> ussdRes.ussdString.b_ussdString,
+                                     ussd->len,
+                                     ussd->data,
+                                     0 );
+          }
+          else
+            memcpy( ussd->data, 
+                    prcUSSDReq -> ussdRes.ussdString.b_ussdString,
+                    ussd->len );
+
+          ussd->data[ussd->len]=0x00;
+
+          R_AT( RAT_CUSD, (T_ACI_CMD_SRC)owner )
+            ( CUSD_MOD_NoActReq, ussd, dcs );
+          
+          MFREE(ussd);
+        }
+      }
+      else
+      {
+        R_AT( RAT_CUSD, (T_ACI_CMD_SRC)owner )
+        ( CUSD_MOD_NoActReq, NULL, ACI_NumParmNotPresent );
+      }
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+      break;
+      /*lint -e{408}*/ 
+    case ( KSD_CMD_USSD ) :
+
+      MALLOC(ussd, sizeof(T_ACI_USSD_DATA));
+
+      memset( &ksStat, 0, sizeof(ksStat));
+      ksStat.ksdCmd        = KSD_CMD_USSD;
+      ksStat.ir.rKSUS.mode = CUSD_MOD_NoActReq;
+      ksStat.ir.rKSUS.ussd = ussd->data;
+      ussd->len               = 0;
+      ussd->data[0]      = 0x0;
+
+      if( prcUSSDReq -> v_ussdRes )
+      {
+        if( prcUSSDReq -> ussdRes.v_ussdDataCodingScheme )
+        {
+          dcs                 = prcUSSDReq -> ussdRes.ussdDataCodingScheme;
+          ksStat.ir.rKSUS.dcs = prcUSSDReq -> ussdRes.ussdDataCodingScheme;
+        }
+        else
+        {
+          ksStat.ir.rKSUS.dcs = ACI_NumParmNotPresent;
+        }
+
+        if( prcUSSDReq -> ussdRes.v_ussdString )
+        {
+          ussd->len = prcUSSDReq -> ussdRes.ussdString.l_ussdString>>3;
+          /* Implements Measure 25 */
+          /* This function is more correct than utl_getAlphabetCb as it takes care 
+             of reserved codings */  
+          if( cmh_getAlphabetCb( (UBYTE)dcs ) EQ 0 ) /* 7bit alphabet */
+          {
+            ussd->len = utl_cvt7To8( prcUSSDReq -> ussdRes.ussdString.b_ussdString,
+                                     ussd->len,
+                                     ussd->data,
+                                     0 );
+          }
+          else
+            memcpy( ussd->data, prcUSSDReq -> ussdRes.ussdString.b_ussdString,
+                    ussd->len );
+
+          if( !utl_cvtGsmIra ( ussd->data,
+                               ussd->len,
+                               ussd->data,
+                               MAX_USSD_LEN,
+                               CSCS_DIR_GsmToIra ))
+          {
+            TRACE_EVENT("utl_cvtGsmIra() could not be performed");
+          }
+        }
+      }
+
+      ksStat.ir.rKSUS.len = ussd->len;
+      ussd->data[ussd->len] = 0x00;
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      TRACE_EVENT_P2("cmhSS_USSDReqProcessed: sId: %d, owner: %d", sId, owner);
+      /* Implements Measure 209, 210, 214 */
+      cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_USSD);
+      MFREE(ussd);
+      break;
+  }
+
+  /* set service table entry to unused */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_USSDDatProcessed       |
++-------------------------------------------------------------------+
+
+  PURPOSE : USSD data was processed.
+
+*/
+
+GLOBAL void cmhSS_USSDDatProcessed( SHORT sId,
+                                    T_PROCESS_USSD_RES *prcUSSDdat )
+{
+  T_ACI_KSIR      ksStat; /* holds KS status */
+  T_ACI_USSD_DATA *ussd;
+  T_OWN           owner = ssShrdPrm.stb[sId].srvOwn;
+#ifdef SIM_TOOLKIT
+  T_text     USSD_resp;
+  T_ACI_SAT_TERM_RESP resp_data; 
+  psaSAT_InitTrmResp( &resp_data );
+#endif /* SIM_TOOLKIT */
+
+  TRACE_FUNCTION ("cmhSS_USSDDatProcessed()");
+
+/*
+ *-------------------------------------------------------------------
+ * check command context
+ *-------------------------------------------------------------------
+ */
+  switch( ssShrdPrm.stb[sId].curCmd )
+  {
+    case( AT_CMD_NONE ):
+
+#ifdef SIM_TOOLKIT
+      if ( satShrdPrm.USSDterm )        /* response to a user defined termination */
+      {
+        psaSAT_SendTrmResp( RSLT_USER_TERM_SS, &resp_data );
+        satShrdPrm.USSDterm = FALSE; /* reinitialize */
+        break;
+      }
+
+      if ( sId EQ satShrdPrm.SentUSSDid                   AND 
+           satShrdPrm.cmdDet.cmdType EQ SAT_CMD_SEND_USSD )
+      {
+        /* Terminal response to SEND USSD when no error */
+        if( prcUSSDdat -> v_ssUserData )
+        {
+          USSD_resp.c_text_str = prcUSSDdat -> ssUserData.l_ssUserData>>3;
+          memcpy( &(USSD_resp.text_str),&(prcUSSDdat -> ssUserData.b_ssUserData), USSD_resp.c_text_str);
+        }
+        else
+        {
+          USSD_resp.c_text_str = 0;
+        }
+
+        USSD_resp.dcs = 0xD4;
+
+        resp_data.text = &USSD_resp;
+
+        psaSAT_SendTrmResp( RSLT_PERF_SUCCESS, &resp_data );
+
+        satShrdPrm.SentUSSDid = NO_ENTRY; /* reinitialize */
+
+        break;
+      }
+#endif /* SIM_TOOLKIT */
+      /* no break if NO SIM_TOOLKIT...
+      or if it is an answer to another ss as the one initiated by SAT */
+    /*lint -fallthrough */
+    case( AT_CMD_CUSD ):
+
+      /* prepare unsolicited result code */
+      if( prcUSSDdat -> v_ssUserData )
+      {
+        MALLOC(ussd, sizeof(T_ACI_USSD_DATA));
+
+        /* SDU offset is assumed to be zero for ussd string */
+        ussd->len = prcUSSDdat -> ssUserData.l_ssUserData>>3;
+
+        memcpy( ussd->data, prcUSSDdat -> ssUserData.b_ssUserData,
+                MAX_USSD_LEN );
+
+        if( utl_cvtGsmIra ( prcUSSDdat -> ssUserData.b_ssUserData,
+                            ussd->len,
+                            ussd->data,
+                            MAX_USSD_LEN,
+                            CSCS_DIR_IraToGsm ) )
+        {
+          ussd->data[ussd->len]=0x00;
+        }
+
+        R_AT( RAT_CUSD, (T_ACI_CMD_SRC)owner )
+          ( CUSD_MOD_NoActReq, ussd, 0 );
+        MFREE(ussd);
+      }
+      else
+      {
+        R_AT( RAT_CUSD, (T_ACI_CMD_SRC)owner )
+          ( CUSD_MOD_NoActReq, NULL, ACI_NumParmNotPresent );
+      }
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+      break;
+      /*lint -e{408}*/ 
+    case ( KSD_CMD_USSD ) :
+
+      memset( &ksStat, 0, sizeof(ksStat));
+      ksStat.ksdCmd = KSD_CMD_USSD;
+      ksStat.ir.rKSUS.mode = CUSD_MOD_NoActReq;
+      ksStat.ir.rKSUS.dcs  = ACI_NumParmNotPresent;
+      ksStat.ir.rKSUS.len  = prcUSSDdat -> ssUserData.l_ssUserData>>3;
+
+
+      if( prcUSSDdat -> v_ssUserData )
+      {
+        prcUSSDdat -> ssUserData.b_ssUserData
+              [prcUSSDdat -> ssUserData.l_ssUserData] = 0x0;
+        ksStat.ir.rKSUS.ussd = prcUSSDdat -> ssUserData.b_ssUserData;
+
+      }
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+     /* Implements Measure 209, 210, 214 */
+      cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_USSD);
+      break;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * set service table entry to unused
+ *-------------------------------------------------------------------
+ */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_FwdChckSS              |
++-------------------------------------------------------------------+
+
+  PURPOSE : Forward check SS indication.
+
+*/
+
+GLOBAL void cmhSS_FwdChckSS( SHORT sId )
+{  
+  TRACE_FUNCTION ("cmhSS_FwdChckSS()");
+
+  /* send unsolicited result code */
+  send_CSSX_notification(NO_ENTRY,
+                              CSSX_CODE_FwrdCheckSS,
+                              ACI_NumParmNotPresent,
+                              NULL, NULL, NULL, NULL);
+
+  
+  /* end of transaction */
+  psaSS_asmEmptyRslt();
+  psaSS_EndTrns(sId);
+
+  /* set service table entry to unused */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+}
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : SSTransFail_default          |
++-------------------------------------------------------------------+
+
+  PURPOSE : SS transaction failed.
+
+*/
+LOCAL void SSTransFail_default ( SHORT sId )
+{
+  T_ACI_CME_ERR error;
+  T_ACI_AT_CMD         current_cmd = ssShrdPrm.stb[sId].curCmd; 
+  T_ACI_CUSD_MOD    errCd;
+  T_OWN         owner       = ssShrdPrm.stb[sId].srvOwn;
+  USHORT        idx = 0;
+  
+  TRACE_FUNCTION ("SSTransFail_default()");
+
+  cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;
+
+  if (ssShrdPrm.stb[sId].errCd EQ ERR_UNEXPECT_DATA)
+  {
+    error = CME_ERR_OpNotAllow;
+  }
+  else
+  {
+    error = CME_ERR_NotPresent;
+  }
+
+  if (current_cmd EQ ((T_ACI_AT_CMD)KSD_CMD_USSD) OR current_cmd EQ AT_CMD_CUSD )
+  {
+    switch (ssShrdPrm.stb[sId].errCd)
+    {
+      case ERR_UNEXPECT_DATA:
+        errCd  = CUSD_MOD_OperationNotSupported;
+        break;
+      default:
+        errCd  = CUSD_MOD_TerminatedByNetwork;
+        break;
+    }
+    for (idx = 0; idx < CMD_SRC_MAX; idx++)
+    {
+      R_AT( RAT_CUSD, (T_ACI_CMD_SRC)idx  )( errCd, NULL, 
+                                ACI_NumParmNotPresent);
+    }
+  }
+  else
+  {
+    R_AT( RAT_CME, (T_ACI_CMD_SRC)owner )( current_cmd, error );
+    cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_CME, current_cmd, -1, BS_SPEED_NotPresent, error );
+  }
+  
+}
+
+
+T_ACI_CME_ERR mapSSerrorCME(UBYTE SSerrCode)
+{
+  /*SRM 04/12/2003 Added decode function to map out SS error returns to CME errors*/
+  /*It may be neccessary to map out other codes in the FAC.DOC sec 6.4 Error Codes*/
+  T_ACI_CME_ERR mapped_SS2cme = CME_ERR_Unknown;
+  
+  TRACE_FUNCTION ("mapSSerrorCME(): map SS err to CME err");
+
+  switch(SSerrCode)
+  {
+  case ERR_NEG_PWD_CHECK:
+    mapped_SS2cme = CME_ERR_WrongPasswd;
+    break;
+    
+  case ERR_TELE_SVC_NOT_PROV:
+    mapped_SS2cme = CME_ERR_OpNotSupp;
+    break;
+  default:
+    mapped_SS2cme = CME_ERR_Unknown;
+    break;
+  }
+  return mapped_SS2cme;
+      
+}
+
+
+GLOBAL SHORT cmhSS_TransFail( SHORT sId )
+{
+  T_ACI_KSIR     ksStat;      /* holds KS status */
+  T_SS_CMD_PRM  *pSSCmdPrm;   /* points to SS command parameters */
+  T_CC_CMD_PRM  *pCCCmdPrm;   /* points to CC command parameters */
+  T_OWN          current_owner  = ssShrdPrm.stb[sId].srvOwn;
+  USHORT         cmdBuf         = ssShrdPrm.stb[sId].curCmd;
+  USHORT         idx            = 0;
+
+  TRACE_FUNCTION ("cmhSS_TransFail()");
+
+  pSSCmdPrm = &cmhPrm[current_owner].ssCmdPrm;
+
+  /* an error occured: kill pending transactions... */
+  pSSCmdPrm->mltyTrnFlg &= ~ssShrdPrm.mltyTrnFlg;
+  psaSS_KillAllPendingTrn( );
+
+  /* Marcus: Issue 1640: 27/01/2003: ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE; */
+  
+#ifdef SIM_TOOLKIT
+  /* if SIM TOOLKIT initiated action send terminal response to SAT */
+  if( current_owner EQ OWN_SRC_SAT )
+  {
+    /* send error message to SAT if not sent previously. Check has 
+       been added to avoid sending multiple terminal response */
+    if ((ssShrdPrm.stb[sId].failType EQ SSF_SS_ENT) OR
+        (ssShrdPrm.stb[sId].failType EQ SSF_CCD_DEC))
+    {
+      psaSAT_SSRejComp(RSLT_NTW_UNAB_PROC);
+    }
+
+    /* free SS Entry */
+    
+    cmhPrm[current_owner].ssCmdPrm.mltyTrnFlg = 0;
+        
+    ssShrdPrm.stb[sId].ntryUsdFlg   = FALSE;
+    ssShrdPrm.stb[sId].srvOwn       = OWN_SRC_INV;
+    ssShrdPrm.stb[sId].curCmd       = AT_CMD_NONE;  /* Marcus: Issue 1640: 27/01/2003 */
+    /* that should be enough to free the SS entry */
+    return 0;
+  }
+#endif /* SIM_TOOLKIT */
+
+  switch( cmdBuf )
+  {
+    case( AT_CMD_NONE ):
+    {
+      if ( ssShrdPrm.stb[sId].opCode EQ OPC_UNSTRUCT_SS_REQ )
+      {
+        for( idx = 0; idx < CMD_SRC_MAX; idx++ )
+        {
+          R_AT( RAT_CUSD, (T_ACI_CMD_SRC)idx ) ( CUSD_MOD_TerminatedByNetwork, NULL, 0 );
+        }     
+      }
+      break;
+    }
+    case( AT_CMD_COLP ):
+    {
+      R_AT( RAT_COLP, (T_ACI_CMD_SRC)current_owner )
+        ( COLP_STAT_Unknown, NULL, NULL, NULL, NULL, NULL);
+      
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)current_owner )
+        ( AT_CMD_COLP);
+      break;
+    }
+    case( AT_CMD_CLIP ):
+    {
+      R_AT( RAT_CLIP, (T_ACI_CMD_SRC)current_owner )
+        ( CLIP_STAT_Unknown, NULL, NULL, MNCC_PRES_NOT_PRES, NULL, NULL, NULL);
+
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)current_owner )
+        ( AT_CMD_CLIP);
+      break;
+    }
+  /* Following case added to fix issue ACI-SPR-23109 */
+    case( AT_CMD_CPWD ):
+    {
+     /* To avoid two response being sent to the terminal, the error code
+         has been mapped to the corresponding CME error and it is displayed
+         to the terminal */
+      T_ACI_CME_ERR mapped_SS2cme = mapSSerrorCME(ssShrdPrm.stb[sId].errCd);
+      R_AT( RAT_CME, (T_ACI_CMD_SRC)current_owner )((T_ACI_AT_CMD) cmdBuf, mapped_SS2cme );
+      cmh_logRslt ( (T_ACI_CMD_SRC)current_owner, RAT_CME,(T_ACI_AT_CMD) cmdBuf, -1, BS_SPEED_NotPresent, mapped_SS2cme );
+      break;
+    }
+    case( AT_CMD_CLIR ):
+    {
+      pCCCmdPrm = &cmhPrm[current_owner].ccCmdPrm;
+
+      R_AT( RAT_CLIR, (T_ACI_CMD_SRC)current_owner )
+        ( pCCCmdPrm -> CLIRmode, CLIR_STAT_Unknown);
+
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)current_owner )
+        ( AT_CMD_CLIR);
+      break;
+    }
+    case( AT_CMD_CCFC ):
+    case( AT_CMD_CCWA ):
+    case( AT_CMD_CLCK ):
+    {
+      if (ssShrdPrm.stb[sId].failType EQ SSF_SS_ENT)
+      {
+        SSTransFail_default( sId );
+      }
+      else if( cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm->mltyTrnFlg))) /*test service flag and clear it*/
+      {
+        if( pSSCmdPrm -> mltyTrnFlg EQ 0 )  /* if no other service flags remaining*/
+        {
+          T_ACI_CME_ERR mapped_SS2cme = mapSSerrorCME(ssShrdPrm.stb[sId].errCd);
+
+          R_AT( RAT_CME, (T_ACI_CMD_SRC)current_owner )( cmdBuf, mapped_SS2cme );
+          cmh_logRslt ( (T_ACI_CMD_SRC)current_owner, RAT_CME, (T_ACI_AT_CMD)cmdBuf, 
+		  	                     -1, BS_SPEED_NotPresent, mapped_SS2cme );
+        }
+      }
+      else
+      { 
+        /* do nothing */ 
+      }
+      break;
+    }
+    case( KSD_CMD_CF ):
+    case( KSD_CMD_CW ):
+    case( KSD_CMD_CB ):
+    case( KSD_CMD_CL ):
+    case( KSD_CMD_PWD ):
+    case( KSD_CMD_CCBS ):
+    case( KSD_CMD_USSD ):
+    {
+      memset( &ksStat, 0, sizeof(ksStat));
+
+      cmhSS_ksdBuildErrRslt( sId, &ksStat, KSD_NO_ERROR );
+
+      if(check_ksd_error( current_owner, sId, &ksStat ))
+      {
+        /* Marcus: Issue 1640: 27/01/2003: ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE; */
+
+        cmhPrm[current_owner].ssCmdPrm.mltyTrnFlg = 0;
+      }
+      else
+      {
+        /*
+        ** CQ12314 : NDH : 23/9/2003
+        ** Added srcID field to ksStat to enable called entity to determine the originator of the command
+        ** and take appropriate action.  (eg to Activate Call Forwarding Icon)
+        */
+        ksStat.srcId = (T_ACI_CMD_SRC)current_owner;
+
+#if defined (MFW)
+        if (ksStat.srcId NEQ CMD_SRC_LCL)
+        {
+          R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
+        }
+#endif
+        R_AT( RAT_KSIR, (T_ACI_CMD_SRC)current_owner )( &ksStat );
+      }
+
+      SSTransFail_default( sId );
+      break;
+    }
+    default:
+    {
+      SSTransFail_default( sId );
+      break;
+    }
+  }
+
+  /* Set extended error cause for KSD  and AT commands */
+  if (ssShrdPrm.stb[sId].errCd)
+  {
+    causeMod  = P_CEER_ss;      /* Set the module for ceer cause */
+    causeCeer = (SHORT)ssShrdPrm.stb[sId].errCd;
+  }
+  
+  /* set service table entry to unused */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+  ssShrdPrm.stb[sId].curCmd     = AT_CMD_NONE;  /* Marcus: Issue 1640: 27/01/2003 */
+  return 0;
+}
+
+
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_sendFie                |
++-------------------------------------------------------------------+
+
+  PURPOSE : forward unsolicited facility responses from SS to terminal
+
+*/
+GLOBAL T_ACI_RETURN cmhSS_sendFie( T_ACI_FAC_DIR        tDirection,
+                                  T_ACI_FAC_TRANS_TYPE tType,
+                                  T_fac_inf           *fie )
+{
+  T_ACI_CMD_SRC tSrc;
+
+  TRACE_EVENT( "cmhSS_sendFie()" );
+
+  for( tSrc=CMD_SRC_LCL; tSrc<CMD_SRC_MAX; tSrc++ )  /* try over all sources */
+  {
+    if( cmhPrm[tSrc].ssCmdPrm.CSCNss_mode.SsCSCNModeState EQ SS_CSCN_MOD_STATE_ON )
+    {
+      switch (cmhPrm[tSrc].ssCmdPrm.CSCNss_mode.SsCSCNModeDirection)
+      {
+        case SS_CSCN_MOD_DIR_BOTH:
+          break; /* printout regardless of direction */
+
+        case SS_CSCN_MOD_DIR_IN:
+          if( tDirection NEQ CSCN_FACILITY_DIRECTION_IN)
+            continue; /* settings for source don't match, advance to next source */
+          break;
+
+        case SS_CSCN_MOD_DIR_OUT:
+          if( tDirection NEQ CSCN_FACILITY_DIRECTION_OUT )
+            continue; /* settings for source don't match, advance to next source */
+          break;
+
+        default:
+          continue; /* illegal setting, advance to next source */
+      }
+      R_AT( RAT_CSSN, tSrc )( tDirection, tType, fie );
+    }
+  }
+  return( AT_CMPL );
+}
+
+
+/* Used in Measure 217 */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_processKSDCF           |
++-------------------------------------------------------------------+
+  PARAMETERS  : sId     - Index into ssShrdPrm.stb
+                opCd    - KSD operation code
+                ssInfo  - SS Information
+  RETURN      : None
+
+  PURPOSE : Process KSD CF. This is common code in cmhSS_SSActDeact and 
+            cmhSS_SSRegistrated_Erased
+
+*/
+
+LOCAL void cmhSS_processKSDCF (SHORT sId, UBYTE opCd, T_ssInfo *ssInfo)
+{
+  T_CF_FEAT    *cfFeat;      /* points to CF feature list element */
+  T_ACI_KSIR   ksStat;       /* holds KS status */
+
+  cfFeat = (T_CF_FEAT *)ssLstBuf;
+  memset( &ksStat, 0, sizeof(ksStat));
+
+  ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+  ksStat.ksdCmd = KSD_CMD_CF;
+  ksStat.ir.rKSCF.opCd  = opCd;
+  ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;
+
+  if( ssInfo->v_forwardingInfo )
+  {
+    cmhSS_ksdFillFwdRes( &ssInfo->forwardingInfo,
+                         &ksStat, cfFeat );
+#if defined(MFW) OR defined(FF_MMI_RIV)
+    if (ksStat.ir.rKSCF.ssCd EQ KSD_SS_NONE)
+      ksStat.ir.rKSCF.ssCd = ssShrdPrm.stb[sId].ssCode;   /* 1a 1b) help the BMI about the last code  (o2 - de) */
+#endif
+  }
+#if defined(MFW) OR defined(FF_MMI_RIV)
+  else 
+  {
+    ksStat.ir.rKSCF.ssCd = ssShrdPrm.stb[sId].ssCode;   /* 2a 2b) help the BMI about the last code (e+ - de) */
+  }
+#endif
+
+  cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_CF);
+}
+
+/* Implements Measure 217 */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSActDeact             |
++-------------------------------------------------------------------+
+  PARAMETERS  : sId     - Index into ssShrdPrm.stb
+                opCd    - KSD operation code
+                ssInfo  - SS Information
+  RETURN      : None
+
+  PURPOSE : Handles the SS Activate or Deactivate result.
+
+*/
+
+LOCAL void cmhSS_SSActDeact ( SHORT sId, UBYTE opCd, T_ssInfo *ssInfo )
+{
+  T_SS_CMD_PRM * pSSCmdPrm;   /* points to SS command parameters */
+  T_ACI_KSIR     ksStat;      /* holds KS status */
+  T_CB_INFO    * cbInfo;      /* points to CB feature list element */
+  T_Cx_BSG     * cwBSG;       /* points to CW basic service list element */
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+  USHORT          cmdBuf = ssShrdPrm.stb[sId].curCmd;
+
+  TRACE_FUNCTION ("cmhSS_SSActDeact()");
+
+/*
+ *-------------------------------------------------------------------
+ * check for command context
+ *-------------------------------------------------------------------
+ */
+  switch( cmdBuf )
+  {
+   /*
+    *----------------------------------------------------------------
+    * process result for +CCFC, +CLCK and +CCWA command
+    *----------------------------------------------------------------
+    */
+    case( AT_CMD_CCFC ):
+    case( AT_CMD_CLCK ):
+    case( AT_CMD_CCWA ):
+
+      pSSCmdPrm = &cmhPrm[owner].ssCmdPrm;
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      /* terminate command */
+      if( cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)))
+      {
+        if( pSSCmdPrm -> mltyTrnFlg EQ 0 )  /* if last service */
+        {
+
+          R_AT( RAT_OK, (T_ACI_CMD_SRC)owner )
+            ( (T_ACI_AT_CMD)cmdBuf );
+          cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_OK, (T_ACI_AT_CMD)cmdBuf, 
+                        -1, BS_SPEED_NotPresent,CME_ERR_NotPresent );
+        }
+      }
+      break;
+
+   /*
+    *----------------------------------------------------------------
+    * process result for KSD CF command
+    *----------------------------------------------------------------
+    */
+    case( KSD_CMD_CF ):
+      cmhSS_processKSDCF ( sId, opCd, ssInfo);
+      break;
+
+   /*
+    *----------------------------------------------------------------
+    * process result for KSD CB command
+    *----------------------------------------------------------------
+    */
+    case( KSD_CMD_CB ):
+
+      cbInfo = (T_CB_INFO *)ssLstBuf;
+      memset( &ksStat, 0, sizeof(ksStat));
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      ksStat.ksdCmd = KSD_CMD_CB;
+      ksStat.ir.rKSCF.opCd  = opCd;
+      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;
+
+      if( ssInfo->v_callBarringInfo )
+      {
+        cmhSS_ksdFillCbRes( &ssInfo->callBarringInfo,
+                            &ksStat, cbInfo );
+      }
+
+      cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_CB);
+      break;
+
+   /*
+    *----------------------------------------------------------------
+    * process result for KSD CW command
+    *----------------------------------------------------------------
+    */
+    case( KSD_CMD_CW ):
+
+      cwBSG = (T_Cx_BSG *)ssLstBuf;
+      memset( &ksStat, 0, sizeof(ksStat));
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      ksStat.ksdCmd = KSD_CMD_CW;
+      ksStat.ir.rKSCW.opCd  = opCd;
+      ksStat.ir.rKSCW.ssErr = KSD_NO_ERROR;
+
+      if( ssInfo->v_ssData )
+      {
+        cmhSS_ksdFillCwRes( &ssInfo->ssData,
+                            &ksStat, cwBSG );
+      }
+      else if (opCd EQ KSD_OP_ACT)
+      {
+        ksStat.ir.rKSCW.ssCd  = KSD_SS_NONE;
+        ksStat.ir.rKSCW.ssSt  = KSD_ST_NONE;
+      }
+
+      cmhSS_ksdCBCF_Res (sId, &ksStat, KSD_CMD_CW);
+      break;
+  }
+
+/*
+ *-------------------------------------------------------------------
+ * set service table entry to unused
+ *-------------------------------------------------------------------
+ */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+
+}
+
+/* Implements Measure 215 */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_SSRegistrated_Erased   |
++-------------------------------------------------------------------+
+  PARAMETERS  : sId     - Index into ssShrdPrm.stb
+                opCd    - KSD operation code
+                ssInfo  - SS Information
+  RETURN      : None
+
+  PURPOSE : Handle SS registration or erasure result.
+
+*/
+
+LOCAL void cmhSS_SSRegistrated_Erased (SHORT sId,
+                                       UBYTE opCd, 
+                                       T_ssInfo *ssInfo)
+{
+  T_SS_CMD_PRM *pSSCmdPrm;   /* points to SS command parameters */
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+
+  TRACE_FUNCTION ("cmhSS_SSRegistrated_Erased()");
+
+  /* check for command context */
+  switch( ssShrdPrm.stb[sId].curCmd )
+  {
+    /* process result for +CCFC command */
+    case( AT_CMD_CCFC ):
+
+      pSSCmdPrm = &cmhPrm[owner].ssCmdPrm;
+
+      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+      
+      TRACE_EVENT_P2( "SS_INFO_VALIDITY:%d During operation %d", 
+                                ssInfo->v_forwardingInfo, opCd);
+      
+      /* terminate command */
+      if( cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)))
+      {
+        if( pSSCmdPrm -> mltyTrnFlg EQ 0 )  /* if last service */
+        {
+          R_AT( RAT_OK, (T_ACI_CMD_SRC)owner )
+            ( AT_CMD_CCFC );
+          cmh_logRslt ((T_ACI_CMD_SRC)owner, RAT_OK, AT_CMD_CCFC, -1,
+                       BS_SPEED_NotPresent,CME_ERR_NotPresent );
+        }
+      }
+      break;
+
+    /* process result for KSD CF command */
+      /*lint -e{408}*/ 
+    case ( KSD_CMD_CF ) :
+      cmhSS_processKSDCF ( sId, opCd, ssInfo);      
+      break;
+  }
+
+  /* set service table entry to unused */
+  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
+}
+
+/* Implements Measure 209, 210, 214 */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_ksdCBCF_Res            |
++-------------------------------------------------------------------+
+  PARAMETERS  : sId     - Index into ssShrdPrm.stb
+                ksStat  - holds KS status 
+                ksdCmd  - KSD command identifier
+  RETURN      : None
+
+  PURPOSE : Sends result for for KSD CB or CFcommand.
+
+*/
+
+LOCAL void cmhSS_ksdCBCF_Res (SHORT sId, T_ACI_KSIR  *ksStat, T_ACI_KSD_CMD ksdCmd)
+{
+  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
+  USHORT          cmdBuf = ssShrdPrm.stb[sId].curCmd;
+
+  if(check_ksd_error( owner, sId, ksStat ))
+  {
+    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
+
+    cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;
+
+    R_AT( RAT_CME, (T_ACI_CMD_SRC)owner )
+      ( (T_ACI_AT_CMD)cmdBuf, CME_ERR_NotPresent );
+  }
+  else
+  {
+      /*
+      ** CQ12314 : NDH : 23/9/2003
+      ** Added srcID field to ksStat to enable called entity to determine the originator of the command
+      ** and take appropriate action.  (eg to Activate Call Forwarding Icon)
+      */
+      ksStat->srcId = (T_ACI_CMD_SRC)owner;
+    
+    #if defined (MFW)
+      if (ksStat->srcId NEQ CMD_SRC_LCL)
+      {
+        R_AT( RAT_KSIR, CMD_SRC_LCL)( ksStat );
+      }
+    #endif
+        
+    R_AT( RAT_KSIR, (T_ACI_CMD_SRC)owner ) ( ksStat );
+
+    if(ksdCmd NEQ KSD_CMD_NONE)
+    {
+      /* terminate command */
+      R_AT( RAT_OK, (T_ACI_CMD_SRC)owner ) (ksdCmd);
+      cmh_logRslt ( (T_ACI_CMD_SRC)owner, RAT_OK, (T_ACI_AT_CMD)KSD_CMD_CF, -1,
+                    BS_SPEED_NotPresent,CME_ERR_NotPresent );
+    }
+  }
+}
+/* Implements Measure 76 */
+/*
++-------------------------------------------------------------------+
+| PROJECT : GSM-PS (6147)    MODULE  : CMH_SSR                      |
+|                            ROUTINE : cmhSS_prepareUSSDRes         |
++-------------------------------------------------------------------+
+  PARAMETERS  : ussdArg - USSD argument
+                dcs - Data Coding Scheme        
+  RETURN      : Filled T_ACI_USSD_DATA structure
+
+  PURPOSE : prepares USSD Response.
+
+*/
+LOCAL T_ACI_USSD_DATA* cmhSS_prepareUSSDRes(T_ussdArg *ussdArg, SHORT *dcs)
+{
+  T_ACI_USSD_DATA   *ussd = NULL;
+
+  TRACE_FUNCTION ("cmhSS_prepareUSSDRes()");
+
+  if( ussdArg->v_ussdDataCodingScheme )
+  {
+    *dcs = ussdArg->ussdDataCodingScheme;
+  }
+
+  if( ussdArg->v_ussdString )
+  {
+    MALLOC(ussd, sizeof(T_ACI_USSD_DATA));
+    
+    /* SDU offset is assumed to be zero for ussd string */
+    ussd->len = ussdArg->ussdString.l_ussdString>>3;
+    if( cmh_getAlphabetCb( (UBYTE)*dcs ) EQ 0 ) /* 7bit alphabet */
+    {
+      ussd->len = utl_cvt7To8( ussdArg->ussdString.b_ussdString,
+                              ussd->len,
+                              ussd->data,
+                              0 );
+    }
+    else
+    {
+      memcpy( ussd->data, ussdArg->ussdString.b_ussdString,
+              ussd->len );
+    }
+
+    TRACE_EVENT_P1("USSD str len: %d", ussd->len);
+    ussd->data[ussd->len]=0x00;
+  }
+  return ussd;
+}
+/*==== EOF ========================================================*/
+