comparison gsm-fw/g23m-gsm/rr/rr_tim.c @ 673:2f7df7a314f8

gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Sun, 28 Sep 2014 23:20:04 +0000
parents
children 3385558575ea
comparison
equal deleted inserted replaced
672:0dc6f9e8e980 673:2f7df7a314f8
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
4 | Modul :
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 DL of the mobile station
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef RR_TIM_C
23 #define RR_TIM_C
24
25 #define ENTITY_RR
26
27 /*==== INCLUDES ===================================================*/
28
29 #include <string.h>
30 #include <stdlib.h>
31 #include <stddef.h> /* offsetof */
32 #include <stdio.h> /* sprintf */
33 #include "typedefs.h"
34 #include "pcm.h"
35 #include "pconst.cdg"
36 #include "mconst.cdg"
37 #include "message.h"
38 #include "ccdapi.h"
39 #include "vsi.h"
40 #include "custom.h"
41 #include "gsm.h"
42 #include "prim.h"
43 #include "cnf_rr.h"
44 #include "tok.h"
45 #include "rr.h"
46 #ifdef TI_PS_FF_AT_P_CMD_CTREG
47 #include "cl_shrd.h"
48 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
49
50 /*==== EXPORT =====================================================*/
51 /*==== PRIVAT =====================================================*/
52 #if !defined(ELEMENTS)
53 #define ELEMENTS(array) (sizeof(array)/sizeof(array[0]))
54 #endif /* !ELEMENTS */
55
56 /*==== VARIABLES ==================================================*/
57 EXTERN UBYTE test_house;
58 #ifdef TI_PS_FF_AT_P_CMD_CTREG
59 EXTERN T_TIME cast2T_Time(UBYTE tab_val);
60 #else
61 EXTERN T_TIME lim_service_mode_time[25];
62 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
63 /*
64 * In the old frame variant most of the timer handling is done
65 * in RR. RR has a timer pool and holds the dependency between
66 * logical timer and timer handle.
67 *
68 * With the new frame variant this is simplified. RR uses a constant
69 * for the timer and gets back the this constant after timeout.
70 *
71 * This is the reason why most of the functions are only needed for
72 * the old frame variant.
73 */
74
75 /*==== FUNCTIONS ==================================================*/
76
77 #if defined(TIMER_TRACE)
78 static void trace_timer (USHORT index, long value)
79 {
80 GET_INSTANCE_DATA;
81 /* Implements Measure#32: Row */
82 static T_S2I_STRING const tim_names[] =
83 {
84 S2I_STRING("T3110"),
85 S2I_STRING("T3122"),
86 S2I_STRING("T3126"),
87 S2I_STRING("T_RESELECT"),
88 S2I_STRING("TREG"),
89 S2I_STRING("TABORT"),
90 S2I_STRING("T_NO_RESELECT"),
91 S2I_STRING("TIM_EXT_MEAS"),
92 #if defined FF_EOTD
93 S2I_STRING("TAPDU"),
94 #endif /* FF_EOTD */
95 S2I_STRING("TNNN"),
96 S2I_STRING("TCSVALID"),
97 S2I_STRING("T_DEDICATED_MODE"),
98 S2I_STRING("T_PLMN_SEARCH"),
99 S2I_STRING("T_FAST_CS"),
100 S2I_STRING("T_NORMAL_CS")
101 };
102 switch(value)
103 {
104 /* Implements Measure#32: Row 431, 432, 433 and 435 */
105 default:/* >0: start */
106 TRACE_TIMER_P2 ("T-Start:%s=%lu", S2I_STRING(tim_names[index]), value);
107 break;
108 case 0:/* EQ 0: stop */
109 TRACE_TIMER_P1 ("T-Stop:%s", S2I_STRING(tim_names[index]));
110 break;
111 case -1:/* -1: expire */
112 TRACE_TIMER_P1 ("T-Expired:%s ", S2I_STRING(tim_names[index]));
113 break;
114 case -2:/* -2: check */
115 if(rr_data->t_running[index])
116 {
117 TRACE_TIMER_P1 ("T-Check:%s active", S2I_STRING(tim_names[index]));
118 }
119 else
120 {
121 TRACE_TIMER_P1 ("T-Check:%s inactive", S2I_STRING(tim_names[index]));
122 }
123 break;
124 }
125 }
126 #else
127 #define trace_timer(index,value)
128 #endif /* TIMER_TRACE */
129
130 /*
131 +--------------------------------------------------------------------+
132 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
133 | STATE : code ROUTINE : tim_t3110 |
134 +--------------------------------------------------------------------+
135
136 PURPOSE : Timeout of timer T3110. Timer is started after reception
137 of channel release message and controls layer 2 disconnection.
138 It starts the configuration of idle mode, if layer 2 has
139 not signalled in time the disconnection of the layer 2 link.
140
141 */
142
143 GLOBAL void tim_t3110 (void)
144 {
145 GET_INSTANCE_DATA;
146 TRACE_FUNCTION ("tim_t3110()");
147
148 if (GET_STATE (STATE_DAT) EQ DAT_CHAN_REL)
149 {
150 /*
151 * Send STOP_DEDICATED_REQUEST to L1 and wait for confirmation
152 */
153 att_stop_dedicated();
154 }
155
156 }
157
158 /*
159 +--------------------------------------------------------------------+
160 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
161 | STATE : code ROUTINE : tim_t3122 |
162 +--------------------------------------------------------------------+
163
164 PURPOSE : Timeout of timer T3122. Started after reception of an
165 immediate assignment reject message. MM does not start
166 any new establishment during the timer is running.
167 After timeout MM is informed. New attempts from MM can
168 be started.
169
170 */
171
172 GLOBAL void tim_t3122 (void)
173 {
174 GET_INSTANCE_DATA;
175 PALLOC (sync, RR_SYNC_IND);
176
177 TRACE_FUNCTION ("tim_t3122()");
178
179 switch (GET_STATE (STATE_DAT))
180 {
181 case DAT_NULL:
182 case DAT_CELL_RESELECT:
183 case DAT_IDLE:
184 case DAT_IMM_ASS:
185 case DAT_IMM_ASS_1:
186 /*
187 * send the indication to MM that T3122 has
188 * timed-out.
189 */
190 sync->ciph = NOT_PRESENT_8BIT;
191 sync->chm.ch_mode = NOT_PRESENT_8BIT;
192 sync->synccs = SYNCCS_T3122_TIM_OUT;
193 memset(&sync->mm_info, 0, sizeof(T_mm_info));
194 sync->mm_info.valid = FALSE;
195 memset(&sync->bcch_info, 0, sizeof(T_bcch_info));
196 sync->bcch_info.v_bcch = FALSE;
197
198 PSENDX (MM, sync);
199 srv_use_stored_prim ();
200 break;
201
202 default:
203 PFREE (sync);
204 break;
205 }
206 }
207
208 /*
209 +--------------------------------------------------------------------+
210 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
211 | STATE : code ROUTINE : tim_t3126 |
212 +--------------------------------------------------------------------+
213
214 PURPOSE : Timeout of timer T3126. This timer is used for two cases.
215 1. It controls that all random bursts are send during a
216 certain time. If (why ever) layer 1 does not confirm
217 all outgoing random bursts, this timer prevents RR
218 from stucking. This functionality is not described in
219 GSM and is introduced for security reasons.
220 2. It controls the reception of an immediate assignment
221 message. This is the normal GSM functionality.
222
223 */
224
225 GLOBAL void tim_t3126 (void)
226 {
227 GET_INSTANCE_DATA;
228 TRACE_FUNCTION ("tim_t3126()");
229
230 if (GET_STATE (STATE_DAT) EQ DAT_IMM_ASS)
231 {
232 if (rr_data->ms_data.all_conf_received)
233 {
234 /*
235 * Normal GSM functionality. Control of the
236 * reception of immediate assignment messages.
237 */
238 TRACE_EVENT ("Immediate Assignment failed");
239
240 dat_send_release_ind ( RRCS_RND_ACC_FAIL );
241
242 /*
243 * Check if we have to do a cell reselection
244 * or if we can return directly to idle mode in the current
245 * cell
246 */
247 TRACE_EVENT("check rej_rec");
248 if (rr_data->imm_ass_rej_rec NEQ TRUE)
249 {
250 /*
251 * search for idle mode cell
252 * (exclude current serving cell, because
253 * the random access was unsuccessfull)
254 */
255 #ifdef GPRS
256 if(att_gprs_cell_has_pbcch())
257 {
258 /*XY: inform GRR, and don't wait for CR_RSP we will get a CR_REQ in this case */
259 att_rrgrr_cr_ind(CR_REQ_CANDIDATE);
260 rr_data->gprs_data.start_proc = START_PROC_NOTHING;
261 }
262 else
263 {
264 #endif
265
266 TRACE_EVENT_P1("rr_data->c_ncell_bcch: %x",rr_data->c_ncell_bcch);
267
268 /*There are three scenarios to be considered */
269 /*
270 * i - The first MPH_MEASUREMENT_IND has not yet arrived
271 * ii - The first MPH_MEASUREMENT_IND has arrived but not all
272 * the SIs have been received
273 * (These are managed below)
274 *
275 * iii - The first MPH_MEASUREMENT_IND has arrived and all the
276 * SIs have been received AND a reselection is pending
277 * This is managed in 'att_bcch_status_to_decoded()'
278 */
279
280 if(((rr_data->first_meas_received EQ TRUE) AND (rr_data->c_ncell_bcch EQ 0)) OR
281 /* Implements RR Clone findings #8 */
282 att_cell_barred_status_cr_no_cr (SC_INDEX)
283 OR
284 (rr_data->nc_data[SC_INDEX].c1 <= 0))
285 {
286 /*XY:n inform GRR, and wait for CR_RSP */
287 #ifdef GPRS
288 att_start_cell_reselection_gprs (CELL_RESELECTION_RACH);
289 #else
290 att_start_cell_reselection (CELL_RESELECTION_RACH);
291 #endif
292 }
293 else
294 {
295 /*
296 * continue camping on current SC until indication of ncell BCCH info
297 * after first measurement indication
298 */
299 rr_data->resel_pending = TRUE;
300 att_return_to_idle();
301 }
302 #ifdef GPRS
303 }
304 #endif
305 }
306 else
307 {
308 /*
309 * we have received an IMMEDIATE ASSIGNMENT REJECT
310 * (the random access procedure was successfull, meaning
311 * that an answer was received from the network, even
312 * if the answer was negative)
313 * In this case we go directly back to the current
314 * serving cell
315 */
316 #ifdef GPRS
317 if(att_gprs_cell_has_pbcch())
318 {
319 /*XY: inform GRR, and don't wait for CR_RSP */
320 att_rrgrr_cr_ind(CR_SUSPENDED_IDLE);
321 rr_data->gprs_data.start_proc = START_PROC_NOTHING;
322 }
323 #endif
324 att_return_to_idle();
325 }
326 }
327 else
328 {
329 /*
330 * Layer 1 has not confirmed all outgoing random bursts
331 * in time. Simulate that all confirmations have received
332 * and start second part of connection establishment
333 * with waiting for the immediate assignment.
334 */
335 TRACE_TIMER ("missing random acc cnf");
336
337 TIMERSTART (T3126, T3126_VALUE);
338 rr_data->ms_data.all_conf_received = TRUE;
339 }
340 }
341 }
342
343 /*
344 +--------------------------------------------------------------------+
345 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
346 | STATE : code ROUTINE : tim_treselect |
347 +--------------------------------------------------------------------+
348
349 PURPOSE : Timeout of timer T_RESELECT. The timer controls reception
350 of the whole BCCH during cell selection and cell reselection.
351
352 */
353
354 GLOBAL void tim_treselect (void)
355 {
356 GET_INSTANCE_DATA;
357 TRACE_FUNCTION ("tim_treselect()");
358
359 switch (GET_STATE (STATE_ATT))
360 {
361 case ATT_CS2:
362 #ifdef GPRS
363 if((rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_SI13) AND test_house)
364 {
365 if(rr_data->ms_data.rr_service EQ LIMITED_SERVICE)
366 {
367 /*
368 * We have found a 'potential' cell for limited service
369 */
370 rr_data->nc_data[CR_INDEX].si13_loc_ind = SI13_NOT_PRESENT;
371 SET_STATE(STATE_GPRS, GPRS_ACTIVATED);
372 att_check_bcch_carrier ();
373 return;
374 }
375 else
376 {
377 /*
378 * There is a problem with some R&S tests where SI13 is indicated
379 * in SI3/4 but there is no SI13 transmitted by the tester. RR continues
380 * to wait to for SI13 having successfully received all other SI's from L1
381 *
382 * The timeout of T_RESELECT would cause this cell to be ignored and
383 * RR would have instructed L1 to check the next BSIC.
384 * Thus, it can happen that after a failed scan of all subsequent frequencies,
385 * MM is indicated with "no cell available" i.e. we lose a GSM-only healthy cell
386 *
387 * Mark the current arfcn as being eligible for LIM service, which RR can camp
388 * onto on the next pass when looking for emergency cells.
389 */
390 if(dat_forb_lai_check (CR_INDEX))
391 {
392 att_store_plmn_in_found_list (&rr_data->nc_data[CR_INDEX].lai);
393 }
394 else
395 {
396 TRACE_EVENT ("Do not store Forbidden LAI PLMN in the found PLMN list");
397 }
398 cs_set_attributes (EMERGENCY_CELL, rr_data->nc_data[CR_INDEX].arfcn);
399 TRACE_EVENT_P1("Setting %x as EMERG", rr_data->nc_data[CR_INDEX].arfcn);
400 }
401 }
402 #endif
403
404 /*
405 * Sometimes SI 2Ter is indicated, but it is never sent
406 * With this patch the inconsistent BCCH is taken.
407 * Fix for defect OMAPS00069058: SI13 is indicated on EBCCH, but never
408 * received. The fix avoids ignoring this cell on TRESELECT timeout.
409 */
410 if ( (rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_2TER)
411 #ifdef GPRS
412 OR
413 (rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_SI13)
414 #endif
415 )
416 {
417 /*
418 * if at least the rest is available, check the
419 * BCCH carrier to camp on a cell.
420 */
421 #ifdef GPRS
422 if ( (rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_SI13) AND
423 (GET_STATE (STATE_GPRS) EQ GPRS_PIM_BCCH )
424 )
425 {
426 rr_data->nc_data[CR_INDEX].si13_loc_ind = SI13_NOT_PRESENT;
427 SET_STATE(STATE_GPRS, GPRS_ACTIVATED);
428 }
429 #endif
430 att_check_bcch_carrier ();
431 }
432 else
433 {
434 /*
435 * initialise the internal data for the next candidate,
436 * because the BCCH is not completely available.
437 */
438 srv_clear_list (&rr_data->cr_data.cd.ncell_list);
439 if (cs_sync_next ())
440 {
441 /*
442 * start FB/SB reading for the next channel.
443 */
444 SET_STATE (STATE_ATT, ATT_CS1);
445 #ifdef GPRS
446 if (GET_STATE (STATE_GPRS) EQ GPRS_PIM_BCCH )
447 {
448 SET_STATE(STATE_GPRS, GPRS_ACTIVATED);
449 }
450 #endif
451 rr_data->old_serving_cell = NOT_PRESENT_8BIT;
452 }
453 }
454 break;
455
456 case ATT_CS3:
457
458 if (rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_2TER)
459 {
460 /*
461 * if all sys infos except SI 2Ter is available, check the
462 * BCCH carrier to camp on a cell.
463 * When GPRS is activate, ATT_STATE is changed from ATT_CS3 to
464 * ATT_IDLE following reception of rrgrr_cr_req from GRR. Hence
465 * it not approprite to check for ATT_STATE for cell reselection
466 * completion. A new flag has been introduced for this purpose.
467 * This is s temporary solution, untill CQ 24632 is submitted
468 * where the SI2TER functionality will be cleaned up.
469 */
470
471 rr_data->cr_treselect_exp = FALSE;
472
473 att_check_bcch_carrier ();
474
475 if(rr_data->cr_treselect_exp)
476 {
477 TRACE_EVENT("Cell Reselection Success");
478 /* cell reselection completed */
479 return;
480 }
481 }
482
483 TRACE_EVENT ("cell reselection failed");
484
485 /*
486 * reset the paging received flag.
487 */
488 rr_data->pag_rec = FALSE;
489 srv_clear_stored_prim (MPH_PAGING_IND);
490
491 /*
492 * Indicate failed reestablishment earlier
493 */
494 if (rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED_RLF)
495 dat_code_reestablishment_fail ();
496
497 /*
498 * start a cell selection after timeout.
499 */
500 rr_data->old_serving_cell = NOT_PRESENT_8BIT;
501
502 /*XY:n don't inform GRR , but call start_cs anyway */
503
504 /* Cell Selection Improvements-LLD section:4.1.3.9
505 * Cell reselection fails due to T_RESELECT timer expiry
506 * Start Fast search
507 */
508 #ifdef GPRS
509 att_start_cell_selection_gprs (RR_ORIGINATED,FAST_SEARCH_MODE);
510 #else
511 att_start_cell_selection (RR_ORIGINATED, CS_NOT_PARALLEL ,FAST_SEARCH_MODE);
512 #endif
513
514 break;
515
516 case ATT_IDLE:
517 case ATT_CON_EST:
518 /*
519 * Parallel scanning for a channel in idle mode has failed.
520 * Initialize the data for the next channel and start
521 * FB/SB reading for this channel.
522 */
523 #ifdef GPRS
524 if( rr_data->sc_data.selection_type EQ CELL_RESELECTION_ON_GPRS_ACT)
525 {
526 /* Cell Selection Improvements-LLD section:4.1.3.9
527 * GPRS activation on current cell fails due to T_RESELECT timer
528 * expiry
529 * Start Fast search
530 */
531 att_start_cell_selection_gprs(MM_ORIGINATED,FAST_SEARCH_MODE);
532 }
533 else
534 {
535 #endif
536 srv_clear_list (&rr_data->cr_data.cd.ncell_list);
537 cs_sync_next ();
538 #ifdef GPRS
539 }
540 #endif
541 break;
542 case ATT_CS_INIT:
543 /* Boot Time Performance Enhancement:
544 * RR has not received the normal RR_ACTIVATE_REQ yet
545 * Free the stored power_cnf and move back to ATT_NULL
546 */
547 if( srv_check_stored_prim(MPH_POWER_CNF))
548 {
549 srv_clear_stored_prim(MPH_POWER_CNF);
550 }
551 SET_STATE(STATE_CELL_SEL, CS_NULL);
552 SET_STATE(STATE_ATT, ATT_NULL);
553 break;
554 }
555 }
556
557 /*
558 +--------------------------------------------------------------------+
559 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
560 | STATE : code ROUTINE : tim_plmn_search_expiry |
561 +--------------------------------------------------------------------+
562
563 PURPOSE : This timer expires to signal end on Manual cell selection.
564
565 */
566 GLOBAL void tim_plmn_search_expiry (void)
567 {
568 GET_INSTANCE_DATA;
569 if(rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI)
570 {
571 /*
572 * Mark all ARFCN's as Checked !
573 * After the next MPH_BSIC_CNF & MPH_UNITDATA_IND,
574 * cs_sync_next_bsic() will return FALSE.
575 */
576 UBYTE i;
577 for ( i=0; i < rr_data->cs_data.max_arfcn; i++ )
578 {
579 rr_data->cs_data.attributes[i] |= CS_CHECK_FLAG;
580 }
581 }
582 }
583
584 /*
585 +--------------------------------------------------------------------+
586 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
587 | STATE : code ROUTINE : tim_tfast_cs |
588 +--------------------------------------------------------------------+
589
590 PURPOSE : This timer expires to signal end on Fast Search. Currently
591 this function just traces the Black Listed channels
592 CSI-LLD section:4.1.3.4.1.9
593 */
594
595 GLOBAL void tim_tfast_cs(void)
596 {
597 TRACE_FUNCTION("tim_tfast_cs()");
598
599 srv_trace_black_list();
600 srv_trace_white_list();
601 }
602
603 /*
604 +--------------------------------------------------------------------+
605 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
606 | STATE : code ROUTINE : tim_tnormal_cs |
607 +--------------------------------------------------------------------+
608
609 PURPOSE : This timer expires to signal end on Normal search.Currently
610 this function just traces the Black Listed channels
611 CSI-LLD section:4.1.3.4.1.10
612 */
613
614 GLOBAL void tim_tnormal_cs(void)
615 {
616 TRACE_FUNCTION("tim_tnormal_cs()");
617
618 srv_trace_black_list();
619 srv_trace_white_list();
620 }
621
622 /*
623 +--------------------------------------------------------------------+
624 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
625 | STATE : code ROUTINE : att_reset_registration_timer |
626 +--------------------------------------------------------------------+
627
628 PURPOSE : This function stops the registration timer early on
629 request of MMI / Keypad driver. This function can be called
630 to avoid too long periods between search attempts to come
631 back to coverage.
632
633 */
634
635 GLOBAL void tim_reset_registration_timer (void)
636 {
637 GET_INSTANCE_DATA;
638 T_TIME status = 0;
639
640 TRACE_FUNCTION ("tim_reset_registration_timer()");
641
642 /*
643 * depending on the current RR service
644 */
645 switch (rr_data->ms_data.rr_service)
646 {
647 case NO_SERVICE:
648 case LIMITED_SERVICE:
649 if (rr_data->ms_data.reg_counter >= 12)
650 {
651 /*
652 * Only if RR has searched already more then 12 times,
653 * that means there is a long period between search attempts
654 * from some minutes.
655 *
656 * Get the remaining time of the timer.
657 */
658 TIMER_STATUS (rr_handle, TREG, &status);
659 if (status)
660 {
661 /*
662 * if the timer is just running, stop the timer,
663 * reset the attempt counter and simulate timeout
664 * by starting the timer again for one second.
665 */
666 TIMERSTOP (TREG);
667 rr_data->ms_data.reg_counter = 0;
668 TIMERSTART (TREG, ONE_SEC);
669 }
670 }
671 break;
672 }
673 }
674
675 /*
676 +--------------------------------------------------------------------+
677 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
678 | STATE : code ROUTINE : tim_treg |
679 +--------------------------------------------------------------------+
680
681 PURPOSE : Timeout of timer TREG. Used by RR to recover from
682 No service to limited / full service or
683 limited service to full service or
684 full service (non-HPLMN) to full service (HPLMN)
685
686 */
687
688 GLOBAL void tim_treg (void)
689 {
690 GET_INSTANCE_DATA;
691 U8 search_mode = 0;
692 #ifdef GPRS
693 UBYTE state;
694 #endif /* GPRS */
695 #ifdef TI_PS_FF_AT_P_CMD_CTREG
696 BOOL ret;
697 UBYTE tab_val;
698 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
699 TRACE_FUNCTION ("tim_treg()");
700
701 /*
702 * clear old cell identification to
703 * signal with RR_ACTIVATE_IND to MM to force
704 * location updatings.
705 */
706 att_reset_old_lai_rac();
707
708 /*
709 * due to : "Network not recovered after a manual registration failure"
710 * do nothing if measurement is running (RR is already in state ATT_CS1)
711 */
712 switch (GET_STATE (STATE_ATT))
713 {
714 case ATT_CS1:
715 case ATT_CS2:
716 break;
717
718 case ATT_CS3:
719 case ATT_DEDICATED:
720 case ATT_CON_EST:
721 /*
722 * handle the expiry event later after state change (by an
723 * additional expiry of TREG)
724 */
725 rr_data->treg_pending = TRUE;
726 break;
727 case ATT_IDLE:
728 #ifdef GPRS
729 state = GET_STATE(STATE_GPRS);
730 switch(state)
731 {
732 case GPRS_PTM_BCCH:
733 case GPRS_PAM_BCCH:
734 case GPRS_PAM_PBCCH:
735 case GPRS_PTM_PBCCH:
736 rr_data->treg_pending = TRUE;
737 break;
738 default:
739 if(GET_STATE(STATE_CELL_SEL) EQ CS_CCO)
740 rr_data->treg_pending = TRUE;
741 break;
742 }
743 if(rr_data->treg_pending)
744 {
745 att_start_registration_timer();
746 break;
747 }
748 #endif
749 /*lint -fallthrough*/
750 default:
751
752 /* Obtain the new search mode
753 * CSI-LLD : 4.1.3.4.1.5
754 */
755 search_mode = cs_get_new_search_mode();
756
757 switch (rr_data->ms_data.rr_service)
758 {
759 case NO_SERVICE:
760 /*
761 * actual there is no service. Depending on the
762 * last request from MM a limited service search
763 * or full service search is started.
764 */
765 /* XY:n inform GRR, and wait for CR_RSP */
766 #ifdef GPRS
767 att_start_cell_selection_gprs(RR_ORIGINATED,search_mode);
768 #else
769 att_start_cell_selection(RR_ORIGINATED, CS_NOT_PARALLEL,search_mode);
770 #endif
771 break;
772
773 case LIMITED_SERVICE:
774 /*
775 * actual there is limited service. Depending on the
776 * frequency area a limited service search or full service
777 * search is started.
778 */
779
780 /* Both American and European carriers are detected in
781 * this area. Perform Non-Parallel search only when the
782 * time gap between search attempts exceeds 2min
783 * CSI-LLD 4.3
784 */
785 if(rr_data->ms_data.reg_counter)
786 {
787 #ifdef TI_PS_FF_AT_P_CMD_CTREG
788 ret = cl_shrd_get_treg(RR_MOD_LIMSERVICE_TIME,
789 (UBYTE)(rr_data->ms_data.reg_counter - 1),
790 &tab_val);
791 if (!ret)
792 {
793 /* Use default on failure */
794 tab_val = lim_service_mode_time [rr_data->ms_data.reg_counter-1];
795 }
796 rr_data->ms_data.reg_time_gap += cast2T_Time(tab_val);
797 #else
798 /* Add the time gap between search attempts */
799 rr_data->ms_data.reg_time_gap +=
800 lim_service_mode_time[rr_data->ms_data.reg_counter-1];
801 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
802 TRACE_EVENT_P2("[%d]reg_counter, [%d]reg_time_gap",
803 rr_data->ms_data.reg_counter,
804 rr_data->ms_data.reg_time_gap);
805 }
806
807 if((rr_data->ms_data.reg_counter < 20) AND
808 (rr_data->ms_data.reg_time_gap < rr_data->dyn_config.lim_ser_nps_delay))
809 {
810 /* Perform parallel search if delay >= 2min. This is to allow time
811 * for emergency calls
812 */
813 att_start_cell_selection(RR_ORIGINATED, CS_PARALLEL,search_mode);
814 }
815 else
816 {
817
818 rr_data->ms_data.reg_time_gap = 0;
819
820 /* Perform Non-Parallel search every >= 2min */
821 #ifdef GPRS
822 att_start_cell_selection_gprs(RR_ORIGINATED,search_mode);
823 #else
824 att_start_cell_selection(RR_ORIGINATED, CS_NOT_PARALLEL,search_mode);
825 #endif
826 }
827 break;
828
829 case FULL_SERVICE:
830 /*
831 * actual there is full service. Nothing to do here.
832 */
833 break;
834 }
835 break;
836 }
837 }
838
839 /*
840 +--------------------------------------------------------------------+
841 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
842 | STATE : code ROUTINE : tim_tnnn |
843 +--------------------------------------------------------------------+
844
845 PURPOSE : Timeout of timer TNNN
846
847 */
848 GLOBAL void tim_tnnn (void)
849 {
850 GET_INSTANCE_DATA;
851 int index;
852 BOOL tnnn_active = FALSE;
853
854 for (index = 0; index < (int)ELEMENTS(rr_data->nc_data); index++)
855 {
856 if (rr_data->nc_data[index].tnnn)
857 {
858 rr_data->nc_data[index].tnnn--; /* decrement all active timer counts */
859 if (rr_data->nc_data[index].tnnn)
860 tnnn_active = TRUE; /* at least one timer count active */
861 else
862 {
863 /* Implements Measure#32: Row 442 */
864 switch(index)
865 {
866 case CR_INDEX:
867 TRACE_TIMER_P1 ("T-Expiry:TNNN[CR%d]", rr_data->nc_data[index].arfcn);
868 break;
869 case SC_INDEX:
870 TRACE_TIMER_P1 ("T-Expiry:TNNN[SC%d]", rr_data->nc_data[index].arfcn);
871 break;
872 default:
873 TRACE_TIMER_P1 ("T-Expiry:TNNN[%d]", rr_data->nc_data[index].arfcn);
874 break;
875 }
876 }
877 }
878 }
879
880 if (!tnnn_active)
881 TIMERSTOP (TNNN); /* no timer count active -> stop physical timer */
882 }
883 /*
884 +--------------------------------------------------------------------+
885 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
886 | STATE : code ROUTINE : tim_tabort |
887 +--------------------------------------------------------------------+
888
889 PURPOSE : Timeout of timer TABORT
890
891 */
892 GLOBAL void tim_tabort (void)
893 {
894 GET_INSTANCE_DATA;
895 TRACE_EVENT("tim_tabort TIMEOUT");
896
897 /* Sometimes SI 2Ter is indicated but it is never sent.
898 * Wait till expiry of T_RESELECT Timer, to give more time to read SI 2Ter.
899 * Do not send RR_ABORT_IND in this special case,
900 * as this will cause MMI to show "No Network"
901 */
902 if( (rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_2TER) AND
903 ((GET_STATE(STATE_ATT) EQ ATT_CS2) OR (GET_STATE(STATE_ATT) EQ ATT_CS3)) )
904 {
905 TRACE_EVENT("SI2 Ter missing - wait for T_RESELECT expiry");
906 TIMERSTART (TABORT, TABORT_VALUE);
907 return;
908 }
909
910 /*If the MS is carrying out a search for a list of PLMNs, this may take */
911 /*longer than 10s and the MMI is not displaying the PLMN name */
912 /*Boot Time:If MM has initiated a power scan for quick registration
913 *do not send RR_ABORT_IND here.
914 */
915 if((rr_data->ms_data.req_mm_service NEQ FUNC_NET_SRCH_BY_MMI) AND
916 (rr_data->ms_data.req_mm_service NEQ FUNC_ST_PWR_SCAN))
917 {
918 att_code_net_lost();
919 #ifdef FF_PS_RSSI
920 RX_SetValue ( 0, RX_QUAL_UNAVAILABLE, RX_ACCE_UNAVAILABLE);
921 #else
922 RX_SetValue (0);
923 #endif
924 }
925 }
926
927 /*
928 +--------------------------------------------------------------------+
929 | PROJECT : GSM-PS MODULE : RR_TIM |
930 | STATE : code ROUTINE : check_tnnn |
931 +--------------------------------------------------------------------+
932
933 PURPOSE : Starts timer TABORT
934
935 */
936 void tstart_tabort( USHORT val )
937 {
938 GET_INSTANCE_DATA;
939 if( rr_data->net_lost )
940 {
941 if(!IS_TIMER_ACTIVE(TABORT))
942 {
943 TIMERSTART (TABORT, val);
944 }
945 }
946 }
947
948 /*
949 +--------------------------------------------------------------------+
950 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
951 | STATE : code ROUTINE : check_tnnn |
952 +--------------------------------------------------------------------+
953
954 PURPOSE : Checks to see if timer TNNN is running or not
955
956 */
957 static int check_tnnn (void)
958 {
959 GET_INSTANCE_DATA;
960 int nc;
961 int tnnn_active = FALSE;
962
963 /* check all timer counter for active state */
964 for (nc = 0; nc < (int)ELEMENTS(rr_data->nc_data); nc++)
965 {
966 if (rr_data->nc_data[nc].tnnn)
967 {
968 tnnn_active = TRUE;
969 break;
970 }
971 }
972 return tnnn_active;
973 }
974
975 /*
976 +--------------------------------------------------------------------+
977 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
978 | STATE : code ROUTINE : set_tnnn |
979 +--------------------------------------------------------------------+
980
981 PURPOSE : Sets timer TNNN
982
983 */
984 GLOBAL void set_tnnn (int index, USHORT value)
985 {
986 GET_INSTANCE_DATA;
987 /* Implements Measure#32: Row 443 */
988 switch (index)
989 {
990 case CR_INDEX:
991 TRACE_TIMER_P2 ("T-Start:TNNN[CR%d]=%d", rr_data->nc_data[index].arfcn, value);
992 break;
993 case SC_INDEX:
994 TRACE_TIMER_P2 ("T-Start:TNNN[SC%d]=%d", rr_data->nc_data[index].arfcn, value);
995 break;
996 default:
997 TRACE_TIMER_P2 ("T-Start:TNNN[%d]=%d", rr_data->nc_data[index].arfcn, value);
998 break;
999 }
1000
1001 if (!check_tnnn ())
1002 {/* up to now there are no timer counter active -> start physical timer */
1003 trace_timer (TNNN, value);
1004 rr_data->t_running[TNNN] = 1;
1005
1006 /*
1007 * start physical periodically timer.
1008 */
1009 TIMER_PSTART (rr_handle, TNNN, ONE_SEC, ONE_SEC);
1010 }
1011
1012 /* set the new timer counter */
1013 rr_data->nc_data[index].tnnn = value / ONE_SEC;
1014 }
1015
1016 /*
1017 +--------------------------------------------------------------------+
1018 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1019 | STATE : code ROUTINE : reset_tnnn |
1020 +--------------------------------------------------------------------+
1021
1022 PURPOSE : Resets timer TNNN
1023
1024 */
1025 GLOBAL void reset_tnnn (int index)
1026 {
1027 GET_INSTANCE_DATA;
1028 if (rr_data->nc_data[index].tnnn)
1029 {
1030 /* Implements Measure#32: Row 444 */
1031 switch (index)
1032 {
1033 case CR_INDEX:
1034 TRACE_TIMER_P1 ("T-Stop:TNNN[CR%d]", rr_data->nc_data[index].arfcn);
1035 break;
1036 case SC_INDEX:
1037 TRACE_TIMER_P1 ("T-Stop:TNNN[SC%d]", rr_data->nc_data[index].arfcn);
1038 break;
1039 default:
1040 TRACE_TIMER_P1 ("T-Stop:TNNN[%d]", rr_data->nc_data[index].arfcn);
1041 break;
1042 }
1043
1044 /* reset the timer counter */
1045 rr_data->nc_data[index].tnnn = 0;
1046
1047 if (IS_TIMER_ACTIVE(TNNN) AND !check_tnnn ())
1048 TIMERSTOP (TNNN);
1049 }
1050 }
1051
1052 /*
1053 +--------------------------------------------------------------------+
1054 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1055 | STATE : code ROUTINE : is_tnnn |
1056 +--------------------------------------------------------------------+
1057
1058 PURPOSE : Returns value of timer TNNN
1059
1060 */
1061 GLOBAL int is_tnnn (int index)
1062 {
1063 GET_INSTANCE_DATA;
1064 if (rr_data->nc_data[index].tnnn)
1065 {
1066 /* Implements Measure#32: Row 446 */
1067 switch (index)
1068 {
1069 case CR_INDEX:
1070 TRACE_TIMER_P2 ("T-Check:TNNN[CR%d]=%d", rr_data->nc_data[index].arfcn,
1071 rr_data->nc_data[index].tnnn*ONE_SEC);
1072 break;
1073 case SC_INDEX:
1074 TRACE_TIMER_P2 ("T-Check:TNNN[SC%d]=%d", rr_data->nc_data[index].arfcn,
1075 rr_data->nc_data[index].tnnn*ONE_SEC);
1076 break;
1077 default:
1078 TRACE_TIMER_P2 ("T-Check:TNNN[%d]=%d", rr_data->nc_data[index].arfcn,
1079 rr_data->nc_data[index].tnnn*ONE_SEC);
1080 break;
1081 }
1082 }
1083 else
1084 {
1085 /* Implements Measure#32: Row 445 */
1086 switch (index)
1087 {
1088 case CR_INDEX:
1089 TRACE_TIMER_P1 ("T-Check:TNNN[CR%d] inactive", rr_data->nc_data[index].arfcn);
1090 break;
1091 case SC_INDEX:
1092 TRACE_TIMER_P1 ("T-Check:TNNN[SC%d] inactive", rr_data->nc_data[index].arfcn);
1093 break;
1094 default:
1095 TRACE_TIMER_P1 ("T-Check:TNNN[%d] inactive", rr_data->nc_data[index].arfcn);
1096 break;
1097 }
1098 }
1099
1100 return rr_data->nc_data[index].tnnn;
1101 }
1102
1103
1104 /*
1105 +--------------------------------------------------------------------+
1106 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1107 | STATE : code ROUTINE : tim_ext_meas |
1108 +--------------------------------------------------------------------+
1109
1110 PURPOSE : Timeout of timer TIM_EXT_MEAS.
1111
1112 */
1113
1114 GLOBAL void tim_ext_meas (void)
1115 {
1116 TRACE_FUNCTION ("tim_ext_meas ()");
1117 dat_emo_stop ( TRUE );
1118 }
1119
1120 #if defined FF_EOTD
1121 /*
1122 +--------------------------------------------------------------------+
1123 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1124 | STATE : code ROUTINE : tim_apdu |
1125 +--------------------------------------------------------------------+
1126
1127 PURPOSE : Timeout of timer TAPDU.
1128
1129 */
1130
1131 GLOBAL void tim_apdu (void)
1132 {
1133 GET_INSTANCE_DATA;
1134 TRACE_FUNCTION ("tim_apdu ()");
1135 rr_applic_rx_init ( &rr_data->applic_rx );
1136 }
1137 #endif /* FF_EOTD */
1138
1139 /*
1140 +--------------------------------------------------------------------+
1141 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1142 | STATE : code ROUTINE : tim_exec_timeout |
1143 +--------------------------------------------------------------------+
1144
1145 PURPOSE : execute timeout for the new frame variant.
1146
1147 */
1148
1149 GLOBAL void tim_exec_timeout (USHORT index)
1150 {
1151 GET_INSTANCE_DATA;
1152 TRACE_FUNCTION ("tim_exec_timeout()");
1153
1154 if (index >= NUM_OF_RR_TIMERS)
1155 {
1156 #if defined(TIMER_TRACE)
1157 SYST_TRACE_P ((SYST, "tim_exec_timeout(%u)", index));
1158 #endif
1159 }
1160 else
1161 {
1162 if (index NEQ TNNN) /* TNNN timer has its own trace */
1163 {
1164 trace_timer (index, -1);
1165 rr_data->t_running[index] = 0;
1166 }
1167
1168 if (rr_data->t_expire[index])
1169 rr_data->t_expire[index] ();
1170 }
1171 }
1172
1173 /*
1174 +--------------------------------------------------------------------+
1175 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1176 | STATE : code ROUTINE : tim_stop_timer |
1177 +--------------------------------------------------------------------+
1178
1179 PURPOSE : stop timer in the new frame variant.
1180
1181 */
1182
1183 GLOBAL void tim_stop_timer (USHORT index)
1184 {
1185 GET_INSTANCE_DATA;
1186 TRACE_FUNCTION ("tim_stop_timer()");
1187
1188 if (index >= NUM_OF_RR_TIMERS)
1189 {
1190 #if defined(TIMER_TRACE)
1191 SYST_TRACE_P ((SYST, "tim_stop_timer(%u)", index));
1192 #endif
1193 }
1194 else
1195 {
1196 trace_timer (index, 0);
1197 rr_data->t_running[index] = 0;
1198 TIMER_STOP (rr_handle, index);
1199 }
1200 }
1201
1202 /*
1203 +--------------------------------------------------------------------+
1204 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1205 | STATE : code ROUTINE : tim_start_timer |
1206 +--------------------------------------------------------------------+
1207
1208 PURPOSE : start timer in the new frame variant.
1209
1210 */
1211
1212 GLOBAL void tim_start_timer (USHORT index, T_TIME value)
1213 {
1214 GET_INSTANCE_DATA;
1215 TRACE_FUNCTION ("tim_start_timer()");
1216
1217 if (index >= NUM_OF_RR_TIMERS)
1218 {
1219 #if defined(TIMER_TRACE)
1220 SYST_TRACE_P ((SYST, "tim_start_timer(%u)", index));
1221 #endif
1222 }
1223 else
1224 {
1225 trace_timer (index, value);
1226 rr_data->t_running[index] = 1;
1227 TIMER_START (rr_handle, index, value);
1228
1229 }
1230 }
1231
1232 /*
1233 +--------------------------------------------------------------------+
1234 | PROJECT : GSM-PS (6147) MODULE : RR_TIM |
1235 | STATE : code ROUTINE : tim_check_timer |
1236 +--------------------------------------------------------------------+
1237
1238 PURPOSE : Checks if a specified timer is running
1239
1240 */
1241 #if defined(TIMER_TRACE)
1242 GLOBAL BOOL tim_check_timer(USHORT index)
1243 {
1244 GET_INSTANCE_DATA;
1245 TRACE_FUNCTION ("tim_check_timer()");
1246
1247 if (index >= NUM_OF_RR_TIMERS)
1248 {
1249 SYST_TRACE_P ((SYST, "tim_check_timer(%u)", index));
1250 return FALSE;
1251 }
1252 else
1253 {
1254 trace_timer (index, -2);
1255 return (rr_data->t_running[index]);
1256 }
1257 }
1258 #endif /* TIMER_TRACE */
1259 #endif /* RR_TIM_C */