view src/g23m-gsm/sms/sms_tlp.c @ 265:e57bfdadf49a

mmiIcons.c: fix bogus icnType in incoming_call_animate[] The incoming call animation icons are actually drawn in 256-color format, but they were incorrectly declared as BMP_FORMAT_32BIT_COLOUR in the incoming_call_animate[] array. Why were they still getting displayed correctly despite this bogosity? Answer: because the mmi_dialogs_animation_new_CB() function overrides the icon bitmap type to 0x02, which means 256-color format. Needless to say, the icon format should be made correct at the source of the data, and at some later point we may need to remove the override from the animation display function.
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 17 May 2021 07:18:36 +0000
parents fa8dc04885d8
children
line wrap: on
line source

/*
+-----------------------------------------------------------------------------
|  Project :  GSM-F&D (8411)
|  Modul   :  SMS_TLP
+-----------------------------------------------------------------------------
|  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 transfer layer
|             capability of the module Short Message Service.
+-----------------------------------------------------------------------------
*/
#ifndef SMS_TLP_C
#define SMS_TLP_C
 
#define ENTITY_SMS

/*==== INCLUDES ===================================================*/

#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include "typedefs.h"
#include "pcm.h"
#include "vsi.h"
#include "custom.h"
#include "gsm.h"
#include "message.h"
#include "ccdapi.h"
#include "prim.h"
#include "cus_sms.h"
#include "cnf_sms.h"
#include "mon_sms.h"
#include "pei.h"
#include "tok.h"
#include "sms.h"
#include "gdi.h"
#include "sms_em.h"

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

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

/*==== VARIABLES ==================================================*/

/*==== TEST =======================================================*/

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

/* Implements Measure# 7 */
/*
+----------------------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                                  |
| STATE   : code                ROUTINE : tl_sim_rd_record_update_state            |
+----------------------------------------------------------------------------------+

  PURPOSE : This routine process primitive SIM_READ_RECORD_CONF for the 
            cases MMI_FIND_FIRST and MMI_FIND_NEXT
            
*/

LOCAL BOOL tl_sim_rd_record_update_state(T_SIM_READ_RECORD_CNF *read_cnf)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION("tl_sim_rd_record_update_state()");  
   
  if ((GET_STATE(STATE_MMI) EQ MMI_FIND_FIRST 
       AND sms_data->sim_mem_update)
       OR (GET_STATE(STATE_MMI) EQ MMI_STATE_UPDATE 
       AND sms_data->sim_mem_update))
  {
    /*
     * Either the SMS record has been changed or both the SMS record
     * and the SMS status have been changed 
     */
     PFREE (read_cnf);
     sms_data->stored_mmi_state = MMI_IDLE;
     return TRUE; /* return; */
  }
  else if (GET_STATE(STATE_MMI) EQ MMI_STATE_UPDATE)
  {
    /*
     * Only SMS record's status has been changed. 
     */
    sms_data->stored_read_cnf = read_cnf;
    return TRUE;  /* return; */
  }
  sms_data->stored_mmi_state = MMI_IDLE;
  
  return FALSE;
}



/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_CP                     |
| STATE   : code                ROUTINE : tl_init                    |
+--------------------------------------------------------------------+

  PURPOSE : Initialize the transfer layer.

*/

