/* 
+----------------------------------------------------------------------------- 
|  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 =====================================================*/

/*==== 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 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;
  UBYTE      cmdBuf  = ssShrdPrm.stb[sId].curCmd;

  TRACE_FUNCTION ("cmhSS_SSResultFailure()");

  switch( cmdBuf )
  {
    case( AT_CMD_NONE ): break;

    case( KSD_CMD_CF ):
    case( KSD_CMD_CW ):
    case( KSD_CMD_CB ):
    case( KSD_CMD_CL ):
    case( KSD_CMD_PWD ):
    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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif
        
        R_AT( RAT_KSIR, owner )
          ( &ksStat );
      }

      /* NO BREAK HERE... Continue... */
      
      /* lint -fallthrough */
    default:

      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

      if (owner > OWN_NONE AND owner < OWN_MAX) /* Just to remove LINT warning */
      {
        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;
      }

      R_AT( RAT_CME, owner )
        ( cmdBuf, CME_ERR_NotPresent );
      cmh_logRslt ( owner, RAT_CME, cmdBuf, -1, -1, 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, owner )
    ( clip_status, NULL, NULL, 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 )
{
  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, 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, 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, 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, owner )
    ( colr_status );
}


LOCAL void cmhSS_CLCK_CCWA_Interrogated( SHORT sId, T_INTERROGATE_SS_RES *irgtSS, UBYTE 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_bearerService EQ 0 AND
      irgtSS->interrogateSSRes.basicServiceGroupList.c_teleservice   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 = queried_classes;
  }
  else
  {
    srvStat.class_type = srvStat.class_type & queried_classes;
  }

  switch( cmdBuf)
  {
  case( AT_CMD_CCWA ):
    R_AT( RAT_CCWA, owner )
      ( &srvStat, NULL, NULL, PRES_NOT_PRES, CLASS_NotPresent, NULL );
    break;
    
  case( AT_CMD_CLCK ):
    R_AT( RAT_CLCK, 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 = CLASS_VceDatFax & queried_classes;

    R_AT( RAT_CCFC, 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 = irgtSS->interrogateSSRes.forwardingFeatureList.
            ff[idx].forwardedToNumber.npi;
          ccfcStat.type.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_bcdDigit)
        {
          utl_BCD2DialStr
            (irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
            forwardedToSubaddress.bcdDigit,
            ccfcStat.subaddr,
            irgtSS->interrogateSSRes.forwardingFeatureList.ff[idx].
            forwardedToSubaddress.c_bcdDigit);
          
          ccfcStat.satype.tos = irgtSS->interrogateSSRes.
            forwardingFeatureList.ff[idx].
            forwardedToSubaddress.tos;
          ccfcStat.satype.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, 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 = CLASS_VceDatFax & queried_classes;
        ccfcStat.clsstat.status  = STATUS_NotActive;

        R_AT( RAT_CCFC, 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 = irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
            ccbsf[idx].b_subscriberNumber.npi;
          ccbsSet.type.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_bcdDigit )
        {
          utl_BCD2DialStr
            (irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].b_subscriberSubaddress.bcdDigit,
            ccbsSet.subaddr,
            irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.ccbsf[idx].b_subscriberSubaddress.c_bcdDigit);
          
          ccbsSet.satype.tos = irgtSS->interrogateSSRes.cliRestrictionInfo.ccbsFeatureList.
            ccbsf[idx].b_subscriberSubaddress.tos;
          ccbsSet.satype.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 */
  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  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 );
    }
  }
  
  if(check_ksd_error( owner, sId, &ksStat ))
  {
    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

    cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

    R_AT( RAT_CME, owner )
      ( 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 = owner;
    
    #if defined (MFW)
      if (ksStat.srcId NEQ CMD_SRC_LCL)
      {
        R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
      }
    #endif
        
    R_AT( RAT_KSIR, owner )
      ( &ksStat );
  }
}

