comparison g23m-gsm/mm/mm_tim.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS (8410)
4 | Modul : MM_TIM
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This Modul defines the timer handling functions
18 | for the component MM of the mobile station
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef MM_TIM_C
23 #define MM_TIM_C
24
25 #include "config.h"
26 #include "fixedconf.h"
27 #include "condat-features.h"
28
29 #define ENTITY_MM
30
31 /*==== INCLUDES ===================================================*/
32 #if defined (NEW_FRAME)
33
34 #include <string.h>
35 #include <stdlib.h>
36 #include <stddef.h>
37 #include "typedefs.h"
38 #include "pcm.h"
39 #include "pconst.cdg"
40 #include "mconst.cdg"
41 #include "message.h"
42 #include "ccdapi.h"
43 #include "vsi.h"
44 #include "custom.h"
45 #include "gsm.h"
46 #include "prim.h"
47 #include "cnf_mm.h"
48 #include "mon_mm.h"
49 #include "pei.h"
50 #include "tok.h"
51 #include "mm.h"
52
53 #else
54
55 #include <string.h>
56 #include <stdlib.h>
57 #include <stddef.h>
58 #include "stddefs.h"
59 #include "pcm.h"
60 #include "pconst.cdg"
61 #include "mconst.cdg"
62 #include "message.h"
63 #include "ccdapi.h"
64 #include "custom.h"
65 #include "gsm.h"
66 #include "prim.h"
67 #include "cnf_mm.h"
68 #include "mon_mm.h"
69 #include "vsi.h"
70 #include "pei.h"
71 #include "tok.h"
72 #include "mm.h"
73
74 #endif
75 /*==== EXPORT =====================================================*/
76
77 /*==== PRIVAT =====================================================*/
78
79 /*==== VARIABLES ==================================================*/
80
81 #if defined (OPTION_TIMER)
82 LOCAL T_TIMER_CONFIG config_table[NUM_OF_MM_TIMERS];
83 #endif
84
85
86 /*==== FUNCTIONS ==================================================*/
87 #if defined (OPTION_TIMER)
88 /*
89 +--------------------------------------------------------------------+
90 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
91 | STATE : code ROUTINE : tim_init_timer |
92 +--------------------------------------------------------------------+
93
94 PURPOSE : Initialise Time-out FIFO and configuration data.
95
96 */
97
98
99 GLOBAL BOOL tim_init_timer (void)
100 {
101 USHORT i;
102
103 TRACE_FUNCTION ("tim_init_timer()");
104
105 for (i = 0; i < NUM_OF_MM_TIMERS; i++)
106 {
107 config_table[i].t_mode = TIMER_RESET;
108 config_table[i].t_val = 0L;
109 }
110
111 return TRUE;
112 }
113 #endif /* #if defined (OPTION_TIMER) */
114
115 #if defined (OPTION_TIMER)
116
117 /*
118 +--------------------------------------------------------------------+
119 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
120 | STATE : code ROUTINE : tim_config_timer |
121 +--------------------------------------------------------------------+
122
123 PURPOSE : Configure Timer
124
125 */
126
127 GLOBAL void tim_config_timer (UBYTE t_num, UBYTE t_mod, ULONG t_val)
128 {
129 TRACE_FUNCTION ("tim_config_timer()");
130
131 assert (t_num < NUM_OF_MM_TIMERS);
132
133 if (t_num < NUM_OF_MM_TIMERS)
134 {
135 config_table[t_num].t_mode = t_mod;
136 config_table[t_num].t_val = t_val;
137 }
138 else
139 {
140 TRACE_ERROR ("tim_config_timer(): index out of range");
141 }
142 }
143 #endif /* #if defined (OPTION_TIMER) */
144
145 #if defined (NEW_FRAME)
146 /*
147 +--------------------------------------------------------------------+
148 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
149 | STATE : code ROUTINE : tim_exec_timeout |
150 +--------------------------------------------------------------------+
151
152 PURPOSE : execute timeout
153
154 */
155
156 GLOBAL void tim_exec_timeout (USHORT index)
157 {
158 GET_INSTANCE_DATA;
159 /* typedef void (*T_VOID_FUNC)(); */ /* Already defined */
160
161 static const T_VOID_FUNC timer_jump_table[NUM_OF_MM_TIMERS] =
162 {
163 tim_t_reg, /* T_REGISTRATION */
164 tim_t3210, /* T3210 */
165 tim_t3211, /* T3211 */
166 tim_t3212, /* T3212 */
167 tim_t3213, /* T3213 */
168 tim_t3220, /* T3220 */
169 tim_t3230, /* T3230 */
170 tim_t3240, /* T3240 */
171
172 tim_t_hplmn /* T_HPLMN */
173 #ifdef REL99
174 , tim_t3241 /* T3241 */
175 #endif
176 };
177
178 if (index < NUM_OF_MM_TIMERS)
179 {
180 /*
181 * Timeout is handled in SDL like the reception of a primitive,
182 * so enable also this trace if primitive traces are enabled only
183 */
184 /* Implements Measure#36 */
185 #if defined(NCONFIG)
186 /* partab is not defined when NCONFIG is defined */
187 TRACE_EVENT_P1 ("tim_exec_timeout: index (%d)", index);
188 #else /* not (NCONFIG) */
189 #if defined (TRACE_PRIM) AND defined(OPTION_TIMER)
190 TRACE_EVENT_P1 ("tim_exec_timeout (%s)", partab[index].keyword);
191 #endif
192 #endif /* NCONFIG */
193
194 mm_data->t_running[index] = FALSE;
195 timer_jump_table[index]();
196 }
197 else
198 {
199 TRACE_ERROR ("tim_exec_timeout(): index out of range");
200 }
201 }
202
203
204 /*
205 +--------------------------------------------------------------------+
206 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
207 | STATE : code ROUTINE : tim_stop_timer |
208 +--------------------------------------------------------------------+
209
210 PURPOSE : stop timer
211
212 */
213
214 GLOBAL void tim_stop_timer (USHORT index)
215 {
216 GET_INSTANCE_DATA;
217 assert (index < NUM_OF_MM_TIMERS);
218
219 if (index < NUM_OF_MM_TIMERS)
220 {
221 /* Implements Measure#36 */
222 #if defined(NCONFIG)
223 /* partab is not defined when NCONFIG is defined */
224 TRACE_EVENT_P1 ("tim_stop_timer: index (%d)", index);
225 #else /* not (NCONFIG) */
226 #if defined (TRACE_PRIM) AND defined(OPTION_TIMER)
227 TRACE_EVENT_P1 ("tim_stop_timer (%s)", partab[index].keyword);
228 #endif
229 #endif /* NCONFIG */
230
231 mm_data->t_running[index] = FALSE;
232 TIMER_STOP (mm_handle, index);
233 }
234 else
235 {
236 TRACE_ERROR ("tim_stop_timer(): index out of range");
237 }
238 }
239
240 /*
241 +--------------------------------------------------------------------+
242 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
243 | STATE : code ROUTINE : tim_start_timer |
244 +--------------------------------------------------------------------+
245
246 PURPOSE : start timer
247
248 */
249
250 GLOBAL void tim_start_timer (USHORT index, T_TIME value)
251 {
252 GET_INSTANCE_DATA;
253 assert (index < NUM_OF_MM_TIMERS);
254
255 if (index < NUM_OF_MM_TIMERS)
256 {
257 /* Implements Measure#36 */
258 #if defined(NCONFIG)
259 /* partab is not defined when NCONFIG is defined */
260 TRACE_EVENT_P1 ("tim_start_timer: index (%d)", index);
261 #else /* not (NCONFIG) */
262 #if defined (TRACE_PRIM) AND defined(OPTION_TIMER)
263 TRACE_EVENT_P1 ("tim_start_timer (%s)", partab[index].keyword);
264 #endif
265 #endif /* NCONFIG */
266 #if defined (OPTION_TIMER)
267 switch (config_table[index].t_mode)
268 {
269 case TIMER_SET:
270 value = config_table[index].t_val;
271 break;
272
273 case TIMER_RESET:
274 value = value;
275 break;
276
277 case TIMER_SPEED_UP:
278 value = value / config_table[index].t_val;
279 if (value == 0)
280 value = 1;
281 TRACE_EVENT_P1 ("timer_speed_up (%d)", value);
282 break;
283
284 case TIMER_SLOW_DOWN:
285 value = value * config_table[index].t_val;
286 TRACE_EVENT_P1 ("timer_speed_down (%d)", value);
287 break;
288
289 default:
290 TRACE_FUNCTION ("ERROR: UNKNOWN MODE");
291 return;
292 }
293 #endif
294
295 mm_data->t_running[index] = TRUE;
296
297 TIMER_START (mm_handle, index, value);
298 }
299 else
300 {
301 TRACE_ERROR ("tim_start_timer(): index out of range");
302 }
303 }
304
305 #endif /* #if defined (NEW_FRAME) */
306
307 /*
308 +--------------------------------------------------------------------+
309 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
310 | STATE : code ROUTINE : tim_t3210 |
311 +--------------------------------------------------------------------+
312
313 PURPOSE : Timeout of timer T3210
314
315 */
316
317 GLOBAL void tim_t3210 (void)
318 {
319 GET_INSTANCE_DATA;
320 TRACE_FUNCTION ("tim_t3210()");
321
322 switch (GET_STATE (STATE_MM))
323 {
324 case MM_LUP_INITIATED:
325 case MM_WAIT_FOR_RR_CONN_LUP:
326 TIMERSTOP (T3240);
327 mm_abort_connection (ABCS_NORM);
328 /*
329 * The RR connection is aborted normally. RR guarantees that this will
330 * be answered by RR_RELEASE_IND.
331 * This has the advange that GMM gets the MMGMM_NREG_IND after the
332 * channel release of layer 2 if GPRS present without any disadvantage
333 * for a GSM only protocol stack. No state change here.
334 */
335 break;
336
337 default: /* Ignore event */
338 break;
339 }
340 }
341
342 /*
343 +--------------------------------------------------------------------+
344 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
345 | STATE : code ROUTINE : tim_t3211 |
346 +--------------------------------------------------------------------+
347
348 PURPOSE : Timeout of timer T3211
349
350 */
351
352 // T3211 handling routine does the same as T3213 handling routine now ...
353
354 GLOBAL void tim_t3211 (void)
355 {
356 GET_INSTANCE_DATA;
357 TRACE_FUNCTION ("tim_t3211()");
358
359 switch (GET_STATE (STATE_MM))
360 {
361 // If we leave these states and reenter a full service IDLE state,
362 // mm_release_rr_connection()
363 // for MM_WAIT_FOR_OUTG_MM_CONN and MM_WAIT_FOR_RR_CONN_MM will
364 // handle the update.
365 // mm_rr_activate_cnf() for MM_WAIT_FOR_RR_ACTIVE will also
366 // handle the an outstanding update if coming back to full
367 // service IDLE state.
368 // mm_rr_abort_ind() will be called if the state was
369 // MM_PLMN_SEARCH_NORMAL_SERVICE, if there is an outstanding
370 // updating procedure and the new service is full service,
371 // this will be checked there after state transition.
372 // MM_IDLE_NO_CELL_AVAILABLE / RR_ACTIVATE_IND is handled also.
373 // No need to store the timer anymore into the queue.
374
375 /*
376 // case MM_WAIT_FOR_OUTG_MM_CONN:
377 // case MM_WAIT_FOR_RR_CONN_MM:
378 // case MM_WAIT_FOR_RR_ACTIVE:
379 case MM_PLMN_SEARCH_NORMAL_SERVICE:
380 // case MM_IDLE_NO_CELL_AVAILABLE:
381 mm_write_entry (TIMEOUT, T3211, 0);
382 break;
383 */
384
385 case MM_IDLE_ATTEMPT_TO_UPDATE:
386 case MM_IDLE_NORMAL_SERVICE:
387 mm_continue_running_update ();
388 break;
389
390 default: /* Ignore event */
391 break;
392 }
393 }
394
395 /*
396 +--------------------------------------------------------------------+
397 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
398 | STATE : code ROUTINE : tim_t3212 |
399 +--------------------------------------------------------------------+
400
401 PURPOSE : Timeout of counter timer for timer T3212
402
403 */
404
405 GLOBAL void tim_t3212 (void)
406 {
407 GET_INSTANCE_DATA;
408 TRACE_FUNCTION ("tim_t3212()");
409
410 switch (GET_STATE (STATE_MM))
411 {
412 case MM_NULL:
413 case MM_IDLE_NO_IMSI:
414 break; /* Forget the event */
415
416 case MM_IDLE_NORMAL_SERVICE:
417 mm_data->t3212_timeout = TRUE;
418 mm_data->attempt_cnt = 0; /* Expiry of timer T3212 */
419 if (!mm_normal_upd_needed())
420 {
421 /* MM is updated on the cell, no Imm Ass Rej, no cell barred */
422 if (mm_lup_allowed_by_gmm())
423 {
424 mm_periodic_loc_upd ();
425 }
426 else
427 {
428 mm_mmgmm_lup_needed_ind (MMGMM_T3212);
429 /* No state change, remains in MM_IDLE_NORMAL_SERVICE */
430 }
431 }
432 break;
433
434 case MM_IDLE_ATTEMPT_TO_UPDATE:
435 if (mm_data->mm.mm_info.t3212 NEQ T3212_NO_PRD_UPDAT)
436 {
437 mm_data->t3212_timeout = TRUE;
438 mm_data->attempt_cnt = 0; /* Expiry of timer T3212 */
439 if (mm_lup_allowed_by_gmm())
440 {
441 mm_normal_loc_upd ();
442 }
443 else
444 {
445 mm_mmgmm_lup_needed_ind (MMGMM_T3212);
446 /* No state change, remains in MM_IDLE_ATTEMPT_TO_UPDATE */
447 }
448 }
449 break;
450
451 default: /* Store the event until it is possible to handle it */
452 mm_data->t3212_timeout = TRUE;
453 break;
454 }
455 }
456
457 /*
458 +--------------------------------------------------------------------+
459 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
460 | STATE : code ROUTINE : tim_t3213 |
461 +--------------------------------------------------------------------+
462
463 PURPOSE : Timeout of timer T3213
464
465 */
466
467 GLOBAL void tim_t3213 (void)
468 {
469 GET_INSTANCE_DATA;
470 TRACE_FUNCTION ("tim_t3213()");
471
472 switch (GET_STATE (STATE_MM))
473 {
474 /*
475 case MM_WAIT_FOR_OUTG_MM_CONN:
476 case MM_WAIT_FOR_RR_CONN_MM:
477 case MM_WAIT_FOR_RR_ACTIVE:
478 case MM_PLMN_SEARCH_NORMAL_SERVICE:
479 mm_write_entry (TIMEOUT, T3213, 0);
480 break;
481 */
482
483 case MM_IDLE_ATTEMPT_TO_UPDATE:
484 case MM_IDLE_NORMAL_SERVICE:
485 /*
486 * if something is received from RR or T3213 was already restarted 2 times --> delay of additional 8 seconds
487 * continue the LUP attempts
488 */
489 mm_data->t3213_restart++;
490 if (mm_data->t3213_restart > MAX_REST_T3213)
491 mm_continue_running_update ();
492 else
493 TIMERSTART (T3213, T_3213_VALUE);
494 break;
495
496 default: /* Ignore event */
497 break;
498 }
499 }
500
501 /*
502 +--------------------------------------------------------------------+
503 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
504 | STATE : code ROUTINE : tim_t3220 |
505 +--------------------------------------------------------------------+
506
507 PURPOSE : Timeout of timer T3220
508
509 */
510
511 GLOBAL void tim_t3220 (void)
512 {
513 GET_INSTANCE_DATA;
514 TRACE_FUNCTION ("tim_t3220()");
515
516 switch (GET_STATE (STATE_MM))
517 {
518 case MM_IMSI_DETACH_INIT:
519 case MM_WAIT_FOR_RR_CONN_DETACH:
520 /*
521 * The RR connection is aborted normally. RR guarantees that this will
522 * be answered by RR_RELEASE_IND. If MM receives the RR_RELEASE_IND,
523 * the IMSI DETACH procedure ends and appropriate actions are taken.
524 * This has the advange that GMM gets the MMGMM_NREG_CNF after the
525 * channel release of layer 2 if GPRS present without any disadvantage
526 * for a GSM only protocol stack. No state change here.
527 */
528 mm_abort_connection (ABCS_NORM);
529 break;
530
531 default: /* Ignore event */
532 break;
533 }
534 }
535
536 /*
537 +--------------------------------------------------------------------+
538 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
539 | STATE : code ROUTINE : tim_t3230 |
540 +--------------------------------------------------------------------+
541
542 PURPOSE : Timeout of timer T3230
543
544 */
545
546 GLOBAL void tim_t3230 (void)
547 {
548 GET_INSTANCE_DATA;
549 TRACE_FUNCTION ("tim_t3230()");
550
551 /*
552 * If T3230 expires (i.e. no response is given but a RR connection is
553 * available) the MM connection establishment is aborted and the requesting
554 * CM sublayer is informed. If no other MM connection exists then the mobile
555 * station shall proceed as described in section 4.5.3.1 for release of the
556 * RR connection. Otherwise the mobile station shall return to the MM
557 * sublayer state where the request of an MM connection was received,
558 * i.e. to MM sublayer state MM connection active. Other ongoing
559 * MM connections (if any) shall not be affected.
560 * [GSM 04.08 subclause 4.5.1.2 b)]
561 *
562 * If all MM connections are released by their CM entities, the
563 * mobile station shall set timer T3240 and enter the state
564 * WAIT FOR NETWORK COMMAND, expecting the release of the RR connection.
565 * [Excerpt from GSM 04.08 subclause 4.5.3.1]
566 */
567
568 switch (GET_STATE (STATE_MM))
569 {
570 case MM_WAIT_FOR_REESTABLISH:
571 case MM_WAIT_FOR_OUTG_MM_CONN:
572 mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_ACTIVE);
573 mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_PENDING);
574 mm_data->wait_for_accept = FALSE;
575 TIMERSTART (T3240, T_3240_VALUE);
576 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
577 break;
578
579 case MM_CONN_ACTIVE: /* wait_for_accept expected to be TRUE */
580 mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_PENDING);
581 mm_data->wait_for_accept = FALSE;
582 if ((mm_count_connections (CM_ACTIVE) EQ 0) AND
583 (mm_count_connections (CM_STORE) EQ 0))
584 {
585 TIMERSTART (T3240, T_3240_VALUE);
586 SET_STATE (STATE_MM, MM_WAIT_FOR_NW_CMD);
587 }
588 USE_STORED_ENTRIES();
589 break;
590
591 default: /* Ignore event */
592 break;
593 }
594 }
595
596 /*
597 +--------------------------------------------------------------------+
598 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
599 | STATE : code ROUTINE : tim_t3240 |
600 +--------------------------------------------------------------------+
601
602 PURPOSE : Timeout of timer T3240
603
604 */
605
606 GLOBAL void tim_t3240 (void)
607 {
608 GET_INSTANCE_DATA;
609 TRACE_FUNCTION ("tim_t3240()");
610
611 switch (GET_STATE (STATE_MM))
612 {
613 case MM_PROCESS_PROMPT:
614 case MM_WAIT_FOR_NW_CMD:
615 mm_abort_connection (ABCS_NORM);
616 mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_ACTIVE);
617 mm_mmxx_rel_ind (MMCS_TIMER_RECOVERY, CM_PENDING);
618
619 /*
620 * The RR connection is aborted normally. RR guarantees that this will
621 * be answered by RR_RELEASE_IND.
622 * This has the advange that GMM gets the MMGMM_CM_RELEASE_IND after the
623 * channel release of layer 2 if GPRS present without any disadvantage
624 * for a GSM only protocol stack. No state change here.
625 */
626 break;
627
628 case MM_LUP_REJECTED:
629 mm_abort_connection (ABCS_NORM);
630 /*
631 * The RR connection is aborted normally. RR guarantees that this will
632 * be answered by RR_RELEASE_IND.
633 * This has the advange that GMM gets the MMGMM_NREG_IND after the
634 * channel release of layer 2 if GPRS present without any disadvantage
635 * for a GSM only protocol stack. No state change here.
636 */
637 break;
638
639 default: /* Ignore event */
640 break;
641 }
642 }
643
644 #ifdef REL99
645 /*
646 +--------------------------------------------------------------------+
647 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
648 | STATE : code ROUTINE : tim_t3241 |
649 +--------------------------------------------------------------------+
650
651 PURPOSE : Timeout of timer T3241
652
653 */
654
655 GLOBAL void tim_t3241 (void)
656 {
657 GET_INSTANCE_DATA;
658 TRACE_FUNCTION ("tim_t3241()");
659
660 switch (GET_STATE (STATE_MM))
661 {
662 case MM_RR_CONN_RELEASE_NOT_ALLOWED:
663 mm_abort_connection (ABCS_NORM);
664 /*
665 * The RR connection is aborted normally. RR guarantees that this will
666 * be answered by RR_RELEASE_IND.
667 * This has the advange that GMM gets the MMGMM_CM_RELEASE_IND after the
668 * channel release of layer 2 if GPRS present without any disadvantage
669 * for a GSM only protocol stack. No state change here.
670 */
671 break;
672 default: /* Ignore event */
673 break;
674 }
675 }
676 #endif
677
678
679 /*
680 +----------------------------------------------------------------------------+
681 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
682 | STATE : code ROUTINE : tim_t_hplmn |
683 +----------------------------------------------------------------------------+
684
685 PURPOSE : Timeout of timer T_HPLMN.
686 This timer allows control of the PPLMN rescan and
687 national roaming procedure to recover the HPLMN.
688 */
689
690 GLOBAL void tim_t_hplmn (void)
691 {
692 GET_INSTANCE_DATA;
693 TRACE_FUNCTION ("tim_t_hplmn()");
694
695 /*
696 * Launch the scan procedure if it still makes sense to do it according to
697 * MM state.
698 */
699 if (mm_full_service_pplmn_scan())
700 {
701 mm_data->plmn_scan_mm = TRUE;
702 mm_data->first_attach_mem = FALSE;
703 mm_func_mmgmm_net_req();
704 }
705 }
706
707
708 /*
709 +--------------------------------------------------------------------+
710 | PROJECT : GSM-PS (6147) MODULE : MM_TIM |
711 | STATE : code ROUTINE : tim_t_reg |
712 +--------------------------------------------------------------------+
713
714 PURPOSE : Timeout of timer T_REG.
715 This timer is not foreseen by the recommendations.
716 It is MM's health monitor timer, checking
717 the conditions whether an update has been missed.
718
719 */
720
721 GLOBAL void tim_t_reg (void)
722 {
723 GET_INSTANCE_DATA;
724 TRACE_FUNCTION ("tim_t_reg()");
725
726 switch (GET_STATE (STATE_MM))
727 {
728 case MM_NULL:
729 break; /* No timer activity in this state */
730
731 case MM_IDLE_NORMAL_SERVICE: /* 19.1 */
732 /* Restart the registration timer */
733 TIMERSTART (T_REGISTRATION, T_REG_VALUE);
734
735 /*
736 * As it is not expected that the timer catches in state
737 * MM_IDLE_NORMAL_SERVICE in FTA, there is no test
738 * here for a test SIM. The goal is to have an MM
739 * where the timer never catches in MM_IDLE_NORMAL_SERVICE.
740 */
741
742 /* Check whether T3211, T3213 are running retriggering update anyway */
743 if ((TIMERACTIVE (T3211) OR TIMERACTIVE (T3213)) AND
744 (mm_data->loc_upd_type.lut NEQ NOT_RUNNING))
745 return;
746
747 /* Check whether MM is temporary barred and cannot update now */
748 if ((mm_data->idle_entry EQ RRCS_ACCESS_BARRED) OR
749 (mm_data->idle_entry EQ RRCS_RND_ACC_DELAY))
750 return;
751
752 /*
753 * Check whether we are in an ATTACH update procedure, but there is no
754 * T3211, T3213 timer running and MM is not temporary barred.
755 */
756 if (mm_attach_upd_needed() OR mm_normal_upd_needed())
757 {
758 TRACE_ERROR ("Recover ATTACH/NORMAL");
759
760 mm_mmgmm_lup_needed_ind (MMGMM_REG_TIMER);
761
762 if (mm_normal_upd_needed ())
763 {
764 mm_data->attempt_cnt = 0; /* New location area */
765 mm_normal_loc_upd ();
766 }
767 else
768 {
769 mm_attach_loc_upd ();
770 }
771 return;
772 }
773
774 /*
775 * Check whether T3212 should run, but is not running.
776 * If so, something irregular has happened and
777 * we have to start the update immediately.
778 */
779 if (mm_data->mm.mm_info.t3212 NEQ T3212_NO_PRD_UPDAT AND
780 (!TIMERACTIVE (T3212) OR mm_data->t3212_timeout))
781 {
782 /*
783 * The networks says we have periodic updating,
784 * but unexpectedly T3212 is not running or T3212 timed out.
785 */
786 TRACE_ERROR ("Recover PERIODIC");
787
788 if (mm_lup_allowed_by_gmm())
789 {
790 mm_periodic_loc_upd ();
791 }
792 else
793 {
794 // Don't add recovery code now for GPRS, maybe more has to be done.
795 // mm_mmgmm_lup_needed_ind (MMGMM_REG_TIMER);
796 }
797 return;
798 }
799 break;
800
801 case MM_IDLE_ATTEMPT_TO_UPDATE: /* 19.2 */
802 /* Restart the registration timer */
803 TIMERSTART (T_REGISTRATION, T_REG_VALUE);
804
805 /* Timer only handled in this state if a normal SIM is present */
806 if (mm_data->reg.op.sim_ins EQ SIM_NO_INSRT OR
807 mm_data->reg.op.ts EQ TS_AVAIL)
808 return;
809
810 /* Check whether T3211, T3213 are running retriggering update anyway */
811 if ((TIMERACTIVE (T3211) OR TIMERACTIVE (T3213)) AND
812 (mm_data->loc_upd_type.lut NEQ NOT_RUNNING))
813 return;
814
815 if (TIMERACTIVE (T3212))
816 return;
817
818
819 /* Check whether MM is temporary barred and cannot update now */
820 if ((mm_data->idle_entry EQ RRCS_ACCESS_BARRED) OR
821 (mm_data->idle_entry EQ RRCS_RND_ACC_DELAY))
822 return;
823
824 if (mm_gsm_alone ())
825 {
826 mm_normal_loc_upd ();
827 }
828 else
829 {
830 mm_mmgmm_lup_needed_ind (MMGMM_REG_TIMER);
831 /* No state change, remains in MM_IDLE_ATTEMPT_TO_UPDATE */
832 }
833 break;
834
835 default:
836 /* Restart the registration timer */
837 TIMERSTART (T_REGISTRATION, T_REG_VALUE);
838 break;
839 }
840 }
841
842 #endif