view src/g23m-gsm/ss/ss_ss.c @ 263:b5e8dfd114a7

Switch_ON(): go into charging boot mode on either CHGSTS or CHGPRES If someone were to plug and then unplug a charger into a switched-off phone in an extremely brief "glitch" manner, we should do an automatic power-off on boot in this condition. When we were checking only CHGPRES in Switch_ON(), we would go into Misc boot state instead, which is undesirable. Now if we have a CHGSTS but not CHGPRES condition, we will go into charging boot mode, and FCBM will then do the automatic power-off upon detecting absence of the charger in its periodic polling.
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 14 May 2021 05:50:36 +0000
parents fa8dc04885d8
children
line wrap: on
line source

/* 
+----------------------------------------------------------------------------- 
|  Project :  
|  Modul   :  
+----------------------------------------------------------------------------- 
|  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 modul defines the functions for the supplementary
|             services.
+----------------------------------------------------------------------------- 
*/ 

#ifndef SS_SS_C
#define SS_SS_C

#define ENTITY_SS

/*==== INCLUDES ===================================================*/
#if defined (NEW_FRAME)

#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "typedefs.h"
#include "pcm.h"
#include "pconst.cdg"
#include "mconst.cdg"
#include "message.h"
#include "ccdapi.h"
#include "vsi.h"
#include "custom.h"
#include "gsm.h"
#include "prim.h"
#include "cnf_ss.h"
#include "mon_ss.h"
#include "pei.h"
#include "tok.h"
#include "ss.h"
#include "ss_em.h"

#else

#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "stddefs.h"
#include "pcm.h"
#include "pconst.cdg"
#include "mconst.cdg"
#include "message.h"
#include "ccdapi.h"
#include "custom.h"
#include "gsm.h"
#include "prim.h"
#include "cnf_ss.h"
#include "mon_ss.h"
#include "vsi.h"
#include "pei.h"
#include "tok.h"
#include "ss.h"
#include "ss_em.h"

#endif

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

/*==== PRIVAT =====================================================*/

/*==== VARIABLES ==================================================*/
#ifdef TI_PS_HCOMM_CHANGE
#else
#if defined (NEW_FRAME)
EXTERN T_HANDLE         hCommMM;         /* MM   Communication       */
EXTERN T_HANDLE         hCommMMI;        /* MMI  Communication       */
#else
EXTERN T_VSI_CHANDLE  hCommMM;         /* MM   Communication       */
EXTERN T_VSI_CHANDLE  hCommMMI;        /* MMI  Communication       */
#endif
#endif

#ifdef SS_TEST
UBYTE  trc[100];
#endif

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

/*
 * -------------------------------------------------------------------
 * PRIMITIVE Processing functions
 * -------------------------------------------------------------------
 */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_init_ss_data            |
+--------------------------------------------------------------------+

  PURPOSE : Initialize the SS data for the module supplem. services.

*/