/* 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 */
  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  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_teleservice   EQ 0 AND
      irgtSS->interrogateSSRes.basicServiceGroupList.c_bearerService 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_teleservice AND lstSpce;
      idx++, cbInfo++, lstSpce-- )
      {
        cbInfo->bsCd = irgtSS->interrogateSSRes.basicServiceGroupList.
          teleservice[idx];
        cbInfo->bsTp = KSD_BS_TP_Tele; 
        cbInfo->ssSt = KSD_ST_A;
      }
      
      for( idx=0;
      idx < irgtSS->interrogateSSRes.basicServiceGroupList.
        c_bearerService AND lstSpce;
      idx++, cbInfo++, lstSpce-- )
      {
        cbInfo->bsCd = irgtSS->interrogateSSRes.basicServiceGroupList.
          bearerService[idx];
        cbInfo->bsTp = KSD_BS_TP_Bearer;
        cbInfo->ssSt = KSD_ST_A;
      }
      
      ksStat.ir.rKSCB.c_cbInfoLst = MAX_CB_INFO_NR - lstSpce;
    }
  }
  
  if(check_ksd_error( owner, sId, &ksStat ))
  {
    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

    cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

    R_AT( RAT_CME, owner )
      ( 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 = owner;
    
    #if defined (MFW)
      if (ksStat.srcId NEQ CMD_SRC_LCL)
      {
        R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
      }
    #endif
        
    R_AT( RAT_KSIR, owner )
      ( &ksStat );
  }
}

/* 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 */
  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  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_bearerService EQ 0 AND
      irgtSS->interrogateSSRes.basicServiceGroupList.c_teleservice 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 );
    }
  }
  
  if(check_ksd_error( owner, sId, &ksStat ))
  {
    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

    cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

    R_AT( RAT_CME, owner )
      ( 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 = owner;
    
    #if defined (MFW)
      if (ksStat.srcId NEQ CMD_SRC_LCL)
      {
        R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
      }
    #endif
        
    R_AT( RAT_KSIR, owner )
      ( &ksStat );
  }
}

/* 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;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  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;
  }
  
  if(check_ksd_error( owner, sId, &ksStat ))
  {
    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

    cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

    R_AT( RAT_CME, owner )
      ( 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 = owner;
    
    #if defined (MFW)
      if (ksStat.srcId NEQ CMD_SRC_LCL)
      {
        R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
      }
    #endif
        
    R_AT( RAT_KSIR, owner )
      ( &ksStat );
  }
}

/* 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 */
  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  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 );
    }
  }

  if(check_ksd_error( owner, sId, &ksStat ))
  {
    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

    cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

    R_AT( RAT_CME, owner )
      ( 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 = owner;
    
    #if defined (MFW)
      if (ksStat.srcId NEQ CMD_SRC_LCL)
      {
        R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
      }
    #endif
        
    R_AT( RAT_KSIR, owner )
      ( &ksStat );
  }
}

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, 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;
  UBYTE           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, owner )
    ( cmdBuf );
  cmh_logRslt( owner, RAT_OK, cmdBuf, -1, -1, -1 );

  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 )
{
  T_SS_CMD_PRM *pSSCmdPrm;   /* points to SS command parameters */
  T_ACI_KSIR   ksStat;       /* holds KS status */
  T_CF_FEAT    *cfFeat;      /* points to CF feature list element */
  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  TRACE_FUNCTION ("cmhSS_SSRegistrated()");

  /* 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;

      if( !regSS -> ssInfo.v_forwardingInfo )
      {
        TRACE_EVENT( "WRONG SS INFO DURING REGISTER CF" );
      }

      /* terminate command */
      if( cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)))
      {
        if( pSSCmdPrm -> mltyTrnFlg EQ 0 )  /* if last service */
        {
          R_AT( RAT_OK, owner )
            ( AT_CMD_CCFC );
          cmh_logRslt ( owner, RAT_OK, AT_CMD_CCFC, -1, -1, -1 );
        }
      }
      break;

    /* process result for KSD CF command */
    case( KSD_CMD_CF ):

      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  = KSD_OP_REG;
      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;

      if( regSS->ssInfo.v_forwardingInfo )
      {
        cmhSS_ksdFillFwdRes( &regSS->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) 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) help the BMI about the last code */
      }
