line source
+ − /*
+ − +-----------------------------------------------------------------------------
+ − | Project : GSM-PS (8410)
+ − | Modul : MM_TIM
+ − +-----------------------------------------------------------------------------
+ − | 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 timer handling functions
+ − | for the component MM of the mobile station
+ − +-----------------------------------------------------------------------------
+ − */
+ −
+ − #ifndef MM_TIM_C
+ − #define MM_TIM_C
+ −
+ − #include "config.h"
+ − #include "fixedconf.h"
+ − #include "condat-features.h"
+ −
+ − #define ENTITY_MM
+ −
+ − /*==== 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_mm.h"
+ − #include "mon_mm.h"
+ − #include "pei.h"
+ − #include "tok.h"
+ − #include "mm.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_mm.h"
+ − #include "mon_mm.h"
+ − #include "vsi.h"
+ − #include "pei.h"
+ − #include "tok.h"
+ − #include "mm.h"
+ −
+ − #endif
+ − /*==== EXPORT =====================================================*/
+ −
+ − /*==== PRIVAT =====================================================*/
+ −
+ − /*==== VARIABLES ==================================================*/
+ −
+ − #if defined (OPTION_TIMER)
+ − LOCAL T_TIMER_CONFIG config_table[NUM_OF_MM_TIMERS];
+ − #endif
+ −
+ −
+ − /*==== FUNCTIONS ==================================================*/
+ − #if defined (OPTION_TIMER)
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_init_timer |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Initialise Time-out FIFO and configuration data.
+ −
+ − */
+ −
+ −
+ − GLOBAL BOOL tim_init_timer (void)
+ − {
+ − USHORT i;
+ −
+ − TRACE_FUNCTION ("tim_init_timer()");
+ −
+ − for (i = 0; i < NUM_OF_MM_TIMERS; i++)
+ − {
+ − config_table[i].t_mode = TIMER_RESET;
+ − config_table[i].t_val = 0L;
+ − }
+ −
+ − return TRUE;
+ − }
+ − #endif /* #if defined (OPTION_TIMER) */
+ −
+ − #if defined (OPTION_TIMER)
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_config_timer |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Configure Timer
+ −
+ − */
+ −
+ − GLOBAL void tim_config_timer (UBYTE t_num, UBYTE t_mod, ULONG t_val)
+ − {
+ − TRACE_FUNCTION ("tim_config_timer()");
+ −
+ − assert (t_num < NUM_OF_MM_TIMERS);
+ −
+ − if (t_num < NUM_OF_MM_TIMERS)
+ − {
+ − config_table[t_num].t_mode = t_mod;
+ − config_table[t_num].t_val = t_val;
+ − }
+ − else
+ − {
+ − TRACE_ERROR ("tim_config_timer(): index out of range");
+ − }
+ − }
+ − #endif /* #if defined (OPTION_TIMER) */
+ −
+ − #if defined (NEW_FRAME)
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_exec_timeout |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : execute timeout
+ −
+ − */
+ −
+ − GLOBAL void tim_exec_timeout (USHORT index)
+ − {
+ − GET_INSTANCE_DATA;
+ − /* typedef void (*T_VOID_FUNC)(); */ /* Already defined */
+ −
+ − static const T_VOID_FUNC timer_jump_table[NUM_OF_MM_TIMERS] =
+ − {
+ − tim_t_reg, /* T_REGISTRATION */
+ − tim_t3210, /* T3210 */
+ − tim_t3211, /* T3211 */
+ − tim_t3212, /* T3212 */
+ − tim_t3213, /* T3213 */
+ − tim_t3220, /* T3220 */
+ − tim_t3230, /* T3230 */
+ − tim_t3240, /* T3240 */
+ −
+ − tim_t_hplmn /* T_HPLMN */
+ − #ifdef REL99
+ − , tim_t3241 /* T3241 */
+ − #endif
+ − };
+ −
+ − if (index < NUM_OF_MM_TIMERS)
+ − {
+ − /*
+ − * Timeout is handled in SDL like the reception of a primitive,
+ − * so enable also this trace if primitive traces are enabled only
+ − */
+ − /* Implements Measure#36 */
+ − #if defined(NCONFIG)
+ − /* partab is not defined when NCONFIG is defined */
+ − TRACE_EVENT_P1 ("tim_exec_timeout: index (%d)", index);
+ − #else /* not (NCONFIG) */
+ − #if defined (TRACE_PRIM) AND defined(OPTION_TIMER)
+ − TRACE_EVENT_P1 ("tim_exec_timeout (%s)", partab[index].keyword);
+ − #endif
+ − #endif /* NCONFIG */
+ −
+ − mm_data->t_running[index] = FALSE;
+ − timer_jump_table[index]();
+ − }
+ − else
+ − {
+ − TRACE_ERROR ("tim_exec_timeout(): index out of range");
+ − }
+ − }
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_stop_timer |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : stop timer
+ −
+ − */
+ −
+ − GLOBAL void tim_stop_timer (USHORT index)
+ − {
+ − GET_INSTANCE_DATA;
+ − assert (index < NUM_OF_MM_TIMERS);
+ −
+ − if (index < NUM_OF_MM_TIMERS)
+ − {
+ − /* Implements Measure#36 */
+ − #if defined(NCONFIG)
+ − /* partab is not defined when NCONFIG is defined */
+ − TRACE_EVENT_P1 ("tim_stop_timer: index (%d)", index);
+ − #else /* not (NCONFIG) */
+ − #if defined (TRACE_PRIM) AND defined(OPTION_TIMER)
+ − TRACE_EVENT_P1 ("tim_stop_timer (%s)", partab[index].keyword);
+ − #endif
+ − #endif /* NCONFIG */
+ −
+ − mm_data->t_running[index] = FALSE;
+ − TIMER_STOP (mm_handle, index);
+ − }
+ − else
+ − {
+ − TRACE_ERROR ("tim_stop_timer(): index out of range");
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_start_timer |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : start timer
+ −
+ − */
+ −
+ − GLOBAL void tim_start_timer (USHORT index, T_TIME value)
+ − {
+ − GET_INSTANCE_DATA;
+ − assert (index < NUM_OF_MM_TIMERS);
+ −
+ − if (index < NUM_OF_MM_TIMERS)
+ − {
+ − /* Implements Measure#36 */
+ − #if defined(NCONFIG)
+ − /* partab is not defined when NCONFIG is defined */
+ − TRACE_EVENT_P1 ("tim_start_timer: index (%d)", index);
+ − #else /* not (NCONFIG) */
+ − #if defined (TRACE_PRIM) AND defined(OPTION_TIMER)
+ − TRACE_EVENT_P1 ("tim_start_timer (%s)", partab[index].keyword);
+ − #endif
+ − #endif /* NCONFIG */
+ − #if defined (OPTION_TIMER)
+ − switch (config_table[index].t_mode)
+ − {
+ − case TIMER_SET:
+ − value = config_table[index].t_val;
+ − break;
+ −
+ − case TIMER_RESET:
+ − value = value;
+ − break;
+ −
+ − case TIMER_SPEED_UP:
+ − value = value / config_table[index].t_val;
+ − if (value == 0)
+ − value = 1;
+ − TRACE_EVENT_P1 ("timer_speed_up (%d)", value);
+ − break;
+ −
+ − case TIMER_SLOW_DOWN:
+ − value = value * config_table[index].t_val;
+ − TRACE_EVENT_P1 ("timer_speed_down (%d)", value);
+ − break;
+ −
+ − default:
+ − TRACE_FUNCTION ("ERROR: UNKNOWN MODE");
+ − return;
+ − }
+ − #endif
+ −
+ − mm_data->t_running[index] = TRUE;
+ −
+ − TIMER_START (mm_handle, index, value);
+ − }
+ − else
+ − {
+ − TRACE_ERROR ("tim_start_timer(): index out of range");
+ − }
+ − }
+ −
+ − #endif /* #if defined (NEW_FRAME) */
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3210 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3210
+ −
+ − */
+ −
+ − GLOBAL void tim_t3210 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3210()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_LUP_INITIATED:
+ − case MM_WAIT_FOR_RR_CONN_LUP:
+ − TIMERSTOP (T3240);
+ − mm_abort_connection (ABCS_NORM);
+ − /*
+ − * The RR connection is aborted normally. RR guarantees that this will
+ − * be answered by RR_RELEASE_IND.
+ − * This has the advange that GMM gets the MMGMM_NREG_IND after the
+ − * channel release of layer 2 if GPRS present without any disadvantage
+ − * for a GSM only protocol stack. No state change here.
+ − */
+ − break;
+ −
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3211 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3211
+ −
+ − */
+ −
+ − // T3211 handling routine does the same as T3213 handling routine now ...
+ −
+ − GLOBAL void tim_t3211 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3211()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − // If we leave these states and reenter a full service IDLE state,
+ − // mm_release_rr_connection()
+ − // for MM_WAIT_FOR_OUTG_MM_CONN and MM_WAIT_FOR_RR_CONN_MM will
+ − // handle the update.
+ − // mm_rr_activate_cnf() for MM_WAIT_FOR_RR_ACTIVE will also
+ − // handle the an outstanding update if coming back to full
+ − // service IDLE state.
+ − // mm_rr_abort_ind() will be called if the state was
+ − // MM_PLMN_SEARCH_NORMAL_SERVICE, if there is an outstanding
+ − // updating procedure and the new service is full service,
+ − // this will be checked there after state transition.
+ − // MM_IDLE_NO_CELL_AVAILABLE / RR_ACTIVATE_IND is handled also.
+ − // No need to store the timer anymore into the queue.
+ −
+ − /*
+ − // case MM_WAIT_FOR_OUTG_MM_CONN:
+ − // case MM_WAIT_FOR_RR_CONN_MM:
+ − // case MM_WAIT_FOR_RR_ACTIVE:
+ − case MM_PLMN_SEARCH_NORMAL_SERVICE:
+ − // case MM_IDLE_NO_CELL_AVAILABLE:
+ − mm_write_entry (TIMEOUT, T3211, 0);
+ − break;
+ − */
+ −
+ − case MM_IDLE_ATTEMPT_TO_UPDATE:
+ − case MM_IDLE_NORMAL_SERVICE:
+ − mm_continue_running_update ();
+ − break;
+ −
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3212 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of counter timer for timer T3212
+ −
+ − */
+ −
+ − GLOBAL void tim_t3212 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3212()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_NULL:
+ − case MM_IDLE_NO_IMSI:
+ − break; /* Forget the event */
+ −
+ − case MM_IDLE_NORMAL_SERVICE:
+ − mm_data->t3212_timeout = TRUE;
+ − mm_data->attempt_cnt = 0; /* Expiry of timer T3212 */
+ − if (!mm_normal_upd_needed())
+ − {
+ − /* MM is updated on the cell, no Imm Ass Rej, no cell barred */
+ − if (mm_lup_allowed_by_gmm())
+ − {
+ − mm_periodic_loc_upd ();
+ − }
+ − else
+ − {
+ − mm_mmgmm_lup_needed_ind (MMGMM_T3212);
+ − /* No state change, remains in MM_IDLE_NORMAL_SERVICE */
+ − }
+ − }
+ − break;
+ −
+ − case MM_IDLE_ATTEMPT_TO_UPDATE:
+ − if (mm_data->mm.mm_info.t3212 NEQ T3212_NO_PRD_UPDAT)
+ − {
+ − mm_data->t3212_timeout = TRUE;
+ − mm_data->attempt_cnt = 0; /* Expiry of timer T3212 */
+ − if (mm_lup_allowed_by_gmm())
+ − {
+ − mm_normal_loc_upd ();
+ − }
+ − else
+ − {
+ − mm_mmgmm_lup_needed_ind (MMGMM_T3212);
+ − /* No state change, remains in MM_IDLE_ATTEMPT_TO_UPDATE */
+ − }
+ − }
+ − break;
+ −
+ − default: /* Store the event until it is possible to handle it */
+ − mm_data->t3212_timeout = TRUE;
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3213 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3213
+ −
+ − */
+ −
+ − GLOBAL void tim_t3213 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3213()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − /*
+ − case MM_WAIT_FOR_OUTG_MM_CONN:
+ − case MM_WAIT_FOR_RR_CONN_MM:
+ − case MM_WAIT_FOR_RR_ACTIVE:
+ − case MM_PLMN_SEARCH_NORMAL_SERVICE:
+ − mm_write_entry (TIMEOUT, T3213, 0);
+ − break;
+ − */
+ −
+ − case MM_IDLE_ATTEMPT_TO_UPDATE:
+ − case MM_IDLE_NORMAL_SERVICE:
+ − /*
+ − * if something is received from RR or T3213 was already restarted 2 times --> delay of additional 8 seconds
+ − * continue the LUP attempts
+ − */
+ − mm_data->t3213_restart++;
+ − if (mm_data->t3213_restart > MAX_REST_T3213)
+ − mm_continue_running_update ();
+ − else
+ − TIMERSTART (T3213, T_3213_VALUE);
+ − break;
+ −
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3220 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3220
+ −
+ − */
+ −
+ − GLOBAL void tim_t3220 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3220()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_IMSI_DETACH_INIT:
+ − case MM_WAIT_FOR_RR_CONN_DETACH:
+ − /*
+ − * The RR connection is aborted normally. RR guarantees that this will
+ − * be answered by RR_RELEASE_IND. If MM receives the RR_RELEASE_IND,
+ − * the IMSI DETACH procedure ends and appropriate actions are taken.
+ − * This has the advange that GMM gets the MMGMM_NREG_CNF after the
+ − * channel release of layer 2 if GPRS present without any disadvantage
+ − * for a GSM only protocol stack. No state change here.
+ − */
+ − mm_abort_connection (ABCS_NORM);
+ − break;
+ −
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3230 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3230
+ −
+ − */
+ −
+ − GLOBAL void tim_t3230 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3230()");
+ −
+ − /*
+ − * If T3230 expires (i.e. no response is given but a RR connection is
+ − * available) the MM connection establishment is aborted and the requesting
+ − * CM sublayer is informed. If no other MM connection exists then the mobile
+ − * station shall proceed as described in section 4.5.3.1 for release of the
+ − * RR connection. Otherwise the mobile station shall return to the MM
+ − * sublayer state where the request of an MM connection was received,
+ − * i.e. to MM sublayer state MM connection active. Other ongoing
+ − * MM connections (if any) shall not be affected.
+ − * [GSM 04.08 subclause 4.5.1.2 b)]
+ − *
+ − * If all MM connections are released by their CM entities, the
+ − * mobile station shall set timer T3240 and enter the state
+ − * WAIT FOR NETWORK COMMAND, expecting the release of the RR connection.
+ − * [Excerpt from GSM 04.08 subclause 4.5.3.1]
+ − */
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_WAIT_FOR_REESTABLISH:
+ − case MM_WAIT_FOR_OUTG_MM_CONN:
+ − mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_ACTIVE);
+ − mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_PENDING);
+ − mm_data->wait_for_accept = FALSE;
+ − TIMERSTART (T3240, T_3240_VALUE);
+ − SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
+ − break;
+ −
+ − case MM_CONN_ACTIVE: /* wait_for_accept expected to be TRUE */
+ − mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_PENDING);
+ − mm_data->wait_for_accept = FALSE;
+ − if ((mm_count_connections (CM_ACTIVE) EQ 0) AND
+ − (mm_count_connections (CM_STORE) EQ 0))
+ − {
+ − TIMERSTART (T3240, T_3240_VALUE);
+ − SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
+ − }
+ − USE_STORED_ENTRIES();
+ − break;
+ −
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3240 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3240
+ −
+ − */
+ −
+ − GLOBAL void tim_t3240 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3240()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_PROCESS_PROMPT:
+ − case MM_WAIT_FOR_NW_CMD:
+ − mm_abort_connection (ABCS_NORM);
+ − mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_ACTIVE);
+ − mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_PENDING);
+ −
+ − /*
+ − * The RR connection is aborted normally. RR guarantees that this will
+ − * be answered by RR_RELEASE_IND.
+ − * This has the advange that GMM gets the MMGMM_CM_RELEASE_IND after the
+ − * channel release of layer 2 if GPRS present without any disadvantage
+ − * for a GSM only protocol stack. No state change here.
+ − */
+ − break;
+ −
+ − case MM_LUP_REJECTED:
+ − mm_abort_connection (ABCS_NORM);
+ − /*
+ − * The RR connection is aborted normally. RR guarantees that this will
+ − * be answered by RR_RELEASE_IND.
+ − * This has the advange that GMM gets the MMGMM_NREG_IND after the
+ − * channel release of layer 2 if GPRS present without any disadvantage
+ − * for a GSM only protocol stack. No state change here.
+ − */
+ − break;
+ −
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ −
+ − #ifdef REL99
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t3241 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T3241
+ −
+ − */
+ −
+ − GLOBAL void tim_t3241 (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t3241()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_RR_CONN_RELEASE_NOT_ALLOWED:
+ − mm_abort_connection (ABCS_NORM);
+ − /*
+ − * The RR connection is aborted normally. RR guarantees that this will
+ − * be answered by RR_RELEASE_IND.
+ − * This has the advange that GMM gets the MMGMM_CM_RELEASE_IND after the
+ − * channel release of layer 2 if GPRS present without any disadvantage
+ − * for a GSM only protocol stack. No state change here.
+ − */
+ − break;
+ − default: /* Ignore event */
+ − break;
+ − }
+ − }
+ − #endif
+ −
+ −
+ − /*
+ − +----------------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t_hplmn |
+ − +----------------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T_HPLMN.
+ − This timer allows control of the PPLMN rescan and
+ − national roaming procedure to recover the HPLMN.
+ − */
+ −
+ − GLOBAL void tim_t_hplmn (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t_hplmn()");
+ −
+ − /*
+ − * Launch the scan procedure if it still makes sense to do it according to
+ − * MM state.
+ − */
+ − if (mm_full_service_pplmn_scan())
+ − {
+ − mm_data->plmn_scan_mm = TRUE;
+ − mm_data->first_attach_mem = FALSE;
+ − mm_func_mmgmm_net_req();
+ − }
+ − }
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
+ − | STATE : code ROUTINE : tim_t_reg |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Timeout of timer T_REG.
+ − This timer is not foreseen by the recommendations.
+ − It is MM's health monitor timer, checking
+ − the conditions whether an update has been missed.
+ −
+ − */
+ −
+ − GLOBAL void tim_t_reg (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("tim_t_reg()");
+ −
+ − switch (GET_STATE (STATE_MM))
+ − {
+ − case MM_NULL:
+ − break; /* No timer activity in this state */
+ −
+ − case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
+ − /* Restart the registration timer */
+ − TIMERSTART (T_REGISTRATION, T_REG_VALUE);
+ −
+ − /*
+ − * As it is not expected that the timer catches in state
+ − * MM_IDLE_NORMAL_SERVICE in FTA, there is no test
+ − * here for a test SIM. The goal is to have an MM
+ − * where the timer never catches in MM_IDLE_NORMAL_SERVICE.
+ − */
+ −
+ − /* Check whether T3211, T3213 are running retriggering update anyway */
+ − if ((TIMERACTIVE (T3211) OR TIMERACTIVE (T3213)) AND
+ − (mm_data->loc_upd_type.lut NEQ NOT_RUNNING))
+ − return;
+ −
+ − /* Check whether MM is temporary barred and cannot update now */
+ − if ((mm_data->idle_entry EQ RRCS_ACCESS_BARRED) OR
+ − (mm_data->idle_entry EQ RRCS_RND_ACC_DELAY))
+ − return;
+ −
+ − /*
+ − * Check whether we are in an ATTACH update procedure, but there is no
+ − * T3211, T3213 timer running and MM is not temporary barred.
+ − */
+ − if (mm_attach_upd_needed() OR mm_normal_upd_needed())
+ − {
+ − TRACE_ERROR ("Recover ATTACH/NORMAL");
+ −
+ − mm_mmgmm_lup_needed_ind (MMGMM_REG_TIMER);
+ −
+ − if (mm_normal_upd_needed ())
+ − {
+ − mm_data->attempt_cnt = 0; /* New location area */
+ − mm_normal_loc_upd ();
+ − }
+ − else
+ − {
+ − mm_attach_loc_upd ();
+ − }
+ − return;
+ − }
+ −
+ − /*
+ − * Check whether T3212 should run, but is not running.
+ − * If so, something irregular has happened and
+ − * we have to start the update immediately.
+ − */
+ − if (mm_data->mm.mm_info.t3212 NEQ T3212_NO_PRD_UPDAT AND
+ − (!TIMERACTIVE (T3212) OR mm_data->t3212_timeout))
+ − {
+ − /*
+ − * The networks says we have periodic updating,
+ − * but unexpectedly T3212 is not running or T3212 timed out.
+ − */
+ − TRACE_ERROR ("Recover PERIODIC");
+ −
+ − if (mm_lup_allowed_by_gmm())
+ − {
+ − mm_periodic_loc_upd ();
+ − }
+ − else
+ − {
+ − // Don't add recovery code now for GPRS, maybe more has to be done.
+ − // mm_mmgmm_lup_needed_ind (MMGMM_REG_TIMER);
+ − }
+ − return;
+ − }
+ − break;
+ −
+ − case MM_IDLE_ATTEMPT_TO_UPDATE: /* 19.2 */
+ − /* Restart the registration timer */
+ − TIMERSTART (T_REGISTRATION, T_REG_VALUE);
+ −
+ − /* Timer only handled in this state if a normal SIM is present */
+ − if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT OR
+ − mm_data->reg.op.ts EQ TS_AVAIL)
+ − return;
+ −
+ − /* Check whether T3211, T3213 are running retriggering update anyway */
+ − if ((TIMERACTIVE (T3211) OR TIMERACTIVE (T3213)) AND
+ − (mm_data->loc_upd_type.lut NEQ NOT_RUNNING))
+ − return;
+ −
+ − if (TIMERACTIVE (T3212))
+ − return;
+ −
+ −
+ − /* Check whether MM is temporary barred and cannot update now */
+ − if ((mm_data->idle_entry EQ RRCS_ACCESS_BARRED) OR
+ − (mm_data->idle_entry EQ RRCS_RND_ACC_DELAY))
+ − return;
+ −
+ − if (mm_gsm_alone ())
+ − {
+ − mm_normal_loc_upd ();
+ − }
+ − else
+ − {
+ − mm_mmgmm_lup_needed_ind (MMGMM_REG_TIMER);
+ − /* No state change, remains in MM_IDLE_ATTEMPT_TO_UPDATE */
+ − }
+ − break;
+ −
+ − default:
+ − /* Restart the registration timer */
+ − TIMERSTART (T_REGISTRATION, T_REG_VALUE);
+ − break;
+ − }
+ − }
+ −
+ − #endif