GLOBAL void ss_init_ss_data (void)
{
  GET_INSTANCE_DATA;
  UBYTE i;
  TRACE_FUNCTION ("ss_init_ss_data()");

  ss_init ();
  for (i = 0; i < MAX_INST; i++)
    SET_SS_STATE(ss_data->ss_state,i,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_mmss_error_ind          |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MMSS_ERROR_IND.

*/

GLOBAL void ss_mmss_error_ind (T_MMSS_ERROR_IND  *mmss_error_ind)
{
  GET_INSTANCE_DATA;	
  TRACE_FUNCTION ("ss_mmss_error_ind()");

  ss_data->ti = mmss_error_ind->ti;
  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_CONNECTION_PENDING:
    	PFREE (P2D(ss_data->prim[ss_data->ti]));
      ss_data->prim[ss_data->ti] = NULL;
      /*FALLTHROUGH*/
    case SS_CONNECTED:
    {
      PALLOC (mnss_end_ind, MNSS_END_IND);

      ss_data->ti = mmss_error_ind->ti;

      mnss_end_ind->cause = mmss_error_ind->cause;
      mnss_end_ind->ti    = ss_data->ti;
      memset (&mnss_end_ind->fac_inf, 0, sizeof (T_fac_inf)) ;

      SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

      PSENDX (MMI, mnss_end_ind);
      {
        PALLOC (mmss_release_req, MMSS_RELEASE_REQ);
        mmss_release_req->ti = ss_data->ti;
        PSENDX (MM, mmss_release_req);
      }


      MM_EM_MM_CONNECTION_ABORTED;

      break;
    }

    default:
      break;
  }
  PFREE (mmss_error_ind);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_mmss_establish_cnf      |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MMSS_ESTABLISH_CNF.

*/
GLOBAL void ss_mmss_establish_cnf (T_MMSS_ESTABLISH_CNF *mmss_establish_cnf)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("ss_mmss_establish_cnf()");

  ss_data->ti = mmss_establish_cnf->ti;

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_CONNECTION_PENDING:
      CCD_START;
      {
        T_MNSS_BEGIN_REQ * mnss_begin_req;
        MCAST (ss_register, U_SS_REGISTER);

        ss_register->msg_type    = U_SS_REGISTER;
        mnss_begin_req = (T_MNSS_BEGIN_REQ *)P2D(ss_data->prim[ss_data->ti]);

        
        ss_register->ss_version.c_ver = mnss_begin_req->ss_ver.len;
        if(ss_register->ss_version.c_ver)
        {
          ss_register->v_ss_version = TRUE; 
          memcpy (ss_register->ss_version.ver, 
                  mnss_begin_req->ss_ver.ver,
                  ss_register->ss_version.c_ver);
        }
        else
        {
          ss_register->v_ss_version = FALSE; 
        }
       
        ss_register->ss_facility.c_fac_info = mnss_begin_req->fac_inf.l_fac >> 3;
        if(ss_register->ss_facility.c_fac_info)
        {
          ss_register->v_ss_facility = TRUE;
          memcpy (ss_register->ss_facility.fac_info,
                  &mnss_begin_req->fac_inf.fac[mnss_begin_req->fac_inf.o_fac >>3],
                  ss_register->ss_facility.c_fac_info);
        }
        else
        {
          ss_register->v_ss_facility = FALSE;
        }

        SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_CONNECTED); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

        PFREE (P2D(ss_data->prim[ss_data->ti]));
        ss_data->prim[ss_data->ti] = NULL;
        ss_for_data_req ((USHORT)(LEN_U_SS_REGISTER + ss_register->ss_facility.c_fac_info * 8));

        MM_EM_MM_CONNECTION_ESTABLISHED;  
      
      }
      CCD_END;
      break;

    default:
      break;
  }
  PFREE (mmss_establish_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_mmss_release_ind        |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MMSS_RELEASE_IND.

*/
GLOBAL void ss_mmss_release_ind (T_MMSS_RELEASE_IND *mmss_release_ind)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("ss_mmss_release_ind()");

  ss_data->ti = mmss_release_ind->ti;

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_CONNECTION_PENDING:
    	PFREE (P2D(ss_data->prim[ss_data->ti]));
      ss_data->prim[ss_data->ti] = NULL;

      MM_EM_MM_CONNECTION_FAILED;
      
      /*FALLTHROUGH*/
    case SS_CONNECTED:
    {
      PALLOC (mnss_end_ind, MNSS_END_IND);

      mnss_end_ind->ti = ss_data->ti;
      mnss_end_ind->cause = mmss_release_ind->cause;
      memset (&mnss_end_ind->fac_inf, 0, sizeof (T_fac_inf));
      SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

      MM_EM_MM_CONNECTION_RELEASED;

      PSENDX (MMI, mnss_end_ind);
      break;
    }
    default:
      break;
  }
  PFREE (mmss_release_ind);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_mnss_begin_req          |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSS_BEGIN_REQ.