#endif

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif
        
        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CF );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CF, -1, -1, -1 );
      }
      break;
  }

  /* set service table entry to unused */
  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
}

/*
+-------------------------------------------------------------------+
| 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 )
{
  T_SS_CMD_PRM * pSSCmdPrm;   /* points to SS command parameters */
  T_ACI_KSIR     ksStat;      /* holds KS status */
  T_CF_FEAT    * cfFeat;      /* points to CF feature list element */
  T_OWN           owner  = ssShrdPrm.stb[sId].srvOwn;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  TRACE_FUNCTION ("cmhSS_SSErased()");

  /* 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;

      /* terminate command */
      if( cmhSS_tstAndUnflagTrn( sId, &(pSSCmdPrm -> mltyTrnFlg)))
      {
        if( pSSCmdPrm -> mltyTrnFlg EQ 0 )  /* if last service */
        {
          R_AT( RAT_OK, owner )
            ( AT_CMD_CCFC );
          cmh_logRslt ( owner, RAT_OK, AT_CMD_CCFC, -1, -1, -1 );
        }
      }
      break;

    /* process result for KSD CF command */
    case( KSD_CMD_CF ):

      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  = KSD_OP_ERS;
      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;

      if( ersSS->ssInfo.v_forwardingInfo )
      {
        cmhSS_ksdFillFwdRes( &ersSS->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;   /* 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;   /* 2b) help the BMI about the last code (e+ - de) */
      }
#endif

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif
        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CF );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CF, -1, -1, -1 );
      }
      break;
  }

  /* set service table entry to unused */
  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;
}

/*
+-------------------------------------------------------------------+
| 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 )
{
  T_SS_CMD_PRM * pSSCmdPrm;   /* points to SS command parameters */
  T_ACI_KSIR     ksStat;      /* holds KS status */
  T_CF_FEAT    * cfFeat;      /* points to CF feature list element */
  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;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  TRACE_FUNCTION ("cmhSS_SSActivated()");

/*
 *-------------------------------------------------------------------
 * 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, owner )
            ( cmdBuf );
          cmh_logRslt ( owner, RAT_OK, cmdBuf, -1, -1, -1 );
        }
      }
      break;

   /*
    *----------------------------------------------------------------
    * process result for KSD CF command
    *----------------------------------------------------------------
    */
    case( KSD_CMD_CF ):
      
      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  = KSD_OP_ACT;
      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;

      if( actSS->ssInfo.v_forwardingInfo )
      {
        cmhSS_ksdFillFwdRes( &actSS->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;   /*  1c) 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;   /* 2c) help the BMI about the last code (e+ - de) */
      }
#endif

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CF );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CF, -1, -1, -1 );
      }
      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  = KSD_OP_ACT;
      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;

      if( actSS->ssInfo.v_callBarringInfo )
      {
        cmhSS_ksdFillCbRes( &actSS->ssInfo.callBarringInfo,
                            &ksStat, cbInfo );
      }

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CB );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CB, -1, -1, -1 );
      }
      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  = KSD_OP_ACT;
      ksStat.ir.rKSCW.ssErr = KSD_NO_ERROR;

      if( actSS->ssInfo.v_ssData )
      {
        cmhSS_ksdFillCwRes( &actSS->ssInfo.ssData,
                            &ksStat, cwBSG );
      }
      else
      {
        ksStat.ir.rKSCW.ssCd  = KSD_SS_NONE;
        ksStat.ir.rKSCW.ssSt  = KSD_ST_NONE;
      }

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CW );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CW, -1, -1, -1 );
      }
      break;

  }

/*
 *-------------------------------------------------------------------
 * set service table entry to unused
 *-------------------------------------------------------------------
 */
  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;

}

/*
+-------------------------------------------------------------------+
| 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 )
{
  T_SS_CMD_PRM * pSSCmdPrm;   /* points to SS command parameters */
  T_ACI_KSIR     ksStat;      /* holds KS status */
  T_CF_FEAT    * cfFeat;      /* points to CF feature list element */
  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;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  TRACE_FUNCTION ("cmhSS_SSDeactivated()");