GLOBAL void tl_init ()
{
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_init()");

  SMS_ENT_STATE(sms_data) = SMS_STATE_NOT_AVAILABLE;

  memset (sms_data->data, 0, sizeof (sms_data->data));

  /* This is only for simulation tests*/
  sms_data->data[INST_MO].ti = 6; 

  SMS_SIM_MEM_AVAIL(sms_data)   = TRUE;
  SMS_MEM_CFG(sms_data)         = MEM_SM;
  SMS_MT_HANDLING(sms_data)     = MT_DEF;
  SMS_ST_REPORT(sms_data)       = DS0;
  SMS_SIM_PHASE(sms_data)       = PHASE_2_SIM;
  SMS_MT_ACK_MODE(sms_data)     = SMS_MHC_DEF;
  SMS_NETWORK(sms_data)         = NW_SIM_NONE;

  sms_data->init_done      = FALSE;

  SMS_SIM_PROP(sms_data).status_field = sms_data->sim_status_field;
  SMS_SIM_PROP(sms_data).pid_field  = sms_data->sim_pid_field;
  SMS_SIM_PROP(sms_data).mem_type   = MEM_SM;
  SMS_SIM_PROP(sms_data).max_record = 0;
  SMS_SIM_PROP(sms_data).any_valid  = FALSE;
  /* SMS_ME_PROP(sms_data).status_and_pid = sms_data->me_status_field; */
  /* SMS_ME_PROP(sms_data).status_and_pid = sms_data->me_pid_field; */
  SMS_ME_PROP(sms_data).status_field = NULL;
  SMS_ME_PROP(sms_data).pid_field   = NULL;
  SMS_ME_PROP(sms_data).mem_type    = MEM_ME;
  SMS_ME_PROP(sms_data).max_record  = 0;
  SMS_ME_PROP(sms_data).any_valid   =  FALSE;
  sms_data->sim_mem_update        = FALSE;
#ifdef SIM_TOOLKIT
  sms_data->download_sms    = FALSE;
  sms_data->file_update_ind = NULL;
  sms_data->stored_mmi_state = MMI_IDLE;
  sms_data->stored_read_cnf = NULL;
#endif
  SMS_RP_RCVD(sms_data) = NULL;
#ifdef FF_CPHS
  SMS_CPHS(sms_data) = FALSE;
#endif
#ifdef GPRS
  SMS_ROUTE_PREF(sms_data) = GPRS_SMS_CCT_ONLY;
#endif
  sms_data->pr_cntrl.delivery_state    = SMS_DELIVER_STATUS_RESUME;
  sms_data->concat_cntrl.concatenation = FALSE;
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_abort_to_mmi        |
+--------------------------------------------------------------------+

  PURPOSE : Abort a SIM related SMS command to MMI.

*/

LOCAL void tl_sim_abort_to_mmi (USHORT error)
{
  GET_INSTANCE_DATA;
  switch (GET_STATE (STATE_MMI))
  {
  case MMI_REPLACE:
#ifdef REL99
    if(SMS_INST.failed_msg_retx EQ FALSE)
    {
#endif

      tl_mnsms_submit_cnf (SMS_INST.act_mem, SMS_INST.act_record,
                           SMS_INST.tp_mr_ret, error, NULL);
#ifdef REL99
    }
    else
    {
      tl_mnsms_retrans_cnf (SMS_INST.act_mem, SMS_INST.act_record,
                            SMS_INST.tp_mr_ret, error, NULL);
    }
#endif
    break;
  case MMI_READ:
    tl_mnsms_read_cnf (SMS_INST.act_mem,
                       SMS_INST.act_record, NULL, error);
    break;
  case MMI_WRITE:
    tl_mnsms_store_cnf (SMS_INST.act_mem, SMS_INST.act_record, error);
    break;
  case MMI_DELETE:
    tl_mnsms_delete_cnf (SMS_INST.act_mem, SMS_INST.act_record, 0, error);
    break;
  default:
    break;
  }
  if (sms_data->access_fifo[1] EQ ACCESS_BY_MMI)
  {
    sms_data->access_fifo[1] = ACCESS_EMPTY;
  }
  else if (sms_data->access_fifo[0] EQ ACCESS_BY_MMI)
  {
    sms_data->access_fifo[0] = ACCESS_EMPTY;
  }
  SET_STATE (STATE_MMI, MMI_IDLE);
#ifdef SIM_TOOLKIT
  if (sms_data->file_update_ind NEQ NULL)
  {
     T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind;
     sms_data->file_update_ind = NULL;
     tl_sim_file_update_ind (file_update_ind);  
  }
  if (sms_data->stored_read_cnf NEQ NULL)
  {
     /*
      * Resets the stored MMI state & read_cnf primitive
      */
     sms_data->stored_mmi_state = MMI_IDLE;  
     PFREE (sms_data->stored_read_cnf);
     sms_data->stored_read_cnf = NULL;
  }
#endif
}

/*---- PRIMITIVES --------------------------------------------------*/

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_configure_req     |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_CONFIGURE_REQ.

*/

GLOBAL void tl_mnsms_configure_req (T_MNSMS_CONFIGURE_REQ *configure_req)
{
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0);

  TRACE_FUNCTION ("tl_mnsms_configure_req()");

  if (sms_data)
  {
     sms_data->mem3 = configure_req->pref_mem_3;
     sms_data->mt   = (configure_req->mt < MT_DEF)? configure_req->mt:
                                                MT_DEF;
     sms_data->ds   = configure_req->ds;
     sms_data->mhc  = configure_req->mhc;

     /*
      * If CMMS mode is enabled, store the current value of cmms_mode in sms_data
      */
     if(configure_req->v_cmms_mode)
     {
        sms_data->cmms_mode = configure_req->cmms_mode;
     }

     /*
      * For CMMS if user has set the value for TMMS timer then store that
      * value in sms_data
      */
     if(configure_req->v_tmms_val)
     {
        sms_data->timer_values[TMMS] = configure_req->tmms_val;
     }
  }
  PFREE (configure_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_mo_serv_req       |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_MO_SERV_REQ.
            (set preferred destination (GPRS/GSM) for MO SM)

*/
#if defined GPRS
GLOBAL void tl_mnsms_mo_serv_req (T_MNSMS_MO_SERV_REQ *mo_serv_req)
{
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_mnsms_mo_serv_req()");
  /*
   * send MNSMS_MO_SERV_CNF with configured pref. dst
   */
  {
    PALLOC (mo_serv_cnf, MNSMS_MO_SERV_CNF);
    memset (mo_serv_cnf, 0, sizeof (T_MNSMS_MO_SERV_CNF));

    if (sms_data) /*lint !e774 always True*/
    {
      sms_data->mo_dst_pref = mo_serv_req->mo_sms_serv;
      mo_serv_cnf->mo_sms_serv = sms_data->mo_dst_pref;

      TRACE_EVENT_P1("MO Path: %d", sms_data->mo_dst_pref);
    }
    else
    {
      mo_serv_cnf->mo_sms_serv = NOT_PRESENT_8BIT;
    }
    PSENDX (MMI, mo_serv_cnf);
  }
  PFREE (mo_serv_req);
}
#endif /* GPRS */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_command_cnf       |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_COMMAND_REQ.
*/

GLOBAL void tl_mnsms_command_cnf (UBYTE tp_mr,
                                  USHORT cause,
                                  T_sms_sdu *sms_sdu)
{
  PALLOC (command_cnf, MNSMS_COMMAND_CNF);

  command_cnf->tp_mr = tp_mr;
  command_cnf->cause = cause;

  if (sms_sdu NEQ NULL)
    memcpy (&command_cnf->sms_sdu, sms_sdu, sizeof (T_sms_sdu));
  else
    memset (&command_cnf->sms_sdu, 0, sizeof (T_sms_sdu));

  PSENDX (MMI, command_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_command_req       |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_COMMAND_REQ.

*/

GLOBAL void tl_mnsms_command_req (T_MNSMS_COMMAND_REQ *command_req)
{
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0);

  TRACE_FUNCTION ("tl_mnsms_command_req()");

  if (sms_data)
  {
    switch (SMS_INST_GET_STATE (STATE_TL))
    {
      case TL_IDLE:
        if (sms_timer_check(TRAM))
        {
           tl_mnsms_command_cnf (NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
        }
        else
        {
#ifdef REL99
           SMS_INST.failed_msg_retx = FALSE;
           if(command_req->auto_rep_flag EQ AUTO_REP_FLAG_ENABLED)
           {
             SMS_INST.tl_retx = 0;
           }
           else
           {
             /* Set to the max value so that retransmission will not be done */
             SMS_INST.tl_retx = TL_MAX_RETANS;
           }
#endif
          /*
           * save sdu
           */
           if (SMS_SDU(sms_data) NEQ NULL)
           {
              MFREE (SMS_SDU(sms_data));
           }
           MALLOC (SMS_SDU(sms_data), sizeof(T_sms_sdu));
           memcpy (SMS_SDU(sms_data), &command_req->sms_sdu, sizeof(T_sms_sdu));
          /*
           * TL state transition TL_ESTABLISH
           * EST state transition EST_CMD
           */
           SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
           SET_STATE (STATE_EST, EST_CMD);
          /*
           * establish connection
           */
           tl_establish_connection(TRUE);
        }
        break;

      default:
        tl_mnsms_command_cnf (NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
    }
  }
  else
  {
    tl_mnsms_command_cnf (NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
  }
  PFREE (command_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_delete_cnf        |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_DELETE_REQ.
*/

GLOBAL void tl_mnsms_delete_cnf (UBYTE mem_type,
                                 UBYTE record,
                                 UBYTE next_rec,
                                 USHORT error)
{
  PALLOC (delete_cnf, MNSMS_DELETE_CNF);

  delete_cnf->mem_type = mem_type;
  delete_cnf->rec_num = record;
  delete_cnf->cause = error;
  delete_cnf->delete_rec_next = next_rec;

  SMS_EM_DELETE_SHORT_MESSAGE;

  PSENDX (MMI, delete_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_delete_req        |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_DELETE_REQ.

*/

GLOBAL void tl_mnsms_delete_req (T_MNSMS_DELETE_REQ *delete_req)
{
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0);
  UBYTE       rec_num;  

  TRACE_FUNCTION ("tl_mnsms_delete_req()");

#ifdef REL99
  /* Check if the last failed message is getting  deleted */
  if( ( delete_req->rec_num  EQ SMS_INST.failed_msg_rec_num) AND
      ( delete_req->mem_type EQ SMS_INST.failed_msg_mem ) AND 
       SMS_DATA_REQ(sms_data) NEQ NULL )
  {    
    PFREE (SMS_DATA_REQ(sms_data));
    SMS_DATA_REQ(sms_data) = NULL;
  }
#endif

  if (sms_data NEQ NULL)
  {
    switch (SMS_INST_GET_STATE (STATE_TL))
    {
    case TL_IDLE:
      switch (delete_req->mem_type)
      {
        case MEM_ME:
          /*
           * Mobile Equipment Memory
           */
          if(delete_req->delete_status NEQ CMGD_DEL_INDEX)
          {
            if(delete_req->rec_num EQ 0)
            {
              /* Status value is given. Find the first record satisfying this status value */
              rec_num = tl_search_record_for_delete (&SMS_ME_PROP(sms_data), 1,
                                                     delete_req->delete_status);
              if(rec_num EQ SMS_RECORD_NOT_EXIST)
              {
                tl_mnsms_delete_cnf (delete_req->mem_type, 0, 0, SIM_NO_ERROR);
                break;
              }
            } 
            else
            {
              if(delete_req->rec_num > sms_data->me_backup.max_record)
              {
                tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, 
                                     (USHORT)((SMS_ME_PROP(sms_data).max_record EQ 0)?
                                     SMS_CAUSE_MEM_FAIL: SMS_CAUSE_INV_INDEX));
                break;
              }
              else
              {
                /* Use the record number that ACI has given */
                rec_num = delete_req->rec_num;
              }
            }
          }
          else
          {
            /* There should be a valid rec_num */
            if(delete_req->rec_num EQ 0 || delete_req->rec_num > sms_data->me_backup.max_record)
            {          
              tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0, 
                                   (USHORT)((SMS_ME_PROP(sms_data).max_record EQ 0)?
                                   SMS_CAUSE_MEM_FAIL: SMS_CAUSE_INV_INDEX));
              break;
            }
            else
            {
             rec_num = delete_req->rec_num;
            }
          }
          
          if (tl_get_status (&SMS_ME_PROP(sms_data), rec_num-1) & 1)
          {
            /*
             * entry is used
             */
            UBYTE data[SIZE_EF_SMS];
            UBYTE next_rec_num = 0;

            data[0] = 0;
            memset (&data[1], 0xFF, SIZE_EF_SMS-1);
            tl_store_status (&SMS_ME_PROP(sms_data), rec_num-1, SIM_SMS_FREE);
/* Implements Measure#32: Row 95 */
            pcm_WriteRecord ((UBYTE *)ef_sms_id, rec_num,
                             SIZE_EF_SMS, data);

            TRACE_EVENT_P1 ("mem cap avail %d", sms_data->mem_cap_avail);
            
            if (!sms_data->mem_cap_avail)
            {
              SMS_SEL_MEM(sms_data) = delete_req->mem_type;
              SMS_SEL_REC(sms_data) = delete_req->rec_num;

              GET_MO_INSTANCE(sms_data);
               /*
                * TL  state transition TL_ESTABLISH
                * EST state transition EST_SMMA
                * MMI state transition MMI_DELETE
                * 
                */
              SET_STATE (STATE_MMI, MMI_DELETE);
              SET_STATE (STATE_EST, EST_SMMA);
              SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
                 /*
                  * 1st shot
                  */
              SMS_INST.retrans  = FALSE;
                 /*
                  * establish connection
                  */
              tl_establish_connection(FALSE);
                 /*
                  * wait for processing of RP-SMMA
                  */
              PFREE (delete_req);    
              return;
            }
            
            if(delete_req->delete_status NEQ CMGD_DEL_INDEX) 
            {            
              /* Status value is given. Find the next record satisfying this status value */
              next_rec_num = tl_search_record_for_delete (&SMS_ME_PROP(sms_data), rec_num,
                                                          delete_req->delete_status);
            }

            tl_mnsms_delete_cnf (delete_req->mem_type, rec_num, next_rec_num, SIM_NO_ERROR);
          }
          else
          {         
            tl_mnsms_delete_cnf (delete_req->mem_type, rec_num, 0, SMS_CAUSE_INV_INDEX);
          }
                    
          break;
        
        case MEM_SM:
          /*
           * SIM memory
           */
          if(delete_req->delete_status NEQ CMGD_DEL_INDEX)
          {
            if(delete_req->rec_num EQ 0)
            {
              /* Status value is given. Find the first record satisfying this status value */
              rec_num = tl_search_record_for_delete (&SMS_SIM_PROP(sms_data), 1,
                                                     delete_req->delete_status);

              if(rec_num EQ SMS_RECORD_NOT_EXIST)
              {
                tl_mnsms_delete_cnf (delete_req->mem_type, 0, 0, SIM_NO_ERROR);
                break;
              }
 
            }
            else
            {
              if(delete_req->rec_num > sms_data->sim_backup.max_record)
              {
                tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0,
                                     SMS_CAUSE_INV_INDEX);
                break;
              }
              else
              {
                /* Use the record number that he has given */
                rec_num = delete_req->rec_num;
              }
            }            
          }
          else
          {
            /* There should be a valid rec_num */
            if(delete_req->rec_num EQ 0 || delete_req->rec_num > sms_data->sim_backup.max_record)
            {
              tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0,
                                   SMS_CAUSE_INV_INDEX);
              break;
            }
            else
            {
             rec_num = delete_req->rec_num;
            }
          }
          
          if (tl_get_status (&SMS_SIM_PROP(sms_data), rec_num-1) & 1)
          {
            /*
             * entry is used
             */
            SMS_SEL_MEM(sms_data) = delete_req->mem_type;
            SMS_SEL_REC(sms_data) = rec_num;
            SMS_REC_STATUS(sms_data) = delete_req->delete_status;

            tl_set_access_fifo (ACCESS_BY_MMI);
            SET_STATE (STATE_MMI, MMI_DELETE);
            SMS_INST_SET_STATE (STATE_TL, TL_OTHER);
            tl_sim_update_req (rec_num, SMS_RECORD_FREE, NULL);
          }
          else
          {         
            tl_mnsms_delete_cnf (delete_req->mem_type, rec_num, 0, SMS_CAUSE_INV_INDEX);
          }

          break;

        case MEM_SR:
          tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0,
                               SMS_CAUSE_MEM_FAIL);
          break;

        default:
          tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0,
                               SMS_CAUSE_PARAM_WRONG);
          break;
      }
      break;

    default:
      tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0,
                           SMS_CAUSE_ENTITY_BUSY);
      break;
    }
  }
  else
    tl_mnsms_delete_cnf (delete_req->mem_type, delete_req->rec_num, 0,
                         SMS_CAUSE_ENTITY_BUSY);
  PFREE (delete_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_read_cnf          |
+--------------------------------------------------------------------+

  PURPOSE : Generate an error response to the primitive
            MNSMS_READ_REQ.
*/

GLOBAL void tl_mnsms_read_cnf (UBYTE mem_type,
                               UBYTE record,
                               UBYTE *data,
                               USHORT error)
{
 GET_INSTANCE_DATA;
  PALLOC (read_cnf, MNSMS_READ_CNF); /* T_MNSMS_READ_CNF */

  read_cnf->mem_type = mem_type;
  read_cnf->rec_num = record;
  switch (mem_type)
  {
  case MEM_SM:
    if (sms_data->init_done)
    {    
      read_cnf->rec_next = tl_search_record (&SMS_SIM_PROP(sms_data),
                                             (USHORT)(record + 1),
                                             SMS_REC_STATUS(sms_data));
      read_cnf->rec_max = SMS_SIM_PROP(sms_data).max_record;
    }
    else
    {
      read_cnf->rec_next = SMS_RECORD_NOT_EXIST;
      read_cnf->rec_max = SMS_RECORD_NOT_EXIST;
    }
    break;
  case MEM_ME:
    read_cnf->rec_next = tl_search_record (&SMS_ME_PROP(sms_data),
                                           (USHORT)(record + 1),
                                           SMS_REC_STATUS(sms_data));
    read_cnf->rec_max = SMS_ME_PROP(sms_data).max_record;
    break;
  default:
    read_cnf->rec_next = SMS_RECORD_NOT_EXIST;
    read_cnf->rec_max = SMS_RECORD_NOT_EXIST;
    break;
  }
  read_cnf->cause = error;
  read_cnf->rec_status = SMS_RECORD_NOT_EXIST;  /* ffs */

  if (data NEQ NULL)
  {
    read_cnf->status = data[0];
    read_cnf->sms_sdu.l_buf = SIM_PDU_BIT_LEN;
    read_cnf->sms_sdu.o_buf = 0;
    memcpy (read_cnf->sms_sdu.buf, &data[1], SIM_PDU_LEN);
    tl_adjust_message_len (SMS_VT_SIM_PDU, (BUF_tpdu *)&read_cnf->sms_sdu);
  }
  else
  {
    if (record EQ SMS_RECORD_NOT_EXIST)
    {
      read_cnf->status = SMS_RECORD_FREE;
    }
    else
    {
      switch (mem_type)
      {
        case MEM_ME:
          read_cnf->status = tl_get_status (&SMS_ME_PROP(sms_data), record-1);
          break;
        case MEM_SM:
          read_cnf->status = tl_get_status (&SMS_SIM_PROP(sms_data), record-1);
          break;
        default: 
          read_cnf->status = SMS_RECORD_FREE;
          break;
      }
    }
    memset (&read_cnf->sms_sdu, 0, sizeof(T_sms_sdu));
  }
  PSENDX (MMI, read_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_read_req          |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_READ_REQ.

*/

GLOBAL void tl_mnsms_read_req (T_MNSMS_READ_REQ *read_req)
{
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0);

  TRACE_FUNCTION ("tl_mnsms_read_req()");

  if (sms_data)
  {
    switch (SMS_INST_GET_STATE (STATE_TL))
    {
      case TL_IDLE:
        SMS_READ_MODE(sms_data) = read_req->read_mode;
        switch (read_req->mem_type)
        {
          case MEM_ME:     /* Mobile Equipment Memory */
            tl_read_me_memory (read_req->rec_num,
                               read_req->status);
            break;
          case MEM_SM:     /* SIM memory */
            if (sms_data->init_done)
            {
              tl_read_sim_memory (read_req->rec_num,
                                  read_req->status);
            }
            else
            {
              tl_mnsms_read_cnf (read_req->mem_type,
                       read_req->rec_num, NULL, SMS_CAUSE_ENTITY_BUSY);
            }
            break;
          case MEM_SR:
            tl_mnsms_read_cnf (read_req->mem_type,
                               read_req->rec_num, NULL,
                               SMS_CAUSE_MEM_FAIL);
            break;
          default:
            tl_mnsms_read_cnf (read_req->mem_type,
                               read_req->rec_num, NULL,
                               SMS_CAUSE_PARAM_WRONG);
            break;
        }
        break;

      default:
        tl_mnsms_read_cnf (read_req->mem_type,
                           read_req->rec_num, NULL, SMS_CAUSE_ENTITY_BUSY);
        break;
    }
  }
  else
    tl_mnsms_read_cnf (read_req->mem_type,
                       read_req->rec_num, NULL, SMS_CAUSE_ENTITY_BUSY);

  PFREE (read_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_store_cnf         |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_STORE_REQ.
*/

GLOBAL void tl_mnsms_store_cnf (UBYTE mem_type,
                                UBYTE record,
                                USHORT error)
{
  PALLOC (store_cnf, MNSMS_STORE_CNF);

  store_cnf->mem_type = mem_type;
  store_cnf->rec_num = record;
  store_cnf->cause = error;

  PSENDX (MMI, store_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_store_req         |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_STORE_REQ.

*/

GLOBAL void tl_mnsms_store_req (T_MNSMS_STORE_REQ *store_req)
{
  USHORT index;
  UBYTE dummy;
  int byte_len;
  BOOL mem_full = FALSE;
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE(0);

  TRACE_FUNCTION ("tl_mnsms_store_req()");

#ifdef REL99
  /* Check if the last failed message is getting replaced */
  if( ( store_req->condx    NEQ SMS_CONDX_OVR_NON    ) AND
      ( store_req->rec_num  EQ SMS_INST.failed_msg_rec_num ) AND
      ( store_req->mem_type EQ SMS_INST.failed_msg_mem ) AND 
       SMS_DATA_REQ(sms_data) NEQ NULL )
  {    
    PFREE (SMS_DATA_REQ(sms_data));
    SMS_DATA_REQ(sms_data) = NULL;
  }  
#endif

  if (sms_data NEQ NULL)
  {
    switch (SMS_INST_GET_STATE (STATE_TL))
    {
    case TL_IDLE:
      if (tl_check_status_value (store_req->status) EQ NOT_PRESENT_8BIT)
      {                    /* invalid status value */
        tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num,
                            SMS_CAUSE_PARAM_WRONG);
        break;
      }
      switch (store_req->mem_type)
      {
      case MEM_SM:
        if (store_req->rec_num EQ SMS_RECORD_NOT_EXIST)
        {
          if ((index = tl_get_free_space (MEM_SM)) EQ 0)
            mem_full = TRUE;

        SMS_EM_SET_CHANGE_FLAG_1;

        }
        else
        {
          if (store_req->rec_num > SMS_SIM_PROP(sms_data).max_record)
            index = 0;
          else if (store_req->condx EQ SMS_CONDX_OVR_NON)
          {
            if ((tl_get_status (&SMS_SIM_PROP(sms_data), store_req->rec_num-1) & 1)
                EQ SMS_RECORD_FREE)
              index = store_req->rec_num;
            else
              index = 0;
          }
          else if (store_req->condx EQ SMS_CONDX_OVR_MO)
          {
            switch (tl_get_status (&SMS_SIM_PROP(sms_data), store_req->rec_num-1) & 7)
            {
            case SMS_RECORD_STO_UNSENT:
            case SMS_RECORD_STO_SENT:
              index = store_req->rec_num;
              break;

            default:
              index = 0;
              break;
            }
          }
          else
            index = store_req->rec_num;

        SMS_EM_SET_CHANGE_FLAG_2;

        }
        break;

      case MEM_ME:
        if (store_req->rec_num EQ SMS_RECORD_NOT_EXIST)
        {
          if ((index = tl_get_free_space (MEM_ME)) EQ 0)
            mem_full = TRUE;


          SMS_EM_SET_CHANGE_FLAG_1;

        }
        else
        {
          if (store_req->condx EQ SMS_CONDX_OVR_NON)
          {
            if ((tl_get_status (&SMS_ME_PROP(sms_data), store_req->rec_num-1) & 1)
                EQ SMS_RECORD_FREE)
              index = store_req->rec_num;
            else
              index = 0;
          }
          else if (store_req->condx EQ SMS_CONDX_OVR_MO)
          {
            switch (tl_get_status (&SMS_ME_PROP(sms_data), store_req->rec_num-1) & 7)
            {
            case SMS_RECORD_STO_UNSENT:
            case SMS_RECORD_STO_SENT:
              index = store_req->rec_num;
              break;

            default:
              index = 0;
              break;
            }
          }
          else
            index = store_req->rec_num;

        SMS_EM_SET_CHANGE_FLAG_2;

        }
        break;

      case MEM_SR:
        tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num,
                            SMS_CAUSE_MEM_FAIL);
        PFREE (store_req);
        return;

      default:
        tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num,
                            SMS_CAUSE_PARAM_WRONG);
        PFREE (store_req);
        return;
      }
      if (index > 0)
      {
        /*
         * storage available
         */
        byte_len = (int)store_req->sms_sdu.l_buf >> 3;

        if (store_req->mem_type EQ MEM_SM)
        {
          /*
           * SIM card memory
           */
          tl_store_status (&SMS_SIM_PROP(sms_data), index-1, SIM_SMS_PENDING);
          SMS_REC_STATUS(sms_data) = store_req->status;
          tl_get_pid_dcs (store_req->status,
                          &store_req->sms_sdu,
                          &SMS_PID(sms_data),
                          &dummy);

          memset (&store_req->sms_sdu.buf[byte_len],
                  NOT_PRESENT_8BIT,
                  (SIM_LENGTH_SMS_RECORD-1) - byte_len);

          tl_set_access_fifo (ACCESS_BY_MMI);
          SET_STATE (STATE_MMI, MMI_WRITE);
          SMS_INST_SET_STATE (STATE_TL, TL_OTHER);
          tl_sim_update_req ((UBYTE)index, store_req->status,
                             store_req->sms_sdu.buf);
          break;
        }
        else
        {
          /*
           * memory type is mobile memory
           */
          UBYTE data[SIZE_EF_SMS];

          data[0] =  store_req->status;
          memcpy (&data[1], store_req->sms_sdu.buf, byte_len);
          memset (&data[byte_len + 1],
                  NOT_PRESENT_8BIT,
                  (SIM_LENGTH_SMS_RECORD-1) - byte_len);

/* Implements Measure#32: Row 97 */
          if (pcm_WriteRecord ((UBYTE *)ef_sms_id, index,
                               SIZE_EF_SMS, data) EQ PCM_OK)
          {
            UBYTE pid;

            SMS_EM_STORE_MO_SHORT_MESSAGE;
            
            SMS_EM_CHANGE_SHORT_MESSAGE;

            tl_store_status (&SMS_ME_PROP(sms_data), index-1, store_req->status);
            tl_get_pid_dcs (store_req->status,
                            &store_req->sms_sdu,
                            &pid,
                            &dummy);
            tl_store_pid (&SMS_ME_PROP(sms_data), index-1, pid);
            tl_mnsms_store_cnf (store_req->mem_type, (UBYTE)index,
                                SMS_NO_ERROR);
          }
          else
            tl_mnsms_store_cnf (store_req->mem_type, (UBYTE)index,
                                SMS_CAUSE_MEM_FAIL);
        }
      }
      else
        tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num,
                            (USHORT)((mem_full)? SMS_CAUSE_MEM_FULL:
                                                 SMS_CAUSE_INV_INDEX));
      break;

    default:
      tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num,
                          SMS_CAUSE_ENTITY_BUSY);
      break;
    }
  }
  else
    tl_mnsms_store_cnf (store_req->mem_type, store_req->rec_num,
                        SMS_CAUSE_ENTITY_BUSY);

  PFREE (store_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_submit_cnf        |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_SUBMIT_REQ.
*/

GLOBAL void tl_mnsms_submit_cnf (UBYTE mem_type,
                                 UBYTE record,
                                 UBYTE tp_mr,
                                 USHORT cause,
                                 T_sms_sdu *sms_sdu)
{
  PALLOC (submit_cnf, MNSMS_SUBMIT_CNF);

  TRACE_EVENT_P1 ("cause = %04x", cause);

  submit_cnf->mem_type = mem_type;
  submit_cnf->rec_num = record;
  submit_cnf->tp_mr = tp_mr;
  submit_cnf->cause = cause;

  if (sms_sdu NEQ NULL)
    memcpy (&submit_cnf->sms_sdu, sms_sdu, sizeof (T_sms_sdu));
  else
    memset (&submit_cnf->sms_sdu, 0, sizeof (T_sms_sdu));

  PSENDX (MMI, submit_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_submit_req        |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_SUBMIT_REQ.
*/


GLOBAL void tl_mnsms_submit_req (T_MNSMS_SUBMIT_REQ *submit_req)
{
  UBYTE                      ti;
  register T_SMS_DATA                 *sms_data = GET_SMS_INSTANCE(0);

  TRACE_FUNCTION ("tl_mnsms_submit_req()");

  TRACE_EVENT_P2 ("mem_type = %02X, rec_num = %02X",
                  submit_req->mem_type, submit_req->rec_num);

  if (sms_data)
  {
    switch (SMS_INST_GET_STATE (STATE_TL))
    {
      case TL_SEND_CONTD:
       /*
        * stop timer TLCT
        */
        sms_timer_stop(TLCT);
       /*
        * stop timer TMMS
        */
        sms_timer_stop(TMMS);

      case TL_IDLE:
        if (sms_timer_check(TRAM))
        {
          /*
           * MNSMS_SUBMIT_CNF
           */
           tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num,
                               NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
           break;
        }
       /*
        * save submit request with sms sdu
        */
        SMS_SEL_MEM(sms_data) = submit_req->mem_type;
        SMS_SEL_REC(sms_data) = submit_req->rec_num;
        SMS_CONDX(sms_data)   = submit_req->condx;
        SMS_MODIFY(sms_data)  = submit_req->modify;

        if (SMS_SDU(sms_data) NEQ NULL)
        {
           MFREE (SMS_SDU(sms_data));
        }
        MALLOC (SMS_SDU(sms_data), sizeof(T_sms_sdu));
        memcpy (SMS_SDU(sms_data), &submit_req->sms_sdu, sizeof(T_sms_sdu));
       /*
        * check whether concatenated
        */
        if (!tl_concat_check(SMS_SDU(sms_data)))
        {
           /*
            * error understanding the sdu
            */
            TRACE_ERROR ("error with concat sim pdu");
           /*
            * negative response MNSMS_SUBMIT_CNF
            */
            tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num,
                             NOT_PRESENT_8BIT, SMS_CAUSE_PARAM_WRONG, NULL);
           /*
            * Send MNSMS_REPORT_IND if cmms_mode is equal 1or 2
            */
            if(CMMS_ACTIVE)
            {
               tl_mnsms_cmms_end_ind();
            }
           /*
            * give up
            */
            MFREE (SMS_SDU(sms_data));
            PFREE (submit_req);
            return;
        }
#ifdef REL99
        /* Check whether MO msg is sent thru retransmission request. Initially False */ 
        SMS_INST.failed_msg_retx = FALSE;
        if(submit_req->auto_rep_flag EQ AUTO_REP_FLAG_ENABLED)
        {
          SMS_INST.tl_retx = 0;
        }
        else
        {
          /* Set to the max value so that retransmission will not be done */
          SMS_INST.tl_retx = TL_MAX_RETANS;
        }
#endif

        
       /*
        * TL  state transition TL_ESTABLISH
        * EST state transition EST_SEND
        */
        SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
        SET_STATE (STATE_EST, EST_SEND);
       /*
        * establish connection
        */
        ti = SMS_INST.ti;
        tl_establish_connection(TRUE);
       /*
        * concat control: if needed, release previous connection
        */
        if ((sms_data->concat_cntrl.concatenation EQ TRUE) AND 
            (sms_data->concat_cntrl.release_pending EQ TRUE))
        {
           sms_data->concat_cntrl.release_pending = FALSE;
          /*
           * RL_RELEASE_REQ ==>
           */
           rl_release_req(ti);
          /*
           * check for end of concatenation
           */
           if (sms_data->concat_cntrl.end EQ TRUE)
           {
              /*
               * end of concatenation
               */
               sms_data->concat_cntrl.concatenation = FALSE;
           }
           break;
        }
       /*
        * cmms control: if needed, release previous connection
        */
        if(sms_data->cmms_release_pending EQ TRUE)
        {
           sms_data->cmms_release_pending = FALSE;
           /*
            * Release the previous active MM connection 
            */
           rl_release_req(ti);
        }
        break;

      default:
       /*
        * MNSMS_SUBMIT_CNF
        */
        tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num,
                             NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
    }
  }
  else
  {
   /*
    * MNSMS_SUBMIT_CNF
    */
    tl_mnsms_submit_cnf (submit_req->mem_type, submit_req->rec_num,
                         NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
  }
  PFREE (submit_req);
}


/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_error_ind         |
+--------------------------------------------------------------------+

  PURPOSE : Build and send the primitive MNSMS_ERROR_IND.
*/

GLOBAL void tl_mnsms_error_ind (USHORT error)
{
  PALLOC (error_ind, MNSMS_ERROR_IND);

  error_ind->cause = error;

  PSENDX (MMI, error_ind);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_ack_res           |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_ACK_RES.
*/

GLOBAL void tl_mnsms_ack_res (T_MNSMS_ACK_RES *ack_res)
{
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_mnsms_ack_res()");

  if (sms_data) /*lint !e774 always True*/
  {
    GET_MT_INSTANCE(sms_data);  /* MT operation */

    if (SMS_MT_ACK_MODE(sms_data) NEQ SMS_MHC_PH2PLUS)
    {
      tl_mnsms_error_ind (SMS_CAUSE_OPER_NOT_ALLW);
    }
    else switch (SMS_INST_GET_STATE (STATE_TL))
    {
      case TL_RECEIVE:
        if (sms_timer_check(TR2M))
        {
          T_rp_user_data *rp_ud;
          int sdu_ofs;
          MALLOC (rp_ud, sizeof(T_rp_user_data));

          CCD_START;

          sdu_ofs = ack_res->sms_sdu.buf[ack_res->sms_sdu.o_buf >> 3] + 1;
          rp_ud->tpdu.o_tpdu = 0;
          if (ack_res->sms_sdu.l_buf >= (sdu_ofs << 3) + 2) /* TP-MTI present */
          {
            rp_ud->tpdu.l_tpdu = ack_res->sms_sdu.l_buf - (sdu_ofs << 3);
            memcpy (rp_ud->tpdu.b_tpdu, &ack_res->sms_sdu.buf[sdu_ofs],
                    rp_ud->tpdu.l_tpdu >> 3);
            rp_ud->tp_mti = rp_ud->tpdu.b_tpdu[0] & 3;
            rp_ud->v_tpdu = TRUE;
          }
          else
          {
            rp_ud->tpdu.l_tpdu = 0;
            rp_ud->tp_mti = NOT_PRESENT_8BIT;
            rp_ud->v_tpdu = FALSE;
          }
          if (ack_res->resp EQ SMS_RP_ACK)
            rl_report_req_ack (rp_ud);
          else
          {
            if (!rp_ud->v_tpdu)
            {
              rp_ud->tp_mti = rp_ud->tpdu.b_tpdu[0] = SMS_DELIVER_REPORT;
              rp_ud->tpdu.b_tpdu[1] = SMS_FCS_UNSPECIFIED;  /* TP-FCS */
              rp_ud->tpdu.b_tpdu[2] = 0;                    /* TP-PI */
              rp_ud->tpdu.l_tpdu = 24;                      /* 3 bytes */
              rp_ud->v_tpdu = TRUE;
            }
            rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, rp_ud);
           /*
            * RL_RELEASE_REQ ==>
            */
            rl_release_req(SMS_INST.ti);
          }
          CCD_END;
          MFREE (rp_ud);

          SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
          break;
        }
        /*FALLTHROUGH*/ /*lint -fallthrough*/
      default:
        tl_mnsms_error_ind (SMS_CAUSE_UNEXP_CNMA);
        break;
    }
  }
  PFREE (ack_res);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_pause_req         |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_PAUSE_REQ.
*/
GLOBAL void tl_mnsms_pause_req (T_MNSMS_PAUSE_REQ *pause_req)
{

  TRACE_FUNCTION ("tl_mnsms_pause_req()");

  tl_pause();

  PFREE (pause_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_resume_req        |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_RESUME_REQ.
*/
GLOBAL void tl_mnsms_resume_req (T_MNSMS_RESUME_REQ *resume_req)
{

  TRACE_FUNCTION ("tl_mnsms_resume_req()");

  tl_resume();

  PFREE (resume_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_query_req         |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_QUERY_REQ.
*/
GLOBAL void tl_mnsms_query_req (T_MNSMS_QUERY_REQ *query_req)
{

  TRACE_FUNCTION ("tl_mnsms_query_req()");

  switch (query_req->query_type)
  {
  case SMS_QUERY_DELIVER_STATUS:
     tl_query_deliver_status();
     break;
  default:
     TRACE_ERROR("sms query type unknown!");
  }

  PFREE (query_req);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_resume_cnf        |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_RESUME_REQ.
*/

GLOBAL void tl_mnsms_resume_cnf ( USHORT cause )
{
  PALLOC (resume_cnf, MNSMS_RESUME_CNF);

  resume_cnf->cause = cause;

  PSENDX (MMI, resume_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_query_cnf        |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_QUERY_REQ.
*/

GLOBAL void tl_mnsms_query_cnf ( U8 query_type, U8 status )
{

  switch (query_type)
  {
  case SMS_QUERY_DELIVER_STATUS:
     {
     PALLOC (query_cnf, MNSMS_QUERY_CNF);

     query_cnf->query_type       = SMS_QUERY_DELIVER_STATUS;
     query_cnf->v_deliver_status = 1;
     query_cnf->deliver_status   = status;

     PSENDX (MMI, query_cnf);
     }
     break;
  default:
     TRACE_ERROR("sms query type unknown!");
  }

}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_sms_insert_ind      |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_SMS_INSERT_IND.

*/

GLOBAL void tl_sim_sms_insert_ind (T_SIM_SMS_INSERT_IND *insert_ind)
{
  UBYTE      i;
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_sim_sms_insert_ind()");

  if (sms_data) /*lint !e774 always True*/
  {
    tl_sim_abort_to_mmi (SMS_CAUSE_SIM_BUSY);
    sms_data->init_done = FALSE;
    tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_INITIALISING);
    /*
     * copy SMS initialisation parameter
     */
    SMS_SIM_PHASE(sms_data)     = insert_ind->phase;
    SMS_INST.tp_mr              = insert_ind->tp_mr;
    /*
     * memory capacity exceeded notification flag
     */
    switch (insert_ind->mem_cap_avail)
    {
    case SIM_SMS_MEM_FULL:
       /* 
        * Notification Flag = TRUE
        */
       TRACE_EVENT("SIM_SMS_MEM_FULL => Notification Flag = TRUE");
       break;
    case SIM_SMS_MEM_AVAIL:
       /* 
        * Notification Flag = FALSE
        */
       TRACE_EVENT("SIM_SMS_MEM_AVAIL => Notification Flag = FALSE");
       break;
    case SIM_SMS_NO_MEM:
       /* 
        * SMS storage on SIM not present
        */
       TRACE_EVENT("SIM_SMS_NO_MEM");
       break;
    default:
       TRACE_ERROR("invalid mem cap avail information from sim");
    }
    SMS_SIM_MEM_AVAIL(sms_data) = insert_ind->mem_cap_avail & 1;
    SMS_SAT_DWNLD(sms_data)     = insert_ind->download_sms;

    /*
     * scan status and protocol identifier for all SMS entries
     * first one in tl_find_first, the rest with the for loop
     * in mobile memory
     */
    tl_find_first (MEM_ME);
    for (i = 2; i <= sms_data->me_backup.max_record; i++)
      tl_find_next (MEM_ME, i);

    /*
     * check for existing but empty memory
     */
    if (SMS_ME_PROP(sms_data).max_record > 0
         AND !SMS_ME_PROP(sms_data).any_valid)
      tl_message_ind_from_sim (MEM_ME, 0,
                               SMS_ME_PROP(sms_data).max_record,
                               NULL);
    /*
     * scan status and protocol identifier for all SMS entries
     * in sim memory
     */
#ifdef FF_CPHS
    SET_STATE (STATE_MMI, MMI_FIND_FIRST);
    tl_sim_read_req (SIM_CPHS_VMW, 1);
#elif  defined FF_SMS_NW_RCG_SIM
    SET_STATE (STATE_MMI, MMI_FIND_FIRST);
    tl_sim_read_req (SIM_IMSI, 9);
#else
    tl_find_first (MEM_SM);
#endif
  }
  PFREE (insert_ind);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_read_cnf            |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_READ_CNF.
*/
#if defined(SIM_TOOLKIT) OR defined(FF_CPHS) OR defined(FF_SMS_NW_RCG_SIM)
GLOBAL void tl_sim_read_cnf (T_SIM_READ_CNF *read_cnf)
{
  GET_INSTANCE_DATA;
  USHORT  datafield;

  TRACE_FUNCTION ("tl_sim_file_update_ind()");

  datafield   = sms_data->sms_sim_access_info[read_cnf->req_id].datafield; 
  sms_data->sms_sim_access_info[read_cnf->req_id].entry_used = FALSE;

  if (sms_data)
  {
    switch (GET_STATE (STATE_MMI))
    {
    case MMI_STATE_UPDATE:
      /* 
       * EF_SMSS has been updated by SAT.
       */      
      if (read_cnf->cause EQ SIM_NO_ERROR)
      {
        /* Fetch TP-MR value out of EF_SMSS */
        SMS_INST.tp_mr = read_cnf->trans_data[0];

        if (sms_data->mem_cap_avail NEQ (read_cnf->trans_data[1] & 1))
        {
          /*
           * The memory capacity available flag has been changed.
           * Re-read EF_SMS also even in case this has not been announced
           * by the SIM application.
           */
          sms_data->mem_cap_avail = read_cnf->trans_data[1] & 1;
          sms_data->sim_mem_update = TRUE;
        }
        else
        {
          SET_STATE (STATE_MMI, MMI_IDLE);
        }
      }
      if (sms_data->sim_mem_update)
      {
        tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_INITIALISING);
        tl_find_first (MEM_SM);
#ifdef SIM_TOOLKIT
        if (sms_data->stored_read_cnf NEQ NULL)
        {
          /*
           * Resets the stored MMI state & read_cnf primitive
           */
          sms_data->stored_mmi_state = MMI_IDLE;
          PFREE (sms_data->stored_read_cnf);
          sms_data->stored_read_cnf = NULL;
        }
#endif /* SIM_TOOLKIT */
      }
      else
      {
        PALLOC (file_update_res, SIM_FILE_UPDATE_RES);
        file_update_res->fu_rsc = SIM_FU_SUCCESS;
        file_update_res->source = SRC_SMS;
        PSENDX (SIM, file_update_res);
      }
#ifdef SIM_TOOLKIT
      /*
       * If the SMS has not yet completed reading all the records, start from
       * the place where it has left earlier.
       */
      if( sms_data->stored_read_cnf NEQ NULL)
      {
        SET_STATE(STATE_MMI, sms_data->stored_mmi_state);
        tl_set_access_fifo (ACCESS_BY_MMI);
        tl_sim_read_record_cnf(sms_data->stored_read_cnf);
        sms_data->stored_mmi_state = MMI_IDLE;
        sms_data->stored_read_cnf = NULL;
      }
#endif /* SIM_TOOLKIT */

      break;
#ifdef FF_CPHS
    case MMI_FIND_FIRST:   /* CPHS Voice Message Waiting flag existent? */
#ifdef FF_SMS_NW_RCG_SIM
      if ( datafield EQ SIM_CPHS_VMW)
      {
        SMS_CPHS(sms_data) = read_cnf->cause EQ SIM_NO_ERROR;
        tl_sim_read_req (SIM_IMSI, 9);
        break;
      }
      else if (datafield EQ SIM_IMSI
               AND read_cnf->cause EQ SIM_NO_ERROR)
      {
        tl_check_network_on_sim (read_cnf->trans_data);
      }
      tl_find_first (MEM_SM);
#else
      SMS_CPHS(sms_data) = datafield EQ SIM_CPHS_VMW
                           AND read_cnf->cause EQ SIM_NO_ERROR;
      tl_find_first (MEM_SM);
#endif
#elif defined FF_SMS_NW_RCG_SIM
    case MMI_FIND_FIRST:   /* SIM operator determination required? */
      if (read_cnf->cause EQ SIM_NO_ERROR)
        tl_check_network_on_sim (read_cnf->trans_data);
      tl_find_first (MEM_SM);
      break;
#endif
    default:
      break;
    }
  }
  PFREE (read_cnf);
}
#endif  /* SIM_TOOLKIT OR FF_CPHS */

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLF                    |
| STATE   : code                ROUTINE : tl_sim_update_rec_cnf_mmi  |
+--------------------------------------------------------------------+

  PURPOSE : Processing the function TL_SIM_UPDATE_REC_CNF_MMI.

*/

LOCAL void tl_sim_update_rec_cnf_mmi (
                         T_SIM_UPDATE_RECORD_CNF *update_cnf)
{
   GET_INSTANCE_DATA;
  UBYTE next_rec_num=0,record;
  TRACE_FUNCTION ("tl_sim_update_rec_cnf_mmi()");

  record   = sms_data->sms_sim_access_info[update_cnf->req_id].rec_num;
  sms_data->sms_sim_access_info[update_cnf->req_id].entry_used = FALSE;

  switch (GET_STATE (STATE_MMI))
  {
    case MMI_READ_STATE_UPDATE:
      if (update_cnf->cause EQ SIM_NO_ERROR AND
          record EQ SMS_SEL_REC(sms_data))
      {
        /*
         * update status byte
         */
        tl_store_status (&SMS_SIM_PROP(sms_data), record-1, 
          SMS_RECORD_REC_READ);
      }
      if (SMS_READ_MODE(sms_data) EQ READ_STATUS_CHANGE)
      {
        tl_mnsms_read_cnf (MEM_SM, SMS_SEL_REC(sms_data),
                           NULL, SIM_NO_ERROR);
      }
      else
      {
        tl_mnsms_read_cnf (MEM_SM, SMS_SEL_REC(sms_data),
                           SMS_SIM_READ(sms_data)->linear_data,
                           SIM_NO_ERROR);
        PFREE (SMS_SIM_READ(sms_data));
        SMS_SIM_READ(sms_data) = NULL;
      }
      SMS_READ_MODE(sms_data) = READ_NORMAL;
      SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      break;

    case MMI_WRITE:
      if (update_cnf->cause EQ SIM_NO_ERROR)
      {
        /*
         * update status byte
         */
        tl_store_status (&SMS_SIM_PROP(sms_data), record-1, 
          SMS_REC_STATUS(sms_data));
        tl_store_pid (&SMS_SIM_PROP(sms_data), record-1,
          SMS_PID(sms_data));


        SMS_EM_STORE_MO_SHORT_MESSAGE_2;

        SMS_EM_CHANGE_SHORT_MESSAGE_2;

      }
      else
      {
        tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE);
      }
      tl_mnsms_store_cnf (MEM_SM, record, update_cnf->cause);
      SMS_READ_MODE(sms_data) = READ_NORMAL;
      SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      break;

    case MMI_DELETE:
      if (record EQ SMS_SEL_REC(sms_data))
      {
        if (update_cnf->cause EQ SIM_NO_ERROR)
        {
          tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE);

          TRACE_EVENT_P1 ("mem cap avail %d", sms_data->mem_cap_avail);

          if (!sms_data->mem_cap_avail)
          {
             GET_MO_INSTANCE(sms_data);
            /*
             * TL  state transition TL_ESTABLISH
             * EST state transition EST_SMMA
             */
             SET_STATE (STATE_EST, EST_SMMA);
             SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
            /*
             * 1st shot
             */
             SMS_INST.retrans  = FALSE;
            /*
             * establish connection
             */
             tl_establish_connection(FALSE);
            /*
             * wait for processing of RP-SMMA
             */
             return;
          }
          if(SMS_REC_STATUS(sms_data) NEQ CMGD_DEL_INDEX)
          {            
            /* Status value is given. Find the next record satisfying this status value */
            next_rec_num = tl_search_record_for_delete (&SMS_SIM_PROP(sms_data), 
                                                        record, 
                                                        SMS_REC_STATUS(sms_data));
                                            
            
            TRACE_EVENT_P1 ("tl_sim_update_rec_cnf_mmi :: next_rec_num=%d", next_rec_num);
          }          
          tl_mnsms_delete_cnf (MEM_SM, record, next_rec_num, SIM_NO_ERROR);
        }
        else
          tl_mnsms_delete_cnf (MEM_SM, record, 0, update_cnf->cause);
      }
      else
        tl_mnsms_delete_cnf (MEM_SM, record, 0, SMS_CAUSE_INV_INDEX);

      SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      break;

    case MMI_REPLACE:
      if (record EQ SMS_SEL_REC(sms_data))
      {
        if (update_cnf->cause EQ SIM_NO_ERROR)
        {
#ifdef REL99
          if(SMS_INST.failed_msg_retx EQ FALSE)
          {
#endif
            tl_mnsms_submit_cnf (MEM_SM, record,
                                     SMS_TP_REF_RET(sms_data),
                                     SMS_NO_ERROR, SMS_SDU(sms_data));
#ifdef REL99
          }
          else
          {
            tl_mnsms_retrans_cnf (MEM_SM, record,
                                     SMS_TP_REF_RET(sms_data),
                                     SMS_NO_ERROR, SMS_SDU(sms_data));
          } 
#endif

          /*
           * update status byte
           */
          tl_store_status (&SMS_SIM_PROP(sms_data), record-1, 
            SMS_RECORD_STO_SENT);
          tl_store_pid (&SMS_SIM_PROP(sms_data), record-1,
            SMS_PID_DEFAULT);
        }
        else
        {
#ifdef REL99
          if(SMS_INST.failed_msg_retx EQ FALSE)
          {
#endif
            tl_mnsms_submit_cnf (MEM_SM, SMS_RECORD_NOT_EXIST,
                               SMS_TP_REF_RET(sms_data),
                               update_cnf->cause, SMS_SDU(sms_data));
#ifdef REL99
          }
          else
          {
            tl_mnsms_retrans_cnf (MEM_SM, SMS_RECORD_NOT_EXIST,
                               SMS_TP_REF_RET(sms_data),
                               update_cnf->cause, SMS_SDU(sms_data));
          }    
#endif
          tl_store_status (&SMS_SIM_PROP(sms_data), record-1,
            SMS_RECORD_FREE);    /* reset reservation */
        }
      }
      else
        tl_mnsms_submit_cnf (MEM_SM, record,
                             SMS_TP_REF_RET(sms_data),
                             SMS_CAUSE_INV_INDEX, SMS_SDU(sms_data));

      if (SMS_SDU(sms_data) NEQ NULL)
      {
        MFREE (SMS_SDU(sms_data));
        SMS_SDU(sms_data) = NULL;
      }
      SMS_SEL_REC(sms_data) = SMS_RECORD_NOT_EXIST;
     /*
      * concat control
      */
      if (sms_data->concat_cntrl.concatenation EQ TRUE)
      {
        /*
         * start timer TLCT for next submit req supervision
         */
         sms_timer_start(TLCT);
        /*
         * TL State Transition TL_SEND_CONTD
         */
         SMS_INST_SET_STATE (STATE_TL, TL_SEND_CONTD);
        /*
         * remember to release connection
         */
         sms_data->concat_cntrl.release_pending = TRUE;
      }
      else
      {
        /*
         * TL State Transition TL_IDLE
         */
         SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      }
      break;

    default:
      assert (GET_STATE (STATE_MMI) EQ MMI_IDLE); /* illegal state */
      break;
  }
  SET_STATE (STATE_MMI, MMI_IDLE);
#ifdef SIM_TOOLKIT
  if (sms_data->file_update_ind NEQ NULL)
  {
    T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind;
    sms_data->file_update_ind = NULL;
    tl_sim_file_update_ind (file_update_ind);
  }
#endif
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLF                    |
| STATE   : code                ROUTINE : tl_sim_update_rec_cnf_net  |
+--------------------------------------------------------------------+

  PURPOSE : Processing the function TL_SIM_UPDATE_REC_CNF_NET.

*/

LOCAL void tl_sim_update_rec_cnf_net (T_SIM_UPDATE_RECORD_CNF *update_cnf)
{
	GET_INSTANCE_DATA;
  UBYTE record;
  UBYTE data[SIZE_EF_SMS];

  TRACE_FUNCTION ("tl_sim_update_rec_cnf_net()");

  record   = sms_data->sms_sim_access_info[update_cnf->req_id].rec_num;
  sms_data->sms_sim_access_info[update_cnf->req_id].entry_used = FALSE;


  CCD_START;

  switch (GET_STATE (STATE_NET))
  {
    case NET_WRITE:
      if (update_cnf->cause EQ SIM_NO_ERROR)
      {
        /*
         * update status byte
         */
        tl_store_status (&SMS_SIM_PROP(sms_data), record-1,
          SMS_RECORD_REC_UNREAD);
        tl_store_pid (&SMS_SIM_PROP(sms_data), record-1, SMS_PID(sms_data));
        /*
         * send indication to MMI
         */
        tl_message_ind_from_net (MEM_SM, record,
                                 SMS_SIM_PROP(sms_data).max_record,
                                 SMS_RP_RCVD(sms_data));

        rl_report_req_ack (NULL);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      }
      else switch (sms_data->use_mem_b)   // check alternative B
      {
      case DISPLAY:
        /*
         * Only display of the message
         */
        tl_message_ind_from_net (NOT_PRESENT_8BIT, 0, 0,
                                 SMS_RP_RCVD(sms_data));
        {
          if (sms_data->mhc NEQ SMS_MHC_PH2PLUS)
          {
            rl_report_req_ack (NULL);
            SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
          }
        }
        break;

      case MEM_ME:
        /*
         * memory type is mobile memory
         */
        record = tl_get_free_space (MEM_ME);
        if (record)
        {
          /*
           * store in mobile memory
           */
/* Implements Measure#32: Row 104 */
          if (pcm_WriteRecord ((UBYTE *)ef_sms_id, record,
                               SIZE_EF_SMS, data) EQ PCM_OK)
          {
            /*
             * update status byte
             */
            tl_store_status (&SMS_ME_PROP(sms_data), record-1, SMS_RECORD_REC_UNREAD);
            tl_store_pid (&SMS_ME_PROP(sms_data), record-1, SMS_PID(sms_data));
            /*
             * send indication to MMI
             */
            tl_message_ind_from_net (MEM_ME, record,
                                     SMS_ME_PROP(sms_data).max_record,
                                     SMS_RP_RCVD(sms_data));
            /*
             * acknowledge to the infrastructure
             */
            rl_report_req_ack (NULL);
            SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
            break;
          }
        }
        /*FALLTHROUGH*/ /*lint -fallthrough*/
      default:
        if (tl_get_free_space (MEM_ME) OR tl_get_free_space (MEM_SM))
        {
         /*
          * error to the infrastructure
          */
          rl_report_req_error (SMS_RP_CS_PROTOCOL_ERROR, NULL);
         /*
          * RL_RELEASE_REQ ==>
          */
          rl_release_req(SMS_INST.ti);
	  
        }
        else
        {
          if (update_cnf->cause NEQ SIM_CAUSE_DRV_TEMPFAIL)
          {
            /* change mem_cap_avail flag on SIM and return error */
            tl_sms_memo_exceeded (FALSE);
          }
          else
          {
           /*
            * RP_ERROR =>
            */
            rl_report_req_error (
                                 SMS_RP_CS_PROTOCOL_ERROR, NULL);
           /*
            * RL_RELEASE_REQ ==>
            */
            rl_release_req(SMS_INST.ti);
          }
        }
        tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
        break;

      case IGNORE:
        rl_report_req_ack (NULL);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);

        MFREE (SMS_RP_RCVD(sms_data));
        SMS_RP_RCVD(sms_data) = NULL;
        break;
      }
      sms_data->use_mem_b = NOTHING;

      MFREE (SMS_RP_RCVD(sms_data));
      SMS_RP_RCVD(sms_data) = NULL;
      break;

    case NET_23430_WRITE:
      if (update_cnf->cause EQ SIM_NO_ERROR)
      {
        CCD_END;

        tl_sim_update_req (record,
                           SMS_RECORD_FREE, NULL);

        tl_set_access_fifo (ACCESS_BY_NET);
        SET_STATE (STATE_NET, NET_23430_DELETE);
        return;
      }
      tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE);

      tl_sms_memo_exceeded (FALSE);
      SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      break;

    case NET_23430_DELETE:
      tl_store_status (&SMS_SIM_PROP(sms_data), record-1, SIM_SMS_FREE);
      rl_report_req_ack (NULL);
      SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      break;

    default:
      assert (GET_STATE (STATE_NET) EQ NET_IDLE); /* illegal state */
//      SET_STATE (STATE_NET, NET_IDLE);
      break;
  }
  CCD_END;

  SET_STATE (STATE_NET, NET_IDLE);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_update_cnf          |
+--------------------------------------------------------------------+

  PURPOSE : After updating of EF(SMSS) the Entity state is checked
            and a MNSMS_REPORT_IND is sent to indicate the Ready
            State
*/

GLOBAL void tl_sim_update_cnf (T_SIM_UPDATE_CNF *update_cnf)
{
  GET_INSTANCE_DATA;
  UBYTE       next_rec_num = 0;

  TRACE_FUNCTION ("tl_sim_update_cnf()");
  sms_data->sms_sim_access_info[update_cnf->req_id].entry_used = FALSE;

  switch (tl_read_access_fifo ())
  {
    case ACCESS_BY_MMI:
      if (sms_data->sms_sim_access_info[update_cnf->req_id].datafield EQ SIM_SMSS AND
          SMS_ENT_STATE(sms_data) EQ SMS_STATE_INITIALISING)
      {
        tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_READY);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
        PFREE (update_cnf);
        return;
      }
      if (GET_STATE (STATE_MMI) EQ MMI_DELETE)
      {
        GET_MO_INSTANCE(sms_data);
        /*
         * confirm deletion to user
         */
        if(SMS_REC_STATUS(sms_data) NEQ CMGD_DEL_INDEX)
        {
          /* Status value is given. Find the next record satisfying this status value */
          next_rec_num = tl_search_record_for_delete (((SMS_SEL_MEM(sms_data) EQ MEM_ME)? 
                                                   &SMS_ME_PROP(sms_data):&SMS_SIM_PROP(sms_data)),
                                                   SMS_SEL_REC(sms_data), 
                                                   SMS_REC_STATUS(sms_data));
        }
        tl_mnsms_delete_cnf (SMS_SEL_MEM(sms_data), SMS_SEL_REC(sms_data), next_rec_num, SIM_NO_ERROR);
        SET_STATE (STATE_MMI, MMI_IDLE);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      }
      else if (GET_STATE (STATE_MMI) EQ MMI_RESUME)
      {
        /*
         * confirm resumption to user
         */
        if (sms_data->pr_cntrl.save_cause EQ SMS_NO_ERROR)
        {
          if (update_cnf->cause == SIM_NO_ERROR)
          {
            tl_mnsms_resume_cnf(SMS_NO_ERROR);
          }
          else
          {
            tl_mnsms_resume_cnf(update_cnf->cause);
          }
        }
        else
        {
          tl_mnsms_resume_cnf(sms_data->pr_cntrl.save_cause);
        }
        SET_STATE (STATE_MMI, MMI_IDLE);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      }
      break;
      
    case ACCESS_BY_NET:
      TRACE_EVENT ("SIM_UPDATE_CNF ignored");
      break;
       
    default:      
      TRACE_ERROR ("Unexpected Error Value");
      break; 
  }   
#ifdef SIM_TOOLKIT
  if (sms_data->file_update_ind NEQ NULL)
  {
     T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind;
     sms_data->file_update_ind = NULL;
     tl_sim_file_update_ind (file_update_ind);
  }
#endif
  PFREE (update_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_update_record_cnf   |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_UPDATE_RECORD_CNF.

*/

GLOBAL void tl_sim_update_record_cnf (T_SIM_UPDATE_RECORD_CNF *update_cnf)
{
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_sim_update_record_cnf()");

  switch (tl_read_access_fifo ())
  {
    case ACCESS_BY_NET:
      GET_MT_INSTANCE(sms_data);    /* MT */
      tl_sim_update_rec_cnf_net (update_cnf);
      break;

    case ACCESS_BY_MMI:
      GET_MO_INSTANCE(sms_data);    /* MO */
      tl_sim_update_rec_cnf_mmi (update_cnf);
      break;

    default:
      assert (0);    /* impossible case */
      break;
  }
  PFREE (update_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_read_record_cnf     |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_READ_RECORD_CNF.

*/

GLOBAL void tl_sim_read_record_cnf (T_SIM_READ_RECORD_CNF *read_cnf)
{
  T_SIM_PDU *sim_pdu;
  GET_INSTANCE_DATA;
  UBYTE   record;
  TRACE_FUNCTION ("tl_sim_read_record_cnf()");

  record   = sms_data->sms_sim_access_info[read_cnf->req_id].rec_num;
  sms_data->sms_sim_access_info[read_cnf->req_id].entry_used = FALSE;

  if (sms_data) /*lint !e774 always True*/
  {
    switch (tl_read_access_fifo ())
    {
    case ACCESS_BY_MMI:
      GET_MO_INSTANCE(sms_data);    /* MO */
      switch (GET_STATE (STATE_MMI))
      {
      case MMI_READ:
        /*
         * read attempt from MMI
         */
        if (read_cnf->cause EQ SIM_NO_ERROR AND
            record EQ SMS_SEL_REC(sms_data))
        {
          tl_store_status (&SMS_SIM_PROP(sms_data), record-1,
            read_cnf->linear_data[0]);
          if (SMS_INST_GET_STATE (STATE_TL) EQ TL_SEND)
          {
            MCAST (cp_data, U_CP_DATA);

            MALLOC (sim_pdu, sizeof(T_SIM_PDU));
            CCD_START;
            if (tl_modify_submit (sim_pdu, SMS_MODIFY(sms_data),
                                  SMS_SDU(sms_data),
                                  read_cnf->linear_data) AND
                tl_prepare_submit (sim_pdu, cp_data))
            {
             /*
              * RL_DATA_REQ
              */
              if (!rl_data_req (SMS_INST.tp_mr, cp_data))
              {
                SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
               /*
                * release connection
                */
                rl_release_req(SMS_INST.ti);
               /*
                * send not successful but we confirm with no error ???!!
                */
                tl_mnsms_submit_cnf (MEM_SM, record,
                                     NOT_PRESENT_8BIT, SMS_NO_ERROR, NULL);
              }
            }
            else
            {
              SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
              tl_mnsms_submit_cnf (MEM_SM, record,
                                   NOT_PRESENT_8BIT, SMS_CAUSE_PARAM_WRONG, NULL);
            }
            CCD_END;
            MFREE (sim_pdu);
            MFREE (SMS_SDU(sms_data));
            SMS_SDU(sms_data) = NULL;

            SET_STATE (STATE_MMI, MMI_IDLE);
            break;
          }
          if ((read_cnf->linear_data[0] & 1) EQ SMS_RECORD_FREE)
          {
            tl_mnsms_read_cnf (MEM_SM, 0,
                               NULL, SMS_CAUSE_INV_INDEX);
          }
          else if (((read_cnf->linear_data[0] & 7) EQ SMS_RECORD_REC_UNREAD)
                    AND SMS_READ_MODE(sms_data) NEQ READ_PREVIEW)
          {
            tl_set_access_fifo (ACCESS_BY_MMI);
            SET_STATE (STATE_MMI, MMI_READ_STATE_UPDATE);
            SMS_INST_SET_STATE (STATE_TL, TL_OTHER);
            tl_sim_update_req (record, SMS_RECORD_REC_READ,
                               &read_cnf->linear_data[1]);

            if (SMS_READ_MODE(sms_data) NEQ READ_STATUS_CHANGE)
            {
//              read_cnf->linear_data[0] = SMS_RECORD_REC_READ;
              /*
               * keep read data until reception of UPDATE CONFIRM
               */
              if (SMS_SIM_READ(sms_data) NEQ 0)
                PFREE(SMS_SIM_READ(sms_data));
              SMS_SIM_READ(sms_data) = read_cnf;
              return;   /* read_cnf not to be deallocated */
            }
            PFREE (read_cnf);
            return;     /* keep states */
          }
          else
          {

            SMS_EM_READ_SHORT_MESSAGE_2;

            tl_mnsms_read_cnf (MEM_SM, record,
                               ((SMS_READ_MODE(sms_data) EQ READ_STATUS_CHANGE)?
                                NULL: read_cnf->linear_data),
                               SIM_NO_ERROR);
          }
        }
        else
        {
          if (SMS_INST_GET_STATE (STATE_TL) EQ TL_SEND)
          {
            if (read_cnf->cause EQ SIM_NO_ERROR)
              tl_mnsms_submit_cnf (MEM_SM, record,
                                   NOT_PRESENT_8BIT, SMS_CAUSE_INV_INDEX, NULL);
            else
              tl_mnsms_submit_cnf (MEM_SM, record,
                                   NOT_PRESENT_8BIT, read_cnf->cause, NULL);
          }
          else
            tl_mnsms_read_cnf (MEM_SM, 0,
                               NULL, SMS_CAUSE_INV_INDEX);
        }
        SET_STATE (STATE_MMI, MMI_IDLE);
        SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
        break;

      case MMI_FIND_FIRST:
#ifdef SIM_TOOLKIT
        if (sms_data->file_update_ind NEQ NULL)
        {
          T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind;
          /*
           * Take a backup of the current status of the MMI_STATE
           */
          sms_data->stored_mmi_state = GET_STATE(STATE_MMI);
          SET_STATE (STATE_MMI, MMI_IDLE);
          sms_data->file_update_ind = NULL;
          tl_sim_file_update_ind (file_update_ind);

          /* Implements Measure# 7 */
          if( tl_sim_rd_record_update_state(read_cnf) )
            return;
        }
#endif
        /*
         * first record is scanned
         */
        if (read_cnf->cause EQ SIM_NO_ERROR)
        {
          /* Store max. supported records of the SIM */
          SMS_SIM_PROP(sms_data).max_record = read_cnf->max_record;

          if (SMS_SIM_PROP(sms_data).max_record > MAX_RECORD_SIM)
          {
            /* The number of supported records is limited by SMS */
            SMS_SIM_PROP(sms_data).max_record = MAX_RECORD_SIM;
          }
          else if (SMS_SIM_PROP(sms_data).max_record EQ 0)
          {
            /* We have at least one record as we successfully read it
             * regardless of the returned value from the SIM */
            SMS_SIM_PROP(sms_data).max_record = 1;
          }
          /*
           * continue with MMI_FIND_NEXT
           */
        }
        else
        {
          /*
           * No EF_SMS field on the SIM.
           */          
          SMS_SIM_PROP(sms_data).max_record = 0;
          SET_STATE (STATE_MMI, MMI_IDLE);
          /* 
           * init done
           */
          tl_init_complete();
          break;
        }
      /*FALLTHROUGH*/ /*lint -fallthrough*/
      case MMI_FIND_NEXT:

#ifdef SIM_TOOLKIT
        /*
         * Take a backup of the current status of the MMI_STATE
         */
        sms_data->stored_mmi_state = GET_STATE(STATE_MMI);
#endif /* SIM_TOOLKIT */

        SET_STATE (STATE_MMI, MMI_IDLE); 

#ifdef SIM_TOOLKIT

        if (sms_data->file_update_ind NEQ NULL)
        {
          T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind;
          sms_data->file_update_ind = NULL;
          tl_sim_file_update_ind (file_update_ind);
          
         /* Implements Measure# 7 */ 
         if( tl_sim_rd_record_update_state(read_cnf) )
            return;
        }
#endif
        /*
         * next record is scanned
         */
        if (read_cnf->cause EQ SIM_NO_ERROR)
        {
          if (tl_find_status_pid (MEM_SM,
                                  record,
                                  read_cnf->linear_data,
                                  &SMS_SIM_PROP(sms_data)))
            tl_message_ind_from_sim (MEM_SM, record,
                                     read_cnf->max_record,
                                     read_cnf->linear_data);
          if (record < SMS_SIM_PROP(sms_data).max_record)
            tl_find_next (MEM_SM, (UBYTE)(record + 1));
          else
          {
#ifdef SIM_TOOLKIT
            if (sms_data->sim_mem_update)
            {
              PALLOC (file_update_res, SIM_FILE_UPDATE_RES);
              file_update_res->source = SRC_SMS;
              file_update_res->fu_rsc = SIM_FU_SUCCESS;
              PSENDX (SIM, file_update_res);
              sms_data->sim_mem_update = FALSE;
            }
#endif
            /*
             * check for existing but empty memory
             */
            if (SMS_SIM_PROP(sms_data).max_record > 0
                 AND !SMS_SIM_PROP(sms_data).any_valid)
              tl_message_ind_from_sim (MEM_SM, 0,
                                       SMS_SIM_PROP(sms_data).max_record,
                                       NULL);

           /* 
            * init done
            */
            tl_init_complete();
          }
        }
        else
        {
          /*
           * declare only successful read
           * entries as available
           */
          SMS_SIM_PROP(sms_data).max_record = record - 1;
          // must be doubled
          /* 
           * init done
           */
          tl_init_complete();
        }
        break;

      default:
        assert (GET_STATE (STATE_MMI) EQ MMI_IDLE); /* illegal state */
        break;
      }
#ifdef SIM_TOOLKIT
      if (sms_data->file_update_ind NEQ NULL)
      {
        T_SIM_FILE_UPDATE_IND *file_update_ind = sms_data->file_update_ind;
        sms_data->file_update_ind = NULL;
        tl_sim_file_update_ind (file_update_ind);
      }
#endif
      break;

    case ACCESS_BY_NET:
      GET_MT_INSTANCE(sms_data);    /* MT */
      switch (GET_STATE (STATE_NET))
      {
      case NET_READ:
        if (tl_check_replace_entry (&SMS_RP_RCVD(sms_data)->rp_user_data.tpdu.b_tpdu[1],
                                    &read_cnf->linear_data[1]))
        {
          /*
           *record shall be replaced
           */
          tl_sim_conv_update_req (record, SMS_RP_RCVD(sms_data));

          SMS_EM_REPLACE_SMS_IN_SIM;

          tl_set_access_fifo (ACCESS_BY_NET);
          SET_STATE (STATE_NET, NET_WRITE);
        }
        else
        {
          int i;

          i = tl_check_mt_pid (&SMS_SIM_PROP(sms_data),
                               record + 1,
                               SMS_PID(sms_data));
          if (i > 0)
          {
            tl_set_access_fifo (ACCESS_BY_NET);
            tl_sim_read_record_req((UBYTE)i);
          }
          else
          {
            MCAST (sms_deliver, TP_DELIVER);

            SET_STATE (STATE_NET, NET_IDLE);

            CCD_START;
            ccd_decodeMsg (CCDENT_SMS,
                           DOWNLINK,
                           (T_MSGBUF *)&SMS_RP_RCVD(sms_data)->rp_user_data.tpdu,
                           (UBYTE *)sms_deliver,
                           TP_DELIVER);
            tl_handle_message (sms_deliver);
            CCD_END;
          }
        }
        break;

      default:
        assert (GET_STATE (STATE_NET) EQ NET_IDLE); /* illegal state */
        break;
      }
      break;

    default:
      assert (0);    /* impossible case */
      break;
    }
  }
  PFREE (read_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_remove_ind          |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_REMOVE_IND.

*/

GLOBAL void tl_sim_remove_ind (T_SIM_REMOVE_IND *remove_ind)
{
  USHORT error;
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0);

  TRACE_FUNCTION ("tl_sim_remove_ind()");
  if (sms_data)
  {
    error = (remove_ind->cause EQ SIM_NO_ERROR)?
            SMS_CAUSE_SIM_BUSY: remove_ind->cause;

    tl_sim_abort_to_mmi (error);

    sms_data->init_done = FALSE;
    SMS_SIM_PROP(sms_data).max_record = 0;
    sms_data->me_backup.max_record  = 0;
    sms_data->sim_mem_update = FALSE;
  }
  PFREE (remove_ind);
}

#if defined(SIM_TOOLKIT)
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_toolkit_cnf         |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_TOOLKIT_CNF.

*/

GLOBAL void tl_sim_toolkit_cnf (T_SIM_TOOLKIT_CNF *toolkit_cnf)
{
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_sim_toolkit_cnf()");

  switch (tl_read_access_fifo ())
  {
    case ACCESS_BY_NET:
      GET_MT_INSTANCE(sms_data);    /* MT */
      tl_sim_toolkit_confirm (toolkit_cnf);
      break;

    default:
      assert(0);
      break;
  }
  PFREE (toolkit_cnf);
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_sim_file_update_ind     |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive SIM_FILE_UPDATE_IND.

*/

GLOBAL void tl_sim_file_update_ind (T_SIM_FILE_UPDATE_IND *file_update_ind)
{
  USHORT i;
  BOOL found_sms = FALSE;   /* short messages changed by SAT */
  BOOL found_smss = FALSE;  /* short message status changed by SAT */
  register T_SMS_DATA *sms_data = GET_SMS_INSTANCE (0);

  TRACE_FUNCTION ("tl_sim_file_update_ind()");

  if (sms_data)
  {
    /*
     * avoid interference with active MMI procedure
     */
    switch (GET_STATE (STATE_MMI))
    {
      case MMI_IDLE:
        break;

      default:
        if (sms_data->file_update_ind NEQ NULL)
          PFREE (sms_data->file_update_ind);
        /* store primitive for delayed reaction */
        sms_data->file_update_ind = file_update_ind;
        return;
    }

    for (i = 0; i < file_update_ind->val_nr; i++)
    {
      if((file_update_ind->file_info[i].v_path_info EQ TRUE)  AND
         (file_update_ind->file_info[i].path_info.df_level1   EQ SIM_DF_TELECOM) AND
         (file_update_ind->file_info[i].path_info.v_df_level2 EQ FALSE))
      {
        if (file_update_ind->file_info[i].datafield EQ SIM_SMS)
        {
          /* short messages changed by SAT */
          found_sms = TRUE;
          sms_data->sim_mem_update = TRUE;
        }
        else if (file_update_ind->file_info[i].datafield EQ SIM_SMSS)
        {
          /* short message status changed by SAT */
          found_smss = TRUE;
        }
      }

      if (found_sms AND found_smss)
        break;
    }

    if (found_smss)
    {
      /* short message status changed by SAT */
      tl_sim_read_req (SIM_SMSS, 2);
      sms_data->sim_mem_update = found_sms NEQ FALSE;

      SET_STATE (STATE_MMI, MMI_STATE_UPDATE);
    }
    else if (found_sms)
    {
      /* short messages changed by SAT */
      sms_data->init_done = FALSE;
      SMS_SIM_PROP(sms_data).max_record = 0;
      tl_mnsms_report_ind (SMS_ENT_STATE(sms_data) = SMS_STATE_INITIALISING);
      sms_data->sim_mem_update = TRUE;
      tl_find_first (MEM_SM);
    }
    else
    {
      /* Nothing to do, indicate success to SAT */
      PALLOC (file_update_res, SIM_FILE_UPDATE_RES); /* T_SIM_FILE_UPDATE_RES */
      file_update_res->source = SRC_SMS;
      file_update_res->fu_rsc = SIM_FU_SUCCESS;
      PSENDX (SIM, file_update_res);
    }
  }
  PFREE (file_update_ind);
}

#endif  // SIM_TOOLKIT

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLF                    |
| STATE   : code                ROUTINE : tl_mnsms_cmms_end_ind      |
+--------------------------------------------------------------------+

  PURPOSE : Function used for sending MNSMS_REPORT_IND.Primitive to ACI
            when cmms_mode is eqaul to 1.

*/

GLOBAL void tl_mnsms_cmms_end_ind(void)
{
  GET_INSTANCE_DATA;
  PALLOC (report_ind, MNSMS_REPORT_IND);

  TRACE_FUNCTION ("tl_mnsms_cmms_end_ind()");

  if(sms_data->cmms_mode EQ CMMS_MODE_ONE)
  {
    sms_data->cmms_mode = CMMS_MODE_DEF;
    report_ind->state = SMS_STATE_READY;
    report_ind->v_cmms_mode = TRUE;
    report_ind->cmms_mode = sms_data->cmms_mode;
    PSENDX (MMI, report_ind);
  }
}

#ifdef SIM_PERS_OTA
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_OTA_message_res    |
+--------------------------------------------------------------------+

  PURPOSE : Process the primitive MNSMS_OTA_MESSAGE_RES.

*/

GLOBAL void tl_mnsms_OTA_message_res ( T_MNSMS_OTA_MESSAGE_RES *mnsms_OTA_message_res )
{
  
  T_SMS_DATA *sms_data = GET_INSTANCE(0);
  
  TRACE_FUNCTION ("tl_mnsms_OTA_message_res()");

  if (sms_data) /*lint !e774 always True*/
  { 
    GET_MT_INSTANCE(sms_data);  /* MT operation */	

    switch (SMS_INST_GET_STATE (STATE_TL))
     {
        case TL_RECEIVE:
         if (sms_timer_check(TR2M))
         {
           T_TP_DLVR_REP_ACK *rep_ack ;
           T_rp_user_data *rp_ud;
           MALLOC(rep_ack, sizeof(T_TP_DLVR_REP_ACK));
           MALLOC(rp_ud, sizeof(T_rp_user_data));
         
           rep_ack->tp_vt_mti = SMS_VT_DLVR_REP_ACK;
           rep_ack->tp_udhi = SMS_UDHI_NOT_INCLUDED;
           rep_ack->tp_mti = SMS_DELIVER_REPORT;
           rep_ack->v_tp_udh_inc = FALSE;
         
           memcpy(rep_ack->tp_ud.data, mnsms_OTA_message_res->data,mnsms_OTA_message_res->len);
         
           rep_ack->tp_ud.c_data =mnsms_OTA_message_res->len;  //No of octets
           rep_ack->tp_ud.length = mnsms_OTA_message_res->packedlen;  /*Since default alphabet is used as per 23.040 sec. 9.2.3.16
                           the length contains no of septets of data returned */
                         
           rep_ack->tp_ext = SMS_EXT_NOT_INCLUDED;
           rep_ack->v_tp_ud = TRUE;
           rep_ack->tp_udl_p = SMS_UD_INCLUDED;
           rep_ack->tp_dcs = mnsms_OTA_message_res->tp_dcs;
           rep_ack->v_tp_dcs = TRUE;
           rep_ack->tp_dcs_p = SMS_DCS_INCLUDED;
           rep_ack->tp_pid = mnsms_OTA_message_res->tp_pid;
           rep_ack->v_tp_pid = TRUE;
           rep_ack->tp_pid_p = SMS_PID_INCLUDED;
           rp_ud->tpdu.o_tpdu = 0;
           rp_ud->tpdu.l_tpdu = TPDU_BIT_LEN;
           rp_ud->v_tpdu = (ccd_codeMsg (CCDENT_SMS, UPLINK,
                                        (T_MSGBUF *)&rp_ud->tpdu,
                                        (UBYTE *)rep_ack,
                                         SMS_VT_DLVR_REP_ACK) EQ ccdOK);
           rp_ud->tp_mti = SMS_DELIVER_REPORT;
             
           MFREE (rep_ack);
           rl_report_req_ack (rp_ud);
           MFREE (rp_ud);           
           SMS_INST_SET_STATE (STATE_TL, TL_IDLE);
      }
     else
      {
           /*TR2M TIM EXPIRE -ACI NOT RESPONDED WITHIN TR2M */
     	}
     break;
	 
    default:
        /* INVALID SMS TL STATE IN MNSMS_OTA_MESSAGE_RES */
        break;

   }
 }
  PFREE (mnsms_OTA_message_res);
 
}
#endif /* End OTA */
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_retrans_req        |
+--------------------------------------------------------------------+

  PURPOSE : Handles the primitive MNSMS_RETRANS_REQ. This will support user 
  requested retransmission of the last failed message as per 
  23.040 R99 Section 9.2.3.6.
*/
#ifdef REL99
GLOBAL void tl_mnsms_retrans_req (T_MNSMS_RETRANS_REQ *mnsms_retrans_req)
{
  GET_INSTANCE_DATA;

  TRACE_FUNCTION ("tl_mnsms_retrans_req()");

  switch (SMS_INST_GET_STATE (STATE_TL))
  {
    case TL_SEND_CONTD:
     /*
      * stop timer TLCT
      */
      sms_timer_stop(TLCT);  
    /*FALLTHROUGH*/ /*lint -fallthrough*/
    case TL_IDLE:
      if (sms_timer_check(TRAM))
      {
        /*
         * MNSMS_SUBMIT_CNF
         */
         tl_mnsms_retrans_cnf (SMS_SEL_MEM(sms_data), SMS_SEL_REC(sms_data),
                             NOT_PRESENT_8BIT, SMS_CAUSE_ENTITY_BUSY, NULL);
         break;
      }

       /* Check if MO message is present(stored CPDU data available?) */
      if (SMS_DATA_REQ(sms_data) NEQ NULL)
      {    
        if(mnsms_retrans_req->auto_rep_flag EQ AUTO_REP_FLAG_ENABLED)
        {
          SMS_INST.tl_retx = 0;
        }
        else
        {
          /* Set to the max value so that retransmission will not be done */
          SMS_INST.tl_retx = TL_MAX_RETANS;
        }

        SMS_INST_SET_STATE (STATE_TL, TL_SEND); 

        /* Restore the record number and storage type */
        SMS_SEL_REC(sms_data) = SMS_INST.failed_msg_rec_num;
        SMS_SEL_MEM(sms_data) = SMS_INST.failed_msg_mem;
        SMS_INST.failed_msg_retx = TRUE;
        
        /*
         * TL  state transition TL_ESTABLISH
         * EST state transition EST_SEND
         */
         SMS_INST_SET_STATE (STATE_TL, TL_ESTABLISH);
         SET_STATE (STATE_EST, EST_RTX);
        /*
         * establish connection
         */
         tl_establish_connection(FALSE);       
      }
      else
      {
        tl_mnsms_retrans_cnf (SMS_SEL_MEM(sms_data),SMS_SEL_REC(sms_data), 
                              SMS_TP_REF_RET(sms_data),
                              SMS_CAUSE_FAILED_MSG_NOT_FOUND, NULL);
      }
      break;
    
    default:
       tl_mnsms_retrans_cnf (SMS_SEL_MEM(sms_data),SMS_SEL_REC(sms_data),
                              SMS_TP_REF_RET(sms_data),
                              SMS_CAUSE_ENTITY_BUSY, NULL);
       break;
  }

  PFREE(mnsms_retrans_req);

  return;
}
/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_retrans_cnf        |
+--------------------------------------------------------------------+

  PURPOSE : Generate a response to the primitive MNSMS_RETRANS_REQ.
*/

GLOBAL void tl_mnsms_retrans_cnf ( UBYTE mem_type,
                                   UBYTE record,
                                   UBYTE tp_mr,
                                   USHORT cause,
                                   T_sms_sdu *sms_sdu )
{
  TRACE_FUNCTION ("tl_mnsms_retrans_cnf()");
  {
    PALLOC (retrans_cnf, MNSMS_RETRANS_CNF);
    retrans_cnf->mem_type = mem_type;
    retrans_cnf->rec_num = record;
    retrans_cnf->tp_mr = tp_mr;
    retrans_cnf->cause = cause;

    if (sms_sdu NEQ NULL)
    {
      memcpy (&retrans_cnf->sms_sdu, sms_sdu, sizeof (T_sms_sdu));
    }
    else
    {
      memset (&retrans_cnf->sms_sdu, 0, sizeof (T_sms_sdu)); 
    }

    PSENDX (MMI, retrans_cnf);
  }
}

/*
+--------------------------------------------------------------------+
| PROJECT : GSM-PS (8410)       MODULE  : SMS_TLP                    |
| STATE   : code                ROUTINE : tl_mnsms_send_prog_ind        |
+--------------------------------------------------------------------+

  PURPOSE : Send the primitive MNSMS_SEND_PROG_IND.
*/
GLOBAL void tl_mnsms_send_prog_ind (void)
{
  GET_INSTANCE_DATA;
  TRACE_FUNCTION ("tl_mnsms_send_prog_ind ()");
  {
    PALLOC (send_prog_ind, MNSMS_SEND_PROG_IND);
    send_prog_ind->resend_count = sms_data->data[INST_MO].tl_retx;
    send_prog_ind->max_retrans = TL_MAX_RETANS;  
    PSENDX (MMI, send_prog_ind);
  }
}
#endif /* REL99 */

#endif