*/
GLOBAL void ss_mnss_begin_req (T_MNSS_BEGIN_REQ *mnss_begin_req)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("ss_mnss_begin_req()");

  ss_data->ti = mnss_begin_req->ti;

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_IDLE:
    {
      if (ss_data->ti < 7)
      {
#if defined (NEW_FRAME)
        ss_data->prim[ss_data->ti] = (T_PRIM *)D2P(mnss_begin_req);
#else
        ss_data->prim[ss_data->ti] = D2P(mnss_begin_req);
#endif
        {
          PALLOC (mmss_establish_req, MMSS_ESTABLISH_REQ);

          mmss_establish_req->ti = ss_data->ti;
          SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_CONNECTION_PENDING); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

          PSENDX (MM, mmss_establish_req);

          MM_EM_MM_CONNECTION_STARTED;
         
        }
        return; /* Don't free primitive */
      }
      break;
    }
    default:
      break;
  }
  PFREE (mnss_begin_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_mnss_end_req            |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSS_END_REQ.

*/
GLOBAL void ss_mnss_end_req (T_MNSS_END_REQ *mnss_end_req)
{
  GET_INSTANCE_DATA;	
  TRACE_FUNCTION ("ss_mnss_end_req()");

  ss_data->ti                = mnss_end_req->ti;

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_CONNECTION_PENDING:
      if (ss_data->prim[ss_data->ti] NEQ NULL)
      {
        /* Free stored primitive */
        PFREE (P2D(ss_data->prim[ss_data->ti]));
        ss_data->prim[ss_data->ti] = NULL;
      }

      /* Send MMSS_RELEASE_REQ */
      {
        PALLOC (mmss_release_req, MMSS_RELEASE_REQ); /* T_MMSS_RELEASE_REQ */
        mmss_release_req->ti = ss_data->ti;
        PSENDX (MM, mmss_release_req);
      }

      /* Next state is SS_IDLE */
      SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */
      break;

    case SS_CONNECTED:
      CCD_START;
      {
        MCAST (ss_rel_comp, B_SS_REL_COMP);

        ss_rel_comp->msg_type      = B_SS_REL_COMP;
        ss_rel_comp->v_ss_cause    = FALSE;
        ss_rel_comp->v_ss_facility = (mnss_end_req->fac_inf.l_fac) ?
                                                       TRUE : FALSE;
        ss_rel_comp->ss_facility.c_fac_info = mnss_end_req->fac_inf.l_fac >> 3;
        memcpy (ss_rel_comp->ss_facility.fac_info,
                &mnss_end_req->fac_inf.fac[mnss_end_req->fac_inf.o_fac >>3],
                ss_rel_comp->ss_facility.c_fac_info);
        if (ss_rel_comp->v_ss_facility)
        {
          ss_for_data_req ((USHORT)(LEN_U_SS_RELEASE_COMPLETE + 
                                    ss_rel_comp->ss_facility.c_fac_info * 8));
        }
        else
        {
          ss_for_data_req (LEN_U_SS_RELEASE_COMPLETE);
        }

        {
          PALLOC (mmss_release_req, MMSS_RELEASE_REQ);

          mmss_release_req->ti = ss_data->ti;
          ss_data->ss_state = SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

          PSENDX (MM, mmss_release_req);
        }
      }
      CCD_END;

      MM_EM_MM_RELEASE_COMPLETE_SENT;  

      break;
  }
  PFREE (mnss_end_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_mnss_facility_req       |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSS_FACILITY_REQ.

*/

GLOBAL void ss_mnss_facility_req (T_MNSS_FACILITY_REQ *mnss_facility_req)
{
  GET_INSTANCE_DATA;
  CCD_START;
  {
    MCAST (ss_facility, U_SS_FACILITY);

    TRACE_FUNCTION ("ss_mnss_facility_req()");

    switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
    {
      case SS_CONNECTED:
        ss_data->ti = mnss_facility_req->ti;
        ss_facility->msg_type = U_SS_FACILITY;
        ss_facility->ss_facility.c_fac_info = mnss_facility_req->fac_inf.l_fac >> 3;
        memcpy (ss_facility->ss_facility.fac_info,
                &mnss_facility_req->fac_inf.fac[mnss_facility_req->fac_inf.o_fac >>3],
                ss_facility->ss_facility.c_fac_info);
        ss_for_data_req ((USHORT)(LEN_U_SS_FACILITY + 
                                  ss_facility->ss_facility.c_fac_info * 8));

        MM_EM_FACILITY_MESSAGE_SENT;

        break;
      default:
        break;
    }
  }
  CCD_END;
  PFREE (mnss_facility_req);
}

/*
 * -------------------------------------------------------------------
 * SIGNAL Processing functions
 * -------------------------------------------------------------------
 */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_b_ss_rel_comp           |
+--------------------------------------------------------------------+

  PURPOSE : Process the signal B_SS_REL_COMP.

*/

GLOBAL void ss_b_ss_rel_comp (void)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("ss_b_ss_rel_comp()");

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_IDLE:
      /* Unrecognised TI : Ignore Message TS 24.010 Section 3.7.3 a)*/
      {
        PALLOC (mmss_release_req, MMSS_RELEASE_REQ); /* T_MMSS_RELEASE_REQ */
        mmss_release_req->ti = ss_data->ti;
        PSENDX (MM, mmss_release_req);
      }
      break;

    case SS_CONNECTED:
      if (! ss_data->est_flag)
      {
        MCAST (ss_rel_comp, B_SS_REL_COMP);
        PALLOC (mnss_end_ind, MNSS_END_IND);

        mnss_end_ind->ti = ss_data->ti;
        if (ss_rel_comp->v_ss_cause)
          mnss_end_ind->cause = CAUSE_MAKE(DEFBY_STD, 
                                           ORIGSIDE_NET, 
                                           SS_ORIGINATING_ENTITY, 
                                           ss_rel_comp->ss_cause.cs);
        else
          mnss_end_ind->cause = CAUSE_MAKE(DEFBY_CONDAT, 
                                           ORIGSIDE_NET, 
                                           SS_ORIGINATING_ENTITY, 
                                           NOT_PRESENT_8BIT);
        memcpy (mnss_end_ind->fac_inf.fac, ss_rel_comp->ss_facility.fac_info,
                ss_rel_comp->ss_facility.c_fac_info);
        mnss_end_ind->fac_inf.l_fac = ss_rel_comp->ss_facility.c_fac_info << 3;
        mnss_end_ind->fac_inf.o_fac = 0;

        SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

        PSENDX (MMI, mnss_end_ind);
        {
          PALLOC (mmss_release_req, MMSS_RELEASE_REQ);
          mmss_release_req->ti = ss_data->ti;
          PSENDX (MM, mmss_release_req);
        }

        MM_EM_MM_RELEASE_COMPLETE_RECEIVED;

      }
      break;

    default:
      /* Should never reach here */
      TRACE_FUNCTION("**BAD SS State**");
      break;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_d_ss_facility           |
+--------------------------------------------------------------------+

  PURPOSE : Process the signal D_SS_FACILITY.

*/

GLOBAL void ss_d_ss_facility (void)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("ss_d_ss_facility()");

  switch( ss_data->error )
  {
    case CAUSE_INVALID_MAND_INFO:
      /* Send RELEASE COMPLETE with this cause TS 24.010 Section 3.7.4*/
      send_rel_comp(CAUSE_INVALID_MAND_INFO);
      return;

    default:
      break;
  }

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_IDLE:
      /* Unrecognised TI : TS 24.010 Section 3.7.3 b)*/
      send_rel_comp(CAUSE_INVALID_TI);
      break;

    case SS_CONNECTED:
    {
      MCAST (ss_facility, U_SS_FACILITY);

      if (! ss_data->est_flag)
      {
        PALLOC (mnss_facility_ind, MNSS_FACILITY_IND);

        mnss_facility_ind->ti = ss_data->ti;

        memcpy (mnss_facility_ind->fac_inf.fac, ss_facility->ss_facility.fac_info,
                ss_facility->ss_facility.c_fac_info);
        mnss_facility_ind->fac_inf.l_fac = ss_facility->ss_facility.c_fac_info << 3;
        mnss_facility_ind->fac_inf.o_fac = 0;

        MM_EM_FACILITY_MESSAGE_RECEIVED;
       
        PSENDX (MMI, mnss_facility_ind);
      }
      break;
    }
    default:
      /* Should never reach here */
      TRACE_FUNCTION("**BAD SS State**");
      break;
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_d_ss_register           |
+--------------------------------------------------------------------+

  PURPOSE : Process the signal D_SS_REGISTER.

*/

GLOBAL void ss_d_ss_register (void)
{
  GET_INSTANCE_DATA;
  MCAST (ss_register, U_SS_REGISTER);

  TRACE_FUNCTION ("ss_d_ss_register()");

  switch( ss_data->error )
  {
    case CAUSE_INVALID_MAND_INFO:
      /* Send RELEASE COMPLETE with this cause TS 24.010 Section 3.7.4*/
      send_rel_comp(CAUSE_INVALID_MAND_INFO);
      return;

    default:
      break;
  }

  switch (GET_SS_STATE(ss_data->ss_state,ss_data->ti))
  {
    case SS_CONNECTED:
      /* This TI is already being used therefore ignore Message */
      /* TS 24.010 Section 3.7.3 c) */
      break;

    case SS_IDLE:
      if (ss_data->est_flag AND 
          (ss_data->ti >= 8 AND ss_data->ti < 15))
      {
        PALLOC (mnss_begin_ind, MNSS_BEGIN_IND);

        mnss_begin_ind->ti = ss_data->ti;
        memcpy (mnss_begin_ind->fac_inf.fac, ss_register->ss_facility.fac_info,
                ss_register->ss_facility.c_fac_info);
        mnss_begin_ind->fac_inf.l_fac = ss_register->ss_facility.c_fac_info << 3;
        mnss_begin_ind->fac_inf.o_fac = 0;
        
        SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_CONNECTED); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */

        MM_EM_REGISTER_MESSAGE_RECEIVED;

        PSENDX (MMI, mnss_begin_ind);
      }
      else
      {
        /* REGISTER with set TI flag received. Release the connection */ 
        PALLOC (mmss_release_req, MMSS_RELEASE_REQ); /* T_MMSS_RELEASE_REQ */
        mmss_release_req->ti = ss_data->ti;
        PSENDX (MM, mmss_release_req);
      }
      break;

    default:
      /* Should never reach here */
      TRACE_FUNCTION("**BAD SS State**");
      break;
  }
}

/*
 * -------------------------------------------------------------------
 * Procedures
 * -------------------------------------------------------------------
 */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : ss_init                    |
+--------------------------------------------------------------------+

  PURPOSE :

*/

GLOBAL void ss_init (void)
{
  GET_INSTANCE_DATA;
  memset (ss_data, 0, sizeof (T_SS_DATA));
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (6147)       MODULE  : SS_SS                      |
| STATE   : code                ROUTINE : send_rel_comp              |
+--------------------------------------------------------------------+

  PURPOSE : This functions sends a RELEASE COMPLETE message with a 
            specified 'cause' value

*/

GLOBAL void send_rel_comp(U8 cause)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("send_rel_comp()");

  {
    MCAST (ss_rel_comp, B_SS_REL_COMP);

    ss_rel_comp->msg_type        = B_SS_REL_COMP;
    ss_rel_comp->v_ss_facility   = FALSE;
    ss_rel_comp->v_ss_cause      = TRUE;

    ss_rel_comp->ss_cause.v_cs2  = TRUE;
    ss_rel_comp->ss_cause.cs2    = CS_GSM_PLMN;
 
    ss_rel_comp->ss_cause.v_loc  = TRUE;
    ss_rel_comp->ss_cause.loc    = LOC_PUB_NET_REMOTE_USER;

    ss_rel_comp->ss_cause.v_rec  = TRUE;
    ss_rel_comp->ss_cause.rec    = 0x00;

    ss_rel_comp->ss_cause.v_cs   = TRUE;
    ss_rel_comp->ss_cause.cs     = cause;

    ss_rel_comp->ss_cause.c_diag = 0x00;

    ss_for_data_req(LEN_U_SS_RELEASE_COMPLETE);
  }

  {
    PALLOC (mmss_release_req, MMSS_RELEASE_REQ);
    mmss_release_req->ti = ss_data->ti;
    PSENDX (MM, mmss_release_req);
  }

  SET_SS_STATE(ss_data->ss_state,ss_data->ti,SS_IDLE); /*lint !e502 (Warning -- Warning 502: Expected unsigned type ) */
}

/*
+--------------------------------------------------------------------+
| | STATE   : code                ROUTINE : ss_check_critical_error    |
+--------------------------------------------------------------------+

  PURPOSE : This function checks wheter a critical error has been 
            detected in the air message. Critical errors which prevent 
            the treatment of an air message are 
            - invalid Message ID
            - mandatory IE missing
            - IE coded as comprehension required missing
*/

GLOBAL BOOL ss_check_critical_error (UINT ss_err)
{
  TRACE_FUNCTION ("cc_check_critical_error ()");
  if (ss_err  EQ CAUSE_INVALID_MAND_INFO       OR 
      ss_err  EQ CAUSE_MESSAGE_TYPE_NOT_IMPLEM OR
      ss_err  EQ ERR_INVALID_MID               OR
      ss_err  EQ CAUSE_SERVICE_NOT_IMPLEM        )
  return (TRUE);
  else
  return (FALSE);
}
#endif /* #ifndef SS_SS_C */