/*
 *-------------------------------------------------------------------
 * 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, owner )
            ( cmdBuf );
          cmh_logRslt ( owner, RAT_OK, cmdBuf, -1, -1, -1 );
        }
      }
      break;

   /*
    *----------------------------------------------------------------
    * process result for KSD CF command
    *----------------------------------------------------------------
    */
    case( KSD_CMD_CF ):

      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  = KSD_OP_DEACT;
      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;

      if( deactSS->ssInfo.v_forwardingInfo )
      {
        cmhSS_ksdFillFwdRes( &deactSS->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;   /* 1d) 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;   /* 2d) help the BMI about the last code (e+ - de) */
      }
#endif

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CF );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CF, -1, -1, -1 );
      }
      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  = KSD_OP_DEACT;
      ksStat.ir.rKSCF.ssErr = KSD_NO_ERROR;

      if( deactSS->ssInfo.v_callBarringInfo )
      {
        cmhSS_ksdFillCbRes( &deactSS->ssInfo.callBarringInfo,
                            &ksStat, cbInfo );
      }

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CB );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CB, -1, -1, -1 );
      }
      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  = KSD_OP_DEACT;
      ksStat.ir.rKSCW.ssErr = KSD_NO_ERROR;

      if( deactSS->ssInfo.v_ssData )
      {
        cmhSS_ksdFillCwRes( &deactSS->ssInfo.ssData,
                            &ksStat, cwBSG );
      }

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_CW );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_CW, -1, -1, -1 );
      }
      break;
  }

/*
 *-------------------------------------------------------------------
 * set service table entry to unused
 *-------------------------------------------------------------------
 */
  ssShrdPrm.stb[sId].ntryUsdFlg = FALSE;

}

/*
+-------------------------------------------------------------------+
| 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;
  UBYTE        cmdBuf = ssShrdPrm.stb[sId].curCmd; 

  TRACE_FUNCTION ("cmhSS_getPassword()");

  if(owner EQ OWN_SAT)
  {
    TRACE_EVENT("Owner SAT");
  }

/*
 *-------------------------------------------------------------------
 * check for mandatory info
 *-------------------------------------------------------------------
 */
  if( ! getPWD -> v_guidanceInfo  )
  {
    ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

    R_AT( RAT_CME, owner )
      ( cmdBuf, CME_ERR_NotPresent );
    cmh_logRslt ( owner, RAT_CME, cmdBuf, -1, -1, CME_ERR_NotPresent );
    return;
  }
/*
 *-------------------------------------------------------------------
 * check for command context
 *-------------------------------------------------------------------
 */
  switch( ssShrdPrm.stb[sId].curCmd )
  {
   /*
    *----------------------------------------------------------------
    * 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 > OWN_NONE) /* Just to remove LINT warning */
      {
        pSSCmdPrm = &cmhPrm[owner].ssCmdPrm;
      

        switch( getPWD -> guidanceInfo )
        {
          case( GUI_ENTER_PW ):
            if(strcmp((CHAR*)pSSCmdPrm->CXXXpwd, "FFFF") 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, owner )
                ( AT_CMD_CPWD, CME_ERR_WrongPasswd );
              cmh_logRslt ( owner, RAT_CME, AT_CMD_CPWD, -1, -1, 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, owner )
              ( AT_CMD_CPWD, CME_ERR_WrongPasswd );
            cmh_logRslt ( owner, RAT_CME, AT_CMD_CPWD, -1, -1, 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;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

  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, owner )
        ( AT_CMD_CPWD );
      cmh_logRslt ( owner, RAT_OK, AT_CMD_CPWD, -1, -1, -1 );
      break;

   /*
    *----------------------------------------------------------------
    * process result for KSD PWD command
    *----------------------------------------------------------------
    */
    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 );
      }

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;

        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        /* terminate command */
        R_AT( RAT_OK, owner )
          ( KSD_CMD_PWD );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_PWD, -1, -1, -1 );
      }
      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 )
  {
   /* process result for %CCBS  command */
     case( AT_CMD_CCBS ):
      /* terminate command */
      R_AT( RAT_OK, owner )
        ( AT_CMD_CCBS );
      cmh_logRslt ( owner, RAT_OK, AT_CMD_CCBS, -1, -1, -1 );
      break;

   /* process result for KSD CCBS command */
    case( 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, owner )
        ( KSD_CMD_CCBS );
      cmh_logRslt (owner, RAT_OK, KSD_CMD_CCBS, -1, -1, -1 );
      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
 *-------------------------------------------------------------------
 */
  if( ussdNtfy -> v_ussdArg )
  {
    if( ussdNtfy -> ussdArg.v_ussdDataCodingScheme )
      dcs = ussdNtfy -> ussdArg.ussdDataCodingScheme;

    if( ussdNtfy -> ussdArg.v_ussdString )
    {
      MALLOC(ussd, sizeof(T_ACI_USSD_DATA));
      
      /* SDU offset is assumed to be zero for ussd string */
      ussd->len = ussdNtfy -> ussdArg.ussdString.l_ussdString>>3;

      if( utl_getAlphabetCb( (UBYTE)dcs ) EQ 0 ) /* 7bit alphabet */
      {
        ussd->len = utl_cvt7To8( ussdNtfy -> ussdArg.ussdString.b_ussdString,
                                ussd->len,
                                ussd->data,
                                0 );
      }
      else
        memcpy( ussd->data, ussdNtfy -> ussdArg.ussdString.b_ussdString,
                ussd->len );

      TRACE_EVENT_P1("USSD str len: %d", ussd->len);
      ussd->data[ussd->len]=0x00;
    }

    for( idx = 0; idx < CMD_SRC_MAX; idx++ )
    {
      R_AT( RAT_CUSD, 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)
  {
    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;
  UBYTE           srcId = srcId_cb;
  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 )
  {
    if( ussdReq -> ussdArg.v_ussdDataCodingScheme )
      dcs = ussdReq -> ussdArg.ussdDataCodingScheme;

    if( ussdReq -> ussdArg.v_ussdString )
    {
      MALLOC(ussd, sizeof(T_ACI_USSD_DATA));
      /* SDU offset is assumed to be zero for ussd string */
      ussd->len = ussdReq -> ussdArg.ussdString.l_ussdString>>3;

      if( utl_getAlphabetCb( (UBYTE)dcs ) EQ 0 ) /* 7bit alphabet */
      {
        ussd->len = utl_cvt7To8( ussdReq -> ussdArg.ussdString.b_ussdString,
                                ussd->len,
                                ussd->data,
                                0 );
      }
      else
        memcpy( ussd->data, ussdReq -> ussdArg.ussdString.b_ussdString,
                ussd->len );

      ussd->data[ussd->len]=0x00;
    }

    if(ssShrdPrm.stb[sId].curCmd EQ AT_CMD_CUSD )
    {
      R_AT( RAT_CUSD, ssShrdPrm.stb[sId].srvOwn )
        ( CUSD_MOD_YesActReq, ussd, dcs );
    }
    else if (ssShrdPrm.stb[sId].curCmd EQ 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;

      R_AT( RAT_KSIR, ssShrdPrm.stb[sId].srvOwn )
          ( &ksStat );     
    }
    else
    {
      for( idx = 0; idx < CMD_SRC_MAX; idx++ )
      {
        R_AT( RAT_CUSD, 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;
  UBYTE           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_SAT) OR (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;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;
  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;

          if( utl_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, owner )
            ( CUSD_MOD_NoActReq, ussd, dcs );
          
          MFREE(ussd);
        }
      }
      else
      {
        R_AT( RAT_CUSD, owner )
        ( CUSD_MOD_NoActReq, NULL, ACI_NumParmNotPresent );
      }

      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
      break;

    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;

          if( utl_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);

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        R_AT( RAT_OK, owner )
          ( KSD_CMD_USSD );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_USSD, -1, -1, -1 );
      }
      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;
  UBYTE           cmdBuf = ssShrdPrm.stb[sId].curCmd;

#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, owner )
          ( CUSD_MOD_NoActReq, ussd, 0 );
        MFREE(ussd);
      }
      else
      {
        R_AT( RAT_CUSD, owner )
          ( CUSD_MOD_NoActReq, NULL, ACI_NumParmNotPresent );
      }

      ssShrdPrm.stb[sId].curCmd = AT_CMD_NONE;
      break;

    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;

      if(check_ksd_error( owner, sId, &ksStat ))
      {
        cmhPrm[owner].ssCmdPrm.mltyTrnFlg = 0;

        R_AT( RAT_CME, owner )
          ( 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 = owner;
        
        #if defined (MFW)
          if (ksStat.srcId NEQ CMD_SRC_LCL)
          {
            R_AT( RAT_KSIR, CMD_SRC_LCL)( &ksStat );
          }
        #endif

        R_AT( RAT_KSIR, owner )
          ( &ksStat );

        R_AT( RAT_OK, owner )
          ( KSD_CMD_USSD );
        cmh_logRslt ( owner, RAT_OK, KSD_CMD_USSD, -1, -1, -1 );
      }
      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;
  UBYTE         current_cmd = ssShrdPrm.stb[sId].curCmd, 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 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, idx  )( errCd, NULL, 
                                ACI_NumParmNotPresent);
    }
  }
  else
  {
    R_AT( RAT_CME, owner )( current_cmd, error );
    cmh_logRslt ( owner, RAT_CME, current_cmd, -1, -1, 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_OpNotSupp;
  
  TRACE_FUNCTION ("mapSSerrorCME(): map SS err to CME err");

  switch(SSerrCode)
  {
    
  case ERR_NEG_PWD_CHECK:
    mapped_SS2cme = CME_ERR_WrongPasswd;
    break;
    
  default:
    mapped_SS2cme = CME_ERR_OpNotSupp;
    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;
  UBYTE          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_SAT )
  {
    /* send error message to SAT */
    psaSAT_SSRejComp(RSLT_NTW_UNAB_PROC);

    /* free SS Entry */
    
    cmhPrm[current_owner].ssCmdPrm.mltyTrnFlg = 0;
        
    ssShrdPrm.stb[sId].ntryUsdFlg   = FALSE;
    ssShrdPrm.stb[sId].srvOwn       = NO_VLD_OWN;
    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, idx ) ( CUSD_MOD_TerminatedByNetwork, NULL, 0 );
        }     
      }
      break;
    }
    case( AT_CMD_COLP ):
    {
      R_AT( RAT_COLP, current_owner )
        ( COLP_STAT_Unknown, NULL, NULL, NULL, NULL, NULL);
      
      R_AT( RAT_OK, current_owner )
        ( AT_CMD_COLP);
      break;
    }
    case( AT_CMD_CLIP ):
    {
      R_AT( RAT_CLIP, current_owner )
        ( CLIP_STAT_Unknown, NULL, NULL, PRES_NOT_PRES, NULL, NULL, NULL);

      R_AT( RAT_OK, current_owner )
        ( AT_CMD_CLIP);
      break;
    }
  /* Following case added to fix issue ACI-SPR-23109 */
    case( AT_CMD_CPWD ):
    {
      R_AT( RAT_CME, current_owner )
        ( AT_CMD_CPWD, CME_ERR_WrongPasswd );
      R_AT( RAT_OK, current_owner )
        ( AT_CMD_CPWD);
      break;
    }
    case( AT_CMD_CLIR ):
    {
      pCCCmdPrm = &cmhPrm[current_owner].ccCmdPrm;

      R_AT( RAT_CLIR, current_owner )
        ( pCCCmdPrm -> CLIRmode, CLIR_STAT_Unknown);

      R_AT( RAT_OK, 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, current_owner )( cmdBuf, mapped_SS2cme );
          cmh_logRslt ( current_owner, RAT_CME, cmdBuf, -1, -1, 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 = 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, 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 );
}


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

