comparison src/g23m-gsm/rr/rr_attf.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000 (2018-07-15)
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
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 module defines the functions for the attachment
18 | capability of the module Radio Resource.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef RR_ATTF_C
23 #define RR_ATTF_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 "typedefs.h"
33 #include "pcm.h"
34 #include "pconst.cdg"
35 #include "mconst.cdg"
36 #include "message.h"
37 #include "ccdapi.h"
38 #include "vsi.h"
39 #include "custom.h"
40 #include "gsm.h"
41 #include "prim.h"
42 #include "cnf_rr.h"
43 #include "tok.h"
44 #include "rr.h"
45 #include "rr_em.h"
46 #include "cl_shrd.h"
47
48 #if defined (_SIMULATION_)
49 #include <stdio.h>
50 #endif
51
52
53 /*==== EXPORT =====================================================*/
54
55 /*==== PRIVATE =====================================================*/
56 LOCAL void rr_unpack_plmn (T_plmn *plmn, const UBYTE *packed, USHORT index);
57 /* OMAPS00085607 - N950 Memory Optimization */
58 LOCAL void start_treg_timer(void);
59 #define TWO 2
60
61
62 static void att_build_back_from_dedicated (void);
63 static void att_calculate_c2 (UBYTE index);
64 static SHORT att_calculate_c2_diff (UBYTE index);
65 static UBYTE att_calculate_digits (UBYTE *digits);
66
67
68 static BOOL att_cell_in_data_structures (T_MPH_MEASUREMENT_IND *report,
69 UBYTE index);
70 static UBYTE att_cell_in_measure_report (T_MPH_MEASUREMENT_IND *report,
71 UBYTE index);
72 static void att_check_2ter_read (UBYTE index);
73 static BOOL att_check_cell (void);
74 LOCAL UBYTE att_get_txpwr_max_cch (UBYTE index);
75 static void att_clear_forb_list (int list_type);
76 static void att_clear_parallel_search (void);
77 static void att_code_prr_mm_info (T_mm_info *mm_info);
78 static void att_copy_c2_parameter (T_C2_PARAMETER *c2_par,
79 T_si3_rest_oct *rest_oct );
80 static void att_copy_c2_parameter_si3 (UBYTE index,
81 T_si3_rest_oct *rest_oct);
82 static void att_copy_found_plmn (T_FOUND_LIST * list,
83 USHORT n_in_source_85_dBm,
84 USHORT i_in_copy);
85 static void att_copy_rach_parameter (UBYTE index,
86 T_rach_ctrl *rach,
87 UBYTE indicate_changes);
88 static UBYTE att_get_highest_c2_index (void);
89 static UBYTE att_get_next_highest_c2_idx(UBYTE old_index);
90 static UBYTE att_get_next_highest_c2_val(void);
91 static UBYTE att_get_func (void);
92 static UBYTE att_get_next_highest_rx (void);
93 static void att_insert_cell_in_data (T_MPH_MEASUREMENT_IND *report,
94 UBYTE index);
95 static void att_order_plmns (void);
96 static USHORT att_number_of_plmns_greater_85_dBm (void);
97 static void att_copy_plmns_lower_or_equal_85_dBm (T_FOUND_LIST * list, USHORT i_in_copy);
98 static BOOL att_priority_check (void);
99 static void att_reorder_mph_ncell_req (T_MPH_NEIGHBOURCELL_REQ*
100 mph_ncell_req);
101 static void att_search_cell (void);
102 static void att_select_cell_dedicated (void);
103 static void att_try_old_cell (void);
104 static void att_print_selection_type (UBYTE selection_type);
105 /* Implements Measure#32: Row 36, 39 and 40 */
106 static void att_print_op (T_op *op,
107 T_S2I_STRING titel);
108 static void att_begin_cs (UBYTE req_mm_service);
109
110 #if defined (REL99) && defined (TI_PS_FF_EMR)
111 static void att_check_for_si5ter_and_enhpara (UBYTE old_index);
112 #endif
113
114
115
116
117 LOCAL void att_copy_sys_info_2bis_2ter_par(UBYTE index, T_SI_TYPE si_type,
118 T_LIST *new_2_bis_ter_list,
119 BUF_neigh_cell_desc *neigh_cell_desc,
120 UBYTE indicate_changes);
121
122 /*==== VARIABLES ==================================================*/
123 GLOBAL UBYTE test_house = FALSE;
124
125 /*==== MACROS =====================================================*/
126
127 #if !defined (NTRACE)
128
129 #define TRACE_C1(index)\
130 TRACE_EVENT_P4 ("[%u]i%u C1=%-2d rxlev=%u",\
131 rr_data->nc_data[index].arfcn,index,\
132 rr_data->nc_data[index].c1,\
133 rr_data->nc_data[index].rxlev)
134
135 #define TRACE_C2(index)\
136 TRACE_EVENT_P3 ("[%u]i%u C2=%-2d AT=%d",\
137 rr_data->nc_data[index].arfcn,index,\
138 rr_data->nc_data[index].c2,\
139 rr_data->nc_data[index].avail_time)
140
141 #define TRACE_C1_C2(index)\
142 TRACE_EVENT_P6 ("[%u]i%u C1=%-2d C2=%-2d rxlev=%-2u AT=%d",\
143 rr_data->nc_data[index].arfcn,index,\
144 rr_data->nc_data[index].c1,\
145 rr_data->nc_data[index].c2,\
146 rr_data->nc_data[index].rxlev,\
147 rr_data->nc_data[index].avail_time)
148
149 #define TRACE_SELECTION_TYPE(type) att_print_selection_type(type)
150
151 /* Implements Measure#32: Row 36, 39 and 40 */
152 #define TRACE_OP_TYPE(op,titel) att_print_op (op, S2I_STRING(titel))
153
154 #else /* !NTRACE */
155
156 #define TRACE_C1(i)
157 #define TRACE_C2(i)
158 #define TRACE_C1_C2(i)
159 #define TRACE_SELECTION_TYPE(type)
160 #define TRACE_OP_TYPE(op,titel)
161
162 #endif /* !NTRACE */
163
164 /*==== FUNCTIONS ==================================================*/
165
166 /*
167 * -------------------------------------------------------------------
168 * Procedures
169 * -------------------------------------------------------------------
170 */
171 /* Implements Measure#32: Row 60 */
172 /*
173 +--------------------------------------------------------------------+
174 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
175 | STATE : code ROUTINE : att_print_forb_list
176 +--------------------------------------------------------------------+
177
178 PURPOSE : After a successful location updating request MM informs
179 RR about this. If the location area information is stored
180 inside of one of the forbidden location area lists this
181 information must be updated. In this function, the entry
182 is deleted from the given forbidden list.
183
184 */
185
186 LOCAL void att_print_forb_list ( int list_type,
187 const T_plmn * plmn,
188 USHORT lac,
189 unsigned int index,
190 BOOL to_delete)
191 {
192 if(list_type EQ FORBIDDEN_LIST_NORMAL)
193 {
194 if(to_delete EQ FALSE)
195 {
196 TRACE_EVENT_P1 ( "ADD FORB LIST %u:", index);
197 }
198 else
199 {
200 TRACE_EVENT_P1 ( "DEL FORB LIST %u:", index);
201 }
202 }
203 else
204 {
205 if(to_delete EQ FALSE)
206 {
207 TRACE_EVENT_P1 ( "ADD FORB LIST %u:", index);
208 }
209 else
210 {
211 TRACE_EVENT_P1 ( "DEL ROAM FORB LIST %u:", index);
212 }
213 }
214 TRACE_EVENT_P7 ( " MCC/MNC=%x%x%x/%x%x%x LAC=%x",
215 plmn->mcc[0],
216 plmn->mcc[1],
217 plmn->mcc[2],
218 plmn->mnc[0],
219 plmn->mnc[1],
220 plmn->mnc[2],
221 lac);
222 }
223 /*
224 +--------------------------------------------------------------------+
225 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
226 | STATE : code ROUTINE : att_add_to_forb_list |
227 +--------------------------------------------------------------------+
228
229 PURPOSE : RR stores a list of forbidden location area codes. After
230 a specific location updating reject cause this information
231 will be given by MM with a RR_SYNC_REQ. The check against
232 forbidden location areas is part of the cell selection and
233 cell reselection process.
234
235 */
236
237 GLOBAL void att_add_to_forb_list (int list_type,
238 const T_plmn *plmn,
239 USHORT lac)
240 {
241 GET_INSTANCE_DATA;
242 int i;
243 T_loc_area_ident *forb_list;
244
245 if (list_type EQ FORBIDDEN_LIST_NORMAL)
246 forb_list = &rr_data->ms_data.forb_lac_list[0];
247 else
248 forb_list = &rr_data->ms_data.roam_forb_lac_list[0];
249
250 TRACE_FUNCTION ("att_add_to_forb_list()");
251
252 for (i = 0; i < MAX_LAI; i++)
253 {
254 /*
255 * Check whether the location area code is already stored. In
256 * this case it is not necessary to store it again
257 */
258 if ((lac EQ forb_list[i].lac) AND
259 dat_plmn_equal_req (plmn->mcc, plmn->mnc,
260 forb_list[i].mcc, forb_list[i].mnc))
261 break;
262 }
263
264 if (i EQ MAX_LAI)
265 {
266 /*
267 * Location Area Code is not stored yet. Look for a free entry
268 * and store the location area code.
269 */
270 for (i = 0; i < MAX_LAI; i++)
271 {
272 if (forb_list[i].lac EQ NOT_PRESENT_16BIT)
273 {
274 memcpy (forb_list[i].mcc, plmn->mcc, SIZE_MCC);
275 memcpy (forb_list[i].mnc, plmn->mnc, SIZE_MNC);
276 forb_list[i].lac = lac;
277 break;
278 }
279 }
280
281 if (i EQ MAX_LAI)
282 {
283 /*
284 * all entries are used. Then delete the first (and oldest) one,
285 * move each entry and store the new one in the last position.
286 */
287 memmove (&forb_list[0], &forb_list[1],
288 sizeof (T_loc_area_ident) * (MAX_LAI-1));
289 memcpy (forb_list[MAX_LAI-1].mcc, plmn->mcc, SIZE_MCC);
290 memcpy (forb_list[MAX_LAI-1].mnc, plmn->mnc, SIZE_MNC);
291 forb_list[MAX_LAI-1].lac = lac;
292 i--;
293 }
294 }
295
296 /* Implements Measure#32: Row 4 */
297 att_print_forb_list ( list_type, plmn, lac, i, FALSE);
298 }
299
300
301 /*
302 +--------------------------------------------------------------------+
303 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
304 | STATE : code ROUTINE : att_analyze_measure_report |
305 +--------------------------------------------------------------------+
306
307 PURPOSE : After reception of a MPH_MEASUREMENT_IND from layer 1 the
308 channels are analyzed for a cell reselection decision.
309
310 */
311
312 GLOBAL void att_analyze_measure_report (T_MPH_MEASUREMENT_IND *report)
313 {
314 GET_INSTANCE_DATA;
315 UBYTE i = 0;
316
317 TRACE_FUNCTION ("att_analyze_measure_report()");
318
319 /*
320 * The variable no_reselect controls the condition not to perform a
321 * new cell reselection due to C2(NC) > C2(SC) after a cell reselection
322 * for 15 seconds
323 */
324
325 /*
326 * The fieldtest has shown, that sometimes the serving cell was also reported
327 * as a neighbourcell. This function removes double entries
328 */
329 att_remove_multiple_channels ();
330
331 /*
332 * All possible neighbourcells plus the serving cell are checked.
333 */
334 for (i = 0; i < 6; i++)
335 {
336 /*
337 * The tnnn variable controls the condition that a cell is barred for five seconds
338 * for cell reselection purposes after a random access failure.
339 */
340 /*
341 * check the status of a cell using the data stored in RR for neighbour- and serving
342 * cell.
343 */
344 switch (rr_data->nc_data[i].bcch_status)
345 {
346 case EMPTY:
347 /*
348 * RR has nothing stored in this area. So there is nothing to do.
349 */
350 break;
351
352 case DECODED:
353 /*
354 * In this area RR has stored Data for a neighbourcell. The status is decoded,
355 * that means RR has received a system information 3,4,7 or 8 to calculate
356 * the cell reselection criterion C2.
357 *
358 * Now it is checked against the incoming measurement report.
359 */
360 switch (att_cell_in_measure_report (report, i))
361 {
362 case CELL_IS_INSERTED:
363 /*
364 * The cell is still included in the measurement report, that means
365 * it is one of the six strongest carrier and layer 1 is synchronized
366 * to the cell.
367 *
368 * The time how long the cell is already synchronized is stored up to
369 * a period of 700 seconds. This informatin is used for the calculation
370 * of the cell reselection criterion C2 which may has a time dependent
371 * factor. In fact the frames of layer 1 are counted.
372 */
373 if (rr_data->nc_data[i].avail_time < PERIOD_700_SEC)
374 rr_data->nc_data[i].avail_time += rr_data->ms_data.fn_offset;
375 break;
376
377 case BSIC_HAS_CHANGED:
378 /*
379 * The cell is still included in the measurement report, but layer1
380 * has detected a change of the BSIC during re-synchronisation on the
381 * SB channel. So the stored information for calculation of C2 is useless
382 * and the status and the avail time is cleared.
383 */
384
385 rr_data->nc_data[i].bcch_status = NON_DECODED;
386 rr_data->nc_data[i].avail_time = 0;
387 break;
388
389 case CELL_IS_NOT_INSERTED:
390 /*
391 * The cell is not longer included. The area in RR is released.
392 */
393 rr_data->nc_data[i].bcch_status = EMPTY;
394 break;
395 }
396 break;
397
398 case NON_DECODED:
399 /*
400 * RR has already stored this cell in its data, but has not received
401 * the needed information for calculation of cell reselection criterion C2.
402 *
403 * Now it is checked against the incoming measurement report.
404 */
405 switch (att_cell_in_measure_report (report, i))
406 {
407 case CELL_IS_INSERTED:
408 /*
409 * The cell is still included. For later calculation of the cell
410 * reselection criterion C2 the time is counted for which the cell
411 * is synchronized.
412 */
413 if (rr_data->nc_data[i].avail_time < PERIOD_700_SEC)
414 rr_data->nc_data[i].avail_time += rr_data->ms_data.fn_offset;
415 break;
416
417 case BSIC_HAS_CHANGED:
418 /*
419 * The layer 1 indicated that the BSIC has changed during re-synchronisation
420 * to the SB channel. The status will not change, but the avail time is
421 * resetted.
422 */
423 rr_data->nc_data[i].avail_time = 0;
424 break;
425
426 case CELL_IS_NOT_INSERTED:
427 /*
428 * Layer 1 indicates that the cell is not longer one of the six strongest or
429 * that the synchronisation has been lost. The storage area in RR is released.
430 */
431 rr_data->nc_data[i].bcch_status = EMPTY;
432 rr_data->nc_data[i].avail_time = 0;
433 break;
434 }
435 break;
436 }
437 }
438
439 /*
440 * store the Fieldstrength of the serving cell and update the information
441 * of the power campaign.
442 */
443 rr_data->nc_data[SC_INDEX].rxlev = report->rx_lev_full;
444 cs_set_rxlev (report->rx_lev_full, rr_data->nc_data[SC_INDEX].arfcn);
445
446 if (rr_data->nc_data[SC_INDEX].rxlev >
447 rr_data->lup_rxlev + 10)
448 {
449 /*
450 * A fieldstrength jump more then 10 dBm has been detected. This can be the
451 * trigger for MM to restart a location updating request if needed. It indicates
452 * for example that the mobile has left a tunnel area without coverage.
453 *
454 * This is not used by MM if a test SIM is inserted. It is an improvement for
455 * the field beside the GSM specifications.
456 */
457 PALLOC (sync, RR_SYNC_IND);
458
459 sync->ciph = NOT_PRESENT_8BIT;
460 sync->chm.ch_mode = NOT_PRESENT_8BIT;
461 sync->synccs = SYNCCS_LUP_RETRY;
462 sync->mm_info.valid = FALSE;
463 sync->bcch_info.v_bcch = FALSE;
464
465 PSENDX (MM, sync);
466
467 /*
468 * Store the new value to avoid multiple signalling of the fieldstrength jump
469 */
470 rr_data->lup_rxlev = rr_data->nc_data[SC_INDEX].rxlev;
471 }
472
473 /*
474 * Now look for all neighbourcells in the measurement report if they are new.
475 */
476 for (i = 0; i < report->ncells.no_of_ncells; i++)
477 {
478 cs_set_rxlev (report->ncells.rx_lev[i], report->ncells.arfcn[i]);
479 /*
480 * If a channel is not inside the RR data structure, insert the cell
481 */
482 if (! att_cell_in_data_structures (report, i))
483 att_insert_cell_in_data (report, i);
484 }
485 }
486
487 /*
488 +--------------------------------------------------------------------+
489 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
490 | STATE : code ROUTINE : att_bcch_status_to_decoded |
491 +--------------------------------------------------------------------+
492
493 PURPOSE : After reception of the system information type 3,4,7 or 8
494 the status of a cell changes from NON_DECODED to DECODED
495 and it is possible to calculate the cell reselection
496 criterion C2.
497
498 */
499
500 GLOBAL void att_bcch_status_to_decoded (UBYTE index)
501 {
502 GET_INSTANCE_DATA;
503 TRACE_EVENT_P2 ("[%u]%u att_bcch_status_to_decoded()", rr_data->nc_data[index].arfcn, index);
504
505 rr_data->nc_data[index].bcch_status = DECODED;
506 rr_data->nc_data[index].bcch_counter = 0;
507 rr_data->nc_data[index].c1_counter = 0;
508 #ifdef GPRS
509 if( rr_data->gprs_data.use_c31 NEQ TRUE )
510 {
511 #endif
512
513 if ((rr_data->c_ncell_bcch > 0) AND (rr_data->c_ncell_bcch NEQ NOT_INITIALISED))
514 rr_data->c_ncell_bcch--;
515
516 if (rr_data->resel_pending)
517 {
518 if (rr_data->c_ncell_bcch EQ 0)
519 {
520 SET_STATE (STATE_ATT, ATT_CON_EST);
521 #ifdef GPRS
522 att_start_cell_reselection_gprs(CELL_RESELECTION_RACH);
523 #else
524 att_start_cell_reselection(CELL_RESELECTION_RACH);
525 #endif
526 rr_data->resel_pending = FALSE;
527 rr_data->c_ncell_bcch = NOT_INITIALISED;
528 }
529 }
530 else
531 {
532 att_calculate_c2 (index);
533 }
534 #ifdef GPRS
535 }
536 else
537 {
538 if( rr_data->nc_data[index].v_cr_par EQ CR_PAR_INVALID )
539 {
540 att_convert_idle_c31_cr(index);
541 }
542 else
543 {
544 TRACE_EVENT_P2(" arfcn %d, index = %d has valid CR_ PAR", rr_data->nc_data[index].arfcn, index);
545 }
546 }
547 #endif
548 }
549
550 /*
551 +--------------------------------------------------------------------+
552 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
553 | STATE : code ROUTINE : att_bits_to_byte |
554 +--------------------------------------------------------------------+
555
556 PURPOSE : The function is used to calculate the positions of 1-bits
557 into a byte array. This is needed for calculation of a
558 frequency hopping list for a mobile allocation. The input
559 parameter are the bitmap and the size of the bitmap in bytes.
560 The result is a byte array containing the positions of 1-bits
561 followed by an end identifier NOT_PRESENT_8BIT (0xFF). The
562 maximum size of the incoming array is 32 bytes.
563
564 Example: a mobile allocation looks like this:
565
566 0x42 = 0b01000010 -> bit 15 14 13 12 11 10 9 8
567 0x81 = 0b10000001 -> bit 7 6 5 4 3 2 1 0
568
569 The size of the input array is 2 and the output is:
570
571 1,8,10,15,0xFF (starting with position 1 in bit 0)
572
573 */
574
575 GLOBAL void att_bits_to_byte (UBYTE * num,
576 UBYTE size,
577 UBYTE * bits)
578 {
579 SHORT ix;
580 UBYTE bit;
581 UBYTE buf_ix;
582
583 TRACE_FUNCTION ("att_bits_to_byte()");
584
585 /*
586 * For all bytes in the input field
587 */
588 for (ix = 0; ix < size; ix++)
589 {
590 buf_ix = bits[size-1-ix];
591
592 /*
593 * for each bit inside this byte
594 */
595 bit = 0;
596 while (8 > bit)
597 {
598 if (buf_ix & (1 << bit))
599 {
600 /*
601 * If bit is set, store the position in the output field
602 */
603 *num++ = ((USHORT)ix << 3) + bit + 1;
604 }
605 bit++;
606 }
607 }
608 /*
609 * add the end identifier
610 */
611 *num = NOT_PRESENT_8BIT;
612 }
613
614
615 /*
616 +--------------------------------------------------------------------+
617 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
618 | STATE : code ROUTINE : att_build_cbch |
619 +--------------------------------------------------------------------+
620
621 PURPOSE : configure at the end of the cell selection the CBCH channel
622 in layer 1. The CBCH channel is optional defined in system
623 information type 4.
624 When the cell has PBCCH and it is a Release-99 cell,
625 the CBCH configuration should be taken from gprs database.
626 This information is provided by GRR through RRGRR_CBCH_INFO_IND.
627 CBCH channel configuration is received on PBCCH on PSI8.
628 */
629
630 #ifdef REL99
631 LOCAL void att_build_cbch (void)
632 #else
633 GLOBAL void att_build_cbch (void)
634 #endif
635 {/*lint -e813 supress info of length of T_LIST*/
636 GET_INSTANCE_DATA;
637 T_LIST hop_list;
638 PALLOC (cbch_req, MPH_CBCH_REQ);
639
640 TRACE_FUNCTION ("att_build_cbch()");
641
642 /*
643 * Initialize the primitive to layer 1
644 */
645 memset (cbch_req, 0, sizeof (T_MPH_CBCH_REQ));
646 if (rr_data->ms_data.rr_service EQ FULL_SERVICE)
647 {
648 /*
649 * CBCH is activated only if RR is in full service
650 */
651 if (rr_data->sc_data.cd.cbch_chan_desc_avail NEQ NO_CONTENT )
652 {
653 /*
654 * If a CBCH channel description has been received with
655 * system information tpye 4, activate the channel in layer 1.
656 */
657 cbch_req->cbch.stat = STAT_ACT;
658 cbch_req->cbch.ch = rr_data->sc_data.cd.cbch_chan_desc.chan_type;
659 cbch_req->cbch.tn = rr_data->sc_data.cd.cbch_chan_desc.tn;
660 cbch_req->cbch.tsc = rr_data->sc_data.cd.cbch_chan_desc.tsc;
661 cbch_req->cbch.h = rr_data->sc_data.cd.cbch_chan_desc.hop;
662
663 switch (cbch_req->cbch.h)
664 {
665 case H_NO:
666 /*
667 * CBCH does not use frequency hopping, then configure simply the
668 * channel number
669 */
670 cbch_req->cbch.arfcn = rr_data->sc_data.cd.cbch_chan_desc.arfcn;
671 break;
672
673 case H_FREQ:
674 /*
675 * CBCH uses frequency hopping, then configure MAIO and HSN
676 * and create a frequency hopping list from the cell channel
677 * description in system information 1 and the mobile allocation
678 * in system information 4.
679 */
680 cbch_req->cbch.maio = rr_data->sc_data.cd.cbch_chan_desc.maio;
681 cbch_req->cbch.hsn = rr_data->sc_data.cd.cbch_chan_desc.hsn;
682 srv_create_chan_mob_alloc (&rr_data->sc_data.cd.cell_chan_desc,
683 &hop_list,
684 rr_data->sc_data.cd.cbch_mob_alloc);
685
686 /* CSI-LLD section:4.1.1.11
687 * This function Updates the black list with the MA list received
688 * in the CBCH allocation
689 */
690 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,&hop_list);
691
692 srv_create_list (&hop_list, cbch_req->cbch.ma, MAX_MA_CHANNELS, TRUE,
693 0);
694 break;
695 }
696 }
697 else
698 /*
699 * In all other cases configure layer 1 without CBCH.
700 */
701 cbch_req->cbch.stat = STAT_INACT;
702 }
703
704 PSENDX (PL, cbch_req);
705 }
706
707 #ifdef REL99
708 /*
709 +--------------------------------------------------------------------+
710 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
711 | STATE : code ROUTINE : att_config_cbch |
712 +--------------------------------------------------------------------+
713
714 PURPOSE : The following conditions have to be satisfied for
715 configuring CBCH.
716 1. Full service should have been enabled.
717 2. Mobile should be in idle/packet mode.
718 This function checks these conditions before configuring
719 CBCH. If function is called during packet transfer mode,
720 a flag in GPRS data is set signalling that this function
721 should be called again after entering idle mode.
722 */
723 GLOBAL void att_config_cbch (void)
724 {
725 GET_INSTANCE_DATA;
726 TRACE_FUNCTION ("att_config_cbch()");
727 /*
728 * CBCH is activated only if RR is in full service
729 */
730 if ((rr_data->ms_data.rr_service EQ FULL_SERVICE) )
731 {
732 #ifdef GPRS
733 /* check if mobile is in PTM */
734 if(!dat_gprs_cell_in_ptm())
735 {
736 /* mobile is NOT in packet transfer mode */
737
738 if(!att_gprs_cell_has_pbcch() OR !att_gprs_get_nw_release())
739 {
740 /* This cell does not have pbcch,
741 * OR this is a R - 98 or lower cell.
742 * hence take info stored in SI 4
743 */
744 #endif /* GPRS */
745 att_build_cbch();
746 #ifdef GPRS
747 }
748 else
749 {
750 /* This Cell has PBCCH and also this is Release-99 cell.
751 * Configure ALR if CBCH info is available form GRR.
752 */
753 if(rr_data->gprs_data.cbch_psi_valid)
754 {
755 PALLOC (cbch_req, MPH_CBCH_REQ);
756 memcpy(&(cbch_req->cbch),
757 &(rr_data->gprs_data.cbch_psi8),
758 sizeof(T_cbch));
759 PSENDX (PL, cbch_req);
760 }
761 /*else wait till CBCH info is received from GRR */
762 }
763 rr_data->gprs_data.cbch_info_rxvd_in_ptm = FALSE;
764 }
765 else
766 {
767 rr_data->gprs_data.cbch_info_rxvd_in_ptm = TRUE;
768 }
769 #endif /* GPRS */
770 }
771 else
772 {
773 #ifdef GPRS
774 if(!dat_gprs_cell_in_ptm())
775 #endif /* GPRS */
776 {
777 PALLOC (cbch_req, MPH_CBCH_REQ);
778 memset (cbch_req, 0, sizeof (T_MPH_CBCH_REQ));
779 cbch_req->cbch.stat = STAT_INACT;
780 PSENDX (PL, cbch_req);
781 }
782 }
783 }
784 #endif
785
786 /*
787 +--------------------------------------------------------------------+
788 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
789 | STATE : code ROUTINE : att_build_classmark_req |
790 +--------------------------------------------------------------------+
791
792 PURPOSE : Configure at the end of the cell selection the classmark of
793 the mobile to layer 1. This information is used by layer 1
794 for random access.
795
796 */
797
798 GLOBAL void att_build_classmark_req (void)
799 {
800 GET_INSTANCE_DATA;
801 PALLOC (classmark_req, MPH_CLASSMARK_REQ);
802
803 TRACE_FUNCTION ("att_build_classmark_req()");
804
805 #if defined (_SIMULATION_)
806 /*
807 * In the windows simulation it is necessary to read the data
808 * from the non-volantile memory (PCM) again.
809 */
810 rr_csf_check_rfcap (FALSE);
811 #endif
812
813 if((std EQ STD_DUAL) OR (std EQ STD_DUAL_EGSM))
814 {
815 classmark_req->classmark.pclass = rr_data->ms_data.rf_cap.rf_power.pow_class4[IDX_PWRCLASS_900].pow_class-1;
816 classmark_req->classmark.pclass2 = rr_data->ms_data.rf_cap.rf_power.pow_class4[IDX_PWRCLASS_1800].pow_class-1;
817 }
818 else if(std EQ STD_DUAL_US)
819 {
820 classmark_req->classmark.pclass = rr_data->ms_data.rf_cap.rf_power.pow_class4[IDX_PWRCLASS_850].pow_class-1;
821 classmark_req->classmark.pclass2 = rr_data->ms_data.rf_cap.rf_power.pow_class4[IDX_PWRCLASS_1900].pow_class-1;
822 }
823 else
824 {
825 /*
826 * In single bands only one power class is forwarded to layer 1.
827 */
828 #ifdef GPRS
829
830 #ifdef REL99
831 classmark_req->classmark.pclass = rr_data->ms_data.ra_cap.ra_cap_values.acc_cap.pow_class-1;
832 #else
833 classmark_req->classmark.pclass = rr_data->ms_data.ra_cap.acc_cap.pow_class-1;
834 #endif
835
836 #else
837 if (std EQ STD_1900)
838 {
839 classmark_req->classmark.pclass = rr_data->ms_data.classmark3.pcs1900_cap-1;
840 }
841 else if (std EQ STD_850)
842 {
843 classmark_req->classmark.pclass = rr_data->ms_data.classmark3.gsm850_cap-1;
844 }
845 else
846 {
847 classmark_req->classmark.pclass = rr_data->ms_data.classmark3.radio_cap_1-1;
848 }
849 #endif
850 classmark_req->classmark.pclass2= 0;
851 }
852 PSENDX (PL, classmark_req );
853 }
854
855 /*
856 +--------------------------------------------------------------------+
857 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
858 | STATE : code ROUTINE : att_build_idle_req |
859 +--------------------------------------------------------------------+
860
861 PURPOSE : The function is used to configure the idle mode in layer 1.
862 Two modes are possible: cell selection and cell reselection.
863 In cell selection mode RR has all information to perform
864 a complete layer 1 configuration. In cell reselection mode
865 layer 1 is configured only as much as needed and it is
866 expected that layer 1 goes in paging reorganization mode
867 to catch all pagings and BCCH messages.
868 */
869
870 GLOBAL void att_build_idle_req (UBYTE index,
871 UBYTE mode)
872 {
873 GET_INSTANCE_DATA;
874 T_CELL_DATA *cd;
875 PALLOC (idle_req, MPH_IDLE_REQ);
876
877 TRACE_FUNCTION ("att_build_idle_req()");
878
879 /*
880 * configure the mode of layer 1 (cell selection or cell reselection
881 */
882 idle_req->mod = mode;
883
884 /*
885 * set the pointer to the correct data
886 * serving cell or one of the neighbourcells.
887 */
888 if (index EQ SC_INDEX)
889 {
890 cd = &rr_data->sc_data.cd;
891 #if defined (REL99) && defined (TI_PS_FF_EMR)
892 idle_req->si2quater_status = cd->si2quater_status;
893 idle_req->si2quater_pos = cd->si2quater_pos;
894
895 if ( (mode EQ MODE_CELL_SELECTION ) AND
896 (cd->si2quater_status EQ SI2QUATER_CONFIGURE) AND
897 ((rr_data->sc_data.cd.sys_info_read & (ALL_SYS_INFO_READ | SYS_INFO_2QUATER_READ)) EQ ALL_SYS_INFO_READ))
898 rr_data->sc_data.cd.si2quater_status = SI2QUATER_ACQ_PENDING;
899 #endif
900 }
901 else
902 {
903 #if defined (REL99) && defined (TI_PS_FF_EMR)
904 idle_req->si2quater_status = SI2QUATER_ABSENT;
905 #endif
906 cd = &rr_data->cr_data.cd;
907 }
908
909 /*
910 * look to the reached service of RR
911 */
912 switch (rr_data->ms_data.rr_service)
913 {
914 case LIMITED_SERVICE:
915 /*
916 * In limited mode no pagings are possible. To save
917 * power the minimum number of measurements (equal
918 * to a long paging period) is configured.
919 * The other parameters are independent from BCCH or
920 * SIM card, because paging is not possible.
921 */
922 idle_req->pg = 0;
923 idle_req->tn = 0;
924 idle_req->ncc_permitted = NOT_PRESENT_8BIT;
925 idle_req->dlt = 10; /* for bs_pa_mfmrs = 9 */
926 idle_req->bs_pa_mfrms = 7; /* for bs_pa_mfmrs = 9 */
927 break;
928
929 case FULL_SERVICE:
930 /*
931 * The MS is in full service. In this case the paging
932 * block must be correctly from the SIM and the BCCH
933 * data.
934 */
935 idle_req->pg = dat_calc_paging_group (index);
936 idle_req->tn = dat_calc_tn (index);
937
938 /*
939 * The NCC permitted check in layer 1 is used to
940 * avoid synchronisation to cells of other networks.
941 */
942 #ifdef GPRS
943 if(mode NEQ MODE_CELL_RESELECTION AND
944 mode NEQ MODE_CELL_RESELECTION_SYNC_ONLY)
945 #else
946 if (mode NEQ MODE_CELL_RESELECTION)
947 #endif
948 idle_req->ncc_permitted = cd->ncc_permitted;
949 else
950 idle_req->ncc_permitted = NOT_PRESENT_8BIT;
951
952 idle_req->dlt = dat_calc_downlink_timeout (index);
953 idle_req->bs_pa_mfrms = rr_data->nc_data[index].control_descr.bs_pa_mfrms;
954 break;
955 }
956 idle_req->arfcn = rr_data->nc_data[index].arfcn;
957
958 /* XXX
959 * use ext_bcch for forwarding bsic, this solves
960 * fieldtest problem of mismatch of BSICs.
961 */
962 idle_req->ext_bcch = rr_data->nc_data[index].bsic;
963
964 idle_req->comb_ccch = rr_data->nc_data[index].control_descr.ccch_conf EQ COMB_CCCH_COMB;
965 idle_req->bs_ag_blocks_res =
966 rr_data->nc_data[index].control_descr.bs_ag_blks_res;
967
968 idle_req->power = att_get_txpwr_max_cch (index);
969
970 idle_req->reorg_only = NORMAL_PGM;
971 idle_req->gprs_support = NOT_PRESENT_8BIT;
972 #if defined FF_EOTD
973 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
974 idle_req->eotd_avail = (std EQ STD_1900 OR std EQ STD_850 OR std EQ STD_DUAL_US OR std EQ STD_850_1800 OR std EQ STD_850_900_1800 OR std EQ STD_850_900_1900);
975 #else
976 idle_req->eotd_avail = (std EQ STD_1900 OR std EQ STD_850 OR std EQ STD_DUAL_US);
977 #endif
978 #else
979 idle_req->eotd_avail = 0;
980 #endif
981
982 #ifdef GPRS
983 att_gprs_idle_req(idle_req);
984 #endif
985
986 EM_IDLE_MODE;
987
988 #if defined(_SIMULATION_)
989 switch (idle_req->mod)
990 {
991 case MODE_CELL_SELECTION : /* 0x0 cell selection */
992 TRACE_EVENT_WIN ("MODE_CELL_SELECTION");
993 break;
994 case MODE_CELL_RESELECTION : /* 0x1 cell reselection */
995 TRACE_EVENT_WIN ("MODE_CELL_RESELECTION");
996 break;
997 #if defined(MODE_BACK_FROM_DEDICATED)
998 case MODE_BACK_FROM_DEDICATED : /* 0x2 back from dedicated */
999 TRACE_EVENT_WIN ("MODE_BACK_FROM_DEDICATED");
1000 break;
1001 #endif /* MODE_BACK_FROM_DEDICATED */
1002 case MODE_IMM_ASSIGN : /* 0x3 immediate assignment */
1003 TRACE_EVENT_WIN ("MODE_IMM_ASSIGN");
1004 break;
1005 case MODE_CHAN_ASSIGN : /* 0x4 channel assignment */
1006 TRACE_EVENT_WIN ("MODE_CHAN_ASSIGN");
1007 break;
1008 case MODE_ASYNC_HANDOVER : /* 0x5 asynchronous handover */
1009 TRACE_EVENT_WIN ("MODE_ASYNC_HANDOVER");
1010 break;
1011 case MODE_SYNC_HANDOVER : /* 0x6 synchronous handover */
1012 TRACE_EVENT_WIN ("MODE_SYNC_HANDOVER");
1013 break;
1014 case MODE_PRE_SYNC_HANDOVER : /* 0x7 pre synchronous handover */
1015 TRACE_EVENT_WIN ("MODE_PRE_SYNC_HANDOVER");
1016 break;
1017 case MODE_PSEUDO_SYNC_HANDOVER: /* 0x8 pseudo synchronous handover */
1018 TRACE_EVENT_WIN ("MODE_PSEUDO_SYNC_HANDOVER");
1019 break;
1020 case MODE_SYS_INFO_CHANGE : /* 0x9 sys info has changed */
1021 TRACE_EVENT_WIN ("MODE_SYS_INFO_CHANGE");
1022 break;
1023 case MODE_PACKET_TRANSFER : /* 0xa enter packet transfer mode */
1024 TRACE_EVENT_WIN ("MODE_PACKET_TRANSFER");
1025 break;
1026 case MODE_PDCH_ASSIGN : /* 0xb PDCH assignment */
1027 TRACE_EVENT_WIN ("MODE_PDCH_ASSIGN");
1028 break;
1029 case MODE_CELL_CHANGE_ORDER : /* 0xc Network controlled Cell Change */
1030 TRACE_EVENT_WIN ("MODE_CELL_CHANGE_ORDER");
1031 break;
1032 case MODE_CELL_RESELECTION_SYNC_ONLY: /* 0xc Network controlled Cell Change */
1033 TRACE_EVENT_WIN ("MODE_CR_SYNC_ONLY");
1034 break;
1035 case MODE_CONFIG_PL: /* PBCCH */
1036 TRACE_EVENT_WIN ("MODE_CONFIG_PL");
1037 break;
1038 default:
1039 TRACE_EVENT_WIN_P1 ("idle_req mode %d unknown!", idle_req->mod);
1040 break;
1041 }
1042 #endif /* _SIMULATION_ */
1043 if ((mode EQ MODE_CELL_SELECTION) AND
1044 (rr_data->ms_data.rr_service EQ FULL_SERVICE) AND
1045 (rr_data->cs_data.act_index NEQ NOT_PRESENT_8BIT))
1046 {
1047 rr_data->cs_data.act_index = NOT_PRESENT_8BIT;
1048 rr_csf_fit_capability ();
1049 #if !defined(NTRACE)
1050 rr_csf_trace_power ();
1051 #endif /* !NTRACE */
1052 }
1053 PSENDX (PL, idle_req);
1054 }
1055
1056 /*
1057 +--------------------------------------------------------------------+
1058 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1059 | STATE : code ROUTINE : att_calculate_c1 |
1060 +--------------------------------------------------------------------+
1061
1062 PURPOSE : The function calculates the path loss criterion C1 for
1063 cell selection and cell reselection purposes.
1064
1065 REFERENCE: GSM 5.08, chapter 6.4 Criteria for cell selection and reselection
1066
1067 */
1068
1069 /*
1070 * The following tables define conversion for the power in dBm depending
1071 * on the frequency band (GSM, DCS or PCS) and the power class (1 to 5).
1072 */
1073
1074 /*lint -esym(765,p_dcs) | external could be made static | used by GRR */
1075 /*lint -esym(765,p_pcs) | external could be made static | used by GRR */
1076 /*lint -esym(765,p_gsm) | external could be made static | used by GRR */
1077 /*lint -esym(765,p_control_dcs) | external could be made static | used by GRR */
1078 /*lint -esym(765,p_control_pcs) | external could be made static | used by GRR */
1079 /*lint -esym(765,p_control_gsm) | external could be made static | used by GRR */
1080 const SHORT p_dcs [MAX_CLASSES] = { P_CLASS_1_1800,
1081 P_CLASS_2_1800,
1082 P_CLASS_3_1800,
1083 P_CLASS_3_1800,
1084 P_CLASS_3_1800 };
1085
1086
1087 const SHORT p_pcs [MAX_CLASSES] = { P_CLASS_1_1900,
1088 P_CLASS_2_1900,
1089 P_CLASS_3_1900,
1090 P_CLASS_3_1900,
1091 P_CLASS_3_1900 };
1092
1093 const SHORT p_gsm [MAX_CLASSES] = { P_CLASS_2_900,
1094 P_CLASS_2_900,
1095 P_CLASS_3_900,
1096 P_CLASS_4_900,
1097 P_CLASS_5_900 };
1098
1099
1100 /*
1101 * The following tables converts the air-interface coding of
1102 * the system information parameter MAX_TXPWR_CCCH to a value
1103 * in dBm depending on the frequency standard (GSM, DCS or PCS).
1104 */
1105 const UBYTE p_control_gsm [32] =
1106 { 39, /* 0 -> 39 dBm */
1107 39, /* 1 -> 39 dBm */
1108 39, /* 2 -> 39 dBm */
1109 37, /* 3 -> 37 dBm */
1110 35, /* 4 -> 35 dBm */
1111 33, /* 5 -> 33 dBm */
1112 31, /* 6 -> 31 dBm */
1113 29, /* 7 -> 29 dBm */
1114 27, /* 8 -> 27 dBm */
1115 25, /* 9 -> 25 dBm */
1116 23, /* 10 -> 23 dBm */
1117 21, /* 11 -> 21 dBm */
1118 19, /* 12 -> 19 dBm */
1119 17, /* 13 -> 17 dBm */
1120 15, /* 14 -> 15 dBm */
1121 13, /* 15 -> 13 dBm */
1122 11, /* 16 -> 11 dBm */
1123 9, /* 17 -> 9 dBm */
1124 7, /* 18 -> 7 dBm */
1125 5, /* 19 -> 5 dBm */
1126 5, /* 20 -> 5 dBm */
1127 5, /* 21 -> 5 dBm */
1128 5, /* 22 -> 5 dBm */
1129 5, /* 23 -> 5 dBm */
1130 5, /* 24 -> 5 dBm */
1131 5, /* 25 -> 5 dBm */
1132 5, /* 26 -> 5 dBm */
1133 5, /* 27 -> 5 dBm */
1134 5, /* 28 -> 5 dBm */
1135 5, /* 29 -> 5 dBm */
1136 5, /* 30 -> 5 dBm */
1137 5 /* 31 -> 5 dBm */
1138 };
1139
1140 const UBYTE p_control_dcs [32] =
1141 { 30, /* 0 -> 30 dBm */
1142 28, /* 1 -> 28 dBm */
1143 26, /* 2 -> 26 dBm */
1144 24, /* 3 -> 24 dBm */
1145 22, /* 4 -> 22 dBm */
1146 20, /* 5 -> 20 dBm */
1147 18, /* 6 -> 18 dBm */
1148 16, /* 7 -> 16 dBm */
1149 14, /* 8 -> 14 dBm */
1150 12, /* 9 -> 12 dBm */
1151 10, /* 10 -> 10 dBm */
1152 8, /* 11 -> 8 dBm */
1153 6, /* 12 -> 6 dBm */
1154 4, /* 13 -> 4 dBm */
1155 2, /* 14 -> 2 dBm */
1156 0, /* 15 -> 0 dBm */
1157 0, /* 16 -> 0 dBm */
1158 0, /* 17 -> 0 dBm */
1159 0, /* 18 -> 0 dBm */
1160 0, /* 19 -> 0 dBm */
1161 0, /* 20 -> 0 dBm */
1162 0, /* 21 -> 0 dBm */
1163 0, /* 22 -> 0 dBm */
1164 0, /* 23 -> 0 dBm */
1165 0, /* 24 -> 0 dBm */
1166 0, /* 25 -> 0 dBm */
1167 0, /* 26 -> 0 dBm */
1168 0, /* 27 -> 0 dBm */
1169 0, /* 28 -> 0 dBm */
1170 36, /* 29 -> 36 dBm */
1171 34, /* 30 -> 34 dBm */
1172 32 /* 31 -> 32 dBm */
1173 };
1174
1175 const UBYTE p_control_pcs [32] =
1176 { 30, /* 0 -> 30 dBm */
1177 28, /* 1 -> 28 dBm */
1178 26, /* 2 -> 26 dBm */
1179 24, /* 3 -> 24 dBm */
1180 22, /* 4 -> 22 dBm */
1181 20, /* 5 -> 20 dBm */
1182 18, /* 6 -> 18 dBm */
1183 16, /* 7 -> 16 dBm */
1184 14, /* 8 -> 14 dBm */
1185 12, /* 9 -> 12 dBm */
1186 10, /* 10 -> 10 dBm */
1187 8, /* 11 -> 8 dBm */
1188 6, /* 12 -> 6 dBm */
1189 4, /* 13 -> 4 dBm */
1190 2, /* 14 -> 2 dBm */
1191 0, /* 15 -> 0 dBm */
1192 0, /* 16 -> 0 dBm */
1193 0, /* 17 -> 0 dBm */
1194 0, /* 18 -> 0 dBm */
1195 0, /* 19 -> 0 dBm */
1196 0, /* 20 -> 0 dBm */
1197 0, /* 21 -> 0 dBm */
1198 33, /* 22 -> 33 dBm */
1199 33, /* 23 -> 33 dBm */
1200 33, /* 24 -> 33 dBm */
1201 33, /* 25 -> 33 dBm */
1202 33, /* 26 -> 33 dBm */
1203 33, /* 27 -> 33 dBm */
1204 33, /* 28 -> 33 dBm */
1205 33, /* 29 -> 33 dBm */
1206 33, /* 30 -> 33 dBm */
1207 32 /* 31 -> 32 dBm */
1208 };
1209 /*lint +e765 / used by GRR */
1210
1211 GLOBAL void att_calculate_c1 (UBYTE index)
1212 {
1213 GET_INSTANCE_DATA;
1214 SHORT a;
1215 SHORT b;
1216 const SHORT *p;
1217 const UBYTE *p_control;
1218 SHORT power_offset = 0;
1219 UBYTE ms_power;
1220 SHORT offset;
1221
1222 TRACE_FUNCTION ("att_calculate_c1()");
1223
1224 ms_power = att_get_power ();
1225 switch (std)
1226 {
1227 case STD_900:
1228 case STD_EGSM:
1229 case STD_850:
1230 /*
1231 * The table for the power class conversion is GSM 900, E-GSM or GSM 850
1232 */
1233 p = p_gsm;
1234 /*
1235 * The table for the MAX_TXPWR_CCCH conversion is GSM 900, E-GSM or GSM 850
1236 */
1237 p_control = p_control_gsm;
1238 /*
1239 * The gsm_offset parameter can be set by a dynamic configuration command
1240 * and is not used.
1241 */
1242 offset = rr_data->dyn_config.gsm_offset;
1243 break;
1244
1245 case STD_1900:
1246 p = p_pcs;
1247 p_control = p_control_pcs;
1248
1249 /*
1250 * The dcs_offset parameter can be set by a dynamic configuration command
1251 * and is not used.
1252 */
1253 offset = rr_data->dyn_config.dcs_offset;
1254 break;
1255
1256 case STD_1800:
1257 p = p_dcs;
1258 p_control = p_control_dcs;
1259
1260 /* Ref 04.18 Section 10.5.2.35
1261 * Rest Octets IE includes parameters which are used by the mobile station
1262 * for cell selection and reselection purposes. It may also include the
1263 * POWER OFFSET parameter used by DCS 1800 Class 3 MS.
1264 */
1265
1266 if (ms_power EQ 0x02 AND
1267 rr_data->nc_data[index].c2_par.power_off_ind)
1268 {
1269 power_offset = rr_data->nc_data[index].c2_par.power_off << 1;
1270 }
1271
1272 offset = rr_data->dyn_config.dcs_offset;
1273 break;
1274
1275 case STD_DUAL:
1276 case STD_DUAL_EGSM:
1277 /*
1278 * For dualband mobiles the calculation depends on the channel number
1279 */
1280 if (INRANGE(LOW_CHANNEL_1800,rr_data->nc_data[index].arfcn,HIGH_CHANNEL_1800))
1281 {
1282 /*
1283 * All DCS 1800 channels
1284 */
1285 p = p_dcs;
1286 p_control = p_control_dcs;
1287
1288 /* Ref 04.18 Section 10.5.2.35 */
1289 if (ms_power EQ 0x02 AND
1290 rr_data->nc_data[index].c2_par.power_off_ind)
1291 {
1292 power_offset = rr_data->nc_data[index].c2_par.power_off << 1;
1293 }
1294
1295 offset = rr_data->dyn_config.dcs_offset;
1296 }
1297 else
1298 {
1299 /*
1300 * All GSM 900 and E-GSM channels
1301 */
1302 p = p_gsm;
1303 p_control = p_control_gsm;
1304 offset = rr_data->dyn_config.gsm_offset;
1305 }
1306 break;
1307
1308 case STD_DUAL_US:
1309 if (rr_data->nc_data[index].arfcn < LOW_CHANNEL_1900)
1310 {
1311 /*
1312 * Then it is a GSM 850 channel
1313 */
1314 p = p_gsm;
1315 p_control = p_control_gsm;
1316 offset = rr_data->dyn_config.gsm_offset;
1317 }
1318 else
1319 {
1320 /*
1321 * else it is a PCS 1900 channel
1322 */
1323 p = p_pcs;
1324 p_control = p_control_pcs;
1325
1326 offset = rr_data->dyn_config.dcs_offset;
1327 }
1328 break;
1329
1330 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1331 case STD_850_1800:
1332 case STD_850_900_1800:
1333 if (INRANGE(LOW_CHANNEL_1800,rr_data->nc_data[index].arfcn,HIGH_CHANNEL_1800))
1334 {
1335 /*
1336 * Then it is a DCS 1800 channel
1337 */
1338 p = p_dcs;
1339 p_control = p_control_dcs;
1340
1341 if (ms_power EQ 0x02 AND
1342 rr_data->nc_data[index].c2_par.power_off_ind)
1343 {
1344 power_offset = rr_data->nc_data[index].c2_par.power_off << 1;
1345 }
1346
1347 offset = rr_data->dyn_config.dcs_offset;
1348 }
1349 else
1350 {
1351 /*
1352 * Else it is a GSM 900 and E-GSM or GSM 850 channel
1353 */
1354 p = p_gsm;
1355 p_control = p_control_gsm;
1356 offset = rr_data->dyn_config.gsm_offset;
1357 }
1358 break;
1359
1360 case STD_900_1900:
1361 case STD_850_900_1900:
1362 /*
1363 * For dualband mobiles the calculation depends on the channel number
1364 */
1365 if (INRANGE(LOW_CHANNEL_1900,rr_data->nc_data[index].arfcn,HIGH_CHANNEL_1900))
1366 {
1367 /*
1368 * All PCS 1900 channels
1369 */
1370 p = p_pcs;
1371 p_control = p_control_pcs;
1372
1373 offset = rr_data->dyn_config.dcs_offset;
1374 }
1375 else
1376 {
1377 /*
1378 * All GSM 900 and E-GSM or GSM 850 channels
1379 */
1380 p = p_gsm;
1381 p_control = p_control_gsm;
1382 offset = rr_data->dyn_config.gsm_offset;
1383 }
1384 break;
1385 #endif
1386
1387 default:
1388 /*
1389 * Just for LINT
1390 */
1391 rr_data->nc_data[index].c1 = 0;
1392 return;
1393 }
1394
1395 /*
1396 * Parameter A indicates the difference between current fieldstrength and
1397 * the minimum expected from the infrastructure. It indicates how good is the
1398 * receiving part.
1399 */
1400 #ifdef GPRS
1401 if(rr_data->gprs_data.use_c31)
1402 {
1403 a = (SHORT) rr_data->nc_data[index].rxlev -
1404 (SHORT) rr_data->nc_data[index].cr_par.gprs_rxlev_access_min;
1405 }
1406 else
1407 {
1408 #endif
1409 a = (SHORT) rr_data->nc_data[index].rxlev -
1410 (SHORT) rr_data->nc_data[index].select_para.rxlev_access_min;
1411 #ifdef GPRS
1412 }
1413 #endif
1414
1415 /*
1416 * Parameter B indicates the difference between the maximum sending power
1417 * expected by the infrastructure and the maximum power which is possible by
1418 * the mobile. In the formula the maximum of B and zero is taking in account.
1419 * If B is negative, the MS has enough power to reach the base station,
1420 * because it has more power than expected and it will not have any affect
1421 * in the C1 calculation. If B is positive, the MS will send with less power
1422 * than expected by the infrastructure. Then this difference is subtracted
1423 * from A. The maximum power is expected at the boarder of the cell. If the
1424 * mobile is nearer to the base station, a lower power is needed. On the
1425 * other hand will the mobile receive the base station with a higher
1426 * fieldstrength as on the boarder. So this surplus compensates the lower
1427 * sending capabilities.
1428 */
1429
1430 #ifdef GPRS
1431 if(rr_data->gprs_data.use_c31)
1432 {
1433 b = p_control [rr_data->nc_data[index].cr_par.gprs_ms_txpwr_max_cch] - p[ms_power];
1434 }
1435 else
1436 {
1437 #endif
1438 b = p_control [rr_data->nc_data[index].select_para.ms_txpwr_max_cch] +
1439 power_offset - p[ms_power];
1440 #ifdef GPRS
1441 }
1442 #endif
1443
1444 /*
1445 * The resulting path loss criterion is C1 = A - MAX (B,0)
1446 *
1447 * An additional C1_offset and offset is not really used. This values can
1448 * be configured and may compensate RF problems.
1449 */
1450 rr_data->nc_data[index].c1 = a - att_max (b, 0) + rr_data->c1_offset +
1451 offset;
1452
1453 /*
1454 * To avoid too many reselection the C1 of a neighbourcell is decreased,
1455 * that means beside the GSM specifications a threshold value is introduced.
1456 * If a test SIM card is inserted, this is not used.
1457 */
1458 if (index NEQ SC_INDEX AND index NEQ CR_INDEX AND !dat_test_sim_available())
1459 rr_data->nc_data[index].c1 -= TWO;
1460 }
1461
1462 /*
1463 +--------------------------------------------------------------------+
1464 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1465 | STATE : code ROUTINE : att_calculate_c2 |
1466 +--------------------------------------------------------------------+
1467
1468 PURPOSE : The reselection criterion C2 is used for cell reselection
1469 only and is defined by:
1470
1471 C2 = C1 + CELL_RESELECT_OFFSET -
1472 TEMPORARY OFFSET * H(PENALTY_TIME - T)
1473
1474 for PENALTY_TIME <> 11111
1475
1476 C2 = C1 - CELL_RESELECT_OFFSET
1477
1478 for PENALTY_TIME = 11111
1479
1480 where
1481
1482 For non-serving cells:
1483
1484 H(x) = 0 for x < 0
1485
1486 = 1 for x = 0
1487
1488 For serving cells:
1489
1490 H(x) = 0
1491
1492 T is a timer implemented for each cell in the list of strongest carriers.
1493 T shall be started from zero at the time the cell is placed by the MS on the
1494 list of strongest carriers, except when the previous serving cell is placed
1495 on the list of strongest carriers at cell reselection. In this, case,
1496 T shall be set to the value of PENALTY_TIME (i.e. expired).
1497 CELL_RESELECT_OFFSET applies an offset to the C2 reselection criterion for that cell.
1498
1499 NOTE: CELL_RESELECT_OFFSET may be used to give different priorities to different
1500 bands when multiband operation is used.
1501
1502 TEMPORARY_OFFSET applies a negative offset to C2 for the duration of PENALTY_TIME
1503 after the timer T has started for that cell.
1504
1505 PENALTY_TIME is the duration for which TEMPORARY_OFFSET applies The all ones bit
1506 pattern on the PENALTY_TIME parameter is reserved to change the sign of
1507 CELL_RESELECT_OFFSET and the value of TEMPORARY_OFFSET is ignored as indicated
1508 by the equation defining C2.
1509
1510 CELL_RESELECT_OFFSET, TEMPORARY_OFFSET, PENALTY_TIME and CELL_BAR_QUALIFY are
1511 optionally broadcast on the BCCH of the cell. If not broadcast, the default values
1512 are CELL_BAR_QUALIFY = 0, and C2 = C1. The use of C2 is described in GSM 03.22.
1513
1514 These parameters are used to ensure that the MS is camped on the cell with which it
1515 has the highest probability of successful communication on uplink and downlink.
1516
1517 REFERENCE: GSM 5.08, chapter 6.4 Criteria for cell selection and reselection
1518
1519 */
1520
1521 static void att_calculate_c2 (UBYTE index)
1522 {
1523 GET_INSTANCE_DATA;
1524 USHORT h;
1525 T_NC_DATA *rrd;
1526
1527 TRACE_FUNCTION ("att_calculate_c2()");
1528
1529 /*
1530 * get a pointer to the data of the cell
1531 */
1532 rrd = &rr_data->nc_data[index];
1533
1534 /*
1535 * Calculate C1 as a base if no C2 parameters are available
1536 */
1537 att_calculate_c1 (index);
1538
1539 if ( rrd->c2_par.param_ind EQ 0 )
1540 {
1541 /*
1542 * C2 is equal C1 if no C2 parameters are available.
1543 */
1544 rrd->c2 = rrd->c1;
1545 TRACE_C1_C2(index);
1546 return;
1547 }
1548
1549 /*
1550 * Special case penalty time = 0b11111
1551 */
1552 if (rrd->c2_par.penalty_time EQ 31)
1553 {
1554 rrd->c2 = rrd->c1 - 2 * rrd->c2_par.cell_reselect_offset;
1555 TRACE_C1_C2(index);
1556 return;
1557 }
1558
1559 /*
1560 * Calculate x for H(x) and set H(x)
1561 */
1562 if ((USHORT)((rrd->c2_par.penalty_time + 1) * 20) >=
1563 (USHORT)(rrd->avail_time/PERIOD_1_SEC))
1564 h = 1;
1565 else
1566 h = 0;
1567
1568 /*
1569 * for the serving cells H(x) us ever zero.
1570 */
1571 if (index EQ SC_INDEX)
1572 h = 0;
1573
1574 /*
1575 * Calculate C2 using the formula
1576 */
1577 rrd->c2 = rrd->c1 + 2 * rrd->c2_par.cell_reselect_offset -
1578 10 * rrd->c2_par.temp_offset * h;
1579 if (h EQ 1 AND rrd->c2_par.temp_offset EQ 7)
1580 {
1581 /*
1582 * temp offset = 7 means C2 = - infinite
1583 */
1584 rrd->c2 = -127;
1585 }
1586
1587 TRACE_C1_C2(index);
1588 }
1589
1590 /*
1591 +--------------------------------------------------------------------+
1592 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1593 | STATE : code ROUTINE : att_calculate_c2_diff |
1594 +--------------------------------------------------------------------+
1595
1596 PURPOSE : For cell reselection decision the C2 difference between
1597 a neighbourcell and the serving cell is calculated. This
1598 function shall be called only if both cells are in a
1599 different location area.
1600
1601 If no SIM card is inserted (that means limited service)
1602 the threshold value is not taken in account. This is
1603 beside the GSM specifications and shall ensure a better
1604 coverage of the mobile. It leads not to more signalling
1605 on the air-interface.
1606
1607 REFERENCE: GSM 5.08, chapter 6.6.2 Path loss criteria and timings for
1608 cell re-selection
1609
1610 */
1611
1612 static SHORT att_calculate_c2_diff (UBYTE index)
1613 {
1614 GET_INSTANCE_DATA;
1615 SHORT delta;
1616
1617 TRACE_FUNCTION ("att_calculate_c2_diff()");
1618
1619 /*
1620 * calculate delta
1621 */
1622 delta = rr_data->nc_data[index].c2 - rr_data->nc_data[SC_INDEX].c2;
1623
1624 /* According to 3GPP 05.08 Sec 6.8 MS is supposed to use ZERO for
1625 * CELL_RESELECT_HYSTERESIS when in Limited service.
1626 * c) The MS shall perform cell reselection at least among the cells of
1627 * the PLMN of the cell on which the MS has camped, according to the
1628 * algorithm of 3GPP TS 03.22, except that a zero value of
1629 * CELL_RESELECT_HYSTERESIS shall be used.
1630 */
1631
1632 if ((rr_data->ms_data.imsi_available) AND
1633 (rr_data->ms_data.rr_service NEQ LIMITED_SERVICE))
1634 delta -= 2*rr_data->nc_data[SC_INDEX].select_para.cell_resel_hyst;
1635
1636 /*
1637 * return the difference
1638 */
1639 return delta;
1640 }
1641
1642 /*
1643 +--------------------------------------------------------------------+
1644 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1645 | STATE : code ROUTINE : att_calculate_digits |
1646 +--------------------------------------------------------------------+
1647
1648 PURPOSE : The function calculates the number of the digits in a
1649 mobile identity infoelement. The input parameter contains
1650 one BCD digit in each field entry.
1651
1652 */
1653
1654 static UBYTE att_calculate_digits (UBYTE *digits)
1655 {
1656 UBYTE i = 0;
1657
1658 TRACE_FUNCTION ("att_calculate_digits()");
1659
1660 /*
1661 * Check whether the end is detected
1662 */
1663 while (digits[i] < 0x0A AND i < 16)
1664 i++;
1665
1666 return i;
1667 }
1668
1669
1670
1671
1672
1673 /*
1674 +--------------------------------------------------------------------+
1675 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1676 | STATE : code ROUTINE : att_cell_barred_status_cr_no_cr |
1677 +--------------------------------------------------------------------+
1678
1679 PURPOSE : Checks whether a cell is barred or not for cell reselection
1680 purposes.
1681
1682 CELL_BAR QUALIFY CELL_BAR ACCESS CS priority Status for CR
1683 0 0 normal normal
1684 0 1 barred barred
1685 1 0 low normal (see note 2)
1686 1 1 low normal (see note 2)
1687
1688 If all the following conditions are met, then the "Cell selection priority"
1689 and the "Status for cell reselection" shall be set to normal:
1690
1691 - the cell belongs to the MS HPLMN;
1692 - the MS is in cell test operation mode;
1693 - the CELL_BAR_ACCESS is set to "1";
1694 - the CELL_BAR_QUALIFY is set to "0";
1695 - the Access Control class 15 is barred.
1696
1697 NOTE 1: A low priority cell is only selected if there are no
1698 suitable cells
1699 of normal priority (see GSM 03.22).
1700 NOTE 2: Two identical semantics are used for cross phase
1701 compatibility reasons.
1702 This allows an operator to declare a cell always as a low
1703 priority one for a phase 2 MS, but keeps the opportunity
1704 for an operator to decide wether a phase 1 MS is permitted
1705 to camp on such a cell or not.
1706
1707 REFERENCE: GSM 5.08, chapter 9, table 1a
1708
1709
1710 */
1711 GLOBAL BOOL att_cell_barred_status_cr_no_cr (UBYTE index)
1712 {
1713 GET_INSTANCE_DATA;
1714
1715 TRACE_FUNCTION ("att_cell_barred_status_cr_no_cr()");
1716
1717 TRACE_EVENT_P5 ("[%u]%u cbq=%u cba=%u access class=%04x",
1718 rr_data->nc_data[index].arfcn,
1719 index,
1720 rr_data->nc_data[index].c2_par.cbq,
1721 rr_data->nc_data[index].rach.cell_bar_access,
1722 rr_data->nc_data[index].rach.ac);
1723
1724 /*
1725 * check first the special case
1726 */
1727 if (dat_hplmn (rr_data->nc_data[index].lai.mcc,
1728 rr_data->nc_data[index].lai.mnc) AND
1729 rr_data->cell_test_operation AND
1730 rr_data->nc_data[index].c2_par.cbq EQ 0 AND
1731 rr_data->nc_data[index].rach.cell_bar_access EQ 1)
1732 {
1733 /*
1734 * access class 15 is set
1735 */
1736 if (rr_data->nc_data[index].rach.ac & 0x8000)
1737 return FALSE;
1738 }
1739
1740 /*
1741 * the cell reselection status is normal. According
1742 * to the table above the cell is only barred if
1743 * the cell bar qualifier is set to 0 and the
1744 * cell bar access is set to 1.
1745 */
1746 if((rr_data->nc_data[index].rach.cell_bar_access EQ BARRED_YES) AND
1747 rr_data->nc_data[index].c2_par.cbq EQ CBQ_NO)
1748 return TRUE;
1749 else
1750 return FALSE;
1751
1752
1753 }
1754
1755
1756 /*
1757 +--------------------------------------------------------------------+
1758 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1759 | STATE : code ROUTINE : att_cell_in_data_structures|
1760 +--------------------------------------------------------------------+
1761
1762 PURPOSE : After reception of new measurement values from layer 1
1763 this function checks whether a neighbourcell indicated
1764 with the parameter index is stored inside the RR
1765 storage area.
1766
1767 */
1768
1769 static BOOL att_cell_in_data_structures (T_MPH_MEASUREMENT_IND *report,
1770 UBYTE index)
1771 {
1772 GET_INSTANCE_DATA;
1773 USHORT i;
1774
1775 TRACE_FUNCTION ("att_cell_in_data_structures()");
1776
1777 /*
1778 * check for all areas
1779 */
1780 for (i = 0; i < 6; i++)
1781 {
1782 /*
1783 * If a cell is stored in the data area
1784 */
1785 if (rr_data->nc_data[i].bcch_status NEQ EMPTY)
1786 {
1787 /*
1788 * check the channel number
1789 */
1790 if (rr_data->nc_data[i].arfcn EQ report->ncells.arfcn[index])
1791 return TRUE;
1792 }
1793 }
1794 return FALSE;
1795 }
1796
1797 /*
1798 +--------------------------------------------------------------------+
1799 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1800 | STATE : code ROUTINE : att_remove_multiple_channels |
1801 +--------------------------------------------------------------------+
1802
1803 PURPOSE : During fieldtests it had happens that the measurements from
1804 layer 1 may contain the serving cell as a neighbourcell
1805 (which is possible during connection and can be forwarded
1806 to RR after connection). This leads to double stored data
1807 in RR.
1808
1809 */
1810
1811 GLOBAL void att_remove_multiple_channels (void)
1812 {
1813 GET_INSTANCE_DATA;
1814 USHORT i;
1815
1816 TRACE_FUNCTION ("att_remove_multiple_channels()");
1817
1818 /*
1819 * For all neighbourcells in the measurement report
1820 */
1821 for (i = 0; i < 6; i++)
1822 {
1823 if (rr_data->nc_data[i].arfcn EQ rr_data->nc_data[SC_INDEX].arfcn)
1824 {
1825 /*
1826 * If the neighbourcell channel number is equal to the serving
1827 * cell, clear the whole storage area.
1828 */
1829 rr_data->nc_data[i].arfcn = 0;
1830 rr_data->nc_data[i].bcch_status = EMPTY;
1831 }
1832 }
1833 }
1834
1835
1836 /*
1837 +--------------------------------------------------------------------+
1838 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1839 | STATE : code ROUTINE : att_cell_in_measure_report |
1840 +--------------------------------------------------------------------+
1841
1842 PURPOSE : The function checks whether a cell in the RR storage
1843 area is still in a new measurement report and returns
1844 one of the three possibilities:
1845
1846 CELL_IS_INSERTED the cell is inside with the same BSIC
1847 BSIC_HAS_CHANGED the cell is inside, but the BSIC has changed
1848 CELL_IS_NOT_INSERTED the cell is not longer inside.
1849
1850 */
1851
1852 static UBYTE att_cell_in_measure_report (T_MPH_MEASUREMENT_IND *report,
1853 UBYTE index)
1854 {
1855 GET_INSTANCE_DATA;
1856 UBYTE i;
1857 UBYTE bsic;
1858
1859 TRACE_FUNCTION ("att_cell_in_measure_report()");
1860
1861 /*
1862 * check all neighbourcells in the measurent report
1863 */
1864 for (i = 0; i < report->ncells.no_of_ncells; i++)
1865 {
1866 /*
1867 * Check first the channel number
1868 */
1869 if (rr_data->nc_data[index].arfcn EQ report->ncells.arfcn[i])
1870 {
1871 /*
1872 * Update fieldstrength value in the RR storage area
1873 */
1874 rr_data->nc_data[index].rxlev = report->ncells.rx_lev[i];
1875
1876 /*
1877 * Check whether the BSIC has been changed. Layer 1 sends an
1878 * 8 bit value, but only the lower 6 bits are significant.
1879 */
1880 bsic = rr_data->nc_data[index].bsic & 0x3F;
1881 if (bsic EQ (report->ncells.bsic[i] & 0x3F))
1882 return CELL_IS_INSERTED;
1883 else
1884 {
1885 /*
1886 * If it is a changed BSIC, update the value in the RR storage area.
1887 */
1888 rr_data->nc_data[index].bsic = report->ncells.bsic[i] & 0x3F;
1889 return BSIC_HAS_CHANGED;
1890 }
1891 }
1892 }
1893 /*
1894 * Not found
1895 */
1896 return CELL_IS_NOT_INSERTED;
1897 }
1898
1899 /*
1900 +--------------------------------------------------------------------+
1901 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1902 | STATE : code ROUTINE : att_check_bcch_carrier_cco |
1903 +--------------------------------------------------------------------+
1904
1905 PURPOSE : During a Cell Change Order procedure:
1906 After reception of all needed system information messages
1907 a carrier is checked for cell selection purposes.
1908
1909 */
1910
1911 #ifdef GPRS
1912 LOCAL void att_check_bcch_carrier_cco (void)
1913 {
1914 GET_INSTANCE_DATA;
1915 TRACE_FUNCTION ("att_check_bcch_carrier_cco()");
1916
1917 dat_rrgrr_data_ind (rr_data->gprs_data.dl_data_ind);
1918 rr_data->gprs_data.dl_data_ind = NULL;
1919 att_build_idle_req (CR_INDEX, MODE_CELL_SELECTION);
1920 SET_STATE (STATE_ATT, ATT_IDLE);
1921 dat_att_cell_selected();
1922 if (att_gprs_is_avail())
1923 {
1924 att_signal_gprs_support();
1925 }
1926 att_start_registration_timer ();
1927 }
1928 #endif
1929
1930 /*
1931 +--------------------------------------------------------------------+
1932 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1933 | STATE : code ROUTINE : att_check_bcch_carrier_si |
1934 +--------------------------------------------------------------------+
1935
1936 PURPOSE : After reception of all needed system information messages
1937 a carrier is checked for cell selection purposes.
1938 Perform the check on the presence of the SIs.
1939
1940 */
1941
1942 GLOBAL void att_check_bcch_carrier_si (void)
1943 {
1944 GET_INSTANCE_DATA;
1945 if (rr_data->cr_data.cd.sys_info_read EQ ALL_SYS_INFO_READ)
1946 {
1947 att_check_bcch_carrier ();
1948 }
1949 }
1950
1951 GLOBAL void att_store_plmn_in_found_list (T_loc_area_ident *lai)
1952 {
1953 GET_INSTANCE_DATA;
1954 T_FOUND_ELEMENT *found;
1955
1956 /* Implements RR Clone findings #8 */
1957 BOOL cell_ok = !att_cell_barred_status_cr_no_cr(CR_INDEX) AND
1958 (rr_data->nc_data[CR_INDEX].c1 > 0) AND
1959 att_priority_check ();
1960
1961
1962
1963 if ( (found = att_plmn_in_found_list (lai->mcc, lai->mnc)) NEQ NULL )
1964 {
1965 if ( found->cell_ok EQ 0 AND /* old cell did not allow access */
1966 cell_ok NEQ 0 ) /* new cell does allow access */
1967 {
1968 ; /* a better cell has been found */
1969 }
1970 else
1971 {
1972 found = NULL;
1973 }
1974 }
1975 else
1976 if ( rr_data->sc_data.found_entries < MAX_PLMN AND att_check_network(lai) )
1977 {
1978 found = &rr_data->sc_data.found[rr_data->sc_data.found_entries];
1979 rr_data->sc_data.found_entries++;
1980 }
1981 else
1982 {
1983 TRACE_EVENT ("cannot store PLMN" );
1984 }
1985
1986 if ( found )
1987 {
1988 att_save_found_plmn (
1989 found,
1990 lai->mcc, lai->mnc,
1991 rr_data->nc_data[CR_INDEX].arfcn,
1992 rr_data->nc_data[CR_INDEX].rxlev, lai->lac, (UBYTE)cell_ok);
1993 }
1994 }
1995 /*
1996 +--------------------------------------------------------------------+
1997 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
1998 | STATE : code ROUTINE : att_check_bcch_carrier |
1999 +--------------------------------------------------------------------+
2000
2001 PURPOSE : After reception of all needed system information messages
2002 a carrier is checked for cell selection purposes.
2003
2004 */
2005
2006 GLOBAL void att_check_bcch_carrier (void)
2007 {
2008 GET_INSTANCE_DATA;
2009 T_loc_area_ident * lai;
2010 BOOL plmn_ok = FALSE;
2011 BOOL cell_ok,prio_ok;
2012 UBYTE tried_to_reach_full_try_limited = (rr_data->cs_data.scan_mode EQ CS_SECOND_SCAN);
2013
2014 TRACE_FUNCTION ("att_check_bcch_carrier()");
2015
2016 /*
2017 * stop the timer which controls the reception of
2018 * all system information messages during cell selection.
2019 */
2020 TIMERSTOP (T_RESELECT);
2021
2022 /*
2023 * If procedure RR Network Controlled Cell Change Order
2024 * is running then call a different function and return.
2025 */
2026 #ifdef GPRS
2027 if ( rr_data->gprs_data.tbf_est EQ TBF_EST_CCO )
2028 {
2029 att_check_bcch_carrier_cco();
2030 return;
2031 }
2032 #endif
2033
2034 lai = &rr_data->nc_data[CR_INDEX].lai;
2035
2036 /*
2037 * calculate the path loss criterion
2038 */
2039 att_calculate_c1 (CR_INDEX);
2040 TRACE_C1(CR_INDEX);
2041
2042 /*
2043 * the check depends on the service which has been requested
2044 * by RR. This can be the same as the service requested by MM,
2045 */
2046 switch (rr_data->ms_data.req_mm_service)
2047 {
2048 case FUNC_PLMN_SRCH:
2049 /*
2050 * For full service the mobile country code and the mobile network code
2051 * must match with the PLMN identification requested by MM.
2052 */
2053 plmn_ok = dat_plmn_equal_req (lai->mcc,
2054 lai->mnc,
2055 rr_data->ms_data.plmn.mcc,
2056 rr_data->ms_data.plmn.mnc);
2057
2058 TRACE_EVENT_P6 ( "MCC/MNC r=%x%x%x/%x%x%x",
2059 rr_data->ms_data.plmn.mcc[0],
2060 rr_data->ms_data.plmn.mcc[1],
2061 rr_data->ms_data.plmn.mcc[2],
2062 rr_data->ms_data.plmn.mnc[0],
2063 rr_data->ms_data.plmn.mnc[1],
2064 rr_data->ms_data.plmn.mnc[2]);
2065 TRACE_EVENT_P7 ( "MCC/MNC i=%x%x%x/%x%x%x %s",
2066 lai->mcc[0],
2067 lai->mcc[1],
2068 lai->mcc[2],
2069 lai->mnc[0],
2070 lai->mnc[1],
2071 lai->mnc[2],
2072 plmn_ok?"OK":"");
2073
2074
2075 if (!plmn_ok AND
2076 (GET_STATE(STATE_ATT) EQ ATT_CS2) AND
2077 (rr_data->ms_data.rr_service EQ LIMITED_SERVICE OR
2078 rr_data->ms_data.rr_service EQ NO_SERVICE) AND
2079 (rr_data->cs_data.check_hplmn EQ TRUE) AND
2080 (((rr_data->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1) EQ M_AUTO))
2081 {
2082 /* Compare with HPLMN */
2083 if (rr_data->ms_data.imsi_available)
2084 {
2085 plmn_ok = dat_plmn_equal_req (lai->mcc,
2086 lai->mnc,
2087 &rr_data->ms_data.imsi.ident_dig[0],
2088 &rr_data->ms_data.imsi.ident_dig[3]);
2089 if (plmn_ok)
2090 {
2091 TRACE_EVENT ("HPLMN Matched");
2092 }
2093 }
2094 /* compare with AHPLMN */
2095 if(!plmn_ok AND rr_data->ms_data.ahplmn.v_plmn EQ TRUE)
2096 {
2097 plmn_ok = dat_plmn_equal_req (lai->mcc,
2098 lai->mnc,
2099 rr_data->ms_data.ahplmn.mcc,
2100 rr_data->ms_data.ahplmn.mnc);
2101 if (plmn_ok)
2102 {
2103 TRACE_EVENT ("AHPLMN Matched");
2104 }
2105 }
2106 /* Compare with LRPLMN */
2107 if (!plmn_ok AND rr_data->cs_data.last_reg_plmn.v_plmn EQ V_PLMN_PRES)
2108 {
2109 plmn_ok = dat_plmn_equal_req (lai->mcc,
2110 lai->mnc,
2111 rr_data->cs_data.last_reg_plmn.mcc,
2112 rr_data->cs_data.last_reg_plmn.mnc);
2113 if (plmn_ok)
2114 {
2115 TRACE_EVENT ("LRPLMN Matched");
2116 }
2117 }
2118 /* Compare with Last Serving Cell PLMN from White List */
2119 if ((!plmn_ok) AND (rr_data->sc_data.mm_started EQ RR_ORIGINATED) AND
2120 (rr_data->ms_data.plmn.v_plmn EQ V_PLMN_PRES))
2121 {
2122 plmn_ok = dat_plmn_equal_req (lai->mcc,
2123 lai->mnc,
2124 rr_data->cs_data.white_list.last_sc_lac.mcc,
2125 rr_data->cs_data.white_list.last_sc_lac.mnc);
2126 if (plmn_ok)
2127 {
2128 TRACE_EVENT ("White List PLMN Matched");
2129 }
2130 }
2131 }
2132
2133 if (plmn_ok)
2134 tried_to_reach_full_try_limited = FALSE;
2135 /*lint -fallthrough*/
2136
2137 case FUNC_LIM_SERV_ST_SRCH:
2138 if((rr_data->ms_data.req_mm_service EQ FUNC_LIM_SERV_ST_SRCH) OR
2139 tried_to_reach_full_try_limited)
2140 {
2141 /*
2142 * The mobile shall reach limited service. This is the case
2143 * if no full service is possible or no SIM card is inserted.
2144 *
2145 * The network check is in principle ever true. The function
2146 * att_check_network realises a SW shielding to reject public
2147 * networks in final type approvals.
2148 *
2149 * The criterion for the cell checking is a non-barred cell and
2150 * a positive path loss criterion.
2151 */
2152 plmn_ok = att_check_network (lai);
2153 /* Implements RR Clone findings #8 */
2154 cell_ok = !att_cell_barred_status_cr_no_cr (CR_INDEX) AND
2155 (rr_data->nc_data[CR_INDEX].c1 > 0);
2156
2157 }
2158 else
2159 {
2160 /*
2161 * Full service is requested.
2162 *
2163 * First store PLMN of the cell in the PLMN found list
2164 * if the list is not stored yet and not full. SW shielding
2165 * is taking into account for FTA purposes.
2166 *
2167 * If the cell selection fails and no carrier was suitable,
2168 * at least a list of the found channels is available.
2169 */
2170 if(dat_forb_lai_check (CR_INDEX))
2171 {
2172 att_store_plmn_in_found_list (lai);
2173 }
2174 else
2175 {
2176 TRACE_EVENT ("Do not store Forbidden LAI PLMN in the found PLMN list");
2177 }
2178
2179 /*
2180 * The requirements for the cell are: it must be a non-barred cell,
2181 * it must have a positive path loss criterion. The cell shall not
2182 * be inside of a forbidden location area and it must be a high priority
2183 * cell if it is the first scan first attempt.
2184 */
2185 /* Implements RR Clone findings #8 */
2186 cell_ok = !att_cell_barred_status_cr_no_cr (CR_INDEX) AND
2187 (rr_data->nc_data[CR_INDEX].c1 > 0);
2188
2189
2190 prio_ok = att_priority_check ();
2191
2192 TRACE_EVENT_P1 ( "cell_ok = %d", cell_ok);
2193
2194 TRACE_EVENT_P1 ( "prio_ok = %d", prio_ok);
2195 /*
2196 * if the network and cell are okay, but the priority check fails,
2197 * this cell is a low priority cell and can be checked in the
2198 * first scan second attempt.
2199 */
2200 if (plmn_ok AND cell_ok AND !prio_ok)
2201 cs_set_attributes (LOW_PRIORITY_CELL,
2202 rr_data->nc_data[CR_INDEX].arfcn);
2203
2204 /*
2205 * if the bcch carrier is not suitable for full service,
2206 * but suitable for limited service, try it
2207 * for emergency services in the second attempt.
2208 * priority check is not required for emergency cells
2209 */
2210 if (cell_ok AND !plmn_ok)
2211 cs_set_attributes (EMERGENCY_CELL,
2212 rr_data->nc_data[CR_INDEX].arfcn);
2213
2214 /* Update the cell_ok flag with with priority check flag */
2215 if(cell_ok)
2216 cell_ok = prio_ok;
2217
2218 /* Checking access class and the list for cause #12 for */
2219 /* selection of the cell to camp on may not meet the */
2220 /* requirements of GSM 03.22 subclause 3.5.3, 3.5.4. */
2221 /* However, it is perfectly correct to consider the */
2222 /* forbidden location areas for roaming list here. */
2223
2224
2225 /*
2226 * If cell selection has been launched by MM in manual mode
2227 * we don't check against the forbidden location area lists.
2228 * This is to allow the user to select a network manually
2229 * which is a member of a forbidden list.
2230 * Maybe the distinction manual/automatic is not worth the
2231 * effort, as in contradiction to the forbidden list for
2232 * cause #11 the user can get rid of the forbidden lists for
2233 * cause #12 and #13 either by a power cycle or by simply
2234 * waiting some hours.
2235 */
2236 if (!rr_data->sc_data.mm_started OR
2237 ((rr_data->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1) EQ M_AUTO)
2238 {
2239 /*
2240 * RR started cell selection, or MM started but in automatic
2241 * so ensure no barred LA is entered.
2242 */
2243 if (cell_ok)
2244 {
2245 cell_ok = (dat_forb_lai_check (CR_INDEX) AND
2246 dat_roam_forb_lai_check (CR_INDEX));
2247
2248 /* Candidate for Limited service */
2249 if(!cell_ok)
2250 cs_set_attributes (EMERGENCY_CELL,
2251 rr_data->nc_data[CR_INDEX].arfcn);
2252 }
2253 }
2254
2255 #if defined (_SIMULATION_)
2256 {
2257 /*
2258 * Trace output for cell selection analysis
2259 */
2260 /* Implements RR Clone findings #8 */
2261 BOOL cb_stat = att_cell_barred_status_cr_no_cr (CR_INDEX);
2262
2263 BOOL for_lai = dat_forb_lai_check (CR_INDEX);
2264 BOOL prio = att_priority_check();
2265 TRACE_EVENT_WIN_P1 ( "CB_STAT = %d", cb_stat);
2266 TRACE_EVENT_WIN_P1 ( "C1 = %d", rr_data->nc_data[CR_INDEX].c1);
2267 TRACE_EVENT_WIN_P1 ( "FOR_LAI = %d", for_lai);
2268 TRACE_EVENT_WIN_P1 ( "PRIO = %d", prio);
2269 }
2270 #endif /* _SIMULATION_ */
2271 }
2272 break;
2273
2274 default:
2275 /*
2276 * MM has requested the list of the available PLMNs. The algorithm
2277 * for this is to indicate all carriers as "not suitable" for cell
2278 * selection. As a result the list of the available PLMNs is build
2279 * after scanning all carriers.
2280 *
2281 * First step is to store PLMN in plmn found list if the PLMN is not
2282 * stored yet and the list is not full. SW shielding is used for
2283 * FTA purposes.
2284 */
2285 att_store_plmn_in_found_list (lai);
2286
2287 /*
2288 * Define the channel as a candidate for limited service.
2289 */
2290 cs_set_attributes (EMERGENCY_CELL,
2291 rr_data->nc_data[CR_INDEX].arfcn);
2292
2293 /*
2294 * Remove all channels of the neighbourcell list from the power campaign
2295 * list. If the configuration of the network is sensible, this cell will
2296 * contain also channels of the same network. So it is not necessary to
2297 * scan this channels. The available PLMN list is the same, it consumes
2298 * only time.
2299 */
2300 cs_del_list (&rr_data->cr_data.cd.ncell_list);
2301 plmn_ok = FALSE;
2302 cell_ok = FALSE;
2303
2304 /*
2305 * start synchronisation attempt to the next cell
2306 */
2307 memset (&rr_data->nc_data[CR_INDEX], 0, sizeof (T_NC_DATA));
2308
2309 if (rr_data->ms_data.rr_service EQ NO_SERVICE)
2310 {
2311 SET_STATE (STATE_ATT, ATT_CS1);
2312 }
2313 srv_clear_list (&rr_data->cr_data.cd.ncell_list);
2314 cs_sync_next ();
2315 return;
2316 }
2317
2318 if( (!tried_to_reach_full_try_limited) AND (rr_data->cs_data.scan_mode EQ CS_SECOND_SCAN))
2319 {
2320 if(!cell_ok)
2321 {
2322 /*
2323 * plmn is OK, cell is not OK for full service
2324 * however cell may be OK for limited service
2325 */
2326 tried_to_reach_full_try_limited = TRUE;
2327 /* Implements RR Clone findings #8 */
2328 cell_ok = !att_cell_barred_status_cr_no_cr (CR_INDEX) AND
2329 (rr_data->nc_data[CR_INDEX].c1 > 0);
2330
2331 }
2332 }
2333
2334 /*
2335 * Trace output for cell selection analysis
2336 */
2337 TRACE_EVENT_P1 ( "req.service = %s", _rr_str_FUNC[rr_data->ms_data.req_mm_service]);
2338 TRACE_EVENT_P1 ( "plmn_ok = %d", plmn_ok );
2339 TRACE_EVENT_P1 ( "cell_ok = %d", cell_ok);
2340
2341 /*
2342 * checking of the requirements has been done. The result
2343 * is defined by plmn_ok and cell_ok.
2344 */
2345 if (plmn_ok AND cell_ok)
2346 {
2347 /*
2348 * Network and Cell are okay. Just use the cell
2349 * set RR service according to the checked service
2350 */
2351 /* If the MS reselects back onto the same SC and T3122 is still running, it should */
2352 /* be left running. If a new cell is selected, this timer should be stopped. */
2353
2354 if( rr_data->nc_data[SC_INDEX].arfcn NEQ rr_data->nc_data[CR_INDEX].arfcn)
2355 {
2356 TIMERSTOP(T3122);
2357 }
2358
2359 if (rr_data->ms_data.req_mm_service EQ FUNC_LIM_SERV_ST_SRCH OR
2360 (tried_to_reach_full_try_limited))
2361 {
2362 rr_data->ms_data.rr_service = LIMITED_SERVICE;
2363 }
2364 else
2365 {
2366 rr_data->ms_data.rr_service = FULL_SERVICE;
2367 }
2368
2369 TRACE_EVENT_P4 ("NEW SC [%d]->[%d] (rMM=%s RRs=%s)",
2370 rr_data->nc_data[SC_INDEX].arfcn,
2371 rr_data->nc_data[CR_INDEX].arfcn,
2372 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
2373 _rr_str_SERVICE[rr_data->ms_data.rr_service]);
2374
2375 /*
2376 * set the result in the CR_INDEX area and copy then all
2377 * stuff to the SC_INDEX area.
2378 */
2379 rr_data->nc_data[CR_INDEX].bcch_status = DECODED;
2380 rr_data->nc_data[CR_INDEX].bcch_counter = 0;
2381 rr_data->nc_data[CR_INDEX].c1_counter = 0;
2382 att_copy_cr_data ();
2383 memcpy (&rr_data->sc_data.cd, &rr_data->cr_data.cd,
2384 sizeof (T_CELL_DATA));
2385 rr_data->nc_data[CR_INDEX].arfcn = NOT_PRESENT_16BIT;
2386 #if defined (REL99) && defined (TI_PS_FF_EMR)
2387 rr_data->sc_data.ba_index = rr_data->cr_data.ba_index;
2388 rr_data->cr_data.ba_index = NOT_PRESENT_8BIT;
2389 #endif
2390
2391 /* CSI-LLD section:4.1.1.10
2392 * This function updates the black list after the first successful
2393 * FUNC_PLMN_SEARCH
2394 */
2395 if(rr_data->cs_data.initial_plmn_search EQ INITIAL_PLMN_SEARCH_ACTIVE)
2396 {
2397 cs_update_black_list();
2398 rr_data->cs_data.initial_plmn_search = INITIAL_PLMN_SEARCH_DONE;
2399 }
2400
2401 /* Full service reached. Perform all necessary tasks */
2402 if(rr_data->ms_data.rr_service EQ FULL_SERVICE)
2403 {
2404 att_full_service_found();
2405 }
2406
2407 /*
2408 * Indicate the result of cell selection to MM
2409 */
2410 if (tried_to_reach_full_try_limited)
2411 {
2412 /*
2413 * The result is not what MM has requested.
2414 * E.g. MM has requested full service, but RR has
2415 * reached only limited service. In this case
2416 * MM gets the list of the available PLMNs and may
2417 * select on of the networks for a new attempt in
2418 * case of automatic registration.
2419 */
2420 att_copy_old_lai_rac(CR_INDEX);
2421 #if 0
2422 memcpy (&rr_data->old_lai, &rr_data->nc_data[CR_INDEX].lai,
2423 sizeof(T_loc_area_ident));
2424 rr_data->old_cell_id = rr_data->nc_data[CR_INDEX].cell_id;
2425 #endif
2426
2427 #ifdef GPRS
2428 if(att_gprs_is_avail())
2429 { /* we have GPRS and have reached limited service */
2430 cs_set_stop_active();
2431 if(att_gprs_cell_has_pbcch())
2432 {
2433 att_gprs_stop_pl();
2434 }
2435 else
2436 {
2437 att_set_pl_in_idle_mode ();
2438 }
2439 att_signal_gprs_support();
2440 /* and wait for CR_REQ(CR_COMPLETE) from GRR */
2441 }
2442 else
2443 {
2444 #endif
2445 /*
2446 * Configure layer 1
2447 */
2448 att_set_pl_in_idle_mode ();
2449
2450 /*
2451 * Indicated the data transfer process that the MS is attached.
2452 */
2453 dat_att_cell_selected ();
2454
2455 SET_STATE (STATE_ATT, ATT_IDLE);
2456 cs_set_stop_active();
2457
2458 att_code_rr_abort_ind (RRCS_ABORT_CEL_SEL_FAIL);
2459 att_start_registration_timer ();
2460 att_mph_identity_req ();
2461 srv_use_stored_prim ();
2462 #ifdef GPRS
2463 }
2464 #endif
2465
2466 }
2467 else
2468 {
2469 /*
2470 * the cell selection was successful. The counter
2471 * for failed registration attempts is resetted and
2472 * MM is informed.
2473 */
2474
2475 rr_data->ms_data.reg_counter = 0;
2476 #ifdef GPRS
2477 if(! att_gprs_is_avail())
2478 {
2479 #endif
2480
2481 /*
2482 * Configure layer 1
2483 */
2484 att_set_pl_in_idle_mode ();
2485 /*
2486 * Indicated the data transfer process that the MS is attached.
2487 */
2488 dat_att_cell_selected ();
2489 SET_STATE (STATE_ATT, ATT_IDLE);
2490 cs_set_stop_active();
2491
2492 /* inform GRR if we have GPRS support */
2493 #ifdef GPRS
2494 if(att_gprs_is_avail())
2495 {
2496 att_signal_gprs_support();
2497 }
2498 #endif
2499 /* Inform MM */
2500 if (rr_data->sc_data.mm_started)
2501 att_code_rr_act_cnf ();
2502 else
2503 att_code_rr_act_ind ();
2504
2505 srv_use_stored_prim ();
2506 att_start_registration_timer ();
2507 att_mph_identity_req ();
2508
2509 #ifdef GPRS
2510 }
2511 else
2512 { /* we have GPRS and have reached full service */
2513 cs_set_stop_active();
2514 if(att_gprs_cell_has_pbcch())
2515 {
2516 att_gprs_stop_pl();
2517 }
2518 else
2519 {
2520 att_set_pl_in_idle_mode ();
2521 }
2522 att_signal_gprs_support();
2523 /* and wait for CR_REQ(CR_COMPLETE) from GRR */
2524 }
2525 #endif
2526 /* This flag will help to identify whether cell reselection following
2527 * TRESELECT expiry waiting for SI2TER is successfull or not
2528 */
2529 rr_data->cr_treselect_exp = TRUE;
2530 }
2531 return;
2532 }
2533
2534 /*
2535 * BCCH carrier check has failed
2536 * Either cell_ok or plmn_ok is FALSE or both.
2537 */
2538
2539 if(plmn_ok EQ FALSE)
2540 {
2541 /*
2542 * PLMN is not okay, but the cell
2543 */
2544 if (rr_data->ms_data.imsi_available AND
2545 (dat_test_sim_available () EQ FALSE))
2546 {
2547 /*
2548 * with SIM card, that means full service.
2549 * "delete neighbourcells", that means give all
2550 * neighbourcells a low priority in scanning.
2551 *
2552 * It is assumed that this cell will fail also
2553 * because they are also member of the wrong network.
2554 *
2555 * This is not done during FTA campaign.
2556 */
2557 cs_del_list (&rr_data->cr_data.cd.ncell_list);
2558 }
2559 }
2560
2561 if(plmn_ok AND
2562 cell_ok EQ FALSE)
2563 {
2564 /*
2565 * plmn okay but not the cell
2566 */
2567 if (rr_data->ms_data.imsi_available AND
2568 dat_test_sim_available() EQ FALSE)
2569 {
2570 /*
2571 * with SIM card, that means full service.
2572 * "set neighbourcells", that means give all
2573 * neighbourcells a higher priority in scanning.
2574 * Not done during FTA campaign
2575 */
2576 cs_set_list (&rr_data->cr_data.cd.ncell_list);
2577 }
2578 }
2579
2580 /*
2581 * start synchronisation attempt to the next cell
2582 */
2583 memset (&rr_data->nc_data[CR_INDEX], 0, sizeof (T_NC_DATA));
2584
2585 /*
2586 * After BCCH Reading if the requested service is not found,
2587 * before sending BSIC_REQ RR has to be moved to ATT_CS1.
2588 */
2589
2590 if(rr_data->ms_data.rr_service EQ NO_SERVICE OR
2591 GET_STATE(STATE_ATT) EQ ATT_CS2)
2592 {
2593 SET_STATE (STATE_ATT, ATT_CS1);
2594 }
2595
2596 srv_clear_list (&rr_data->cr_data.cd.ncell_list);
2597 #ifdef GPRS
2598 if(GET_STATE(STATE_ATT) NEQ ATT_IDLE)
2599 gprs_init_data_cr();
2600 #endif
2601 cs_sync_next ();
2602 }
2603
2604 /*
2605 +--------------------------------------------------------------------+
2606 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
2607 | STATE : code ROUTINE : att_check_fplmn_cell |
2608 +--------------------------------------------------------------------+
2609
2610 PURPOSE : If the mobile is in limited service, but MM has requested
2611 full service, RR starts after timeout of the registration
2612 timer new attempts to reach full service. After reading
2613 system information message 3 or 4 of the candidate, this
2614 function is called, to check whether the cell fullfills
2615 the requirements for a full service cell. In this case
2616 a cell reselection is started to read the whole BCCH to
2617 configure layer 1.
2618
2619 */
2620
2621 GLOBAL void att_check_fplmn_cell (void)
2622 {
2623 GET_INSTANCE_DATA;
2624 UBYTE cell_ok;
2625 UBYTE plmn_ok;
2626 T_loc_area_ident * lai = &rr_data->nc_data[CR_INDEX].lai;
2627
2628 TRACE_FUNCTION ("att_check_fplmn_cell()");
2629
2630 /*
2631 * Calculate the path loss criterion
2632 */
2633 att_calculate_c1 (CR_INDEX);
2634 TRACE_C1(CR_INDEX);
2635
2636 /*
2637 * check that the cell is not barred and has a positive path loss
2638 * criterion.
2639 */
2640 /* Implements RR Clone findings #8 */
2641 cell_ok = (!att_cell_barred_status_cr_no_cr (CR_INDEX) AND
2642 (rr_data->nc_data[CR_INDEX].c1 > 0)AND dat_roam_forb_lai_check (CR_INDEX));
2643 ;
2644
2645 /*
2646 * check whether the PLMN identification is equal to the PLMN which has
2647 * been requested by MM.
2648 */
2649 plmn_ok = dat_plmn_equal_req (lai->mcc,
2650 lai->mnc,
2651 rr_data->ms_data.plmn.mcc,
2652 rr_data->ms_data.plmn.mnc);
2653
2654 /*
2655 * stop of T_RESELECT. This timer controls the reception of the initial
2656 * system information message.
2657 */
2658 TIMERSTOP (T_RESELECT);
2659
2660 /*
2661 * store PLMN in plmn found list to provide this information to MM
2662 * at the end of a failed registration attempt.
2663 */
2664 if(dat_forb_lai_check (CR_INDEX))
2665 {
2666 att_store_plmn_in_found_list (lai);
2667 }
2668 else
2669 {
2670 TRACE_EVENT ("Do not store Forbidden LAI PLMN in the found PLMN list");
2671 }
2672
2673 if (plmn_ok)
2674 {
2675 if (cell_ok)
2676 {
2677 /*
2678 * Enable nc monitoring to resume in lower layer
2679 * when recovering full service
2680 */
2681 att_notify_stop_plmn_search (FALSE);
2682
2683 /*
2684 * cell and PLMN are okay, then start cell reselection to read
2685 * the complete BCCH to configure layer 1.
2686 */
2687 /*XY:n inform GRR, and wait for CR_RSP */
2688 #ifdef GPRS
2689 att_start_cell_reselection_gprs (CELL_RESELECTION_CR);
2690 #else
2691 att_start_cell_reselection (CELL_RESELECTION_CR);
2692 #endif
2693 return;
2694 }
2695 }
2696
2697 if (cell_ok)
2698 {
2699 /*
2700 * PLMN is not okay, but the cell
2701 *
2702 * "delete neighbourcells", that means give all
2703 * neighbourcells a low priority in scanning.
2704 */
2705 if (dat_test_sim_available () EQ FALSE)
2706 cs_del_list (&rr_data->cr_data.cd.ncell_list);
2707 }
2708 else
2709 {
2710 /*
2711 * PLMN okay but not the cell
2712 *
2713 * "set neighbourcells", that means give all
2714 * neighbourcells a higher priority in scanning.
2715 */
2716 if (dat_test_sim_available () EQ FALSE)
2717 {
2718 if (plmn_ok)
2719 /*
2720 * with SIM card, that means full service.
2721 * "set neighbourcells", that means give all
2722 * neighbourcells a higher priority in scanning.
2723 */
2724 cs_set_list (&rr_data->cr_data.cd.ncell_list);
2725 else
2726 /*
2727 * with SIM card, that means full service.
2728 * "delete neighbourcells", that means give all
2729 * neighbourcells a low priority in scanning.
2730 *
2731 * It is assumed that this cell will fail also
2732 * because they are also member of the wrong network.
2733 *
2734 * This is not done during FTA campaign.
2735 */
2736 cs_del_list (&rr_data->cr_data.cd.ncell_list);
2737 }
2738 }
2739
2740 /*
2741 * start synchronisation attempt to the next cell
2742 */
2743 memset (&rr_data->nc_data[CR_INDEX], 0, sizeof (T_NC_DATA));
2744 cs_sync_next ();
2745 }
2746
2747 /*
2748 +--------------------------------------------------------------------+
2749 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
2750 | STATE : code ROUTINE : att_check_cell |
2751 +--------------------------------------------------------------------+
2752
2753 PURPOSE : if a cell reselection decision has been taken, this function
2754 looks for a candidate for cell reselection taking in account
2755 several requirements. The reselect_index stores the index
2756 of the RR storage area for the neighbourcell. The return
2757 value indicates whether a cell has been found or not.
2758
2759 */
2760
2761 static BOOL att_check_cell (void)
2762 {
2763 GET_INSTANCE_DATA;
2764 BOOL cell_ok = FALSE;
2765
2766 TRACE_FUNCTION ("att_check_cell()");
2767
2768 /*
2769 * while no suitable candidate has been found,
2770 * but still possible cells available.
2771 */
2772 while (rr_data->reselect_index NEQ NO_AVAILABLE AND ! cell_ok)
2773 {
2774 /*
2775 * calculate the cell reselection criterion C2 for the candidate
2776 */
2777 att_calculate_c2 (rr_data->reselect_index);
2778
2779 /*
2780 * check the cell requirements:
2781 * 1. check the cell barred status (if shall be non-barred)
2782 * 2. the cell shall be not temporarily excluded (tnnn e.g. after random access
2783 * failure).
2784 * 3. the cell must have a positive cell reselection criterion C2.
2785 */
2786
2787 /* Implements RR Clone findings #8 */
2788 cell_ok = (! att_cell_barred_status_cr_no_cr (rr_data->reselect_index) AND
2789 ! is_tnnn (rr_data->reselect_index) AND
2790 rr_data->nc_data[rr_data->reselect_index].c2 > 0);
2791
2792 /*
2793 * Forbidden LA for roaming shall be tested there in case a C2-base cell
2794 * reselection has been triggered on a cell candidate belonging to a
2795 * valid LA but unsuccesfull. Then RR will continue cell reselection
2796 * with the next candidate that might be part of a forbidden LAC.
2797 * Should be trapped by att_check_neighbourcell() at the end of the
2798 * CS3 session... but it skips one CR and secures the process.
2799 * Question : should this test be bypassed if MM requested limited
2800 * service ??
2801 */
2802
2803 if (rr_data->ms_data.rr_service EQ FULL_SERVICE)
2804 {
2805 if (cell_ok)
2806 cell_ok = dat_roam_forb_lai_check (rr_data->reselect_index);
2807 }
2808
2809 if (cell_ok)
2810 {
2811 /*
2812 * suitable cell has been found
2813 */
2814 TRACE_EVENT ("use neighbour cell");
2815
2816 /*
2817 * after random access failure we found another cell,
2818 * that means, we will process a normal cell reselection
2819 * and will not come back directly to idle mode if the
2820 * cell reselection fails for the new cell.
2821 */
2822 if (rr_data->sc_data.selection_type EQ CELL_RESELECTION_RACH)
2823 {
2824 rr_data->sc_data.selection_type = CELL_RESELECTION;
2825 #ifdef GPRS
2826 rr_data->gprs_data.use_c31 = FALSE;
2827 #endif
2828 }
2829
2830 /*
2831 * configure layer 1 for cell reselection
2832 */
2833 TRACE_EVENT_P2 ("config L1 for CR [%d]->[%d]",
2834 rr_data->nc_data[SC_INDEX].arfcn,
2835 rr_data->nc_data[rr_data->reselect_index].arfcn);
2836
2837 #ifdef GPRS
2838 rr_data->gprs_data.ready_state = FALSE; /* Standby */
2839 #endif
2840
2841 att_start_cr_in_pl(rr_data->reselect_index);
2842 }
2843 else
2844 {
2845 /*
2846 * cell is not suitable. Look for another cell.
2847 */
2848 rr_data->reselect_index =
2849 att_get_next_highest_c2_idx (rr_data->reselect_index);
2850 }
2851 }
2852
2853 /*
2854 * return whether a cell has been found or not.
2855 */
2856 return cell_ok;
2857 }
2858
2859 /*
2860 +--------------------------------------------------------------------+
2861 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
2862 | STATE : code ROUTINE : att_clean_buf |
2863 +--------------------------------------------------------------------+
2864
2865 PURPOSE : trigger cleaning of the SI buffers indicated by si_to_clean
2866
2867 */
2868 void att_clean_buf (USHORT si_to_clean)
2869 {
2870 PALLOC(clean_buf, MPH_CLEAN_BUF_REQ);
2871 clean_buf->si_to_clean = si_to_clean;
2872 PSENDX(PL, clean_buf);
2873 }
2874 /*
2875 +--------------------------------------------------------------------+
2876 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
2877 | STATE : code ROUTINE : att_start_cr_in_pl |
2878 +--------------------------------------------------------------------+
2879
2880 PURPOSE : trigger CR in PL and init some necessary parameters
2881
2882 */
2883 void att_start_cr_in_pl(UBYTE index)
2884 {
2885 GET_INSTANCE_DATA;
2886 att_init_pl_status ();
2887 att_build_idle_req (index, MODE_CELL_RESELECTION);
2888
2889 /*
2890 * Clean the CR_INDEX storage area in RR to get the complete
2891 * BCCH of the new cell
2892 */
2893 att_init_cr_data();
2894 memcpy (&rr_data->nc_data[CR_INDEX],
2895 &rr_data->nc_data[index],
2896 sizeof (T_NC_DATA));
2897 srv_clear_list (&rr_data->cr_data.cd.ncell_list);
2898 SET_STATE (STATE_ATT, ATT_CS3);
2899 rr_data->bcch_error = 0;
2900 }
2901
2902 /*
2903 +--------------------------------------------------------------------+
2904 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
2905 | STATE : code ROUTINE : att_stop_dedicated |
2906 +--------------------------------------------------------------------+
2907
2908 PURPOSE : Send primitive MPH_STOP_DEDICATED_REQ
2909
2910 */
2911 GLOBAL void att_stop_dedicated(void)
2912 {
2913 PALLOC(mph_stop_dedi, MPH_STOP_DEDICATED_REQ);
2914 PSENDX(PL, mph_stop_dedi);
2915 }
2916
2917
2918 /*
2919 +--------------------------------------------------------------------+
2920 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
2921 | STATE : code ROUTINE : att_leave_dedicated |
2922 +--------------------------------------------------------------------+
2923
2924 PURPOSE : Decide if we do a CR or return to idle directly
2925
2926 */
2927 GLOBAL void att_leave_dedicated(void)
2928 {
2929 GET_INSTANCE_DATA;
2930 if (IS_TIMER_ACTIVE(T_DEDICATED_MODE))
2931 { /* spent less than 30 seconds in dedicated mode */
2932 TIMERSTOP(T_DEDICATED_MODE);
2933 }
2934 else
2935 { /* spent at least 30 seconds in dedicated mode */
2936 rr_data->mode_after_dedi = MODE_CELL_RESELECTION;
2937 }
2938
2939 if((rr_data->mode_after_dedi EQ MODE_CELL_SELECTION) AND
2940 (rr_data->sc_data.selection_type NEQ BACK_FROM_DEDICATED_RLF)) /*does not seem correct!!!*/
2941 {
2942 /*
2943 * go back directly to the old cell after dedicated
2944 * mode if we were in dedicated mode shorter than 30 seconds
2945 * and have not made a handover in dedicated mode
2946 */
2947 #ifdef GPRS
2948 if(GPRS_SUSPENDED_BCCH EQ GET_STATE(STATE_GPRS))
2949 {
2950 SET_STATE(STATE_GPRS,GPRS_PIM_BCCH);
2951 }
2952 else if(GPRS_SUSPENDED_PBCCH EQ GET_STATE(STATE_GPRS))
2953 {
2954 SET_STATE(STATE_GPRS,GPRS_PIM_PBCCH);
2955 }
2956 #endif
2957 att_return_to_idle();
2958
2959 /*
2960 * restore the neighbour cell list which was valid
2961 * in idle mode (derived from SI 2x)
2962 * Note: SI 5x may contain other neighbour cells than SI 2x
2963 */
2964 memcpy(&rr_data->sc_data.cd.ncell_list,
2965 &rr_data->sc_data.ncell_list_idle,
2966 sizeof(T_LIST));
2967
2968 /*
2969 * restore the sys_info_read bitmap if we are going
2970 * directly to idle
2971 */
2972 rr_data->sc_data.cd.sys_info_read = ALL_SYS_INFO_READ;
2973
2974 if (rr_data->repeat_est)
2975 {
2976 rr_data->repeat_est = FALSE;
2977 dat_start_immediate_assign (rr_data->ms_data.establish_cause);
2978 }
2979 else
2980 {
2981 #ifdef GPRS
2982 if(!att_gprs_cell_has_pbcch())
2983 #endif
2984 att_code_mph_ncell_req(SC_INDEX);
2985 }
2986
2987 /* After Dedicated mode lass than 30 seconds for a Location Area Update or
2988 * routing Area update.
2989 * start black list search to look for inactive carriers
2990 * Cell-Selection Improvement LLD - 4.1.4.3
2991 */
2992 if((rr_data->ms_data.establish_cause EQ ESTCS_SERV_REQ_BY_MM) AND
2993 (rr_data->cs_data.black_list_search_pending EQ TRUE))
2994 {
2995
2996 TRACE_EVENT("black_list_search_pending : 1");
2997
2998 rr_data->cs_data.black_list_search_pending = FALSE;
2999
3000 if(cs_check_region(rr_data->cs_data.region))
3001 {
3002 /* Do not start Black list search,when Black list database is empty */
3003 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3004 if (rr_data->cs_data.region EQ BOTH_REGIONS)
3005 {
3006 if(srv_is_list_set(&rr_data->cs_data.black_list.list[EUROPEAN_REGION]) OR
3007 srv_is_list_set(&rr_data->cs_data.black_list.list[AMERICAN_REGION]))
3008 {
3009 att_start_cell_selection(RR_ORIGINATED,CS_PARALLEL,BLACK_LIST_SEARCH_MODE);
3010 }
3011 else
3012 {
3013 TRACE_EVENT("Black List empty");
3014 }
3015 }
3016 else
3017 {
3018 #endif
3019 if(srv_is_list_set(
3020 &rr_data->cs_data.black_list.list[rr_data->cs_data.region]))
3021 {
3022 att_start_cell_selection(RR_ORIGINATED,CS_PARALLEL,BLACK_LIST_SEARCH_MODE);
3023 }
3024 else
3025 {
3026 TRACE_EVENT("Black List empty");
3027 }
3028 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3029 }
3030 #endif
3031 }
3032 }
3033 }
3034 else
3035 {
3036 #ifdef GPRS
3037 att_start_cell_reselection_gprs(BACK_FROM_DEDICATED);
3038 #else
3039 att_start_cell_reselection(BACK_FROM_DEDICATED);
3040 #endif
3041 }
3042 }
3043
3044 /*
3045 +--------------------------------------------------------------------+
3046 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3047 | STATE : code ROUTINE : att_leave_dat_imm_ass |
3048 +--------------------------------------------------------------------+
3049
3050 PURPOSE : return to idle mode directly and clean up
3051 immediate assignment procedure
3052
3053 */
3054 GLOBAL void att_leave_dat_imm_ass(void)
3055 {
3056 GET_INSTANCE_DATA;
3057 TRACE_FUNCTION ("att_leave_dat_imm_ass()");
3058
3059 #ifdef GPRS
3060 if(GPRS_SUSPENDED_BCCH EQ GET_STATE(STATE_GPRS))
3061 {
3062 SET_STATE(STATE_GPRS,GPRS_PIM_BCCH);
3063 }
3064 else if(GPRS_SUSPENDED_PBCCH EQ GET_STATE(STATE_GPRS))
3065 {
3066 SET_STATE(STATE_GPRS,GPRS_PIM_PBCCH);
3067 }
3068 #endif
3069
3070 att_return_to_idle();
3071
3072 rr_data->repeat_est = FALSE;
3073
3074 #ifdef GPRS
3075 if(!att_gprs_cell_has_pbcch())
3076 #endif
3077 att_code_mph_ncell_req(SC_INDEX);
3078
3079 /*
3080 * start black list search to look for inactive carriers
3081 * Cell-Selection Improvement LLD - 4.1.4.3
3082 */
3083 if((rr_data->ms_data.establish_cause EQ ESTCS_SERV_REQ_BY_MM) AND
3084 (rr_data->cs_data.black_list_search_pending EQ TRUE))
3085 {
3086
3087 TRACE_EVENT("black_list_search_pending : 1");
3088
3089 rr_data->cs_data.black_list_search_pending = FALSE;
3090
3091 if(cs_check_region(rr_data->cs_data.region))
3092 {
3093 /* Do not start Black list search,when Black list database is empty */
3094 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3095 if (rr_data->cs_data.region EQ BOTH_REGIONS)
3096 {
3097 if(srv_is_list_set(&rr_data->cs_data.black_list.list[EUROPEAN_REGION]) OR
3098 srv_is_list_set(&rr_data->cs_data.black_list.list[AMERICAN_REGION]))
3099 {
3100 att_start_cell_selection(RR_ORIGINATED,CS_PARALLEL,BLACK_LIST_SEARCH_MODE);
3101 }
3102 else
3103 {
3104 TRACE_EVENT("Black List empty");
3105 }
3106 }
3107 else
3108 {
3109 #endif
3110 if(srv_is_list_set(&rr_data->cs_data.black_list.list[rr_data->cs_data.region]))
3111 {
3112 att_start_cell_selection(RR_ORIGINATED,CS_PARALLEL,BLACK_LIST_SEARCH_MODE);
3113 }
3114 else
3115 {
3116 TRACE_EVENT("Black List empty");
3117 }
3118 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
3119 }
3120 #endif
3121 }
3122 }
3123 }
3124
3125
3126 /*
3127 +--------------------------------------------------------------------+
3128 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3129 | STATE : code ROUTINE : att_select_cell_dedicated |
3130 +--------------------------------------------------------------------+
3131
3132 PURPOSE : The function selects a cell for cell reselection after
3133 coming back from a dedicated connected (normal release
3134 or radio link failure.
3135
3136 */
3137
3138 static void att_select_cell_dedicated (void)
3139 {
3140 GET_INSTANCE_DATA;
3141 U8 search_mode;
3142
3143 TRACE_FUNCTION ("att_select_cell_dedicated()");
3144
3145 if (rr_data->reselect_index NEQ NO_AVAILABLE)
3146 {
3147 TRACE_EVENT_P3 ("[%u] new CS/CR (mode=%u, sel.type=%d)",
3148 rr_data->nc_data[rr_data->reselect_index].arfcn,
3149 rr_data->mode_after_dedi, rr_data->sc_data.selection_type);
3150
3151 /*
3152 * A cell has been found for coming back from dedicated mode.
3153 * Configure layer 1 for cell reselection.
3154 */
3155 att_start_cr_in_pl(rr_data->reselect_index);
3156 }
3157 else
3158 {
3159 /*
3160 * no suitable cell is available
3161 */
3162 if (rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED_RLF)
3163 {
3164 /*
3165 * In case of coming back after radio link failure
3166 * the old cell shall be used only if no other cell
3167 * is suitable. So the selection type is changed to
3168 * "normal" comeback from dedicated mode. MM is informed
3169 * that no reestablishment is possible and a cell is
3170 * searched again inclusive the old serving cell.
3171 */
3172 rr_data->sc_data.selection_type = BACK_FROM_DEDICATED;
3173 dat_code_reestablishment_fail ();
3174 TIMERSTART (T_RESELECT, TRESELECT_VALUE);
3175 att_search_cell ();
3176 }
3177 else
3178 {
3179 /* Cell Selection Improvements-LLD section:4.1.3.9 */
3180 if((rr_data->net_lost) AND (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH))
3181 {
3182 /* Radio Link failure in dedicated state and cell reselection failed.
3183 * Start Fast search
3184 */
3185 search_mode = FAST_SEARCH_MODE;
3186 }
3187 else
3188 {
3189 /* Normal return from dedicated mode, cell reselection failed
3190 * Start Normal search
3191 */
3192 search_mode = NORMAL_SEARCH_MODE;
3193 }
3194
3195 /*
3196 * there is no candidate for coming back. So a cell
3197 * selection is started from RR.
3198 */
3199 /* XY:n inform GRR, and wait for CR_RSP */
3200 #ifdef GPRS
3201 att_start_cell_selection_gprs (RR_ORIGINATED,search_mode);
3202 #else
3203 att_start_cell_selection (RR_ORIGINATED, CS_NOT_PARALLEL,search_mode);
3204 #endif
3205 }
3206 }
3207 //rr_data->mode_after_dedi = MODE_CELL_SELECTION; /* reset mode */
3208 }
3209
3210
3211 /*
3212 +--------------------------------------------------------------------+
3213 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3214 | STATE : code ROUTINE : att_check_neighbourcell |
3215 +--------------------------------------------------------------------+
3216
3217 PURPOSE : The function checks a cell after cell reselection.
3218
3219 */
3220
3221 GLOBAL void att_check_neighbourcell (void)
3222 {
3223 GET_INSTANCE_DATA;
3224 BOOL cell_ok;
3225 T_loc_area_ident * lai = &rr_data->nc_data[CR_INDEX].lai;
3226
3227 TRACE_FUNCTION ("att_check_neighbourcell()");
3228
3229 #ifdef GPRS
3230 if(att_gprs_check_ncell())
3231 return;
3232 #endif
3233 /*
3234 * Calculate the cell reselection criterion C2 or C31/C32.
3235 */
3236 #ifdef GPRS
3237 if( rr_data->gprs_data.use_c31)
3238 {
3239 att_calculate_c31_c32(CR_INDEX);
3240
3241 /* Implements RR Clone findings #8 */
3242 cell_ok = (!att_cell_barred_status_cr_no_cr (CR_INDEX) AND
3243 att_check_c31_criterion(CR_INDEX) );
3244 }
3245 else
3246 {
3247 #endif
3248 att_calculate_c2 (CR_INDEX);
3249 /*
3250 * Check the cell. It shall not be barred and must have
3251 * a positive cell reselection criterion C2.
3252 */
3253
3254 /* Implements RR Clone findings #8 */
3255 cell_ok = ! att_cell_barred_status_cr_no_cr (CR_INDEX) AND
3256 rr_data->nc_data[CR_INDEX].c2 > 0;
3257
3258
3259 #ifdef GPRS
3260 }
3261 #endif
3262
3263 /*
3264 * the cell can be rejected by the SW shielding function.
3265 * This has only an affect during type approval.
3266 */
3267 if (cell_ok)
3268 cell_ok = att_check_network (lai);
3269
3270 /*
3271 * Check against the list of forbidden location areas for roaming,
3272 * but only if MM requested full service and we are still searching
3273 * for full service. Do not prevent limited service reselection.
3274 */
3275 if (cell_ok AND
3276 (rr_data->cs_data.scan_mode NEQ CS_SECOND_SCAN) AND
3277 (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH))
3278 {
3279 cell_ok = dat_roam_forb_lai_check (CR_INDEX);
3280 }
3281
3282 /*
3283 * Additional tests are performed depending on the cell
3284 * reselection type.
3285 */
3286 TRACE_SELECTION_TYPE (rr_data->sc_data.selection_type);
3287 switch (rr_data->sc_data.selection_type)
3288 {
3289 case CELL_RESELECTION_CR:
3290 /*
3291 * The MS was in idle mode and the check is
3292 * 1. from limited service to full service or
3293 * 2. from full service (VPLMN) to full service (HPLMN)
3294 *
3295 * The resulting RR service is set only if the cell is okay.
3296 */
3297 if (cell_ok)
3298 {
3299 if (rr_data->ms_data.req_mm_service EQ FUNC_LIM_SERV_ST_SRCH OR
3300 rr_data->cs_data.scan_mode EQ CS_SECOND_SCAN)
3301 {
3302 rr_data->ms_data.rr_service = LIMITED_SERVICE;
3303 }
3304 else
3305 {
3306 cell_ok = dat_plmn_equal_req(lai->mcc, lai->mnc,
3307 rr_data->ms_data.plmn.mcc,
3308 rr_data->ms_data.plmn.mnc);
3309 if (cell_ok)
3310 rr_data->ms_data.rr_service = FULL_SERVICE;
3311 else
3312 rr_data->ms_data.rr_service = LIMITED_SERVICE;
3313 }
3314 }
3315 break;
3316
3317 case CELL_SELECTION:
3318 case CELL_RESELECTION:
3319 case CELL_RESELECTION_NC:
3320 case CELL_RESELECTION_RACH:
3321 if(cell_ok)
3322 {
3323 /*
3324 * 2 checks to be made
3325 *
3326 * - In case of FULL SERVICE additionally the PLMN is checked
3327 *
3328 * - We are in LIMITED service.
3329 * If the req_mm_service is FUNC_LIM_SERV_ST_SRCH we
3330 * will stay in LIMITED.
3331 * If we are in limited because of forbidden LAI we enter FULL SERVICE.
3332 */
3333 if(rr_data->ms_data.rr_service EQ FULL_SERVICE)
3334 {
3335 cell_ok = dat_plmn_equal_req (lai->mcc,
3336 lai->mnc,
3337 rr_data->ms_data.plmn.mcc,
3338 rr_data->ms_data.plmn.mnc);
3339 }
3340 else if((rr_data->ms_data.rr_service EQ LIMITED_SERVICE) AND
3341 (rr_data->ms_data.req_mm_service NEQ FUNC_LIM_SERV_ST_SRCH) AND
3342 dat_plmn_equal_req (lai->mcc,
3343 lai->mnc,
3344 rr_data->ms_data.plmn.mcc,
3345 rr_data->ms_data.plmn.mnc) )
3346 {
3347 rr_data->ms_data.rr_service = FULL_SERVICE;
3348 }
3349
3350 }
3351 break;
3352
3353 case BACK_FROM_DEDICATED:
3354 case BACK_FROM_DEDICATED_RLF:
3355 /* The mobile is trying to select a cell after coming back from dedicated
3356 * state. The cell is selected only if it belongs to the previously selected
3357 * PLMN
3358 */
3359 if(cell_ok)
3360 {
3361 /* While selecting a cell after an emergency call, we need not check the
3362 * PLMN ID of the cell */
3363 if(rr_data->ms_data.rr_service EQ FULL_SERVICE)
3364 {
3365 cell_ok = dat_plmn_equal_req (lai->mcc,
3366 lai->mnc,
3367 rr_data->ms_data.plmn.mcc,
3368 rr_data->ms_data.plmn.mnc);
3369 }
3370
3371 TRACE_EVENT_P6 ("B_F_D New PLMN : MCC=%X%X%X MNC=%X%X%X",
3372 lai->mcc[0],
3373 lai->mcc[1],
3374 lai->mcc[2],
3375 lai->mnc[0],
3376 lai->mnc[1],
3377 lai->mnc[2]);
3378 TRACE_EVENT_P6 ("B_F_D Old PLMN : MCC=%X%X%X MNC=%X%X%X",
3379 rr_data->ms_data.plmn.mcc[0],
3380 rr_data->ms_data.plmn.mcc[1],
3381 rr_data->ms_data.plmn.mcc[2],
3382 rr_data->ms_data.plmn.mnc[0],
3383 rr_data->ms_data.plmn.mnc[1],
3384 rr_data->ms_data.plmn.mnc[2]);
3385 }
3386 if(rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED)
3387 break;
3388
3389 /*
3390 * in case of call reestablishment check also call reestablishment flag
3391 */
3392 if (cell_ok)
3393 {
3394 if (rr_data->nc_data[CR_INDEX].rach.re NEQ REESTAB_YES)
3395 cell_ok = FALSE;
3396 }
3397 break;
3398 }
3399
3400 /*
3401 * the requirement check is finished
3402 */
3403 if (cell_ok)
3404 {
3405 TRACE_EVENT_P2 ("NEW SC [%d]->[%d]",
3406 rr_data->nc_data[SC_INDEX].arfcn,
3407 rr_data->nc_data[CR_INDEX].arfcn);
3408
3409 /*
3410 * Stop T_RESELECT, which controls the reception of the complete BCCH
3411 * during Cell Reselection.
3412 */
3413 TIMERSTOP (T_RESELECT);
3414
3415
3416 /* T3122 controls after how long the MS is able to attempt access back to the */
3417 /* cell from which it received a IMM ASSGN REJ. This no longer applies after a */
3418 /* cell reselection onto a new cell. */
3419
3420 TIMERSTOP(T3122);
3421
3422
3423 /*
3424 * copy all data from the SC_INDEX storage area to the neighbourcell area.
3425 * copy all data from the CR_INDEX storage area to the SC_INDEX area.
3426 * old serving cell data index is stored in old_serving_cell.
3427 */
3428 att_copy_cr_data ();
3429
3430 memcpy (&rr_data->sc_data.cd, &rr_data->cr_data.cd,
3431 sizeof (T_CELL_DATA));
3432
3433 if(rr_data->ms_data.rr_service EQ FULL_SERVICE)
3434 {
3435 att_full_service_found();
3436 }
3437
3438 rr_data->nc_data[CR_INDEX].arfcn = NOT_PRESENT_16BIT;
3439 /*
3440 * GSM 5.08, chapter 6.4:
3441 *
3442 * T is a timer implemented for each cell in the list of strongest
3443 * carriers.
3444 * T shall be started from zero at the time the cell is placed by the MS on
3445 * the list of strongest carriers, except when the previous serving cell is
3446 * placed on the list of strongest carriers at cell reselection. In this
3447 * case, T shall be set to the value of PENALTY_TIME (i.e. expired).
3448 */
3449 switch (rr_data->sc_data.selection_type)
3450 {
3451 case CELL_RESELECTION:
3452 case CELL_RESELECTION_NC:
3453 case CELL_RESELECTION_RACH:
3454 /*
3455 * set the avail time of the old serving cell to PENALTY_TIME.
3456 */
3457 if (rr_data->old_serving_cell < SC_INDEX)
3458 rr_data->nc_data[rr_data->old_serving_cell].avail_time =
3459 rr_data->nc_data[rr_data->old_serving_cell].c2_par.penalty_time;
3460 break;
3461
3462 default:
3463 break;
3464 }
3465
3466
3467 /*
3468 * set a barrier of 15 seconds for the next cell reselection
3469 * if it was a cell reselection due to C2(NC) > C2(SC)
3470 */
3471 if (rr_data->sc_data.selection_type EQ CELL_RESELECTION_NC)
3472 TIMERSTART (T_NO_RESELECT, THIRTY_SEC/2);
3473
3474 #ifdef GPRS
3475 if(! att_gprs_is_avail())
3476 {
3477 #endif
3478
3479 /*
3480 * configure layer 1
3481 */
3482 att_remove_bad_rr_data_ncells();
3483 att_set_pl_in_idle_mode ();
3484
3485 /*
3486 * inform data transfer process that the cell is attached.
3487 */
3488 dat_att_cell_selected ();
3489
3490 /*
3491 * inform MM about new cell
3492 */
3493 if (rr_data->sc_data.mm_started)
3494 att_code_rr_act_cnf ();
3495 else
3496 att_code_rr_act_ind ();
3497
3498 SET_STATE (STATE_ATT, ATT_IDLE);
3499 srv_use_stored_prim ();
3500 /*
3501 * Start registration timer if needed
3502 */
3503 att_start_registration_timer ();
3504 /*
3505 * if the cell reselection has been started after a dedicated connection
3506 * attempt with failed SABM / UA content a second attempt is started
3507 * immediately.
3508 */
3509 if (rr_data->repeat_est)
3510 {
3511 rr_data->repeat_est = FALSE;
3512 dat_start_immediate_assign (rr_data->ms_data.establish_cause);
3513 }
3514 #ifdef GPRS
3515 }
3516 else
3517 {
3518 if(rr_data->ms_data.rr_service NEQ FULL_SERVICE)
3519 {
3520 if(att_gprs_cell_has_pbcch())
3521 {
3522 /* set to PIM_BCCH if the cell hs a PBCCH but we
3523 * only have limited service
3524 */
3525 SET_STATE(STATE_GPRS, GPRS_PIM_BCCH);
3526 }
3527 }
3528
3529 if(att_gprs_cell_has_pbcch())
3530 {
3531 att_gprs_stop_pl();
3532 }
3533 else
3534 {
3535 att_remove_bad_rr_data_ncells();
3536 att_set_pl_in_idle_mode ();
3537 }
3538 /* inform GRR if we have GPRS support */
3539 att_signal_gprs_support();
3540 /* and wait for CR_REQ(CR_COMPLETE) from GRR */
3541 }
3542 #endif
3543 }
3544 else
3545 {
3546 /*
3547 * the cell reselection failed for this channel and is continued
3548 * with the next candidate.
3549 */
3550 TRACE_EVENT_P1 ("[%u] CR failed", rr_data->nc_data[CR_INDEX].arfcn);
3551 rr_data->pag_rec = FALSE;
3552 srv_clear_stored_prim (MPH_PAGING_IND);
3553 att_continue_cell_reselect ();
3554 }
3555 }
3556
3557 /*
3558 +--------------------------------------------------------------------+
3559 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3560 | STATE : code ROUTINE : att_check_neighbourcell_si_reestab |
3561 +--------------------------------------------------------------------+
3562
3563 PURPOSE : This function checks if revelant sys info is present is ATT_CS3 state.
3564 Special case : Sys Info 2Ter is not needed if we have a pending call re-establishment
3565
3566 */
3567
3568 GLOBAL void att_check_neighbourcell_si_reestab (void)
3569 {
3570 GET_INSTANCE_DATA;
3571 /*
3572 * Sometimes the network indicates SI2Ter but never sends it.
3573 * If we have a call re-establishment pending, then we must not wait
3574 * for SI2Ter.
3575 */
3576 if( (rr_data->cr_data.cd.sys_info_read EQ ALL_SYS_INFO_READ)
3577 OR
3578 ( (rr_data->cr_data.cd.sys_info_read EQ SYS_INFO_EXCEPT_2TER) AND
3579 (rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED_RLF))
3580 )
3581 {
3582 att_check_neighbourcell ();
3583 }
3584
3585 /*
3586 * In case of Radio Link Failure, check cell for call
3587 * re-establishment capability.
3588 */
3589 if (rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED_RLF)
3590 att_check_reestablishment();
3591
3592 }
3593
3594 /*
3595 +--------------------------------------------------------------------+
3596 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3597 | STATE : code ROUTINE : att_check_reestablishment |
3598 +--------------------------------------------------------------------+
3599
3600 PURPOSE : The function checks whether a cell has no call re-establishment
3601 capability. In this case the cell reselection is resumed
3602 with the next cell.
3603
3604 */
3605
3606 GLOBAL void att_check_reestablishment (void)
3607 {
3608 GET_INSTANCE_DATA;
3609 TRACE_FUNCTION ("att_check_reestablishment()");
3610
3611 if (rr_data->nc_data[CR_INDEX].rach.re NEQ REESTAB_YES)
3612 {
3613 /*
3614 * the cell reselection failed for this channel and is continued
3615 * with the next candidate due to no call re-establishment
3616 * capability.
3617 */
3618 TRACE_EVENT_P2 ("[%u]7 (BCCH-St=%u) have no call re-establishment capability",
3619 rr_data->nc_data[CR_INDEX].arfcn, rr_data->nc_data[CR_INDEX].bcch_status);
3620
3621 rr_data->pag_rec = FALSE;
3622 srv_clear_stored_prim (MPH_PAGING_IND);
3623 att_continue_cell_reselect ();
3624 }
3625 }
3626
3627 /*
3628 +--------------------------------------------------------------------+
3629 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3630 | STATE : code ROUTINE : att_check_reselect_decision|
3631 +--------------------------------------------------------------------+
3632
3633 PURPOSE : After reception of measurement values from layer 1 in
3634 idle mode the cell reselection decision is done by this
3635 function. It checks the measurement related criterions
3636 for cell reselection. The flag start_now indicates
3637 whether only the decision is taken or the cell reselection
3638 is started immediately. It is senseful to delay a cell
3639 reselection during a PLMN available search triggered by MM.
3640
3641 */
3642
3643 GLOBAL void att_check_reselect_decision (UBYTE start_now)
3644 {
3645 GET_INSTANCE_DATA;
3646 UBYTE i;
3647 SHORT delta;
3648
3649 TRACE_FUNCTION ("att_check_reselect_decision()");
3650 #ifdef GPRS
3651 TRACE_EVENT_P2("check_reselect: start_cell_reselection=%u calc %s",
3652 rr_data->start_cell_reselection, rr_data->gprs_data.use_c31 ? "C31,C32":"C2");
3653 #endif
3654 /*
3655 * Calculate for all synchronized neighbourcells, which have
3656 * decoded the system information messages for calculation C2,
3657 * and for the serving cell the cell reselection criterion C2.
3658 */
3659 for (i = 0; i < 7; i++)
3660 {
3661 if (rr_data->nc_data[i].bcch_status EQ DECODED)
3662 {
3663 #ifdef GPRS
3664 if( rr_data->gprs_data.use_c31)
3665 att_calculate_c31_c32(i);
3666 else
3667 #endif
3668 att_calculate_c2 (i);
3669 }
3670 else if (rr_data->nc_data[i].bcch_status NEQ EMPTY AND
3671 rr_data->nc_data[i].arfcn NEQ NOT_PRESENT_16BIT )
3672 {
3673 TRACE_EVENT_P2("[%u]i%u no C2 (SIs missing)",
3674 rr_data->nc_data[i].arfcn,i);
3675 }
3676 }
3677
3678 /*
3679 * Check C1 serving cell < 0 for more then 5 seconds
3680 * The c1_counter counts the number of reports where
3681 * this criterion has passed.
3682 */
3683 if (rr_data->nc_data[SC_INDEX].c1 < 0)
3684 {
3685 /*
3686 * if c1_counter has a value of at least 1 it had happened
3687 * for at least two successive reports, that means more
3688 * then five seconds.
3689 */
3690 if ( (rr_data->nc_data[SC_INDEX].c1_counter > 0)
3691 #ifdef GPRS
3692 OR
3693 (rr_data->gprs_data.use_c31)
3694 #endif
3695 )
3696 {
3697 /*
3698 * reset the counter and start !
3699 */
3700 rr_data->nc_data[SC_INDEX].c1_counter = 0;
3701 #ifdef GPRS
3702 /* check if we can do a cell reselection */
3703 if(!is_nc2_used())
3704 {
3705 #endif
3706 if (start_now )
3707 {
3708 /*XY:n inform GRR, and wait for CR_RSP */
3709 #ifdef GPRS
3710 att_start_cell_reselection_gprs (CELL_RESELECTION);
3711 #else
3712 att_start_cell_reselection (CELL_RESELECTION);
3713 #endif
3714 }
3715 #ifdef GPRS
3716 }
3717 #endif
3718 return;
3719 }
3720 else
3721 {
3722 /*
3723 * the criterion has passed the first time, so
3724 * increase the counter and wait for the next measurement value.
3725 */
3726 rr_data->nc_data[SC_INDEX].c1_counter++;
3727 #if defined(_SIMULATION_)
3728 TRACE_EVENT_WIN_P1 ("CR SC delayed (%d)", rr_data->nc_data[SC_INDEX].c1_counter);
3729 #endif
3730 }
3731 }
3732 else
3733 {
3734 /*
3735 * The C1 of the serving cell is positive, so clear the c1_counter.
3736 */
3737 rr_data->nc_data[SC_INDEX].c1_counter = 0;
3738 #if defined(_SIMULATION_)
3739 TRACE_EVENT_WIN_P1 ("CR SC c1_counter=%d", rr_data->nc_data[SC_INDEX].c1_counter);
3740 #endif
3741 }
3742 /*
3743 * check if C31\C32 based reselection is required
3744 */
3745 #ifdef GPRS
3746 if( rr_data->gprs_data.use_c31 )
3747 {
3748 att_check_c31_reselect_decision(start_now);
3749 return;
3750 }
3751 #endif
3752 /*
3753 * Check C2(NC) > C2(SC) for all neighbourcells
3754 */
3755 for (i = 0; i < 6; i++)
3756 {
3757 /*
3758 * If data is stored for this neighbourcell
3759 */
3760 if (rr_data->nc_data[i].bcch_status EQ DECODED)
3761 {
3762 /*
3763 TRACE_EVENT_P2 ("COMPARE NC[%d]-SC[%d]",
3764 rr_data->nc_data[i].arfcn,
3765 rr_data->nc_data[SC_INDEX].arfcn);
3766 */
3767 #ifdef GPRS
3768 /*
3769 * check if the location area has changed
3770 * or the routing area if the scell supports GPRS
3771 */
3772 {
3773 BOOL la_same, ra_same;
3774
3775 if (dat_plmn_equal_req (rr_data->nc_data[i].lai.mcc,
3776 rr_data->nc_data[i].lai.mnc,
3777 rr_data->nc_data[SC_INDEX].lai.mcc,
3778 rr_data->nc_data[SC_INDEX].lai.mnc)
3779 AND
3780 rr_data->nc_data[i].lai.lac EQ
3781 rr_data->nc_data[SC_INDEX].lai.lac)
3782 la_same = TRUE;
3783 else
3784 la_same = FALSE;
3785 /*
3786 * If gprs is not available do not care about the routing area
3787 *
3788 */
3789 if(att_gprs_is_avail())
3790 {
3791 if(rr_data->nc_data[i].rac EQ NOT_PRESENT_8BIT OR
3792 rr_data->nc_data[i].rac EQ rr_data->nc_data[SC_INDEX].rac)
3793 {
3794 ra_same = TRUE;
3795 }
3796 else
3797 {
3798 ra_same = FALSE;
3799 }
3800 }
3801 else
3802 {
3803 ra_same = TRUE;
3804 }
3805
3806 if(la_same AND ra_same AND !rr_data->gprs_data.ready_state)
3807 #else /* GPRS */
3808 if (dat_plmn_equal_req (rr_data->nc_data[i].lai.mcc,
3809 rr_data->nc_data[i].lai.mnc,
3810 rr_data->nc_data[SC_INDEX].lai.mcc,
3811 rr_data->nc_data[SC_INDEX].lai.mnc)
3812 AND
3813 rr_data->nc_data[i].lai.lac EQ
3814 rr_data->nc_data[SC_INDEX].lai.lac)
3815 #endif /* GPRS */
3816 {
3817 /*
3818 * If it is in the same location area as the serving cell,
3819 * the delta is simply the difference of both cell reselection
3820 * criterion values C2.
3821 */
3822 TRACE_EVENT_P3 ("NC[%d]i%u-SC[%d] same LAI",
3823 rr_data->nc_data[i].arfcn,i,
3824 rr_data->nc_data[SC_INDEX].arfcn);
3825
3826 delta = rr_data->nc_data[i].c2 -
3827 rr_data->nc_data[SC_INDEX].c2;
3828
3829 /*
3830 * 3GPP TS 05.08, section 6.6.2:
3831 * in case of a cell reselection occurring within the previous 15 seconds
3832 * in which case the C2 value for the new cell shall exceed the C2 value
3833 * of the serving cell by at least 5 dB for a period of 5 seconds
3834 */
3835
3836 if ( IS_TIMER_ACTIVE (T_NO_RESELECT) )
3837 {
3838 delta -= 5;
3839 }
3840 else
3841 {
3842 /* When C2(NC)==C2(SC) i.e. delta=0, an invalid cell reselection gets triggered below.
3843 * 'delta' needs to be adjusted to prevent this happening. The '=' in the '>='
3844 * condition below only applies when T_NO_RESELECT timer is active and
3845 * c2_corr has been decremented by 5 (above statement)
3846 */
3847 if(delta EQ 0 )
3848 {
3849 delta = -1;
3850 }
3851 }
3852 }
3853 else
3854 {
3855 /*
3856 * If both are member of different location areas, a threshold
3857 * value CELL_RESELECTION_HYSTERESE is taken in account.
3858 */
3859 TRACE_EVENT_P3 ("NC[%d]i%u-SC[%d] different LAI",
3860 rr_data->nc_data[i].arfcn,i,
3861 rr_data->nc_data[SC_INDEX].arfcn);
3862
3863 delta = att_calculate_c2_diff (i);
3864 }
3865 #ifdef GPRS
3866 }
3867 #endif
3868 /*
3869 * Check cell barred status before going
3870 * into Cell Reselection state.
3871 * This will actually also be checked again
3872 * in att_check_cell but the CRH value will
3873 * not be used for subsequent ncells leading
3874 * to false CR's. We check it here
3875 * to use CRH for the next cell if needed.
3876 */
3877 /* Implements RR Clone findings #8 */
3878 if(att_cell_barred_status_cr_no_cr(i))
3879 delta = -1;
3880
3881 /*
3882 * Do not trigger a cell reselection decision on meas. report
3883 * receipt if the cell belong to a LA not allowed for roaming.
3884 * According to 3.22 chapter 3.5.4 cell reselection on a
3885 * forbidden LA for regional provision of service is allowed.
3886 */
3887 if (rr_data->ms_data.rr_service EQ FULL_SERVICE)
3888 {
3889 if (!dat_roam_forb_lai_check(i))
3890 delta = -1;
3891 }
3892
3893 #if defined(_SIMULATION_)
3894 TRACE_EVENT_WIN_P1 ("delta=%d", delta);
3895 #endif
3896 if(delta == 0) TRACE_EVENT("No reselection delta == 0");
3897 if (delta > 0)
3898 {
3899 /*
3900 * The condition C2(NC) > C2(SC) is fulfilled.
3901 */
3902 if (rr_data->nc_data[i].c1_counter > 0)
3903 {
3904 /*
3905 * the conditions is fulfilled at least two times ( > 5 seconds)
3906 * and there is no barrier to start the cell
3907 * reselection.
3908 */
3909 #ifdef GPRS
3910 /* check if we can do a cell reselection */
3911 if(!is_nc2_used())
3912 {
3913 #endif
3914 if (start_now)
3915 {
3916 rr_data->nc_data[i].c1_counter = 0;
3917 /*XY:n inform GRR, and wait for CR_RSP */
3918 #ifdef GPRS
3919 att_start_cell_reselection_gprs(CELL_RESELECTION_NC);
3920 #else
3921 att_start_cell_reselection (CELL_RESELECTION_NC);
3922 #endif
3923 }
3924 #ifdef GPRS
3925 }
3926 #endif
3927 return;
3928 }
3929 else
3930 {
3931 /*
3932 * The condition has passed the first time or is delayed
3933 * by the barrier to perform a cell reselection due to this reasons
3934 * not faster then in periods of 15 seconds.
3935 */
3936 rr_data->nc_data[i].c1_counter++;
3937 TRACE_EVENT_P3 ("NC[%u]i%u CR delayed (%d)",
3938 rr_data->nc_data[i].arfcn,i,rr_data->nc_data[i].c1_counter);
3939 }
3940 }
3941 else
3942 {
3943 /*
3944 * the condition is not fullfilled and the counter is resetted.
3945 */
3946 rr_data->nc_data[i].c1_counter = 0;
3947 }
3948 }
3949 }
3950 }
3951
3952 /*
3953 +--------------------------------------------------------------------+
3954 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3955 | STATE : code ROUTINE : att_check_barred_status_in_idle|
3956 +--------------------------------------------------------------------+
3957
3958 PURPOSE :
3959
3960 */
3961
3962 GLOBAL void att_check_barred_status_in_idle (void)
3963 {
3964 TRACE_FUNCTION ("att_check_barred_status_in_idle()");
3965
3966 /*
3967 * check whether serving cell is barred
3968 */
3969 /*XY:n inform GRR, and wait for CR_RSP */
3970
3971 /* Implements RR Clone findings #8 */
3972 if (att_cell_barred_status_cr_no_cr (SC_INDEX) EQ TRUE)
3973 {
3974
3975 #ifdef GPRS
3976 att_start_cell_reselection_gprs (CELL_RESELECTION);
3977 #else
3978 att_start_cell_reselection (CELL_RESELECTION);
3979 #endif
3980 }
3981 }
3982
3983
3984 /*
3985 +--------------------------------------------------------------------+
3986 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
3987 | STATE : code ROUTINE : att_clear_forb_list |
3988 +--------------------------------------------------------------------+
3989
3990 PURPOSE : RR stores some forbidden lists. This function clears
3991 the given forbidden list.
3992
3993 */
3994
3995 static void att_clear_forb_list (int list_type)
3996 {
3997 GET_INSTANCE_DATA;
3998 int i;
3999 T_loc_area_ident *forb_list;
4000
4001 TRACE_FUNCTION ("att_clear_forb_list()");
4002
4003 if (list_type EQ FORBIDDEN_LIST_NORMAL)
4004 forb_list = &rr_data->ms_data.forb_lac_list[0];
4005 else
4006 forb_list = &rr_data->ms_data.roam_forb_lac_list[0];
4007
4008 /* Implements Measure#32: Row 29 */
4009 if(list_type EQ FORBIDDEN_LIST_NORMAL)
4010 {
4011 TRACE_EVENT ( "CLEAR FORB LIST");
4012 }
4013 else
4014 {
4015 TRACE_EVENT ( "CLEAR ROAM FORB LIST");
4016 }
4017
4018
4019 for (i = 0; i < MAX_LAI; i++)
4020 {
4021 memset (forb_list[i].mcc, NOT_PRESENT_8BIT, SIZE_MCC);
4022 memset (forb_list[i].mnc, NOT_PRESENT_8BIT, SIZE_MNC);
4023 forb_list[i].lac = NOT_PRESENT_16BIT;
4024 }
4025 }
4026
4027
4028
4029 /*
4030 +--------------------------------------------------------------------+
4031 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4032 | STATE : code ROUTINE : att_clear_registration_data|
4033 +--------------------------------------------------------------------+
4034
4035 PURPOSE : The function is called after reception of RR_SYNC_REQ,
4036 which is sent by MM after some Location Updating Reject
4037 causes which indicate that the IMSI is invalid, paging
4038 shall be suppressed and RR shall enter only a limited mode.
4039
4040 */
4041
4042 GLOBAL void att_clear_registration_data (void)
4043 {
4044 GET_INSTANCE_DATA;
4045 TRACE_FUNCTION ("att_clear_registration_data()");
4046
4047 TRACE_EVENT ("CLEAR registration data (IMSI, MCC, MNC)");
4048
4049 /*
4050 * Clear the IMSI related data and enter the
4051 * limited mode.
4052 */
4053 rr_data->ms_data.operation_mode = 0;
4054 att_clear_parallel_search ();
4055 rr_data->ms_data.current_plmn_search_type = FUNC_LIM_SERV_ST_SRCH;
4056 rr_data->ms_data.imsi_available = FALSE;
4057 rr_data->ms_data.plmn.mcc[0] = NOT_PRESENT_8BIT;
4058 rr_data->ms_data.plmn.mnc[0] = NOT_PRESENT_8BIT;
4059 rr_data->ms_data.v_eq_plmn = FALSE;
4060
4061 /*we only have limited service*/
4062 rr_data->ms_data.rr_service = LIMITED_SERVICE;
4063 rr_data->ms_data.req_mm_service = FUNC_LIM_SERV_ST_SRCH;
4064
4065 TRACE_EVENT_P3 ("att_clear_registration_data: current=%s, service:rMM=%s RRs=%s",
4066 _rr_str_FUNC[rr_data->ms_data.current_plmn_search_type],
4067 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
4068 _rr_str_SERVICE[rr_data->ms_data.rr_service]);
4069
4070 /*
4071 * clear TMSI and ciphering data
4072 */
4073 att_clear_reg_without_imsi ();
4074 att_set_rr_service_info();
4075 }
4076
4077 /*
4078 +--------------------------------------------------------------------+
4079 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4080 | STATE : code ROUTINE : att_clear_reg_without_imsi |
4081 +--------------------------------------------------------------------+
4082
4083 PURPOSE : After some location updating reject causes MM informs RR
4084 that the TMSI and the ciphering data are invalid.
4085
4086 */
4087
4088 GLOBAL void att_clear_reg_without_imsi (void)
4089 {
4090 GET_INSTANCE_DATA;
4091 TRACE_FUNCTION ("att_clear_reg_without_imsi()");
4092
4093 /*
4094 * clear TMSI
4095 */
4096 rr_data->ms_data.tmsi_available = FALSE;
4097 rr_data->ms_data.tmsi_binary = 0;
4098
4099 /*
4100 * clear ciphering data
4101 */
4102 rr_data->ms_data.cksn = CKSN_NOT_PRES;
4103 memset (rr_data->ms_data.kc, NOT_PRESENT_8BIT, KC_STRING_SIZE);
4104 memset (rr_data->ms_data.new_kc, NOT_PRESENT_8BIT, KC_STRING_SIZE);
4105
4106 /*
4107 * update the identities in layer 1.
4108 */
4109 att_mph_identity_req ();
4110 }
4111
4112 /*
4113 +--------------------------------------------------------------------+
4114 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4115 | STATE : code ROUTINE : att_reorder_mph_ncell_req |
4116 +--------------------------------------------------------------------+
4117
4118 PURPOSE : reorders a neighbourcell list for layer 1 to make sure
4119 that the strongest neighbour cells are the first ones
4120 in the list and are therefore measured first by layer 1
4121 */
4122
4123 static void att_reorder_mph_ncell_req (T_MPH_NEIGHBOURCELL_REQ * mph_ncell_req)
4124 {
4125 GET_INSTANCE_DATA;
4126 #define MAX_STRONGEST 6 /* MAX_STRONGEST must be at least 6 but up to 8 makes sense */
4127 UBYTE i_nc,
4128 i_nc1,
4129 c_str_nc = 0,
4130 c_str_cs = 0,
4131 is_old = !IS_TIMER_ACTIVE(TCSVALID),
4132 is_inserted, i, j;
4133 SHORT arfcn,
4134 rxlev,
4135 str_arfcn[MAX_STRONGEST],
4136 str_rxlev[MAX_STRONGEST];
4137
4138 #if defined(_SIMULATION_)
4139 TRACE_EVENT_WIN_P6("ncell_req arfcns:%4d %4d %4d %4d %4d %4d",
4140 mph_ncell_req->arfcn[0] NEQ NOT_PRESENT_16BIT ?
4141 mph_ncell_req->arfcn[0] : -1,
4142 mph_ncell_req->arfcn[1] NEQ NOT_PRESENT_16BIT ?
4143 mph_ncell_req->arfcn[1] : -1,
4144 mph_ncell_req->arfcn[2] NEQ NOT_PRESENT_16BIT ?
4145 mph_ncell_req->arfcn[2] : -1,
4146 mph_ncell_req->arfcn[3] NEQ NOT_PRESENT_16BIT ?
4147 mph_ncell_req->arfcn[3] : -1,
4148 mph_ncell_req->arfcn[4] NEQ NOT_PRESENT_16BIT ?
4149 mph_ncell_req->arfcn[4] : -1,
4150 mph_ncell_req->arfcn[5] NEQ NOT_PRESENT_16BIT ?
4151 mph_ncell_req->arfcn[5] : -1);
4152 #endif
4153
4154 memset (str_arfcn, -1, sizeof str_arfcn); /* for easier debugging */
4155 memset (str_rxlev, -1, sizeof str_rxlev);
4156
4157 /*
4158 * search for the strongest neighbourcells and collect them in
4159 * the arrays str_arfcn/str_rxlev. An arfcn found in the nc_data
4160 * is always stored before an arfcn found in the cs_data. The reason
4161 * is that the nc_data are almost younger and probably more important be
4162 * and there may big differences between the rxlev values for the
4163 * same arfcn delevered by MPHC_RXLEV_IND and by MPHC_RXLEV_PERIODIC_IND
4164 */
4165 for (i_nc = 0; i_nc < MAX_NEIGHBOURCELLS AND
4166 mph_ncell_req->arfcn[i_nc] NEQ NOT_PRESENT_16BIT; i_nc++)
4167 {
4168 arfcn = mph_ncell_req->arfcn[i_nc];
4169
4170 if (arfcn EQ rr_data->nc_data[SC_INDEX].arfcn)
4171 continue; /* processing neighbour cell list in *mph_ncell_req */
4172
4173 /*
4174 * for all channels of stored neighbour cell data
4175 */
4176 is_inserted = FALSE;
4177 for (i_nc1 = 0; i_nc1 < 6; i_nc1++)
4178 {
4179 if (arfcn EQ rr_data->nc_data[i_nc1].arfcn)
4180 {
4181 if (rr_data->nc_data[i_nc1].bcch_status NEQ EMPTY)
4182 {
4183 rxlev = rr_data->nc_data[i_nc1].rxlev;
4184 is_inserted = TRUE; /* avoid double inserting */
4185 for (i = c_str_nc; i > 0 AND rxlev > str_rxlev[i-1]; i--)
4186 ; /* search for the place to insert */
4187 if (i EQ c_str_nc AND c_str_nc >= MAX_STRONGEST)
4188 break; /* not strong enough */
4189 j = (c_str_cs >= MAX_STRONGEST) ? MAX_STRONGEST-1 : c_str_cs;
4190 for ( ; j > i; j--)
4191 { /* make place for current entry */
4192 str_rxlev[j] = str_rxlev[j-1];
4193 str_arfcn[j] = str_arfcn[j-1];
4194 }
4195 str_arfcn[i] = arfcn;
4196 str_rxlev[i] = rxlev;
4197 /* if (c_str_nc < MAX_STRONGEST) needed if MAX_STRONGEST < 6 */
4198 c_str_nc++;
4199 if (c_str_cs < MAX_STRONGEST)
4200 c_str_cs++;
4201 }
4202 break; /* scanning stored neighbour cell data */
4203 }
4204 } /* for: stored neighbour cell data */
4205
4206 if (is_old OR is_inserted)
4207 continue; /* CS measurements are too old */
4208
4209 /*
4210 * for all channels of the power campaign list
4211 */
4212 for (i_nc1 = 0; i_nc1 < rr_data->cs_data.max_arfcn; i_nc1++)
4213 {
4214 if (arfcn EQ rr_data->cs_data.arfcn[i_nc1])
4215 {
4216 rxlev = rr_data->cs_data.rxlev[i_nc1];
4217 for (i = c_str_cs; i > c_str_nc AND rxlev > str_rxlev[i-1]; i--)
4218 ; /* search for the place to insert */
4219 if (i EQ c_str_cs AND c_str_cs >= MAX_STRONGEST)
4220 break; /* not strong enough */
4221 j = (c_str_cs >= MAX_STRONGEST) ? MAX_STRONGEST-1 : c_str_cs;
4222 for (; j > i; j--)
4223 { /* make place for current entry */
4224 str_rxlev[j] = str_rxlev[j-1];
4225 str_arfcn[j] = str_arfcn[j-1];
4226 }
4227 str_arfcn[i] = arfcn;
4228 str_rxlev[i] = rxlev;
4229 if (c_str_cs < MAX_STRONGEST)
4230 c_str_cs++;
4231 break; /* scanning power campaign list */
4232 }
4233 } /* for: power campaign list */
4234 } /* for: mph_ncell_req->arfcn */
4235
4236 TRACE_EVENT_P7("c_str_nc=%u arfcn:%4d %4d %4d %4d %4d %4d",
4237 c_str_nc, str_arfcn[0], str_arfcn[1], str_arfcn[2],
4238 str_arfcn[3], str_arfcn[4], str_arfcn[5]);
4239 TRACE_EVENT_P7("c_str_cs=%u rxlev:%4d %4d %4d %4d %4d %4d",
4240 c_str_cs, str_rxlev[0], str_rxlev[1], str_rxlev[2],
4241 str_rxlev[3], str_rxlev[4], str_rxlev[5]);
4242 /* now reorder the arfcn's in the primitive */
4243 for (i_nc1 = 0; i_nc1 < c_str_cs; i_nc1++)
4244 {
4245 for (i_nc = 0; i_nc < MAX_NEIGHBOURCELLS AND
4246 mph_ncell_req->arfcn[i_nc] NEQ NOT_PRESENT_16BIT; i_nc++)
4247 {
4248 if (str_arfcn[i_nc1] EQ mph_ncell_req->arfcn[i_nc])
4249 { /* swap */
4250 arfcn = mph_ncell_req->arfcn[i_nc1];
4251 mph_ncell_req->arfcn[i_nc1] = mph_ncell_req->arfcn[i_nc];
4252 mph_ncell_req->arfcn[i_nc] = arfcn;
4253 break;
4254 }
4255 } /* for: mph_ncell_req->arfcn */
4256 } /* for: str_arfcn */
4257 TRACE_EVENT_P6("strongest arfcns:%4d %4d %4d %4d %4d %4d",
4258 mph_ncell_req->arfcn[0] NEQ NOT_PRESENT_16BIT ?
4259 mph_ncell_req->arfcn[0] : -1,
4260 mph_ncell_req->arfcn[1] NEQ NOT_PRESENT_16BIT ?
4261 mph_ncell_req->arfcn[1] : -1,
4262 mph_ncell_req->arfcn[2] NEQ NOT_PRESENT_16BIT ?
4263 mph_ncell_req->arfcn[2] : -1,
4264 mph_ncell_req->arfcn[3] NEQ NOT_PRESENT_16BIT ?
4265 mph_ncell_req->arfcn[3] : -1,
4266 mph_ncell_req->arfcn[4] NEQ NOT_PRESENT_16BIT ?
4267 mph_ncell_req->arfcn[4] : -1,
4268 mph_ncell_req->arfcn[5] NEQ NOT_PRESENT_16BIT ?
4269 mph_ncell_req->arfcn[5] : -1);
4270 }
4271
4272 /*
4273 +--------------------------------------------------------------------+
4274 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4275 | STATE : code ROUTINE : att_remove_bad_ncell |
4276 +--------------------------------------------------------------------+
4277
4278 PURPOSE : removes outdated ncells from RR store.
4279
4280 */
4281
4282 GLOBAL void att_remove_bad_rr_data_ncells()
4283 {
4284 GET_INSTANCE_DATA;
4285 T_CELL_DATA * cd;
4286 UBYTE i_nc, index;
4287 UBYTE found;
4288 USHORT act_ncell_list [MAX_NEIGHBOURCELLS];
4289 /*
4290 * get the pointer to the correct list.
4291 */
4292
4293 cd = &rr_data->sc_data.cd;
4294 memset (act_ncell_list, 0xFF, 2*MAX_NEIGHBOURCELLS);
4295 srv_create_list (&cd->ncell_list, act_ncell_list, MAX_NEIGHBOURCELLS, FALSE, 0);
4296
4297 for( index = 0; index < SC_INDEX; index++)
4298 {
4299 TRACE_EVENT_P3("[%u]i%u bcch_status=%u", rr_data->nc_data[index].arfcn,
4300 index, rr_data->nc_data[index].bcch_status);
4301 if( rr_data->nc_data[index].bcch_status NEQ EMPTY )
4302 {
4303 found = FALSE;
4304 for( i_nc = 0; act_ncell_list[i_nc] NEQ NOT_PRESENT_16BIT ; i_nc++)
4305 {
4306 if( rr_data->nc_data[index].arfcn EQ act_ncell_list[i_nc] )
4307 {
4308 found = TRUE;
4309 break;
4310 }
4311 }
4312 if( ! found )
4313 {
4314 TRACE_EVENT_P1(" Removing bad ncell [%u]", rr_data->nc_data[index].arfcn );
4315 rr_data->nc_data[index].bcch_status = EMPTY;
4316 rr_data->nc_data[index].arfcn = 0;
4317 rr_data->nc_data[index].avail_time = 0;
4318 }
4319 }
4320 }
4321 }
4322
4323 /*
4324 +--------------------------------------------------------------------+
4325 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4326 | STATE : code ROUTINE : att_code_mph_ncell_req |
4327 +--------------------------------------------------------------------+
4328
4329 PURPOSE : build a neighbourcell list for layer 1 in idle mode.
4330
4331 */
4332
4333 GLOBAL void att_code_mph_ncell_req (UBYTE index)
4334 {
4335 GET_INSTANCE_DATA;
4336 T_CELL_DATA * cd;
4337
4338 PALLOC (mph_ncell_req, MPH_NEIGHBOURCELL_REQ);
4339
4340 TRACE_FUNCTION ("att_code_mph_ncell_req()");
4341
4342 /*
4343 * get the pointer to the correct list.
4344 */
4345 if (index EQ SC_INDEX)
4346 cd = &rr_data->sc_data.cd;
4347 else
4348 cd = &rr_data->cr_data.cd;
4349
4350
4351 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,&cd->ncell_list);
4352
4353 /*
4354 * use neighbour cell list from system info 2/2bis/2ter
4355 */
4356 memset (mph_ncell_req->arfcn, 0xFF, 2*MAX_NEIGHBOURCELLS);
4357 srv_create_list (&cd->ncell_list,
4358 mph_ncell_req->arfcn, MAX_NEIGHBOURCELLS, FALSE,
4359 0);
4360 memcpy (rr_data->act_ncell_list, mph_ncell_req->arfcn,
4361 sizeof (rr_data->act_ncell_list));
4362
4363 #if defined(_SIMULATION_)
4364 TRACE_EVENT_WIN_P6("ncell_req arfcns:%4d %4d %4d %4d %4d %4d",
4365 mph_ncell_req->arfcn[0] NEQ NOT_PRESENT_16BIT ?
4366 mph_ncell_req->arfcn[0] : -1,
4367 mph_ncell_req->arfcn[1] NEQ NOT_PRESENT_16BIT ?
4368 mph_ncell_req->arfcn[1] : -1,
4369 mph_ncell_req->arfcn[2] NEQ NOT_PRESENT_16BIT ?
4370 mph_ncell_req->arfcn[2] : -1,
4371 mph_ncell_req->arfcn[3] NEQ NOT_PRESENT_16BIT ?
4372 mph_ncell_req->arfcn[3] : -1,
4373 mph_ncell_req->arfcn[4] NEQ NOT_PRESENT_16BIT ?
4374 mph_ncell_req->arfcn[4] : -1,
4375 mph_ncell_req->arfcn[5] NEQ NOT_PRESENT_16BIT ?
4376 mph_ncell_req->arfcn[5] : -1);
4377 #endif
4378
4379 /*
4380 * set the multiband parameter
4381 */
4382 mph_ncell_req->multi_band = rr_data->ncell_mb;
4383 #ifdef GPRS
4384 mph_ncell_req->sync_only = NORMAL_BA;
4385 #endif
4386 /*
4387 * check the list against band restrictions.
4388 */
4389 srv_remove_frequencies_in_array (&mph_ncell_req->arfcn[0]);
4390
4391 att_reorder_mph_ncell_req(mph_ncell_req);
4392 /*
4393 * send the list to layer 1
4394 */
4395 PSENDX (PL, mph_ncell_req);
4396 #if defined (REL99) && defined (TI_PS_FF_EMR)
4397 for_check_and_configure_si2quater(index);
4398 #endif
4399
4400 }
4401
4402 /*
4403 +--------------------------------------------------------------------+
4404 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4405 | STATE : code ROUTINE : att_code_mph_ncell_req_dedicated |
4406 +--------------------------------------------------------------------+
4407
4408 PURPOSE : builds a neighbourcell list for layer 1 in dedicated mode.
4409
4410 */
4411
4412 GLOBAL void att_code_mph_ncell_req_dedicated (void)
4413 {
4414 GET_INSTANCE_DATA;
4415 UBYTE start_index = 0;
4416 UBYTE old_index;
4417
4418 if ( rr_data->emo_arfcn EQ NULL )
4419 {
4420 #if defined (REL99) && defined (TI_PS_FF_EMR)
4421 USHORT si_read = (USHORT) (SYS_INFO_5_READ | SYS_INFO_5BIS_READ);
4422
4423 rr_data->sc_data.ba_list_ded = FALSE;
4424 if ( (rr_data->sc_data.cd.sys_info_read & si_read ) EQ si_read )
4425 {
4426 rr_data->sc_data.ba_list_ded = TRUE;
4427 rr_data->sc_data.ba_list_idle = FALSE;
4428 old_index = rr_data->sc_data.ba_index;
4429 rr_data->sc_data.ba_index = rr_data->sc_data.new_ba_index;
4430 }
4431 else if (rr_data->sc_data.ba_list_idle EQ TRUE)
4432 return;
4433 #endif
4434 {
4435 PALLOC (mph_ncell_req, MPH_NEIGHBOURCELL_REQ);
4436
4437 /*
4438 * initialise data structures,
4439 * clear ncell list to layer 1,
4440 * set multiband parameter.
4441 */
4442 memset (mph_ncell_req->arfcn, 0xFF, 2*MAX_NEIGHBOURCELLS);
4443 mph_ncell_req->multi_band = rr_data->ncell_mb;
4444
4445 /*
4446 * fill system info 5 and 5bis
4447 */
4448 if (rr_data->sc_data.cd.sys_info_read & (SYS_INFO_5_READ | SYS_INFO_5BIS_READ))
4449 start_index = srv_create_list (&rr_data->sc_data.cd.ncell_list,
4450 mph_ncell_req->arfcn,
4451 MAX_NEIGHBOURCELLS,
4452 FALSE,
4453 0);
4454 /*
4455 * fill system info 5ter
4456 */
4457 if (rr_data->sc_data.cd.sys_info_read & SYS_INFO_5TER_READ)
4458 srv_create_list (&rr_data->sc_data.five_ter_list,
4459 mph_ncell_req->arfcn,
4460 MAX_NEIGHBOURCELLS,
4461 FALSE,
4462 start_index);
4463 /*
4464 * Copy complete list for position detection for uplink
4465 * measurement reports.
4466 */
4467 memcpy (rr_data->act_ncell_list, mph_ncell_req->arfcn,
4468 sizeof (rr_data->act_ncell_list));
4469
4470 /*
4471 * check against band restrictions
4472 */
4473 srv_remove_frequencies_in_array (&mph_ncell_req->arfcn[0]);
4474
4475 /*
4476 * send list to layer 1.
4477 */
4478 PSENDX (PL, mph_ncell_req);
4479 }
4480 #if defined (REL99) && defined (TI_PS_FF_EMR)
4481 if (rr_data->sc_data.ba_list_ded NEQ TRUE )
4482 return;
4483 att_check_for_si5ter_and_enhpara(old_index);
4484 #endif
4485 }
4486 }
4487
4488 /*
4489 +--------------------------------------------------------------------+
4490 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4491 | STATE : code ROUTINE : att_code_prr_mm_info |
4492 +--------------------------------------------------------------------+
4493
4494 PURPOSE : provide MM at the end of cell selection or cell reselection
4495 with MM relevant data from the BCCH channel. These
4496 informations are:
4497
4498 IMSI attach / detach
4499 Call Reestablishment capability
4500 Base Station Identification Code
4501 Periodic Location Updating Time T3212
4502 and whether the MS camps in a forbidden location area.
4503
4504 */
4505
4506 static void att_code_prr_mm_info (T_mm_info *mm_info)
4507 {
4508 GET_INSTANCE_DATA;
4509 T_NC_DATA *rrd = &rr_data->nc_data[SC_INDEX];
4510
4511 TRACE_FUNCTION ("att_code_prr_mm_info()");
4512
4513 mm_info->valid = TRUE;
4514 mm_info->att = rrd->control_descr.att;
4515 mm_info->re = rrd->rach.re;
4516 mm_info->ncc = (rrd->bsic >> 3) & 7;
4517 mm_info->bcc = rrd->bsic & 7;
4518 mm_info->t3212 = rrd->control_descr.t3212;
4519 mm_info->la = (!(dat_forb_lai_check (SC_INDEX) AND
4520 dat_roam_forb_lai_check (SC_INDEX)));
4521
4522 /*
4523 * Parameter band needs a dummy value, otherwise component tests of RR
4524 * fail due to lack of ability of TAP
4525 */
4526 mm_info->band = BND_DMY_VAL;
4527 }
4528
4529 /*
4530 +--------------------------------------------------------------------+
4531 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4532 | STATE : code ROUTINE : att_code_rr_abort_ind |
4533 +--------------------------------------------------------------------+
4534
4535 PURPOSE : Indication of a failed cell selection or cell reselection
4536 to MM.
4537
4538 */
4539 GLOBAL void att_code_rr_abort_ind_original (T_RR_DATA *rr_dat, USHORT cause)
4540 {
4541 GET_INSTANCE_DATA;
4542 int i;
4543 PALLOC (abort_ind, RR_ABORT_IND);/* T_RR_ABORT_IND */
4544
4545 TRACE_FUNCTION ("att_code_rr_abort_ind()");
4546
4547 memset (abort_ind, 0, sizeof (*abort_ind));
4548
4549 /*
4550 * Indicates the end of a plmn available search
4551 */
4552 if (rr_dat->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI)
4553 {
4554 /* this sets the state of CS */
4555 cs_set_stop_active();
4556 }
4557
4558 TIMERSTOP(TABORT);
4559 /*
4560 * Set the parameters for MM, especially the requested service
4561 * from MM and the real reached service of RR.
4562 */
4563 abort_ind->op.v_op = 1;
4564 abort_ind->op.ts = (rr_dat->ms_data.operation_mode >> SHIFT_FOR_SIM_TYPE) & 1;
4565 abort_ind->op.m = (rr_dat->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1;
4566 abort_ind->op.sim_ins = (rr_dat->ms_data.operation_mode >> SHIFT_FOR_SIM_INSERTED) & 1;
4567 abort_ind->op.func = rr_dat->ms_data.req_mm_service;
4568 abort_ind->op.service = rr_dat->ms_data.rr_service;
4569 abort_ind->cause = cause;
4570
4571 if(rr_dat->ms_data.rr_service EQ NO_SERVICE)
4572 att_notify_stop_plmn_search (TRUE);
4573 else
4574 att_notify_stop_plmn_search (FALSE);
4575
4576 /*
4577 * resume normal RR operation and update the previous
4578 * requested MM and RR services
4579 */
4580 att_clear_parallel_search ();
4581
4582 rr_dat->ms_data.req_mm_service = att_get_func ();
4583 rr_data->cs_data.scan_mode = CS_NO_SCAN;
4584 TRACE_EVENT_P1 ("cause=%x", cause);
4585
4586 if (cause EQ RRCS_ABORT_CEL_SEL_FAIL)
4587 {
4588 #ifdef GPRS
4589 if (abort_ind->op.func NEQ FUNC_NET_SRCH_BY_MMI AND
4590 abort_ind->op.service EQ NO_SERVICE AND
4591 att_gprs_is_avail())
4592 {
4593 att_signal_gprs_support();
4594 }
4595 #endif
4596
4597 /*
4598 * If the abort cause is cell selection failed
4599 * add the list of available PLMNs.
4600 */
4601 att_order_plmns ();
4602 abort_ind->plmn_avail = rr_dat->sc_data.found_entries;
4603 for (i=0; i < rr_dat->sc_data.found_entries; i++)
4604 {
4605 T_FOUND_ELEMENT *pfound = &rr_dat->sc_data.found[i];
4606
4607 abort_ind->plmn[i] = pfound->plmn;
4608 abort_ind->rxlevel[i] = pfound->rxlev;
4609 abort_ind->lac_list[i] =pfound->lac; //LOL 02.01.2003: added for EONS support
4610
4611 TRACE_EVENT_P9 ("RR_ABORT_IND: [%u] MCC/MNC=%x%x%x/%x%x%x lac=%04x rx=%u",
4612 pfound->arfcn,
4613 pfound->plmn.mcc[0],
4614 pfound->plmn.mcc[1],
4615 pfound->plmn.mcc[2],
4616 pfound->plmn.mnc[0],
4617 pfound->plmn.mnc[1],
4618 pfound->plmn.mnc[2],
4619 pfound->lac,
4620 pfound->rxlev);
4621 }
4622
4623 EM_NET_SEARCH_PASSED;
4624 }
4625 else
4626 {
4627 /*
4628 * else clear this area of the primitive.
4629 */
4630 abort_ind->plmn_avail = 0;
4631 memset (abort_ind->plmn, 0, sizeof (abort_ind->plmn));
4632 memset (abort_ind->rxlevel, 0, sizeof (abort_ind->rxlevel));
4633
4634 EM_NET_SEARCH_FAILED;
4635 }
4636
4637 /*
4638 * Set mobile RF capability for MM messages
4639 */
4640 if (rr_dat->ms_data.rr_service EQ NO_SERVICE)
4641 abort_ind->power = 0;
4642 else
4643 abort_ind->power = att_get_power();
4644
4645 if ((rr_data->ms_data.req_mm_service NEQ FUNC_NET_SRCH_BY_MMI) AND
4646 (cause EQ RRCS_ABORT_CEL_SEL_FAIL))
4647 att_set_rr_service_info();
4648
4649 TRACE_OP_TYPE (&abort_ind->op, "RR_ABORT_IND");
4650 PSENDX (MM, abort_ind);
4651 }
4652
4653 /*
4654 +--------------------------------------------------------------------+
4655 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4656 | STATE : code ROUTINE : att_order_plmns |
4657 +--------------------------------------------------------------------+
4658
4659 PURPOSE : The function orders the found PLMNs after the following
4660 criterions:
4661
4662 all PLMNs with a fieldstrength greater then -85 dBm are
4663 ordered randomly. This is 50 percent of the requirement
4664 regarding GSM 3.22, chapter 4.4.3.1. MM checks then
4665 the HPLMN condition and the preferred PLMN condition.
4666
4667 */
4668
4669 static void att_order_plmns (void)
4670 {
4671 GET_INSTANCE_DATA;
4672 USHORT nr;
4673 USHORT i;
4674 /*
4675 * allocate dynamic memory to build a copy
4676 * of the list which is ordered randomly
4677 */
4678 T_FOUND_LIST * list;
4679
4680 TRACE_FUNCTION ("att_order_plmns()");
4681
4682 /*
4683 * initialize the copy
4684 */
4685 MALLOC (list, sizeof (T_FOUND_LIST));
4686 memset (list, 0, sizeof (T_FOUND_LIST));
4687
4688 /*
4689 * get the number of PLMNs which have a fieldstrength
4690 * greater then -85 dBm.
4691 */
4692 i=0;
4693 while ((nr = att_number_of_plmns_greater_85_dBm()) NEQ 0 )
4694 {
4695 /*
4696 * get a value in the range 0..nr-1
4697 * i.e. select a PLMN greater -85 randomly
4698 */
4699 nr = dat_random (nr);
4700
4701 /*
4702 * copy the nr-th plmn and indicate it in the source
4703 * as copied.
4704 */
4705 att_copy_found_plmn (list, nr, i);
4706
4707 /*
4708 * increment the number of copied networks.
4709 */
4710 i++;
4711 }
4712
4713 /*
4714 * copy all networks with a fieldstrength lower or equal -85 dBm.
4715 */
4716 att_copy_plmns_lower_or_equal_85_dBm (list, i);
4717
4718 /*
4719 * copy back the randomly sorted list
4720 */
4721 for (i=0; i < MAX_PLMN; i++)
4722 rr_data->sc_data.found[i] = list->element[i];
4723
4724 /*
4725 * de-allocate the dynamic memory
4726 */
4727 MFREE (list);
4728 }
4729
4730 /*
4731 +-----------------------------------------------------------------------+
4732 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4733 | STATE : code ROUTINE : att_number_of_plmns_greater_85_dBm |
4734 +-----------------------------------------------------------------------+
4735
4736 PURPOSE : The function calculates the number of available PLMNs with a
4737 fieldstrength higher then -85 dBm.
4738
4739 */
4740
4741 static USHORT att_number_of_plmns_greater_85_dBm (void)
4742 {
4743 GET_INSTANCE_DATA;
4744 USHORT nr = 0;
4745 USHORT i;
4746
4747 for (i=0; i< rr_data->sc_data.found_entries;i++)
4748 {
4749 if (rr_data->sc_data.found[i].plmn.v_plmn EQ V_PLMN_PRES)
4750 {
4751 if (rr_data->sc_data.found[i].rxlev > 25)
4752 {
4753 /*
4754 * -85 dBm = -110 + 25 !
4755 *
4756 * increment the number of found plmns.
4757 */
4758 nr++;
4759 }
4760 }
4761 }
4762
4763 /*
4764 * return the number of PLMNs with a fieldstrength greater than -85 dBm
4765 */
4766 return nr;
4767 }
4768
4769 /*
4770 +-----------------------------------------------------------------------+
4771 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4772 | STATE : code ROUTINE : att_copy_found_plmn |
4773 +-----------------------------------------------------------------------+
4774
4775 PURPOSE : The function copies the n-th plmn with a fieldstrength
4776 higher then -85 dBm in the found plmn copy.
4777
4778 */
4779
4780 static void att_copy_found_plmn (T_FOUND_LIST * list,
4781 USHORT n_in_source_85_dBm,
4782 USHORT i_in_copy)
4783 {
4784 GET_INSTANCE_DATA;
4785 USHORT x_in_source_85_dBm = 0;
4786 USHORT i_in_source = 0;
4787 T_FOUND_ELEMENT *in_source;
4788
4789 in_source = &rr_data->sc_data.found[0];
4790 for (i_in_source=0; i_in_source< rr_data->sc_data.found_entries;
4791 i_in_source++, in_source++)
4792 {
4793 if ((in_source->plmn.v_plmn EQ V_PLMN_PRES) AND (in_source->rxlev > 25))
4794 {
4795 /*
4796 * -85 dBm = -110 + 25 !
4797 *
4798 * increment the number of found plmns.
4799 */
4800 if (x_in_source_85_dBm EQ n_in_source_85_dBm)
4801 {
4802 /*
4803 * n-th PLMN with fieldstrength greater -85 dBm found
4804 */
4805 list->element[i_in_copy] = *in_source;
4806 i_in_copy ++;
4807 in_source->plmn.v_plmn = V_PLMN_NOT_PRES;
4808 return;
4809 }
4810 else
4811 x_in_source_85_dBm++;
4812 }
4813 }
4814 }
4815
4816 /*
4817 +-------------------------------------------------------------------------+
4818 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4819 | STATE : code ROUTINE : att_copy_plmns_lower_or_equal_85_dBm |
4820 +-------------------------------------------------------------------------+
4821
4822 PURPOSE : The function copies the remaining networks with a fieldstrength
4823 lower or equal -85 dBm in the found plmn copy.
4824
4825 */
4826
4827 static void att_copy_plmns_lower_or_equal_85_dBm (T_FOUND_LIST * list,
4828 USHORT i_in_copy)
4829 {
4830 GET_INSTANCE_DATA;
4831 USHORT i_in_source;
4832 T_FOUND_ELEMENT * in_source = &rr_data->sc_data.found[0];
4833
4834 for (i_in_source=0; i_in_source< rr_data->sc_data.found_entries;
4835 i_in_source++, in_source++)
4836 {
4837 if (in_source->plmn.v_plmn EQ V_PLMN_PRES)
4838 {
4839 /*
4840 * PLMN with fieldstrength less or equal -85 dBm found
4841 */
4842 list->element[i_in_copy] = *in_source;
4843 i_in_copy ++;
4844 }
4845 }
4846 }
4847 /*
4848 +--------------------------------------------------------------------+
4849 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4850 | STATE : code ROUTINE : att_code_net_lost |
4851 +--------------------------------------------------------------------+
4852
4853 PURPOSE :
4854
4855 */
4856
4857 GLOBAL void att_code_net_lost (void)
4858 {
4859 GET_INSTANCE_DATA;
4860 PALLOC (abort_ind, RR_ABORT_IND);
4861
4862 TRACE_FUNCTION ("att_code_net_lost()");
4863
4864 srv_clear_stored_prim (RR_ESTABLISH_REQ);
4865
4866 abort_ind->op.v_op = 1;
4867 abort_ind->op.ts = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_TYPE) & 1;
4868 abort_ind->op.m = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1;
4869 abort_ind->op.sim_ins = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_INSERTED) & 1;
4870 abort_ind->op.func = rr_data->ms_data.req_mm_service;
4871 abort_ind->op.service = NO_SERVICE;
4872
4873 abort_ind->cause = RRCS_ABORT_CEL_SEL_FAIL;
4874
4875 abort_ind->plmn_avail = 0;
4876 memset (abort_ind->plmn, 0, sizeof(abort_ind->plmn));
4877 memset (abort_ind->rxlevel, 0, sizeof (abort_ind->rxlevel));
4878
4879 TRACE_OP_TYPE (&abort_ind->op, "RR_ABORT_IND");
4880 PSENDX (MM, abort_ind);
4881
4882 rr_data->old_lai.lac = 0xFFFF;
4883 #ifdef GPRS
4884 rr_data->old_rac = NOT_PRESENT_8BIT;
4885 #endif
4886 }
4887
4888 /*
4889 +--------------------------------------------------------------------+
4890 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
4891 | STATE : code ROUTINE : att_code_rr_act_cnf |
4892 +--------------------------------------------------------------------+
4893
4894 PURPOSE : The function indicates a successful end of cell selection.
4895 The cell selection was initiated by MM.
4896
4897 */
4898
4899 GLOBAL void att_code_rr_act_cnf (void)
4900 {
4901 GET_INSTANCE_DATA;
4902 T_NC_DATA * rrd = &rr_data->nc_data[SC_INDEX];
4903
4904 PALLOC (rr_activate_cnf, RR_ACTIVATE_CNF);
4905
4906 TRACE_FUNCTION ("att_code_rr_act_cnf()");
4907
4908 TRACE_EVENT ("cell selection");
4909
4910
4911 rr_data->net_lost = FALSE;
4912
4913 TIMERSTOP(TABORT);
4914
4915 /*
4916 * indicate the requested MM service and the reached RR service
4917 * to MM.
4918 */
4919 rr_activate_cnf->op.v_op = 1;
4920 rr_activate_cnf->op.ts = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_TYPE) & 1;
4921 rr_activate_cnf->op.m = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1;
4922 rr_activate_cnf->op.sim_ins = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_INSERTED) & 1;
4923 rr_activate_cnf->op.func = rr_data->ms_data.req_mm_service;
4924 rr_activate_cnf->op.service = rr_data->ms_data.rr_service;
4925
4926 TRACE_EVENT_P9 ("RR_ACTIVATE_CNF[%u]: rMM=%s RRs=%s MCC/MNC=%x%x%x/%x%x%x",
4927 rrd->arfcn,
4928 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
4929 _rr_str_SERVICE[rr_data->ms_data.rr_service],
4930 rrd->lai.mcc[0],
4931 rrd->lai.mcc[1],
4932 rrd->lai.mcc[2],
4933 rrd->lai.mnc[0],
4934 rrd->lai.mnc[1],
4935 rrd->lai.mnc[2]);
4936
4937 if(GET_STATE(STATE_ATT) EQ ATT_CS_INIT )
4938 { /*Boot Time: Indicate only the start of power scan to MM*/
4939 memset( &rr_activate_cnf->mm_info, 0, sizeof(rr_activate_cnf->mm_info));
4940 memset( &rr_activate_cnf->plmn, 0, sizeof(rr_activate_cnf->plmn));
4941 rr_activate_cnf->lac = NOT_PRESENT_16BIT;
4942 rr_activate_cnf->cid = NOT_PRESENT_16BIT;
4943 rr_activate_cnf->gprs_indication = NOT_PRESENT_8BIT;
4944 rr_activate_cnf->power = NOT_PRESENT_8BIT;
4945 }
4946 else
4947 {
4948 /*
4949 * stop possibly parallel PLMN search
4950 */
4951 att_notify_stop_plmn_search (FALSE);
4952
4953 /*
4954 * resume normal RR operation and update the previous
4955 * requested MM and RR services
4956 */
4957 att_clear_parallel_search ();
4958 rr_data->ms_data.req_mm_service = att_get_func ();
4959 rr_data->cs_data.scan_mode = CS_NO_SCAN;
4960
4961
4962 if (rr_data->ms_data.req_mm_service NEQ rr_activate_cnf->op.func)
4963 {
4964 TRACE_EVENT_P2 ("rMM=%s RRs=%s resume normal RR operation",
4965 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
4966 _rr_str_SERVICE[rr_data->ms_data.rr_service]);
4967 }
4968 TRACE_OP_TYPE (&rr_activate_cnf->op, "RR_ACTIVATE_CNF");
4969
4970 /*
4971 * indicate the relevant BCCH parameter to MM
4972 */
4973 att_code_prr_mm_info (&rr_activate_cnf->mm_info);
4974
4975 /*
4976 * indicate the PLMN, Location Area and Cell Identity to NN
4977 */
4978 rr_activate_cnf->plmn.v_plmn = V_PLMN_PRES;
4979 memcpy (rr_activate_cnf->plmn.mcc, rrd->lai.mcc, SIZE_MCC);
4980 memcpy (rr_activate_cnf->plmn.mnc, rrd->lai.mnc, SIZE_MNC);
4981
4982 #if defined(_SIMULATION_)
4983 /* Implements Measure#32: Row 40 */
4984 att_print_mcc_mnc(rrd->arfcn, rrd->lai.mcc, rrd->lai.mnc, S2I_STRING("RR_ACTIVATE_CNF"));
4985 #endif
4986
4987 rr_activate_cnf->lac = rrd->lai.lac;
4988 rr_activate_cnf->cid = rrd->cell_id;
4989
4990 EM_PLMN_SRCH_PASSED;
4991
4992 /*
4993 * store the current location area and cell id to avoid
4994 * double signalling to MM
4995 */
4996 att_copy_old_lai_rac(SC_INDEX);
4997 #if 0
4998 memcpy (&rr_data->old_lai, &rr_data->nc_data[SC_INDEX].lai,
4999 sizeof(T_loc_area_ident));
5000 rr_data->old_cell_id = rr_data->nc_data[SC_INDEX].cell_id;
5001 #endif
5002
5003 #ifdef GPRS
5004 /*
5005 * indicates whether gprs operation is provided by the cell
5006 */
5007 /* MS Patch: CQ 24473 */
5008 rr_activate_cnf->gprs_indication = (rr_data->nc_data[SC_INDEX].rac NEQ
5009 NOT_PRESENT_8BIT);
5010
5011 #else
5012 rr_activate_cnf->gprs_indication = FALSE;
5013 #endif
5014
5015 /*
5016 * set the power class needed for some MM messages depending
5017 * on the frequency standard and the channel number
5018 */
5019 rr_activate_cnf->power = att_get_power();
5020
5021 /*
5022 * Display the Signal bar after camping on a cell with Full service
5023 */
5024 #ifdef FF_PS_RSSI
5025 RX_SetValue (rr_data->nc_data[SC_INDEX].rxlev,
5026 RX_QUAL_UNAVAILABLE,
5027 rr_data->nc_data[SC_INDEX].select_para.rxlev_access_min);
5028 #else
5029 RX_SetValue (rr_data->nc_data[SC_INDEX].rxlev);
5030 #endif
5031 att_set_rr_service_info();
5032 }
5033
5034 PSENDX (MM, rr_activate_cnf);
5035 }
5036
5037 /*
5038 +--------------------------------------------------------------------+
5039 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5040 | STATE : code ROUTINE : att_code_rr_act_ind |
5041 +--------------------------------------------------------------------+
5042
5043 PURPOSE : The function indicates a successful end of RR originated
5044 cell selection or a successful end of cell reselection.
5045
5046 */
5047
5048 GLOBAL void att_code_rr_act_ind (void)
5049 {
5050 GET_INSTANCE_DATA;
5051 T_NC_DATA * rrd = &rr_data->nc_data[SC_INDEX];
5052
5053 TRACE_FUNCTION ("att_code_rr_act_ind()");
5054
5055 TRACE_EVENT ("cell reselection");
5056
5057 rr_data->net_lost = FALSE;
5058
5059 TIMERSTOP (TABORT);
5060
5061 /* It is expected that this works, but this means that */
5062 /* the la-field in T_mm_info is superflous. This is also */
5063 /* true with some other variables in T_mm_info. */
5064
5065 /*
5066 * Special case if we have reselected on a cell belonging to a forbidden
5067 * location area in FS : it should not be possible on a LAC barred with a
5068 * LU_REJ(#13) ie roaming not allowed but can happen with a LAC barred
5069 * for regional provision of service ie LU_REJ(#12).
5070 * Then a RR_ABORT_IND is sent to MM to switch the entity into limited
5071 * service even if RR is happy with full service. An empty list of
5072 * available PLMN is reported so that no PLMN selection is triggered
5073 * by MM if MS is in automatic mode.
5074 */
5075 if (rr_data->ms_data.rr_service EQ FULL_SERVICE)
5076 {
5077 if (!(dat_forb_lai_check (SC_INDEX) AND
5078 dat_roam_forb_lai_check (SC_INDEX)))
5079 {
5080 /*
5081 * store the current location area and cell id to notify MM
5082 * when we are back in service
5083 */
5084 att_copy_old_lai_rac(SC_INDEX);
5085 #if 0
5086 memcpy (&rr_data->old_lai, &rr_data->nc_data[SC_INDEX].lai,
5087 sizeof(T_loc_area_ident));
5088 rr_data->old_cell_id = rr_data->nc_data[SC_INDEX].cell_id;
5089 #endif
5090
5091 /*
5092 * Indicate limited service, no PLMN available to MM
5093 */
5094 rr_data->sc_data.found_entries = 0;
5095 rr_data->ms_data.rr_service = LIMITED_SERVICE;
5096 att_code_rr_abort_ind (RRCS_ABORT_CEL_SEL_FAIL);
5097 rr_data->ms_data.rr_service = FULL_SERVICE;
5098
5099 return;
5100 }
5101 }
5102
5103 /* Set the black list search flag, whenever the location area or
5104 * routing area changes, so that black list search is started
5105 * after location/routing area update
5106 */
5107 if(rr_data->dyn_config.bl_cs_en)
5108 {
5109 if((!dat_plmn_equal_req (rrd->lai.mcc, rrd->lai.mnc,
5110 rr_data->old_lai.mcc, rr_data->old_lai.mnc))
5111 OR
5112 (rrd->lai.lac NEQ rr_data->old_lai.lac ))
5113 {
5114 /* Location area has changed. This flag shall be used to start black
5115 * list search after location area update
5116 */
5117 rr_data->cs_data.black_list_search_pending = TRUE;
5118 }
5119 #ifdef GPRS
5120 if(att_gprs_is_avail() AND (GET_STATE(STATE_GPRS) EQ GPRS_PIM_BCCH))
5121 {
5122 if((rrd->rac NEQ NOT_PRESENT_8BIT) AND (rrd->rac NEQ rr_data->old_rac))
5123 {
5124 /* Routing area has changed. This flag shall be used to start black
5125 * list search after routing area update in PIM_BCCH state
5126 */
5127 rr_data->cs_data.black_list_search_pending = TRUE;
5128 }
5129 }
5130 #endif
5131
5132 if(rr_data->cs_data.black_list_search_pending)
5133 TRACE_EVENT("black_list_search_pending : 1");
5134 }
5135
5136 /*
5137 * check the current location area identification and cell identity
5138 * against the last signalled one to MM. If it is not the same
5139 * a signalling with RR_ACTIVATE_IND is needed
5140 */
5141 if (!dat_plmn_equal_req (rrd->lai.mcc, rrd->lai.mnc,
5142 rr_data->old_lai.mcc, rr_data->old_lai.mnc)
5143 OR
5144 rrd->lai.lac NEQ rr_data->old_lai.lac
5145 OR
5146 rrd->cell_id NEQ rr_data->old_cell_id)
5147 {
5148 PALLOC (rr_activate_ind, RR_ACTIVATE_IND);
5149
5150 /*
5151 * A cell change has occurred. So a running Immediate assignment reject
5152 * timer is stopped.
5153 */
5154 /* If the MS reselects back onto the same SC (ARFCN) and T3122 is still
5155 running, it should be left running. If a new cell is selected, this timer
5156 should is stopped. MM is not informed, because it have already received a
5157 RR_ABORT_IND and left its state.*/
5158
5159 TIMERSTOP (T3122);
5160
5161
5162
5163 /*
5164 * indicate the requested MM service and the reached RR service
5165 * to MM.
5166 */
5167 rr_activate_ind->op.v_op = 1;
5168 rr_activate_ind->op.ts = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_TYPE) & 1;
5169 rr_activate_ind->op.m = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SEARCH_OFFSET) & 1;
5170 rr_activate_ind->op.sim_ins = (rr_data->ms_data.operation_mode >> SHIFT_FOR_SIM_INSERTED) & 1;
5171 if (rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI)
5172 rr_activate_ind->op.func = FUNC_PLMN_SRCH;
5173 else
5174 rr_activate_ind->op.func = rr_data->ms_data.req_mm_service;
5175 rr_activate_ind->op.service = rr_data->ms_data.rr_service;
5176
5177 TRACE_OP_TYPE (&rr_activate_ind->op, "RR_ACTIVATE_IND");
5178
5179 /*
5180 * stop possibly parallel PLMN search
5181 */
5182 att_notify_stop_plmn_search (FALSE);
5183
5184 /*
5185 * resume normal RR operation and update the previous
5186 * requested MM and RR services
5187 */
5188 att_clear_parallel_search();
5189 rr_data->ms_data.req_mm_service = att_get_func ();
5190 rr_data->cs_data.scan_mode = CS_NO_SCAN;
5191
5192
5193 /*
5194 * indicate the relevant BCCH parameter to MM
5195 */
5196 att_code_prr_mm_info (&rr_activate_ind->mm_info);
5197
5198 /*
5199 * indicate the PLMN, Location Area and Cell Identity to NN
5200 */
5201 rr_activate_ind->plmn.v_plmn = V_PLMN_PRES;
5202 memcpy (rr_activate_ind->plmn.mcc, rrd->lai.mcc, SIZE_MCC);
5203 memcpy (rr_activate_ind->plmn.mnc, rrd->lai.mnc, SIZE_MNC);
5204 #if defined(_SIMULATION_)
5205 /* Implements Measure#32: Row 40 */
5206 att_print_mcc_mnc(rrd->arfcn, rrd->lai.mcc, rrd->lai.mnc, S2I_STRING("RR_ACTIVATE_IND"));
5207 #endif
5208 rr_activate_ind->lac = rrd->lai.lac;
5209 rr_activate_ind->cid = rrd->cell_id;
5210
5211 /*
5212 * store the current location area and cell id to avoid
5213 * double signalling to MM
5214 */
5215 att_copy_old_lai_rac(SC_INDEX);
5216 #if 0
5217 memcpy (&rr_data->old_lai, &rr_data->nc_data[SC_INDEX].lai,
5218 sizeof(T_loc_area_ident));
5219 rr_data->old_cell_id = rr_data->nc_data[SC_INDEX].cell_id;
5220 #endif
5221
5222 #ifdef GPRS
5223 /*
5224 * indicates whether gprs operation is provided by the cell
5225 */
5226 /* MS Patch: CQ 24473 */
5227 rr_activate_ind->gprs_indication = (rr_data->nc_data[SC_INDEX].rac NEQ
5228 NOT_PRESENT_8BIT);
5229
5230 #else
5231 rr_activate_ind->gprs_indication = FALSE;
5232 #endif
5233
5234 /*
5235 * set the power class needed for some MM messages depending
5236 * on the frequency standard and the channel number
5237 */
5238 rr_activate_ind->power = att_get_power();
5239 /*
5240 * Limited to full service reselection
5241 * TMSI/IMSI data to be refreshed in TIL otherwise no paging possible
5242 */
5243 att_mph_identity_req();
5244
5245 EM_CELL_RESEL_FINISHED;
5246
5247 EM_FMM_RESEL_END_IND;
5248
5249 PSENDX (MM, rr_activate_ind);
5250 }
5251 else
5252 {
5253 /*
5254 * indicate changed imsi attach status or
5255 * changed periodic location updating time to MM
5256 * if it has changed, else it is only signalled to MM.
5257 */
5258 PALLOC (sync, RR_SYNC_IND);
5259
5260 att_code_prr_mm_info (&sync->mm_info);
5261 sync->ciph = NOT_PRESENT_8BIT;
5262 sync->chm.ch_mode = NOT_PRESENT_8BIT;
5263
5264 switch (rr_data->sc_data.selection_type)
5265 {
5266 case CELL_SELECTION:
5267 case CELL_RESELECTION:
5268 case CELL_RESELECTION_NC:
5269 case CELL_RESELECTION_RACH:
5270 case CELL_RESELECTION_CR:
5271 /*
5272 * cell reselection in idle mode
5273 */
5274 sync->synccs = SYNCCS_IDLE_SELECTION;
5275 break;
5276 default:
5277 /*
5278 * cell reselection after dedicated mode
5279 */
5280 sync->synccs = SYNCCS_BACK_FROM_DEDICATED;
5281 break;
5282 }
5283
5284 sync->bcch_info.v_bcch = FALSE;
5285 PSENDX (MM, sync);
5286 EM_FMM_RESEL_END_IND;
5287 }
5288 att_set_rr_service_info();
5289 }
5290
5291
5292
5293 /*
5294 +--------------------------------------------------------------------+
5295 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5296 | STATE : code ROUTINE : att_get_power |
5297 +--------------------------------------------------------------------+
5298
5299 PURPOSE : get the power class needed for some MM messages depending
5300 on the frequency standard and the channel number of the
5301 serving cell.
5302
5303 */
5304
5305 GLOBAL UBYTE att_get_power (void)
5306 {
5307 GET_INSTANCE_DATA;
5308 UBYTE power = 0;
5309 UBYTE power_idx = (UBYTE)-1;
5310
5311 TRACE_FUNCTION ("att_get_power()");
5312
5313 /* new method, use directly the rf capabilities */
5314 /* coding of power class according to classmark 3 [1..5] */
5315 switch (std)
5316 {
5317 case STD_900:
5318 case STD_EGSM:
5319 power_idx = IDX_PWRCLASS_900;
5320 break;
5321 case STD_1800:
5322 power_idx = IDX_PWRCLASS_1800;
5323 break;
5324
5325 case STD_DUAL:
5326 case STD_DUAL_EGSM:
5327 if (INRANGE(LOW_CHANNEL_1800,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_1800))
5328 power_idx = IDX_PWRCLASS_1800;
5329 else
5330 power_idx = IDX_PWRCLASS_900;
5331 break;
5332
5333 case STD_1900:
5334 power_idx = IDX_PWRCLASS_1900;
5335 break;
5336
5337 case STD_850:
5338 power_idx = IDX_PWRCLASS_850;
5339 break;
5340
5341 case STD_DUAL_US:
5342 if (rr_data->nc_data[SC_INDEX].arfcn < LOW_CHANNEL_1900)
5343 power_idx = IDX_PWRCLASS_850;
5344 else
5345 power_idx = IDX_PWRCLASS_1900;
5346 break;
5347
5348 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
5349 case STD_850_1800:
5350 if (INRANGE(LOW_CHANNEL_1800,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_1800))
5351 power_idx = IDX_PWRCLASS_1800;
5352 else
5353 power_idx = IDX_PWRCLASS_850;
5354 break;
5355
5356 case STD_900_1900:
5357 if (INRANGE(LOW_CHANNEL_1900,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_1900))
5358 power_idx = IDX_PWRCLASS_1900;
5359 else
5360 power_idx = IDX_PWRCLASS_900;
5361 break;
5362
5363 case STD_850_900_1800:
5364 if (INRANGE(LOW_CHANNEL_1800,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_1800))
5365 power_idx = IDX_PWRCLASS_1800;
5366 else if (INRANGE(LOW_CHANNEL_850,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_850))
5367 power_idx = IDX_PWRCLASS_850;
5368 else
5369 power_idx = IDX_PWRCLASS_900;
5370 break;
5371
5372 case STD_850_900_1900:
5373 if (INRANGE(LOW_CHANNEL_1900,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_1900))
5374 power_idx = IDX_PWRCLASS_1900;
5375 else if (INRANGE(LOW_CHANNEL_850,rr_data->nc_data[SC_INDEX].arfcn,HIGH_CHANNEL_850))
5376 power_idx = IDX_PWRCLASS_850;
5377 else
5378 power_idx = IDX_PWRCLASS_900;
5379 break;
5380 #endif
5381 }
5382
5383 if (power_idx NEQ (UBYTE)-1)
5384 power = rr_data->ms_data.rf_cap.rf_power.pow_class4[power_idx].pow_class;
5385 else
5386 power = 0;
5387
5388 /*
5389 TRACE_EVENT_P3 ("power=%u(new), idx=%d, std=%u", power, power_idx, std);
5390 */
5391
5392 if (power)
5393 power--; /* coding of power class according to classmark 1 and 2 [0..4] */
5394
5395 return power;
5396 }
5397
5398 /*
5399 +--------------------------------------------------------------------+
5400 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5401 | STATE : code ROUTINE : att_continue_cell_reselect |
5402 +--------------------------------------------------------------------+
5403
5404 PURPOSE : A cell reselection candidate has failed. Inside this function
5405 the next one is searched.
5406
5407 */
5408
5409 GLOBAL void att_continue_cell_reselect (void)
5410 {
5411 GET_INSTANCE_DATA;
5412 TRACE_FUNCTION ("att_continue_cell_reselect()");
5413
5414 switch (rr_data->sc_data.selection_type)
5415 {
5416 case BACK_FROM_DEDICATED:
5417 case BACK_FROM_DEDICATED_RLF:
5418 /*
5419 * After a dedicated connection
5420 */
5421 rr_data->reselect_index =
5422 att_get_next_highest_c2_idx (rr_data->reselect_index);
5423 att_select_cell_dedicated ();
5424 break;
5425
5426 default:
5427 /*
5428 * In idle mode
5429 */
5430 #ifdef GPRS
5431 if( rr_data->gprs_data.use_c31)
5432 {
5433 rr_data->reselect_index = att_get_next_best_c32_index(TRUE);
5434 if (! att_check_cell_c31())
5435 att_try_old_cell();
5436 }
5437 else
5438 {
5439 #endif
5440 rr_data->reselect_index =
5441 att_get_next_highest_c2_idx (rr_data->reselect_index);
5442 /*
5443 * If no other cell is available, try the old one
5444 */
5445 if (! att_check_cell ())
5446 {
5447 TRACE_EVENT ("no further cell found -> try old one");
5448 att_try_old_cell ();
5449 }
5450 else
5451 {
5452 TRACE_EVENT_P2 ("try next cell [%u]i%u",
5453 rr_data->nc_data[rr_data->reselect_index].arfcn,
5454 rr_data->reselect_index);
5455 }
5456
5457
5458
5459 #ifdef GPRS
5460 }
5461 #endif
5462 break;
5463 }
5464 }
5465
5466 /*
5467 +--------------------------------------------------------------------+
5468 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5469 | STATE : code ROUTINE : att_copy_rach_parameter |
5470 +--------------------------------------------------------------------+
5471
5472 PURPOSE : After reception of system information message 1 to 4 in
5473 idle mode or cell selection / reselection the RACH parameters
5474 are stored. The flag indicate_changes defines whether
5475 changes in the RACH parameter shall be forwarded to MM
5476 (in idle mode for serving cell) or not (any other cases).
5477
5478 */
5479
5480 static void att_copy_rach_parameter (UBYTE index,
5481 T_rach_ctrl *rach,
5482 UBYTE indicate_changes)
5483 {
5484 GET_INSTANCE_DATA;
5485 T_NC_DATA *rrd = &rr_data->nc_data[index];
5486
5487 TRACE_FUNCTION ("att_copy_rach_parameter()");
5488
5489 if (index EQ SC_INDEX AND
5490 indicate_changes)
5491 {
5492 /*
5493 * compare only for serving cell
5494 */
5495 if (rrd->rach.re NEQ rach->re)
5496 {
5497 /*
5498 * change of reestablishment flag indicate to MM
5499 */
5500 PALLOC (sync, RR_SYNC_IND);
5501 rrd->rach.re = rach->re;
5502
5503 att_code_prr_mm_info (&sync->mm_info);
5504 sync->ciph = NOT_PRESENT_8BIT;
5505 sync->chm.ch_mode = NOT_PRESENT_8BIT;
5506 sync->synccs = SYNCCS_SYS_INFO_CHANGE;
5507 memset(&sync->bcch_info, 0, sizeof(T_bcch_info));
5508 sync->bcch_info.v_bcch = FALSE;
5509 PSENDX (MM, sync);
5510 }
5511
5512 if (rrd->rach.ac NEQ rach->ac)
5513 {
5514 /*
5515 * change of access classes indicate to MM
5516 */
5517 PALLOC (sync, RR_SYNC_IND);
5518
5519 sync->ciph = NOT_PRESENT_8BIT;
5520 sync->chm.ch_mode = NOT_PRESENT_8BIT;
5521 sync->synccs = SYNCCS_ACC_CLS_CHA;
5522 memset(&sync->mm_info, 0, sizeof(T_mm_info));
5523 sync->mm_info.valid = FALSE;
5524 memset(&sync->bcch_info, 0, sizeof(T_bcch_info));
5525 sync->bcch_info.v_bcch = FALSE;
5526 PSENDX (MM, sync);
5527 }
5528 }
5529
5530 rrd->rach = *rach;
5531 }
5532
5533 /*
5534 +--------------------------------------------------------------------+
5535 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5536 | STATE : code ROUTINE : att_copy_sys_info_1_par |
5537 +--------------------------------------------------------------------+
5538
5539 PURPOSE : copy the relevant system information type 1 parameter after
5540 reception in idle mode or during cell selection or cell
5541 reselection.
5542
5543 */
5544
5545 GLOBAL void att_copy_sys_info_1_par (UBYTE index,
5546 T_D_SYS_INFO_1 *sys_info_1,
5547 T_LIST *cell_chan_desc)
5548 {
5549 GET_INSTANCE_DATA;
5550 T_CELL_DATA * cd;
5551 UBYTE indicate_changes = index EQ SC_INDEX;
5552
5553 switch (index)
5554 {
5555 case SC_INDEX:
5556 case CR_INDEX:
5557 /*
5558 * set pointer to data
5559 */
5560 if (index EQ SC_INDEX)
5561 cd = &rr_data->sc_data.cd;
5562 else
5563 cd = &rr_data->cr_data.cd;
5564
5565 /*
5566 * If a cell channel description is not stored for
5567 * this cell or the new cell channel description is
5568 * different, store the new one.
5569 */
5570 if (cd->v_cell_chan_desc EQ NO_CONTENT OR
5571 srv_compare_list (&cd->cell_chan_desc,
5572 cell_chan_desc) EQ FALSE)
5573 {
5574 srv_copy_list (&cd->cell_chan_desc,
5575 cell_chan_desc,
5576 sizeof (T_LIST));
5577
5578 cd->v_cell_chan_desc = WITH_CHANGED_CONTENT;
5579 if((indicate_changes) AND (GET_STATE(STATE_ATT) EQ ATT_IDLE)
5580 AND ( rr_data->sc_data.cd.cbch_chan_desc.hop EQ H_FREQ) )
5581 {
5582 #ifdef REL99
5583 att_config_cbch();
5584 #else
5585 att_build_cbch();
5586 #endif
5587 }
5588 }
5589 /* Get the band indicator value from SI1 message */
5590 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
5591 cd->band_indicator = sys_info_1->si1_rest_oct.band_indicator;
5592 if (index EQ SC_INDEX)
5593 {
5594 att_update_std_band_indicator (cd->band_indicator);
5595 }
5596 #endif
5597 break;
5598 }
5599
5600 att_copy_rach_parameter (index, &sys_info_1->rach_ctrl, indicate_changes);
5601
5602 /*
5603 * Indicate that the system information type 1 message has been read.
5604 */
5605 att_set_sys_info_read (SYS_INFO_1_READ, index);
5606 }
5607
5608 /*
5609 +--------------------------------------------------------------------+
5610 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5611 | STATE : code ROUTINE : att_copy_sys_info_2bis_par |
5612 +--------------------------------------------------------------------+
5613
5614 PURPOSE : copy the relevant system information type 2bis parameter after
5615 reception in idle mode (in this case changes are to detect)
5616 or during cell selection or cell reselection.
5617
5618 */
5619
5620 GLOBAL void att_copy_sys_info_2bis_par (UBYTE index,
5621 T_D_SYS_INFO_2BIS *sys_info_2bis,
5622 T_LIST *new_2bis_list,
5623 UBYTE ncell_ext,
5624 UBYTE indicate_changes)
5625 {
5626 /* Implements RR Clone findings #3 */
5627
5628 TRACE_FUNCTION ("att_copy_sys_info_2bis_par()");
5629
5630
5631 /* Implements RR Clone findings #3 */
5632 att_copy_sys_info_2bis_2ter_par(index, SI_TYPE_2BIS, new_2bis_list,
5633 &sys_info_2bis->neigh_cell_desc,
5634 indicate_changes);
5635
5636
5637
5638 att_copy_rach_parameter (index, &sys_info_2bis->rach_ctrl, indicate_changes);
5639 }
5640
5641 /*
5642 +--------------------------------------------------------------------+
5643 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5644 | STATE : code ROUTINE : att_copy_sys_info_2_par |
5645 +--------------------------------------------------------------------+
5646
5647 PURPOSE : copy the relevant system information type 2 parameter after
5648 reception in idle mode (in this case changes are to detect)
5649 or during cell selection or cell reselection.
5650
5651 */
5652
5653 GLOBAL void att_copy_sys_info_2_par (UBYTE index,
5654 T_D_SYS_INFO_2 *sys_info_2,
5655 T_LIST *new_2_list,
5656 UBYTE ncell_ext,
5657 UBYTE indicate_changes)
5658 {
5659 GET_INSTANCE_DATA;
5660 T_LIST new_list;
5661 T_CELL_DATA *cd;
5662 BOOL modified = FALSE;
5663
5664 TRACE_FUNCTION ("att_copy_sys_info_2_par()");
5665
5666 switch (index)
5667 {
5668 case SC_INDEX:
5669 case CR_INDEX:
5670 if (index EQ SC_INDEX)
5671 {
5672 cd = &rr_data->sc_data.cd;
5673 if ((cd->sys_info_read & SYS_INFO_2_READ) EQ SYS_INFO_2_READ)
5674 {
5675 srv_copy_list (&cd->ncell_list, new_2_list, sizeof (T_LIST));
5676 att_clean_buf ((USHORT)(IND_SI_2BIS | IND_SI_2TER));
5677 cd->sys_info_read &= ~(SYS_INFO_2BIS_READ | SYS_INFO_2TER_READ);
5678 att_check_2ter_read (index);
5679 }
5680 else
5681 srv_merge_list (&cd->ncell_list, new_2_list);
5682
5683 if( cd->ncell_ext NEQ ncell_ext )
5684 {
5685 PALLOC (mph_sync_req, MPH_SYNC_REQ);
5686 mph_sync_req->cs = CS_SYS_INFO_2BIS_SUPPORT_CHANGED;
5687 PSENDX (PL, mph_sync_req);
5688 cd->ncell_ext = ncell_ext;
5689 }
5690 modified = TRUE;
5691 #ifdef GPRS
5692 rr_data->gprs_data.ba_bcch_modified= FALSE;
5693 #endif
5694 }
5695 else
5696 {
5697 cd = &rr_data->cr_data.cd;
5698 /*
5699 * merge 2 list with the old neighbour cell list
5700 */
5701 srv_copy_list (&new_list, &cd->ncell_list,
5702 sizeof (T_LIST));
5703 srv_merge_list (&new_list, new_2_list);
5704
5705 if (srv_compare_list (&cd->ncell_list, &new_list) EQ FALSE)
5706 {
5707 /*
5708 * both lists are different
5709 */
5710 srv_copy_list (&cd->ncell_list, &new_list, sizeof (T_LIST));
5711 modified = TRUE;
5712 }
5713 cd->ncell_ext = ncell_ext;
5714 }
5715
5716 /* CSI-LLD section:4.1.1.11
5717 * This function Updates the black list with the BA list received in si2
5718 */
5719 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,&cd->ncell_list);
5720
5721 dat_store_neigh_cell_desc (SYS_INFO_2_MSG, index,
5722 &sys_info_2->neigh_cell_desc,&cd->ncell_list);
5723 /*
5724 * Indicate that the system information type 2 message has been read
5725 * and if applicable the system information type 2bis is not needed to read.
5726 */
5727 att_set_sys_info_read (SYS_INFO_2_READ, index);
5728 if (ncell_ext EQ 0)
5729 att_set_sys_info_read (SYS_INFO_2BIS_READ, index);
5730 /*
5731 * forward new neighbour cell list to layer 1 if
5732 * changes shall be indicated
5733 */
5734 if (modified AND indicate_changes)
5735 {
5736 att_code_mph_ncell_req (index);
5737 }
5738
5739 /*
5740 * copy ncc permitted field
5741 */
5742 cd->ncc_permitted = sys_info_2->ncc_permit;
5743 break;
5744 }
5745 att_copy_rach_parameter (index, &sys_info_2->rach_ctrl, indicate_changes);
5746
5747 }
5748
5749 /*
5750 +--------------------------------------------------------------------+
5751 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5752 | STATE : code ROUTINE : att_copy_sys_info_2ter_par |
5753 +--------------------------------------------------------------------+
5754
5755 PURPOSE : copy the relevant system information type 2ter parameter after
5756 reception in idle mode or during cell selection or cell
5757 reselection.
5758
5759 */
5760 GLOBAL void att_copy_sys_info_2ter_par (UBYTE index,
5761 T_D_SYS_INFO_2TER *sys_info_2ter,
5762 T_LIST *new_2ter_list,
5763 UBYTE indicate_changes)
5764 {
5765
5766 /* Implements RR Clone findings #3 */
5767
5768 TRACE_FUNCTION ("att_copy_sys_info_2ter_par()");
5769
5770 /* Implements RR Clone findings #8 */
5771 att_copy_sys_info_2bis_2ter_par(index, SI_TYPE_2TER, new_2ter_list,
5772 &sys_info_2ter->neigh_cell_desc,
5773 indicate_changes);
5774 }
5775
5776 /*
5777 +--------------------------------------------------------------------+
5778 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5779 | STATE : code ROUTINE : att_check_2ter_read |
5780 +--------------------------------------------------------------------+
5781
5782 PURPOSE : checks whether to wait for SI_2ter.
5783 */
5784
5785 static void att_check_2ter_read (UBYTE index)
5786 {
5787 GET_INSTANCE_DATA;
5788 if (rr_data->nc_data[index].c2_par.two_ter EQ FALSE)
5789 att_set_sys_info_read (SYS_INFO_2TER_READ, index);
5790
5791 /*
5792 * only in dualband standards 2ter is taken in account
5793 * in single bands it is ignored.
5794 */
5795 switch (std)
5796 {
5797 case STD_900:
5798 case STD_EGSM:
5799 case STD_1800:
5800 case STD_850:
5801 case STD_1900:
5802 att_set_sys_info_read (SYS_INFO_2TER_READ, index);
5803 break;
5804 default:
5805 break;
5806 }
5807 }
5808 /*
5809 +--------------------------------------------------------------------+
5810 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
5811 | STATE : code ROUTINE : att_copy_sys_info_3_par |
5812 +--------------------------------------------------------------------+
5813
5814 PURPOSE : copy the relevant system information type 3 parameter after
5815 reception in idle mode or during cell selection or cell
5816 reselection.
5817 */
5818
5819 /*
5820 * conversion from air interface coding for DTX usage to internal
5821 * notation
5822 */
5823 static const UBYTE dtx_bcch [3] = { DTX_USED, DTX_USED, DTX_NOT_USED };
5824
5825
5826 GLOBAL void att_copy_sys_info_3_par (UBYTE index,
5827 T_D_SYS_INFO_3 *sys_info_3,
5828 UBYTE indicate_changes)
5829 {
5830 GET_INSTANCE_DATA;
5831 T_NC_DATA * rrd = &rr_data->nc_data[index];
5832 UBYTE lai_changed = FALSE;
5833 UBYTE control_changed_mm = FALSE;
5834 UBYTE control_changed_l1 = FALSE;
5835 TRACE_FUNCTION ("att_copy_sys_info_3_par()");
5836
5837 #if defined(_SIMULATION_)
5838 TRACE_EVENT_WIN_P7 ( "MCC o/i[%d]= %x%x%x/%x%x%x",
5839 ((int)rrd->arfcn),
5840 rrd->lai.mcc[0],
5841 rrd->lai.mcc[1],
5842 rrd->lai.mcc[2],
5843 sys_info_3->loc_area_ident.mcc[0],
5844 sys_info_3->loc_area_ident.mcc[1],
5845 sys_info_3->loc_area_ident.mcc[2]);
5846 TRACE_EVENT_WIN_P7 ( "MNC o/i[%d]= %x%x%x/%x%x%x",
5847 ((int)rrd->arfcn),
5848 rrd->lai.mnc[0],
5849 rrd->lai.mnc[1],
5850 rrd->lai.mnc[2],
5851 sys_info_3->loc_area_ident.mnc[0],
5852 sys_info_3->loc_area_ident.mnc[1],
5853 sys_info_3->loc_area_ident.mnc[2]);
5854 #endif
5855
5856 if (index EQ SC_INDEX)
5857 {
5858 /*
5859 * compare only for serving cell
5860 *
5861 * check location area information and cell id
5862 */
5863 if (rrd->cell_id NEQ sys_info_3->cell_ident)
5864 lai_changed = TRUE;
5865 rrd->cell_id = sys_info_3->cell_ident;
5866
5867 if (!dat_plmn_equal_req (sys_info_3->loc_area_ident.mcc,
5868 sys_info_3->loc_area_ident.mnc,
5869 rrd->lai.mcc,
5870 rrd->lai.mnc))
5871 lai_changed = TRUE;
5872 if (rrd->lai.lac NEQ sys_info_3->loc_area_ident.lac)
5873 lai_changed = TRUE;
5874 #if defined(_SIMULATION_)
5875 TRACE_EVENT_WIN_P3 ( "LAI[%d] changed=%d indicate_changes=%d",
5876 rr_data->nc_data[index].arfcn, lai_changed, indicate_changes);
5877 #endif
5878
5879 if (lai_changed AND indicate_changes)
5880 {
5881 /*
5882 * If a change of location area code is detected,
5883 * signal this as a cell reselection to MM to force
5884 * a location updating.
5885 */
5886 att_reset_old_lai_rac();
5887 memcpy (&rrd->lai, &sys_info_3->loc_area_ident,
5888 sizeof (T_loc_area_ident));
5889 att_code_rr_act_ind ();
5890 #ifdef GPRS
5891 if (att_gprs_is_avail())
5892 {
5893 /*XY: inform GRR, and don't wait for CR_RSP */
5894 att_rrgrr_cr_ind(CR_ABNORMAL);
5895 /*
5896 * we are in the process of acquiring SIs because GRR
5897 * has requested it. We have to set the sys_info_read bitmap
5898 * to complete. in order to send a GPRS_SI13_IND to GRR below.
5899 * The missing SIs which RR requested will still arrive from ALR
5900 * so it does not matter that we reset the bitmap now.
5901 */
5902 att_set_sys_info_read(ALL_SYS_INFO_READ, SC_INDEX);
5903 rr_data->gprs_data.start_proc = START_PROC_NOTHING;
5904 att_signal_gprs_support();
5905 }
5906 #endif
5907 }
5908
5909 /*
5910 * check imsi attach status and
5911 * periodic location update time
5912 */
5913 if ((rrd->control_descr.att NEQ sys_info_3->ctrl_chan_desc.att
5914 OR
5915 rrd->control_descr.t3212 NEQ sys_info_3->ctrl_chan_desc.t3212)
5916 AND
5917 indicate_changes)
5918 control_changed_mm = TRUE;
5919
5920 /*
5921 * check control channel description
5922 */
5923 if (rrd->control_descr.bs_ag_blks_res NEQ
5924 sys_info_3->ctrl_chan_desc.bs_ag_blks_res)
5925 control_changed_l1 = TRUE;
5926 if (rrd->control_descr.ccch_conf NEQ
5927 sys_info_3->ctrl_chan_desc.ccch_conf)
5928 control_changed_l1 = TRUE;
5929 if (rrd->control_descr.bs_pa_mfrms NEQ
5930 sys_info_3->ctrl_chan_desc.bs_pa_mfrms)
5931 control_changed_l1 = TRUE;
5932
5933 /*
5934 * check cell selection parameters
5935 */
5936 if (rrd->select_para.ms_txpwr_max_cch NEQ
5937 sys_info_3->cell_select.ms_txpwr_max_cch)
5938 {
5939 control_changed_l1 = TRUE;
5940 TRACE_EVENT_P2("txpwr_max_cch changed from %d -> %d in SI3", rrd->select_para.ms_txpwr_max_cch,
5941 sys_info_3->cell_select.ms_txpwr_max_cch);
5942 }
5943 }
5944
5945 /*
5946 * store location information and control channel description
5947 */
5948 rrd->cell_id = sys_info_3->cell_ident;
5949 #ifdef REL99
5950 rrd->mscr_flag = sys_info_3->ctrl_chan_desc.mscr;
5951 #endif
5952 memcpy (&rrd->lai, &sys_info_3->loc_area_ident,
5953 sizeof (T_loc_area_ident));
5954 memcpy (&rrd->control_descr, &sys_info_3->ctrl_chan_desc,
5955 sizeof (T_ctrl_chan_desc));
5956
5957 if (control_changed_mm)
5958 {
5959 /*
5960 * indicate changed imsi attach status or
5961 * changed periodic location updating time to MM
5962 */
5963 PALLOC (sync, RR_SYNC_IND);
5964
5965 att_code_prr_mm_info (&sync->mm_info);
5966 sync->ciph = NOT_PRESENT_8BIT;
5967 sync->chm.ch_mode = NOT_PRESENT_8BIT;
5968 sync->synccs = SYNCCS_SYS_INFO_CHANGE;
5969 sync->bcch_info.v_bcch = FALSE;
5970 PSENDX (MM, sync);
5971 }
5972
5973 /*
5974 * store the system information type 3 message parameter.
5975 */
5976 switch (index)
5977 {
5978 case SC_INDEX:
5979 rr_data->sc_data.cd.cell_options.pow_ctrl =
5980 sys_info_3->cell_opt_bcch.pow_ctrl;
5981 rr_data->sc_data.cd.cell_options.rlt =
5982 sys_info_3->cell_opt_bcch.rlt;
5983 rr_data->sc_data.cd.dtx =
5984 dtx_bcch [sys_info_3->cell_opt_bcch.dtx_b];
5985 rr_data->sc_data.cd.dtx_half =
5986 rr_data->sc_data.cd.dtx_full =
5987 rr_data->sc_data.cd.dtx;
5988 #if defined (REL99) && defined (TI_PS_FF_EMR)
5989 /*The SI-2quater information that we store is useful for monitoring appropriate
5990 BCCH periodically: no need to change status in re-acquisition*/
5991 if ( sys_info_3->si3_rest_oct.v_si2quater_ind )
5992 {
5993 if ( rr_data->sc_data.cd.si2quater_status EQ SI2QUATER_ABSENT)
5994 rr_data->sc_data.cd.si2quater_status = SI2QUATER_CONFIGURE;
5995 rr_data->sc_data.cd.si2quater_pos = sys_info_3->si3_rest_oct.si2quater_ind.si2quater_pos;
5996 }
5997 #endif
5998 break;
5999
6000 case CR_INDEX:
6001 rr_data->cr_data.cd.cell_options.pow_ctrl =
6002 sys_info_3->cell_opt_bcch.pow_ctrl;
6003 rr_data->cr_data.cd.cell_options.rlt =
6004 sys_info_3->cell_opt_bcch.rlt;
6005 rr_data->cr_data.cd.dtx =
6006 dtx_bcch [sys_info_3->cell_opt_bcch.dtx_b];
6007 rr_data->cr_data.cd.dtx_half =
6008 rr_data->cr_data.cd.dtx_full =
6009 rr_data->cr_data.cd.dtx;
6010 #if defined (REL99) && defined (TI_PS_FF_EMR)
6011 /*The SI-2quater information that we store is used only if this cell is selected
6012 In case of serving cell, this information should be useful for monitoring appropriate
6013 BCCH periodically*/
6014 rr_data->cr_data.cd.si2quater_status = SI2QUATER_ABSENT;
6015 if ( sys_info_3->si3_rest_oct.v_si2quater_ind )
6016 {
6017 rr_data->cr_data.cd.si2quater_status = SI2QUATER_CONFIGURE;
6018 rr_data->cr_data.cd.si2quater_pos = sys_info_3->si3_rest_oct.si2quater_ind.si2quater_pos;
6019 }
6020 #endif
6021 break;
6022 }
6023
6024 memcpy (&rrd->select_para, &sys_info_3->cell_select,
6025 sizeof (T_cell_select));
6026 att_copy_rach_parameter (index, &sys_info_3->rach_ctrl,
6027 indicate_changes);
6028
6029
6030 att_copy_c2_parameter_si3 (index, &sys_info_3->si3_rest_oct);
6031
6032 att_set_sys_info_read (SYS_INFO_3_READ, index);
6033 att_check_2ter_read (index);
6034
6035 if (control_changed_l1 AND indicate_changes)
6036 {
6037 /*
6038 * forward changed control channel description
6039 * to layer 1
6040 */
6041 att_build_idle_req (SC_INDEX, MODE_SYS_INFO_CHANGE);
6042 #ifdef REL99
6043 att_config_cbch ();
6044 #else
6045 att_build_cbch();
6046 #endif
6047 }
6048 }
6049
6050 /*
6051 +--------------------------------------------------------------------+
6052 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6053 | STATE : code ROUTINE : att_copy_sys_info_4_par |
6054 +--------------------------------------------------------------------+
6055
6056 PURPOSE : copy the relevant system information type 4 parameter after
6057 reception in idle mode or during cell selection or cell
6058 reselection.
6059 */
6060
6061 GLOBAL void att_copy_sys_info_4_par (UBYTE index,
6062 T_D_SYS_INFO_4 *sys_info_4,
6063 UBYTE indicate_changes)
6064 {
6065 GET_INSTANCE_DATA;
6066 T_NC_DATA * rrd = &rr_data->nc_data[index];
6067 UBYTE lai_changed = FALSE;
6068 UBYTE control_changed_l1 = FALSE;
6069 T_CELL_DATA * cd;
6070
6071 TRACE_FUNCTION ("att_copy_sys_info_4_par()");
6072
6073 switch (index)
6074 {
6075 case SC_INDEX:
6076 case CR_INDEX:
6077 /*
6078 * set pointer to data
6079 */
6080 if (index EQ SC_INDEX)
6081 cd = &rr_data->sc_data.cd;
6082 else
6083 cd = &rr_data->cr_data.cd;
6084
6085 if (index EQ SC_INDEX)
6086 {
6087 /*
6088 * compare only for serving cell
6089 *
6090 * check location information
6091 */
6092 if (!dat_plmn_equal_req (sys_info_4->loc_area_ident.mcc,
6093 sys_info_4->loc_area_ident.mnc,
6094 rrd->lai.mcc,
6095 rrd->lai.mnc))
6096 lai_changed = TRUE;
6097 if (rrd->lai.lac NEQ sys_info_4->loc_area_ident.lac)
6098 lai_changed = TRUE;
6099
6100 if (lai_changed AND indicate_changes)
6101 {
6102 /*
6103 * If a change of location area code is detected,
6104 * signal this as a cell reselection to MM to force
6105 * a location updating.
6106 */
6107 att_reset_old_lai_rac();
6108 memcpy (&rrd->lai, &sys_info_4->loc_area_ident,
6109 sizeof (T_loc_area_ident));
6110 att_code_rr_act_ind ();
6111 #ifdef GPRS
6112 if (att_gprs_is_avail())
6113 {
6114 /*XY: inform GRR, and don't wait for CR_RSP */
6115 att_rrgrr_cr_ind(CR_ABNORMAL);
6116 /*
6117 * we are in the process of acquiring SIs because GRR
6118 * has requested it. We have to set the sys_info_read bitmap
6119 * to complete. in order to send a GPRS_SI13_IND to GRR below.
6120 * The missing SIs which RR requested will still arrive from ALR
6121 * so it does not matter that we reset the bitmap now.
6122 */
6123 att_set_sys_info_read(ALL_SYS_INFO_READ, SC_INDEX);
6124 rr_data->gprs_data.start_proc = START_PROC_NOTHING;
6125 att_signal_gprs_support();
6126 }
6127 #endif
6128 }
6129
6130 /*
6131 * check cell selection parameters
6132 */
6133 if (rrd->select_para.ms_txpwr_max_cch NEQ
6134 sys_info_4->cell_select.ms_txpwr_max_cch)
6135 {
6136 control_changed_l1 = TRUE;
6137 TRACE_EVENT_P2("txpwr_max_cch changed from %d -> %d in SI4", rrd->select_para.ms_txpwr_max_cch,
6138 sys_info_4->cell_select.ms_txpwr_max_cch);
6139 }
6140 }
6141
6142 if (sys_info_4->v_chan_desc)
6143 {
6144 /*
6145 * the message contains a CBCH channel description.
6146 */
6147 if(memcmp(&cd->cbch_chan_desc,&sys_info_4->chan_desc, sizeof (T_chan_desc)) NEQ 0)
6148 {
6149 memcpy (&cd->cbch_chan_desc, &sys_info_4->chan_desc, sizeof (T_chan_desc));
6150 cd->cbch_chan_desc_avail = WITH_CONTENT;
6151 att_bits_to_byte (cd->cbch_mob_alloc,
6152 sys_info_4->mob_alloc.c_mac,
6153 sys_info_4->mob_alloc.mac);
6154 if( (index EQ SC_INDEX) AND ( GET_STATE(STATE_ATT) EQ ATT_IDLE))
6155 #ifdef REL99
6156 att_config_cbch();
6157 #else
6158 att_build_cbch();
6159 #endif
6160 }
6161 }
6162 else
6163 {
6164 memset (&cd->cbch_chan_desc, 0, sizeof (T_chan_desc));
6165 if( cd->cbch_chan_desc_avail NEQ NO_CONTENT)
6166 {
6167 cd->cbch_chan_desc_avail = NO_CONTENT;
6168 if( (index EQ SC_INDEX) AND ( GET_STATE(STATE_ATT) EQ ATT_IDLE))
6169 #ifdef REL99
6170 att_config_cbch();
6171 #else
6172 att_build_cbch();
6173 #endif
6174 }
6175 }
6176
6177 /*
6178 * set system information bits
6179 */
6180 att_set_sys_info_read (SYS_INFO_4_READ, index);
6181 break;
6182 default:
6183 break;
6184 }
6185
6186 /*
6187 * copy the parameters
6188 */
6189 rrd->v_acs = sys_info_4->cell_select.acs; /* use of sys info 7&8 */
6190 rrd->lai = sys_info_4->loc_area_ident;
6191 rrd->select_para = sys_info_4->cell_select;
6192 att_copy_rach_parameter (index, &sys_info_4->rach_ctrl, indicate_changes);
6193
6194 if (control_changed_l1 AND indicate_changes)
6195 {
6196 /*
6197 * forward changed control channel description
6198 * to layer 1
6199 */
6200 att_build_idle_req (SC_INDEX, MODE_SYS_INFO_CHANGE);
6201 att_build_cbch ();
6202 }
6203 }
6204
6205 /*
6206 +--------------------------------------------------------------------+
6207 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6208 | STATE : code ROUTINE : att_copy_sys_info_7_8_par |
6209 +--------------------------------------------------------------------+
6210
6211 PURPOSE : copy the relevant system information type 7 and 8
6212 parameter after reception in idle mode for neighbourcells.
6213 The messages are only expected if system information
6214 message 4 does not contain the C2 parameter due to a big
6215 CBCH channel description and system information
6216 message 3 is hidden by the own paging block.
6217
6218 */
6219
6220 GLOBAL void att_copy_sys_info_7_8_par (UBYTE index,
6221 T_D_SYS_INFO_8 *sys_info_8)
6222 {
6223 GET_INSTANCE_DATA;
6224 TRACE_FUNCTION ("att_copy_sys_info_7_8_par()");
6225
6226 /*
6227 * system info 4 does not contain enough information
6228 */
6229 if (rr_data->nc_data[index].v_acs)
6230 att_copy_c2_parameter_si4 (index, (T_si4_rest_oct *)&sys_info_8->si8_rest_oct);
6231 }
6232
6233 /*
6234 +--------------------------------------------------------------------+
6235 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6236 | STATE : code ROUTINE : att_copy_c2_parameter |
6237 +--------------------------------------------------------------------+
6238
6239 PURPOSE : Rest Octets of System Information Type 3/4/7/8 are decoded
6240 to get the C2 parameter for cell reselection.
6241 */
6242
6243 static void att_copy_c2_parameter (T_C2_PARAMETER *c2_par,
6244 T_si3_rest_oct *rest_oct )
6245 {
6246 TRACE_FUNCTION ("att_copy_c2_parameter()");
6247
6248 /* Optional selection parameters */
6249 if(rest_oct->v_opt_sel_par)
6250 {
6251 c2_par->param_ind = TRUE;
6252 c2_par->cbq = rest_oct->opt_sel_par.cell_bar_qual;
6253 c2_par->cell_reselect_offset = rest_oct->opt_sel_par.cell_resel_offs;
6254 c2_par->temp_offset = rest_oct->opt_sel_par.temp_offs;
6255 c2_par->penalty_time = rest_oct->opt_sel_par.penalty_time;
6256 }
6257 else
6258 {
6259 c2_par->param_ind = FALSE;
6260 c2_par->cbq = 0;
6261 c2_par->cell_reselect_offset = 0;
6262 c2_par->temp_offset = 0;
6263 c2_par->penalty_time = 0;
6264 }
6265
6266 /* Optional Power Offset */
6267 if(rest_oct->v_pow_offs)
6268 {
6269 c2_par->power_off_ind = TRUE;
6270 c2_par->power_off = rest_oct->pow_offs;
6271 }
6272 else
6273 {
6274 c2_par->power_off_ind = FALSE;
6275 c2_par->power_off = 0;
6276 }
6277 }
6278
6279 /*
6280 +--------------------------------------------------------------------+
6281 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6282 | STATE : code ROUTINE : att_copy_c2_parameter_si3 |
6283 +--------------------------------------------------------------------+
6284
6285 PURPOSE : rest octets of system information 3 are decoded
6286 to get the C2 parameter for cell reselection.
6287 */
6288
6289 static void att_copy_c2_parameter_si3 (UBYTE index,
6290 T_si3_rest_oct *rest_oct)
6291 {
6292 GET_INSTANCE_DATA;
6293 T_NC_DATA * nc = &rr_data->nc_data[index];
6294 T_C2_PARAMETER * c2_par = &nc->c2_par;
6295
6296 TRACE_FUNCTION ("att_copy_c2_parameter_si3()");
6297
6298 att_copy_c2_parameter (c2_par, rest_oct);
6299
6300 if(index EQ SC_INDEX AND
6301 c2_par->two_ter NEQ rest_oct->v_si2ter_ind)
6302 {
6303 PALLOC (mph_sync_req, MPH_SYNC_REQ);
6304 mph_sync_req->cs = CS_SYS_INFO_2TER_SUPPORT_CHANGED;
6305 PSENDX (PL, mph_sync_req);
6306 }
6307 /* System Information 2ter Indicator */
6308 if (rest_oct->v_si2ter_ind)
6309 {
6310 c2_par->two_ter = TRUE;
6311 }
6312 else
6313 {
6314 c2_par->two_ter = FALSE;
6315 }
6316
6317 /* Early Classmark Sending Control */
6318 if (rest_oct->v_es_ind_tag)
6319 {
6320 c2_par->ecsc = TRUE;
6321 }
6322 else
6323 {
6324 c2_par->ecsc = FALSE;
6325 }
6326
6327 #ifdef GPRS
6328 if (rest_oct->v_gprs_indic)
6329 nc->rac = rest_oct->gprs_indic.ra_color;
6330 else
6331 nc->rac = NOT_PRESENT_8BIT;
6332 #endif
6333 }
6334
6335 /*
6336 +--------------------------------------------------------------------+
6337 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6338 | STATE : code ROUTINE : att_copy_c2_parameter_si4 |
6339 +--------------------------------------------------------------------+
6340
6341 PURPOSE : Rrest Octets of System Information Type 4 are decoded
6342 to get the C2 parameter for cell reselection.
6343
6344 */
6345
6346 GLOBAL void att_copy_c2_parameter_si4 (UBYTE index,
6347 T_si4_rest_oct *rest_oct)
6348 {
6349 GET_INSTANCE_DATA;
6350 T_NC_DATA * nc = &rr_data->nc_data[index];
6351 T_C2_PARAMETER * c2_par = &nc->c2_par;
6352
6353 TRACE_FUNCTION ("att_copy_c2_parameter_si4()");
6354
6355 att_copy_c2_parameter (c2_par, (T_si3_rest_oct *)rest_oct);
6356
6357 #ifdef GPRS
6358 if (rest_oct->v_gprs_indic)
6359 nc->rac = rest_oct->gprs_indic.ra_color;
6360 else
6361 nc->rac = NOT_PRESENT_8BIT;
6362 #endif
6363 }
6364
6365 /*
6366 +--------------------------------------------------------------------+
6367 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6368 | STATE : code ROUTINE : att_get_highest_c2_index |
6369 +--------------------------------------------------------------------+
6370
6371 PURPOSE : If a cell reselection shall be performed, a ranking
6372 of the available candidates is done. Depending on the
6373 calculated C2 values a C2-Index is used (because more
6374 than one cell can have the same C2-value or the value
6375 changes during cell reselection). This function looks
6376 for the cell with the highest c2 index.
6377
6378 */
6379
6380 static UBYTE att_get_highest_c2_index (void)
6381 {
6382 GET_INSTANCE_DATA;
6383 UBYTE max_result = SC_INDEX;
6384 UBYTE next_result;
6385 UBYTE result;
6386 UBYTE i;
6387
6388 TRACE_FUNCTION ("att_get_highest_c2_index()");
6389
6390 switch (rr_data->sc_data.selection_type)
6391 {
6392 case BACK_FROM_DEDICATED:
6393 case BACK_FROM_DEDICATED_RLF:
6394 /*
6395 * prepare cell reselection list
6396 */
6397 for (i = 0; i < 7; i++)
6398 {
6399 rr_data->nc_data[i].c2_used = FALSE;
6400 if (rr_data->nc_data[i].bcch_status NEQ EMPTY)
6401 if (rr_data->nc_data[i].rxlev > rr_data->nc_data[max_result].rxlev)
6402 max_result = i;
6403 }
6404
6405 if (rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED)
6406 {
6407 /*
6408 * In case of normal release start with serving cell
6409 */
6410 rr_data->nc_data[SC_INDEX].c2_used = TRUE;
6411 max_result = SC_INDEX;
6412 rr_data->ms_data.c2_tab[SC_INDEX] = MAX_C2;
6413 result = SC_INDEX;
6414 }
6415 else
6416 {
6417 /*
6418 * In case of call re-establishment start with highest fieldstrength
6419 */
6420 rr_data->nc_data[max_result].c2_used = TRUE;
6421 rr_data->ms_data.c2_tab[max_result] = MAX_C2;
6422 result = max_result;
6423 }
6424 /*
6425 * Fill with the rest of neighbourcells
6426 */
6427 while ((next_result = att_get_next_highest_rx ())
6428 NEQ NO_AVAILABLE)
6429 {
6430 rr_data->ms_data.c2_tab[next_result] =
6431 rr_data->ms_data.c2_tab[result] - 1;
6432 result = next_result;
6433 }
6434 break;
6435
6436 case CELL_RESELECTION_CR:
6437 /*
6438 * Start with CR cell (from idle mode to another cell)
6439 */
6440 rr_data->nc_data[CR_INDEX].c2_used = TRUE;
6441 max_result = CR_INDEX;
6442 result = max_result;
6443 rr_data->ms_data.c2_tab[CR_INDEX] = MAX_C2;
6444 /*
6445 * Fill with the rest of neighbourcells
6446 */
6447 while ((next_result = att_get_next_highest_rx ())
6448 NEQ NO_AVAILABLE)
6449 {
6450 rr_data->ms_data.c2_tab[next_result] =
6451 rr_data->ms_data.c2_tab[result] - 1;
6452 result = next_result;
6453 }
6454 break;
6455
6456 default:
6457 /*
6458 * Normal Cell reselection
6459 *
6460 * use a corrected C2 value for calculation,
6461 * because for cell reselection due to C2(NC) > C2(SC) a
6462 * threshold value must be taken in account if serving
6463 * and neighbourcell are members of different location areas.
6464 */
6465 att_calculate_c2 (SC_INDEX);
6466 rr_data->nc_data[SC_INDEX].c2_corr = rr_data->nc_data[SC_INDEX].c2;
6467
6468 /*
6469 * Calculate the corrected C2 values for all available neighbourcells.
6470 */
6471 for (i = 0; i < 6; i++)
6472 {
6473 if (rr_data->nc_data[i].bcch_status EQ DECODED)
6474 {
6475 att_calculate_c2 (i);
6476 rr_data->nc_data[i].c2_corr = rr_data->nc_data[i].c2;
6477
6478 /*
6479 * Take the cell reselection hysterese threshold value in
6480 * account, if there are different location areas,
6481 * a cell reselection due to C2(NC) > C2(SC)
6482 */
6483 #ifdef GPRS
6484 /*
6485 * check if the location area has changed
6486 * or the routing area if the scell supports GPRS
6487 */
6488 {
6489 BOOL la_changed, ra_changed;
6490
6491 if (!dat_plmn_equal_req (rr_data->nc_data[i].lai.mcc,
6492 rr_data->nc_data[i].lai.mnc,
6493 rr_data->nc_data[SC_INDEX].lai.mcc,
6494 rr_data->nc_data[SC_INDEX].lai.mnc)
6495 OR
6496 rr_data->nc_data[i].lai.lac NEQ
6497 rr_data->nc_data[SC_INDEX].lai.lac)
6498 la_changed = TRUE;
6499 else
6500 la_changed = FALSE;
6501
6502 if(att_gprs_is_avail())
6503 {
6504 if(rr_data->nc_data[i].rac NEQ
6505 rr_data->nc_data[SC_INDEX].rac)
6506 ra_changed = TRUE;
6507 else
6508 ra_changed = FALSE;
6509 }
6510 else
6511 {
6512 ra_changed = FALSE;
6513 }
6514
6515 if(la_changed OR ra_changed OR rr_data->gprs_data.ready_state)
6516 #else
6517 if (!dat_plmn_equal_req (rr_data->nc_data[i].lai.mcc,
6518 rr_data->nc_data[i].lai.mnc,
6519 rr_data->nc_data[SC_INDEX].lai.mcc,
6520 rr_data->nc_data[SC_INDEX].lai.mnc)
6521 OR
6522 rr_data->nc_data[i].lai.lac NEQ
6523 rr_data->nc_data[SC_INDEX].lai.lac)
6524 #endif
6525 {
6526 if ((rr_data->ms_data.imsi_available) AND
6527 (rr_data->ms_data.rr_service NEQ LIMITED_SERVICE) AND
6528 (rr_data->sc_data.selection_type EQ CELL_RESELECTION_NC))
6529 {
6530 rr_data->nc_data[i].c2_corr -=
6531 2*rr_data->nc_data[SC_INDEX].select_para.cell_resel_hyst;
6532 }
6533 }
6534 else
6535 {
6536 /*
6537 * in case of a cell reselection occurring within the previous 15 seconds
6538 * in which case the C2 value for the new cell shall exceed the C2 value
6539 * of the serving cell by at least 5 dB for a period of 5 seconds
6540 */
6541
6542 if ( IS_TIMER_ACTIVE (T_NO_RESELECT) )
6543 {
6544 rr_data->nc_data[i].c2_corr -= 5;
6545 }
6546 else
6547 {
6548 /* If the C2(NC)=C2(SC), this will get mis-interpreted in the check below
6549 * c2_corr must be adjusted to make this condition false. The '=' in the '>='
6550 * condition below only applies when T_NO_RESELECT timer is active and
6551 * c2_corr has been decremented by 5 (above statement)
6552 */
6553 if( rr_data->nc_data[i].c2_corr EQ rr_data->nc_data[max_result].c2_corr)
6554 {
6555 rr_data->nc_data[i].c2_corr -= 1;
6556 }
6557 }
6558 }
6559 #ifdef GPRS
6560 }
6561 #endif
6562 }
6563 }
6564
6565 /*
6566 * Now find the the highest one
6567 */
6568 for (i = 0; i < 7; i++)
6569 {
6570 rr_data->nc_data[i].c2_used = FALSE;
6571 if (rr_data->nc_data[i].bcch_status EQ DECODED)
6572 {
6573 if (rr_data->nc_data[i].c2_corr >=
6574 rr_data->nc_data[max_result].c2_corr)
6575 max_result = i;
6576 }
6577 }
6578
6579 result = max_result;
6580
6581 rr_data->nc_data[result].c2_used = TRUE;
6582 rr_data->ms_data.c2_tab[result] = MAX_C2;
6583
6584 /*
6585 * make the ranking for the other cells.
6586 */
6587 while ((next_result = att_get_next_highest_c2_val ())
6588 NEQ NO_AVAILABLE)
6589 {
6590 rr_data->ms_data.c2_tab[next_result] =
6591 rr_data->ms_data.c2_tab[result] - 1;
6592 result = next_result;
6593 }
6594 break;
6595 }
6596
6597 /*
6598 * return the index of the highest C2.
6599 */
6600 return max_result;
6601 }
6602
6603 /*
6604 +--------------------------------------------------------------------+
6605 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6606 | STATE : code ROUTINE : att_get_next_highest_c2_idx|
6607 +--------------------------------------------------------------------+
6608
6609 PURPOSE : During the ranking of the cell reselection list this
6610 function searches for the cell with the next highest c2 index.
6611
6612 */
6613
6614 static UBYTE att_get_next_highest_c2_idx (UBYTE old_index)
6615 {
6616 GET_INSTANCE_DATA;
6617 UBYTE new_index = NO_AVAILABLE;
6618 UBYTE i;
6619
6620 TRACE_FUNCTION ("att_get_next_highest_c2_idx()");
6621
6622 /*
6623 * depending on the cell reselection type
6624 */
6625 switch (rr_data->sc_data.selection_type)
6626 {
6627 case BACK_FROM_DEDICATED:
6628 case BACK_FROM_DEDICATED_RLF:
6629 /*
6630 * check all cells
6631 */
6632 for (i = 0; i <= SC_INDEX; i++)
6633 {
6634 /*
6635 * If cell is available and is not selected yet
6636 */
6637 if (rr_data->nc_data[i].bcch_status NEQ EMPTY AND
6638 rr_data->ms_data.c2_tab[i] NEQ MAX_C2)
6639 {
6640 /*
6641 * it is the first candidate, then select it
6642 */
6643 if (new_index EQ NO_AVAILABLE)
6644 new_index = i;
6645 else
6646 {
6647 /*
6648 * else take the one with the higher C2
6649 */
6650 if (rr_data->ms_data.c2_tab[i] >
6651 rr_data->ms_data.c2_tab[new_index])
6652 new_index = i;
6653 }
6654 }
6655 }
6656
6657 /*
6658 * If a new cell is found, mark this cell as selected
6659 * for the next round
6660 */
6661 if (new_index NEQ NO_AVAILABLE)
6662 rr_data->ms_data.c2_tab[new_index] = MAX_C2;
6663 break;
6664
6665 default:
6666 /*
6667 * all other cell reselections
6668 */
6669 for (i = 0; i <= SC_INDEX; i++)
6670 {
6671 if (rr_data->nc_data[i].bcch_status EQ DECODED)
6672 {
6673 if (old_index NEQ i)
6674 {
6675 if (new_index EQ NO_AVAILABLE)
6676 {
6677 if (rr_data->ms_data.c2_tab[i] <
6678 rr_data->ms_data.c2_tab[old_index])
6679 {
6680 new_index = i;
6681 }
6682 }
6683 else
6684 {
6685 if (rr_data->ms_data.c2_tab[i] >
6686 rr_data->ms_data.c2_tab[new_index] AND
6687 rr_data->ms_data.c2_tab[i] <
6688 rr_data->ms_data.c2_tab[old_index])
6689 {
6690 new_index = i;
6691 }
6692 }
6693 }
6694 }
6695 }
6696 break;
6697 }
6698 return new_index;
6699 }
6700
6701 /*
6702 +--------------------------------------------------------------------+
6703 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6704 | STATE : code ROUTINE : att_get_next_highest_c2_val|
6705 +--------------------------------------------------------------------+
6706
6707 PURPOSE : During the ranking of the cell reselection list this
6708 function searches for the cell with the next highest c2 value.
6709
6710 */
6711
6712 static UBYTE att_get_next_highest_c2_val (void)
6713 {
6714 GET_INSTANCE_DATA;
6715 UBYTE new_index = NO_AVAILABLE;
6716 UBYTE i;
6717
6718 TRACE_FUNCTION ("att_get_next_highest_c2_val()");
6719
6720 /*
6721 * look for all cells inclusive the serving cell
6722 */
6723 for (i = 0; i < 7; i++)
6724 {
6725 /*
6726 * the cell must have read the system infos to calculate c2.
6727 */
6728 if (rr_data->nc_data[i].bcch_status EQ DECODED)
6729 {
6730 /*
6731 * if not ranked yet
6732 */
6733 if (rr_data->nc_data[i].c2_used EQ FALSE)
6734 {
6735 /*
6736 * if no cell is selected yet,
6737 * then select this one.
6738 */
6739 if (new_index EQ NO_AVAILABLE)
6740 {
6741 new_index = i;
6742 }
6743 else
6744 {
6745 /*
6746 * the corrected c2 value must be higher
6747 * then the selected one.
6748 */
6749 if (rr_data->nc_data[i].c2_corr >
6750 rr_data->nc_data[new_index].c2_corr)
6751 {
6752 new_index = i;
6753 }
6754 }
6755 }
6756 }
6757 }
6758
6759 /*
6760 * a cell has been selected, then mark this cell
6761 * to be not selected the next time.
6762 */
6763 if (new_index NEQ NO_AVAILABLE)
6764 {
6765 rr_data->nc_data[new_index].c2_used = TRUE;
6766 }
6767
6768 /*
6769 * return the selected cell index
6770 */
6771 return new_index;
6772 }
6773
6774 /*
6775 +--------------------------------------------------------------------+
6776 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6777 | STATE : code ROUTINE : att_get_next_highest_rx |
6778 +--------------------------------------------------------------------+
6779
6780 PURPOSE : During the ranking of the cell reselection list this
6781 function searches for the cell with the next highest rx value.
6782
6783 */
6784
6785 static UBYTE att_get_next_highest_rx (void)
6786 {
6787 GET_INSTANCE_DATA;
6788 UBYTE new_index = NO_AVAILABLE;
6789 UBYTE i;
6790
6791 TRACE_FUNCTION ("att_get_next_highest_rx()");
6792
6793 /*
6794 * for all neighbourcells and the serving cell
6795 */
6796 for (i = 0; i < 7; i++)
6797 {
6798 /*
6799 * if something is stored for this index
6800 * that means at least MS is synchronized.
6801 */
6802 if (rr_data->nc_data[i].bcch_status NEQ EMPTY)
6803 {
6804 /*
6805 * the cell has not been ranked
6806 */
6807 if (rr_data->nc_data[i].c2_used EQ FALSE)
6808 {
6809 /*
6810 * if it is the first cell in this attempt,
6811 * then select it.
6812 */
6813 if (new_index EQ NO_AVAILABLE)
6814 {
6815 new_index = i;
6816 }
6817 else
6818 {
6819 /*
6820 * to select the cell it must have a higher
6821 * fieldstrength
6822 */
6823 if (rr_data->nc_data[i].rxlev >
6824 rr_data->nc_data[new_index].rxlev)
6825 {
6826 new_index = i;
6827 }
6828 }
6829 }
6830 }
6831 }
6832
6833 /*
6834 * A cell has been selected, then mark it as
6835 * ranked to avoid selection in the next attempt.
6836 */
6837 if (new_index NEQ NO_AVAILABLE)
6838 {
6839 rr_data->nc_data[new_index].c2_used = TRUE;
6840 }
6841
6842 /*
6843 * return the index of the selected cell.
6844 */
6845 return new_index;
6846 }
6847
6848
6849 /*
6850 +--------------------------------------------------------------------+
6851 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
6852 | STATE : code ROUTINE : att_handle_rr_act_req |
6853 +--------------------------------------------------------------------+
6854
6855 PURPOSE : MM requests with the primitive RR_ACTIVATE_REQ one of the
6856 following procedures:
6857
6858 1. Full Service - search for a specific PLMN
6859 2. Limited Service - search for a cell for limited service
6860 3. PLMN Search - request the PLMN available list.
6861
6862 */
6863
6864 GLOBAL void att_handle_rr_act_req (UBYTE initial_act,
6865 T_RR_ACTIVATE_REQ *rr_activate_req)
6866 {
6867 GET_INSTANCE_DATA;
6868 UBYTE count = 0;
6869 TRACE_FUNCTION ("att_handle_rr_act_req()");
6870
6871 /*
6872 * stop time control for an ongoing cell reselection
6873 */
6874 TIMERSTOP (T_RESELECT);
6875 TIMERSTOP (TABORT);
6876
6877 rr_data->net_lost = FALSE;
6878
6879 if (initial_act)
6880 {
6881 /*
6882 * read ms data from e2prom
6883 */
6884 att_clear_parallel_search();
6885 rr_csf_ms_cap ();
6886 rr_csf_check_rfcap (FALSE);
6887 rr_csf_read_imei (&rr_data->ms_data.imei);
6888 rr_data->ms_data.rr_service = NO_SERVICE; /* set initial to no service */
6889 }
6890
6891 for(count=0;count<MAX_MCC_SHIELD;count++)
6892 {
6893 TRACE_EVENT_P3 ( "Current software shielded MCC are =%d%d%d",
6894 rr_data->dyn_config.mcc_shield.mcc[count][0],
6895 rr_data->dyn_config.mcc_shield.mcc[count][1],
6896 rr_data->dyn_config.mcc_shield.mcc[count][2]);
6897 }
6898
6899 /*
6900 * store EPLMN list, if available, for use in cell selection/reselection.
6901 */
6902 att_copy_eplmn_list(&rr_activate_req->eq_plmn_list);
6903
6904 /*
6905 * store operation mode data
6906 */
6907 rr_data->ms_data.operation_mode =
6908 (rr_activate_req->op.ts << 7) +
6909 (rr_activate_req->op.m << 6) +
6910 (rr_activate_req->op.sim_ins << 5);
6911
6912 /*
6913 * some optimisations must be removed for the FTA campaign.
6914 */
6915 if (dat_test_sim_available() EQ TRUE)
6916 test_house = TRUE;
6917
6918 att_set_func (rr_activate_req->op.func);
6919 /*
6920 * start cell selection procedure
6921 */
6922 rr_data->ms_data.req_mm_service = att_get_func ();
6923
6924 TRACE_EVENT_P6 ("RR_ACTIVATE_REQ: %s func op=%s %scurrent=%s rMM=%s RRs=%s",
6925 initial_act ? "initial" : "",
6926 _rr_str_FUNC[rr_activate_req->op.func],
6927 _rr_str_PARFUNC[rr_data->ms_data.parallel_net_plmn_search_type],
6928 _rr_str_FUNC[rr_data->ms_data.current_plmn_search_type],
6929 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
6930 _rr_str_SERVICE[rr_data->ms_data.rr_service]);
6931
6932 switch (rr_data->ms_data.req_mm_service)
6933 {
6934 case FUNC_LIM_SERV_ST_SRCH:
6935 #ifdef GPRS
6936 att_set_gprs_indication(rr_activate_req->gprs_indication);
6937 #endif
6938 rr_data->c1_offset = C1_OFFSET;
6939
6940 att_begin_cs(FUNC_LIM_SERV_ST_SRCH);
6941 break;
6942
6943 case FUNC_NET_SRCH_BY_MMI:
6944 /*
6945 * clear found_channel parameter from previous search
6946 */
6947 switch(GET_STATE(STATE_ATT))
6948 {
6949 case ATT_IDLE:
6950 case ATT_CON_EST:
6951 /* Cell Selection Improvements-LLD section:4.1.3.9 */
6952 att_start_cell_selection(MM_ORIGINATED, CS_PARALLEL,FULL_SEARCH_MODE);
6953 break;
6954
6955 default:
6956 att_begin_cs(FUNC_NET_SRCH_BY_MMI);
6957 break;
6958 }
6959 EM_NET_SEARCH_STARTED;
6960 break;
6961
6962 case FUNC_PLMN_SRCH:
6963 /*
6964 * copy full service parameter from SIM
6965 */
6966 #ifdef GPRS
6967 att_set_gprs_indication (rr_activate_req->gprs_indication);
6968 #endif
6969 if (rr_data->ms_data.rr_service NEQ NO_SERVICE)
6970 cs_clear_attributes (CHECKED_FLAG, rr_data->nc_data[SC_INDEX].arfcn);
6971
6972 /* Implements Measure#32: Row 52,53 */
6973 att_print_mcc_mnc (NOT_PRESENT_16BIT, rr_data->ms_data.plmn.mcc,
6974 rr_data->ms_data.plmn.mnc, S2I_STRING("old_req_plmn"));
6975 att_print_mcc_mnc (NOT_PRESENT_16BIT, rr_activate_req->plmn.mcc,
6976 rr_activate_req->plmn.mnc, S2I_STRING("new_req_plmn"));
6977
6978 memcpy (&rr_data->ms_data.plmn, &rr_activate_req->plmn, sizeof (T_plmn));
6979 rr_data->ms_data.cksn = rr_activate_req->cksn;
6980 memcpy (rr_data->ms_data.new_kc, &rr_activate_req->kcv.kc, KC_STRING_SIZE);
6981 rr_data->ms_data.access_classes = rr_activate_req->accc;
6982
6983 #if defined(_SIMULATION_)
6984 /* Implements Measure#32: Row 52 */
6985 att_print_mcc_mnc(rr_data->nc_data[SC_INDEX].arfcn,
6986 rr_data->ms_data.plmn.mcc, rr_data->ms_data.plmn.mnc, S2I_STRING("req"));
6987 #endif
6988
6989 /*
6990 * copy IMSI if available
6991 */
6992 if (rr_activate_req->imsi_struct.id_type EQ TYPE_IMSI)
6993 {
6994 memset (&rr_data->ms_data.imsi, 0, sizeof (rr_data->ms_data.imsi));
6995 rr_data->ms_data.imsi_available = TRUE;
6996 rr_data->ms_data.imsi.ident_type = TYPE_IMSI;
6997 rr_data->ms_data.imsi.v_ident_dig = TRUE;
6998 rr_data->ms_data.imsi.c_ident_dig =
6999 att_calculate_digits (rr_activate_req->imsi_struct.id);
7000 rr_data->ms_data.imsi.odd_even =
7001 rr_data->ms_data.imsi.c_ident_dig & 1;
7002 memcpy (rr_data->ms_data.imsi.ident_dig, rr_activate_req->imsi_struct.id, 16);
7003 }
7004 else
7005 rr_data->ms_data.imsi_available = FALSE;
7006
7007 /*
7008 * copy TMSI if available
7009 */
7010 if (rr_activate_req->tmsi_struct.id_type EQ TYPE_TMSI)
7011 {
7012 rr_data->ms_data.tmsi_available = TRUE;
7013 rr_data->ms_data.tmsi_binary = rr_activate_req->tmsi_struct.tmsi_dig;
7014 }
7015 else
7016 rr_data->ms_data.tmsi_available = FALSE;
7017
7018 if (dat_test_sim_available())
7019 rr_data->c1_offset = 0;
7020 else
7021 rr_data->c1_offset = C1_OFFSET;
7022
7023 /* CSI-LLD section:4.1.1.11
7024 * First FUNC_PLMN_SEARCH
7025 */
7026 if(rr_data->cs_data.initial_plmn_search EQ INITIAL_PLMN_SEARCH_NOT_ACTIVE)
7027 {
7028 rr_data->cs_data.initial_plmn_search = INITIAL_PLMN_SEARCH_ACTIVE;
7029 }
7030
7031 cs_set_bcch_info(&rr_activate_req->bcch_info);
7032
7033 att_begin_cs(FUNC_PLMN_SRCH);
7034 EM_PLMN_SRCH_STARTED;
7035 break;
7036
7037 case FUNC_ST_PWR_SCAN:
7038 SET_STATE(STATE_ATT, ATT_CS_INIT );
7039 att_start_cell_selection(MM_ORIGINATED, CS_NOT_PARALLEL,FULL_SEARCH_MODE);
7040 break;
7041 }
7042
7043 PFREE (rr_activate_req);
7044 }
7045
7046 /*
7047 +--------------------------------------------------------------------+
7048 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7049 | STATE : code ROUTINE : att_begin_cs |
7050 +--------------------------------------------------------------------+
7051
7052 PURPOSE : This function initializes a cell selection or starts BCCH
7053 reading depending on the ATT state on an RR_ACTIVATE_REQ
7054 */
7055
7056 static void att_begin_cs (UBYTE req_mm_service)
7057 {
7058 GET_INSTANCE_DATA;
7059 if(GET_STATE(STATE_ATT) EQ ATT_CS_INIT )
7060 {
7061 SET_STATE(STATE_ATT, ATT_CS1 ); /*Boot Time*/
7062
7063 /* Boot Time Performance Enhancement:
7064 * Start the TABORT timer on receiving the second activate_req
7065 */
7066 tstart_tabort(TABORT_VALUE);
7067
7068 /* Invalidate whitelist if its PLMN ID does not match
7069 * with the requested PLMN
7070 */
7071 if((rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH) AND
7072 (!dat_plmn_equal_req(rr_data->cs_data.white_list.last_sc_lac.mcc,
7073 rr_data->cs_data.white_list.last_sc_lac.mnc,
7074 rr_data->ms_data.plmn.mcc,
7075 rr_data->ms_data.plmn.mnc)))
7076 {
7077 rr_data->cs_data.white_list.region = NOT_PRESENT_8BIT;
7078 }
7079 if( srv_check_stored_prim(MPH_POWER_CNF))
7080 {
7081 srv_use_stored_prim();
7082 }
7083 /*
7084 * reset the time for net search to finish
7085 * a PLMN available search during 60 seconds.
7086 */
7087 if( req_mm_service EQ FUNC_NET_SRCH_BY_MMI)
7088 TIMERSTART(T_PLMN_SEARCH, T_PLMN_SEARCH_VALUE);
7089 }
7090 else
7091 {
7092 /* Cell Selection Improvements-LLD section:4.1.3.9 */
7093 att_start_cell_selection(MM_ORIGINATED, CS_NOT_PARALLEL,FULL_SEARCH_MODE);
7094 }
7095 }
7096
7097 /*
7098 +--------------------------------------------------------------------+
7099 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7100 | STATE : code ROUTINE : att_increase_power_on_time |
7101 +--------------------------------------------------------------------+
7102
7103 PURPOSE : A requirement in GSM 5.08 indicates that the list of
7104 forbidden location areas must be cleared all 12 hours.
7105 Therefore this counters power_on_low and power_on_high
7106 are used. They are triggered by the periodic measurement
7107 reports in idle mode.
7108
7109 */
7110
7111 GLOBAL void att_increase_power_on_time (USHORT inc)
7112 {
7113 GET_INSTANCE_DATA;
7114 TRACE_FUNCTION ("att_increase_power_on_time()");
7115
7116 /*
7117 * increment power_on_low
7118 */
7119 rr_data->power_on_low += inc;
7120 if (rr_data->power_on_low >= 60)
7121 {
7122 /* if it is more then 60 seconds,
7123 * increment power_on_high = minutes
7124 */
7125 rr_data->power_on_low = 0;
7126 rr_data->power_on_high++;
7127 if (rr_data->power_on_high >= 720)
7128 {
7129 /*
7130 * after 12 hours = 720 minutes clear all forbidden location area lists
7131 */
7132 rr_data->power_on_low = 0;
7133 rr_data->power_on_high = 0;
7134 att_clear_forb_list (FORBIDDEN_LIST_NORMAL);
7135 att_clear_forb_list (FORBIDDEN_LIST_ROAMING);
7136 }
7137 }
7138 }
7139
7140
7141 #if defined (TI_PS_FF_RTD) AND defined (REL99)
7142 LOCAL void att_init_rtd_data(T_rr_enh_para *p_cur)
7143 {
7144 UBYTE j,k;
7145 TRACE_FUNCTION ("att_init_rtd_data");
7146
7147 for(j = 0;j < MAX_NR_OF_NCELL; j++ )
7148 {
7149 p_cur->enh_para.enh_cell_list[j].v_rtd = FALSE;
7150 for(k = 0;k < MAX_NUM_OF_RTD_VALUES; k++)
7151 p_cur->enh_para.enh_cell_list[j].rtd[k]= RTD_NOT_AVAILABLE;
7152 p_cur->enh_para.enh_cell_list[j].c_rtd = 0;
7153 }/*for*/
7154 return;
7155 }
7156 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
7157
7158 /*
7159 +--------------------------------------------------------------------+
7160 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7161 | STATE : code ROUTINE : att_init_cell_selection |
7162 +--------------------------------------------------------------------+
7163
7164 PURPOSE : The function initializes some variables needed for control
7165 of cell selection and cell reselection.
7166
7167 */
7168
7169 GLOBAL void att_init_cell_selection (UBYTE selection,
7170 BOOL initiator)
7171 {
7172 GET_INSTANCE_DATA;
7173 #if defined (TI_PS_FF_RTD) AND defined (REL99)
7174 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current;
7175 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
7176
7177 TRACE_FUNCTION ("att_init_cell_selection()");
7178
7179 TRACE_EVENT_P2 ("init CELL_%sSELECTION %s_ORIGINATED",
7180 (selection EQ CELL_SELECTION) ? "" : "RE",
7181 (initiator EQ MM_ORIGINATED) ? "MM" : "RR" );
7182
7183 /*
7184 * store type of selection and the initiator (RR or MM).
7185 */
7186 rr_data->sc_data.selection_type = selection;
7187 rr_data->sc_data.mm_started = initiator;
7188
7189 /*
7190 * clear the list of the found PLMNs
7191 */
7192 rr_data->sc_data.found_entries = 0;
7193
7194 /*
7195 * clear the bitmap indicating whether all system information
7196 * messages are read.
7197 */
7198 att_init_cr_data();
7199
7200 #if defined (TI_PS_FF_RTD) AND defined (REL99)
7201 att_init_rtd_data(p_cur);
7202 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
7203
7204
7205 /*
7206 * reset multiband parameter
7207 */
7208 rr_data->ncell_mb = 0;
7209
7210 if (GET_STATE (STATE_ATT) EQ ATT_CS2 OR GET_STATE (STATE_ATT) EQ ATT_CS3)
7211 {
7212 rr_data->nc_data[SC_INDEX].lai.mcc[0] = NOT_PRESENT_8BIT;
7213 rr_data->nc_data[SC_INDEX].lai.mnc[0] = NOT_PRESENT_8BIT;
7214 }
7215 }
7216
7217 /*
7218 +--------------------------------------------------------------------+
7219 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7220 | STATE : code ROUTINE : att_init_gsm_data |
7221 +--------------------------------------------------------------------+
7222
7223 PURPOSE : Intialize all gsm specific variables of RR.
7224
7225 */
7226
7227 GLOBAL void att_init_gsm_data (void)
7228 {
7229 GET_INSTANCE_DATA;
7230 SHORT i;
7231 UBYTE save;
7232 UBYTE gprs_ms, cmsp;
7233 BOOL ms_configured, cmsp_configured;
7234
7235 #if defined (TI_PS_FF_RTD) AND defined (REL99)
7236 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current;
7237 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
7238
7239
7240 TRACE_FUNCTION ("att_init_gsm_data()");
7241
7242 save = rr_data->dyn_config.no_sys_time;
7243
7244 /* save configured GPRS multislot class */
7245 ms_configured = rr_data->ms_data.multislot_class_configured;
7246 gprs_ms = rr_data->ms_data.rf_cap.rf_ms.gprs_ms_class;
7247 dat_emo_stop ( FALSE );
7248
7249 /* save configured CMSP bit */
7250 cmsp_configured = rr_data->ms_data.cmsp_configured;
7251 cmsp = rr_data->ms_data.rf_cap.cmsp;
7252
7253 /*
7254 * clar all RR data with the default value
7255 */
7256 memset (rr_data, 0, sizeof (T_RR_DATA));
7257
7258 /*
7259 * some parameters have a different default value
7260 */
7261 rr_data->lup_rxlev = 63;
7262 rr_data->dyn_config.no_sys_time = save;
7263 rr_data->ms_data.cksn = CKSN_NOT_PRES;
7264
7265 /* restore configured GPRS multislot class */
7266 if (ms_configured)
7267 {
7268 rr_data->ms_data.multislot_class_configured = TRUE;
7269 rr_data->ms_data.rf_cap.rf_ms.gprs_ms_class = gprs_ms;
7270 TRACE_EVENT_P1 ("'gprs_ms_class' configured to a value of %d", gprs_ms);
7271 }
7272
7273 /* restore configured CMSP bit */
7274 if (cmsp_configured)
7275 {
7276 rr_data->ms_data.cmsp_configured = TRUE;
7277 rr_data->ms_data.rf_cap.cmsp= cmsp;
7278 TRACE_EVENT_P1 ("'cmsp' configured to a value of %d", cmsp);
7279 }
7280 #if defined (REL99) AND defined (TI_PS_FF_EMR) AND defined (GPRS)
7281 rr_data->ms_data.enable_ps_emr = TRUE;
7282 #endif
7283 for (i = 0; i < 8; i++)
7284 {
7285 rr_data->nc_data[i].lai.mcc[0] = NOT_PRESENT_8BIT;
7286 rr_data->nc_data[i].lai.mnc[0] = NOT_PRESENT_8BIT;
7287 }
7288 #if defined (REL99) && defined (TI_PS_FF_EMR)
7289 /*Default initializations for EMR*/
7290 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS);
7291 for_set_default_emr_data(&rr_data->sc_data.emr_data_current);
7292 for_set_default_emr_data(&rr_data->sc_data.emr_data_temp);
7293 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE;
7294 rr_data->sc_data.ba_list_ded = rr_data->sc_data.ba_list_idle = FALSE;
7295 rr_data->sc_data.ba_index = NOT_PRESENT_8BIT;
7296 #endif
7297 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
7298 rr_data->sc_data.cd.band_indicator = NOT_PRESENT_8BIT;
7299 rr_data->cr_data.cd.band_indicator = NOT_PRESENT_8BIT;
7300 #endif
7301
7302 #if defined (TI_PS_FF_RTD) AND defined (REL99)
7303 att_init_rtd_data(p_cur);
7304 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
7305
7306 /*
7307 * clear the forbidden lists
7308 */
7309 att_clear_forb_list (FORBIDDEN_LIST_NORMAL);
7310 att_clear_forb_list (FORBIDDEN_LIST_ROAMING);
7311
7312 /*
7313 * indicate all RR timer as not running
7314 */
7315 memset (rr_data->t_running, 0, sizeof (rr_data->t_running));
7316 rr_data->t_expire[T3110] = tim_t3110;
7317 rr_data->t_expire[T3122] = tim_t3122;
7318 rr_data->t_expire[T3126] = tim_t3126;
7319 rr_data->t_expire[TREG] = tim_treg;
7320 rr_data->t_expire[T_RESELECT] = tim_treselect;
7321 rr_data->t_expire[TIM_EXT_MEAS] = tim_ext_meas;
7322 rr_data->t_expire[T_NO_RESELECT] = NULL;
7323 rr_data->t_expire[TCSVALID] = NULL;
7324 rr_data->t_expire[TABORT] = tim_tabort;
7325 rr_data->t_expire[T_PLMN_SEARCH] = tim_plmn_search_expiry;
7326 rr_data->t_expire[T_FAST_CS] = tim_tfast_cs;
7327 rr_data->t_expire[T_NORMAL_CS] = tim_tnormal_cs;
7328
7329 rr_data->net_lost = FALSE;
7330
7331
7332 #if defined FF_EOTD
7333 rr_data->t_expire[TAPDU] = tim_apdu;
7334 #endif /* FF_EOTD */
7335 rr_data->t_expire[TNNN] = tim_tnnn;
7336 rr_data->t_expire[T_DEDICATED_MODE] = NULL;
7337 rr_data->treg_pending = FALSE;
7338
7339 rr_data->old_serving_cell = NOT_PRESENT_8BIT;
7340 rr_data->ms_data.rr_service = NO_SERVICE;
7341
7342 /* tch loop "open" */
7343 rr_data->tch_loop_subch = NOT_PRESENT_8BIT;
7344
7345 #if defined FF_EOTD
7346 rr_data->eotd_req_id = NOT_PRESENT_16BIT;
7347 #endif /* FF_EOTD */
7348
7349 #ifdef _SIMULATION_
7350 {
7351 int i=0;
7352 for (;i<NUM_OF_RR_TIMERS;i++)
7353 {
7354 #ifdef OPTION_TIMER
7355 /* vsi_t_config is removed in latest GPF */
7356 #endif
7357 }
7358 }
7359 #endif
7360 }
7361
7362 /*
7363 +--------------------------------------------------------------------+
7364 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7365 | STATE : code ROUTINE : att_init_pl_status |
7366 +--------------------------------------------------------------------+
7367
7368 PURPOSE : the function clear the cell channel description list
7369 of the serving cell.
7370
7371 */
7372
7373 GLOBAL void att_init_pl_status (void)
7374 {
7375 GET_INSTANCE_DATA;
7376 TRACE_FUNCTION ("att_init_pl_status()");
7377
7378 rr_data->sc_data.cd.v_cell_chan_desc = NO_CONTENT;
7379 srv_clear_list (&rr_data->sc_data.cd.cell_chan_desc);
7380 }
7381
7382 /*
7383 +--------------------------------------------------------------------+
7384 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7385 | STATE : code ROUTINE : att_insert_cell_in_data |
7386 +--------------------------------------------------------------------+
7387
7388 PURPOSE : During the analysis of an incoming measurement report a
7389 new cell has been detected. The data of this cell are
7390 stored in RR.
7391
7392 */
7393
7394 static void att_insert_cell_in_data (T_MPH_MEASUREMENT_IND *report,
7395 UBYTE index)
7396 {
7397 GET_INSTANCE_DATA;
7398 UBYTE i;
7399 T_NC_DATA * rrd;
7400
7401 TRACE_FUNCTION ("att_insert_cell_in_data()");
7402
7403 /*
7404 * search for a free entry in the RR storage area.
7405 */
7406 for (i = 0; i < 6; i++)
7407 if (rr_data->nc_data[i].bcch_status EQ EMPTY)
7408 break;
7409
7410 if (i < 6)
7411 {
7412 /*
7413 * RR will ever find a free area, because all
7414 * cells which are not longer in the measurement
7415 * report, are removed from the RR storage.
7416 * The if-condition is only for security reasons
7417 *
7418 * Store the data from the measurement report and
7419 * wait for the system information messages.
7420 */
7421 rrd = &rr_data->nc_data[i];
7422 rrd->bsic = report->ncells.bsic[index];
7423 rrd->arfcn = report->ncells.arfcn[index];
7424 rrd->rxlev = report->ncells.rx_lev[index];
7425 rrd->bcch_status = NON_DECODED;
7426 rrd->avail_time = 0;
7427 #ifdef GPRS
7428 if( rr_data->gprs_data.use_c31 )
7429 att_insert_c31_cr_data_in_cell(i);
7430 #endif
7431 }
7432 }
7433
7434 /*
7435 +--------------------------------------------------------------------+
7436 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7437 | STATE : code ROUTINE : att_max |
7438 +--------------------------------------------------------------------+
7439
7440 PURPOSE : The function calculates the maximum from two values a and b.
7441
7442 */
7443
7444 GLOBAL SHORT att_max (SHORT a,
7445 SHORT b)
7446 {
7447 TRACE_FUNCTION ("att_max()");
7448
7449 return ((a > b) ? a : b);
7450 }
7451
7452
7453 /*
7454 +--------------------------------------------------------------------+
7455 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7456 | STATE : code ROUTINE : att_plmn_in_found_list |
7457 +--------------------------------------------------------------------+
7458
7459 PURPOSE : The function checks whether a PLMN identification is already
7460 stored in the found list or not during cell selection / cell
7461 reselection.
7462
7463 */
7464
7465 GLOBAL T_FOUND_ELEMENT *att_plmn_in_found_list (UBYTE *mcc, UBYTE *mnc)
7466 {
7467 GET_INSTANCE_DATA;
7468 T_FOUND_ELEMENT *result = NULL;
7469 int i;
7470 T_FOUND_ELEMENT *found;
7471
7472 TRACE_FUNCTION ("att_plmn_in_found_list()");
7473
7474 /*
7475 * look for all entries, which are already stored
7476 */
7477 /*att_print_mcc_mnc(0, mcc, mnc, "compare with");*/
7478 found = &rr_data->sc_data.found[0];
7479 for (i = 0; i < rr_data->sc_data.found_entries; i++, found++)
7480 {
7481 /*
7482 * compare mobile country code and mobile network code.
7483 */
7484 /*att_print_mcc_mnc(found->arfcn, found->plmn.mcc, found->plmn.mnc, "list");*/
7485 if (dat_plmn_equal_req (mcc, mnc,
7486 found->plmn.mcc, found->plmn.mnc))
7487 {
7488 result = found;
7489 /*att_print_mcc_mnc(found->arfcn, mcc, mnc, "found");*/
7490 break;
7491 }
7492 }
7493
7494 /*
7495 * return the result of the compare.
7496 */
7497 return result;
7498 }
7499
7500 /*
7501 +--------------------------------------------------------------------+
7502 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7503 | STATE : code ROUTINE : att_save_found_plmn |
7504 +--------------------------------------------------------------------+
7505
7506 PURPOSE : The function set all list elements of a found PLMN.
7507 It marks the element as present (V_PLMN_PRES)
7508
7509 */
7510
7511 GLOBAL void att_save_found_plmn (T_FOUND_ELEMENT *element, UBYTE mcc[], UBYTE mnc[],
7512 USHORT arfcn, UBYTE rxlev, USHORT lac, UBYTE cell_ok)
7513 {
7514 GET_INSTANCE_DATA;
7515 element->plmn.v_plmn = V_PLMN_PRES;
7516 memcpy (element->plmn.mcc, mcc, SIZE_MCC);
7517 memcpy (element->plmn.mnc, mnc, SIZE_MNC);
7518 element->arfcn = arfcn;
7519 element->rxlev = rxlev;
7520 element->lac = lac; /* LOL 02.01.2003: added for EONS support */
7521 element->cell_ok = cell_ok;
7522 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
7523 if (rr_data->cs_data.region EQ BOTH_REGIONS)
7524 {
7525 element->region = srv_get_region_from_std_arfcn (std, arfcn);
7526 }
7527 else
7528 {
7529 #endif
7530 element->region = rr_data->cs_data.region;
7531 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
7532 }
7533 #endif
7534
7535 TRACE_EVENT_P9 ("[%u] save new PLMN (%x%x%x %x%x%x) region=%d, entries=%u",
7536 arfcn, mcc[0], mcc[1], mcc[2], mnc[0], mnc[1], mnc[2],element->region,
7537 rr_data->sc_data.found_entries+1);
7538 }
7539
7540 /*
7541 +--------------------------------------------------------------------+
7542 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7543 | STATE : code ROUTINE : att_priority_check |
7544 +--------------------------------------------------------------------+
7545
7546 PURPOSE : The function checks the priority of a cell during cell
7547 selection. It must be differed between first and second
7548 attempt.
7549
7550 During the first attempt it will be differed between
7551 low and high (or normal) priority.
7552
7553 In the first attempt the cell bar qualifier is used to
7554 differ between low and high priority. Beside this there
7555 is an exception defined in GSM 5.08 chapter 9.
7556
7557 In the second attempt the priority check is ever successful.
7558
7559 */
7560
7561 static BOOL att_priority_check (void)
7562 {
7563 GET_INSTANCE_DATA;
7564 TRACE_FUNCTION ("att_priority_check()");
7565
7566 /*
7567 * During the First Scan second attempt and second scan the priority
7568 * check is ever successful.
7569 */
7570 if((rr_data->cs_data.scan_mode EQ CS_FIRST_SCAN_SECOND_ATTEMPT) OR
7571 (rr_data->cs_data.scan_mode EQ CS_SECOND_SCAN))
7572 {
7573 return TRUE;
7574 }
7575
7576 /*
7577 * Exception condition handling according GSM 5.08, chapter 9
7578 */
7579 if (dat_hplmn (rr_data->nc_data[CR_INDEX].lai.mcc,
7580 rr_data->nc_data[CR_INDEX].lai.mnc) AND
7581 rr_data->cell_test_operation AND
7582 rr_data->nc_data[CR_INDEX].c2_par.cbq EQ 0 AND
7583 rr_data->nc_data[CR_INDEX].rach.cell_bar_access EQ 1 AND
7584 (rr_data->nc_data[CR_INDEX].rach.ac & 0x8000) NEQ 0)
7585 return TRUE;
7586
7587 /*
7588 * Else the cell bar qualifier indicates the priority
7589 */
7590 if (rr_data->nc_data[CR_INDEX].c2_par.cbq)
7591 return FALSE;
7592 else
7593 return TRUE;
7594 }
7595
7596 /*
7597 +--------------------------------------------------------------------+
7598 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7599 | STATE : code ROUTINE : att_remove_bad_ncell |
7600 +--------------------------------------------------------------------+
7601
7602 PURPOSE : During fieldtest sometimes a neighbourcell in the
7603 measurement report was equal to a neighbourcell. This
7604 function deletes neighbourcell data if the channel is
7605 equal to the serving cell.
7606
7607 */
7608
7609 GLOBAL void att_remove_bad_ncell (T_MPH_MEASUREMENT_IND *report)
7610 {
7611 GET_INSTANCE_DATA;
7612 SHORT i = 0;
7613 SHORT j;
7614 T_ncells *pncells = &report->ncells;
7615 TRACE_FUNCTION ("att_remove_bad_ncell()");
7616
7617 /*
7618 * for all neighbourcells in the measurement report.
7619 */
7620 while (i < pncells->no_of_ncells)
7621 {
7622 /*
7623 * Do nothing if the channel number is different from
7624 * the serving cell.
7625 */
7626 if (pncells->arfcn[i] NEQ rr_data->nc_data[SC_INDEX].arfcn)
7627 i++;
7628 else
7629 {
7630 /*
7631 * else overwrite this entry by moving the rest one index
7632 */
7633 for (j = i + 1; j < pncells->no_of_ncells; j++)
7634 {
7635 pncells->arfcn[j-1] = pncells->arfcn[j];
7636 pncells->rx_lev[j-1] = pncells->rx_lev[j];
7637 pncells->bsic[j-1] = pncells->bsic[j];
7638 pncells->time_alignmt[j-1] = pncells->time_alignmt[j];
7639 pncells->frame_offset[j-1] = pncells->frame_offset[j];
7640 }
7641
7642 /*
7643 * clean the last entry
7644 */
7645 pncells->bsic[j-1] = 0;
7646 pncells->arfcn[j-1] = 0;
7647 pncells->rx_lev[j-1] = 0;
7648 pncells->time_alignmt[j-1] = 0;
7649 pncells->frame_offset[j-1] = 0;
7650 pncells->no_of_ncells--;
7651 }
7652 }
7653 }
7654
7655
7656 /*
7657 +--------------------------------------------------------------------+
7658 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7659 | STATE : code ROUTINE : att_allow_lai_in_list |
7660 +--------------------------------------------------------------------+
7661
7662 PURPOSE : After a successful location updating request MM informs
7663 RR about this. If the location area information is stored
7664 inside of one of the forbidden location area lists this
7665 information must be updated. In this function, the entry
7666 is deleted from the given forbidden list.
7667
7668 */
7669
7670 LOCAL void att_allow_lai_in_list (int list_type,
7671 const T_plmn * plmn,
7672 USHORT lac)
7673 {
7674 GET_INSTANCE_DATA;
7675 unsigned int i;
7676 T_loc_area_ident *forb_list;
7677
7678 if (list_type EQ FORBIDDEN_LIST_NORMAL)
7679 forb_list = &rr_data->ms_data.forb_lac_list[0];
7680 else
7681 forb_list = &rr_data->ms_data.roam_forb_lac_list[0];
7682
7683 TRACE_FUNCTION ("att_allow_lai_in_list()");
7684
7685 for (i = 0; i < (MAX_LAI-1); i++)
7686 {
7687 if ((lac EQ forb_list[i].lac) AND
7688 dat_plmn_equal_req (plmn->mcc, plmn->mnc,
7689 forb_list[i].mcc, forb_list[i].mnc))
7690 {
7691 /*
7692 * if the location area code is stored, overwrite this information
7693 * and fill the last issue with a default value
7694 */
7695 /* Implements Measure#32: Row 60 */
7696 att_print_forb_list ( list_type, plmn, lac, i, TRUE);
7697
7698 memmove (&forb_list[i], &forb_list[i + 1],
7699 (MAX_LAI - i - 1) * sizeof (T_loc_area_ident));
7700 forb_list[MAX_LAI - 1].lac = NOT_PRESENT_16BIT;
7701 memset (forb_list[MAX_LAI - 1].mcc, NOT_PRESENT_8BIT, SIZE_MCC);
7702 memset (forb_list[MAX_LAI - 1].mnc, NOT_PRESENT_8BIT, SIZE_MNC);
7703 }
7704 }
7705 }
7706
7707
7708 /*
7709 +--------------------------------------------------------------------+
7710 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7711 | STATE : code ROUTINE : att_rem_lai_from_forb_list |
7712 +--------------------------------------------------------------------+
7713
7714 PURPOSE : After a successful location updating request MM informs
7715 RR about this. If the location area information is stored
7716 inside of one of the forbidden location area lists this
7717 information must be updated. In this function, the entry
7718 is deleted from all forbidden lists.
7719
7720 */
7721
7722 GLOBAL void att_rem_lai_from_forb_list (const T_plmn * plmn,
7723 USHORT lac)
7724 {
7725 TRACE_FUNCTION ("att_rem_lai_from_forb_list()");
7726
7727 att_allow_lai_in_list (FORBIDDEN_LIST_NORMAL, plmn, lac);
7728 att_allow_lai_in_list (FORBIDDEN_LIST_ROAMING, plmn, lac);
7729 }
7730
7731
7732 /*
7733 +--------------------------------------------------------------------+
7734 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7735 | STATE : code ROUTINE : att_search_cell |
7736 +--------------------------------------------------------------------+
7737
7738 PURPOSE : This function searches for a cell for cell reselection.
7739
7740 */
7741
7742 static void att_search_cell (void)
7743 {
7744 GET_INSTANCE_DATA;
7745 TRACE_FUNCTION ("att_search_cell()");
7746 #if defined(_SIMULATION_)
7747 TRACE_SELECTION_TYPE (rr_data->sc_data.selection_type);
7748 #endif /* _SIMULATION_ */
7749
7750 /*
7751 * depending on the cell reselection mode.
7752 */
7753 switch (rr_data->sc_data.selection_type)
7754 {
7755 case BACK_FROM_DEDICATED:
7756 case BACK_FROM_DEDICATED_RLF:
7757 /*
7758 * back from dedicated use the fieldstrength of the
7759 * cells as the criterion
7760 */
7761 rr_data->reselect_index = att_get_highest_c2_index ();
7762 att_select_cell_dedicated ();
7763 break;
7764
7765 case CELL_RESELECTION:
7766 case CELL_RESELECTION_NC:
7767 #ifdef GPRS
7768 if( rr_data->gprs_data.use_c31 )
7769 {
7770 SHORT i;
7771 TRACE_EVENT ("c32 used in att_search_cell");
7772 for( i = 0; i < 6; i++ )
7773 rr_data->nc_data[i].c32_used = FALSE;
7774
7775 rr_data->ms_data.old_cell_tried = FALSE;
7776
7777 rr_data->reselect_index = att_get_next_best_c32_index (FALSE);
7778
7779 /*
7780 * if no suitable cell is available
7781 * try the old cell again.
7782 */
7783 if (! att_check_cell_c31 ())
7784 att_try_old_cell ();
7785
7786 break;
7787 }
7788 #endif
7789 /*lint -fallthrough*/
7790 default:
7791 /*
7792 * cell reselection in idle mode, use the cell
7793 * reselection criterion C2.
7794 */
7795 rr_data->ms_data.old_cell_tried = FALSE;
7796 rr_data->reselect_index = att_get_highest_c2_index ();
7797
7798 /*
7799 * if no suitable cell is available
7800 * try the old cell again.
7801 */
7802 if (! att_check_cell ())
7803 att_try_old_cell ();
7804 break;
7805 }
7806 EM_FMM_RESEL_START_IND;
7807 }
7808
7809
7810 /*
7811 +--------------------------------------------------------------------+
7812 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7813 | STATE : code ROUTINE : att_set_pl_in_idle_mode |
7814 +--------------------------------------------------------------------+
7815
7816 PURPOSE : The function configures the idle mode at the end of
7817 cell selection and cell reselection.
7818
7819 */
7820
7821 GLOBAL void att_set_pl_in_idle_mode (void)
7822 {
7823 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
7824 GET_INSTANCE_DATA;
7825 #endif
7826 TRACE_FUNCTION ("att_set_pl_in_idle_mode()");
7827 /* Update std value depending upon the band indicator value */
7828 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
7829 att_update_std_band_indicator (rr_data->sc_data.cd.band_indicator);
7830 #endif
7831 /*
7832 * forward classmark information to layer 1 for random access procedure
7833 */
7834 att_build_classmark_req ();
7835
7836 /*
7837 * configure the idle mode (paging group etc.)
7838 */
7839 att_build_idle_req (SC_INDEX, MODE_CELL_SELECTION);
7840
7841 /*
7842 * configure the CBCH channel
7843 */
7844 #ifdef REL99
7845 att_config_cbch ();
7846 #else
7847 att_build_cbch();
7848 #endif
7849
7850 /*
7851 * configure the neighbourcell list
7852 */
7853 att_code_mph_ncell_req (SC_INDEX);
7854
7855 /*
7856 * store the neighbourcell information in PCM and the SIM card.
7857 */
7858 }
7859
7860 /*
7861 +--------------------------------------------------------------------+
7862 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7863 | STATE : code ROUTINE : att_set_sys_info_read |
7864 +--------------------------------------------------------------------+
7865
7866 PURPOSE : The decision whether all system information messages are
7867 read during cell selection / cell reselection is done with
7868 this function. The variable sys_info_read is organized as
7869 a bitmap. Each system information message belongs to one
7870 bit of the bitmap.
7871
7872 */
7873
7874 GLOBAL void att_set_sys_info_read (USHORT mess_bit, UBYTE index)
7875 {
7876 GET_INSTANCE_DATA;
7877 T_CELL_DATA * cd;
7878 USHORT si;
7879
7880 TRACE_FUNCTION ("att_set_sys_info_read()");
7881
7882 /*
7883 * set pointer to data
7884 */
7885 if (index EQ SC_INDEX)
7886 cd = &rr_data->sc_data.cd;
7887 else if (index EQ CR_INDEX)
7888 cd = &rr_data->cr_data.cd;
7889 else
7890 {
7891 TRACE_EVENT ("unexpected index in att_set_sys_info_read()");
7892 return;
7893 }
7894
7895 /*
7896 * set the bit of the bitmap according to the message type.
7897 */
7898 cd->sys_info_read |= mess_bit;
7899
7900 #if !defined(NTRACE)
7901 si = cd->sys_info_read;
7902 /* if (GET_STATE (STATE_ATT) EQ ATT_CS2) comment out just for debugging */
7903 {
7904 if (si EQ ALL_SYS_INFO_READ)
7905 {
7906 TRACE_EVENT ("SI complete");
7907 }
7908 else
7909 {
7910 #ifdef GPRS
7911 TRACE_EVENT_P9 ( "await SI%s%s%s%s%s%s%s (%x) for %s",
7912 (si & SYS_INFO_1_READ ) ? "" : " 1" ,
7913 (si & SYS_INFO_2_READ ) ? "" : " 2" ,
7914 (si & SYS_INFO_2BIS_READ) ? "" : " 2bis",
7915 (si & SYS_INFO_3_READ ) ? "" : " 3" ,
7916 (si & SYS_INFO_4_READ ) ? "" : " 4" ,
7917 (si & SYS_INFO_2TER_READ) ? "" : " 2ter",
7918 (si & SYS_INFO_13_READ ) ? "" : " 13",
7919 si,
7920 (index EQ SC_INDEX ) ? "SC_INDEX" : "CR_INDEX");
7921 #else
7922 TRACE_EVENT_P8 ( "await SI%s%s%s%s%s%s (%x) for %s",
7923 (si & SYS_INFO_1_READ ) ? "" : " 1" ,
7924 (si & SYS_INFO_2_READ ) ? "" : " 2" ,
7925 (si & SYS_INFO_2BIS_READ) ? "" : " 2bis",
7926 (si & SYS_INFO_3_READ ) ? "" : " 3" ,
7927 (si & SYS_INFO_4_READ ) ? "" : " 4" ,
7928 (si & SYS_INFO_2TER_READ) ? "" : " 2ter",
7929 si,
7930 (index EQ SC_INDEX ) ? "SC_INDEX" : "CR_INDEX");
7931 #endif
7932 }
7933 }
7934 #endif /* !NTRACE */
7935 }
7936
7937 /*
7938 +--------------------------------------------------------------------+
7939 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
7940 | STATE : code ROUTINE : att_start_cell_reselection |
7941 +--------------------------------------------------------------------+
7942
7943 PURPOSE : The function is called at the beginning of a cell
7944 reselection.
7945
7946 */
7947
7948 GLOBAL void att_start_cell_reselection (UBYTE mode)
7949 {
7950 GET_INSTANCE_DATA;
7951 #ifdef GPRS
7952 T_GPRS_DATA *gprs_data = &rr_data->gprs_data;
7953 #endif
7954
7955 TRACE_FUNCTION ("att_start_cell_reselection()");
7956
7957 if( mode EQ BACK_FROM_DEDICATED_RLF)
7958 {
7959 /*
7960 * Allow 20 seconds for call re-establishment
7961 * In case of data link failure
7962 */
7963 tstart_tabort(2 * TABORT_VALUE);
7964 }
7965 else
7966 {
7967 tstart_tabort(TABORT_VALUE);
7968 }
7969
7970 #ifdef GPRS
7971 if ( gprs_data->rrgrr_ext_meas_req NEQ NULL )
7972 {
7973 /*
7974 * Save the request to perform Cell Reselection.
7975 * Then stop the Ext Meas procedure.
7976 * At the very end of the Ext Meas continue with CR.
7977 */
7978 gprs_data->ext_meas_ctrl |= EXT_MEAS_START_CR;
7979 rr_data->sc_data.selection_type = mode;
7980 att_rrgrr_ext_meas_stop_req(NULL);
7981 return;
7982 }
7983 #endif
7984
7985 /*
7986 * intialise some variables
7987 */
7988 rr_data->dyn_config.fcr = 0;
7989 rr_data->dyn_config.scr = 0;
7990 rr_data->bcch_error = 0;
7991 rr_data->pag_rec = FALSE;
7992 srv_clear_stored_prim (MPH_PAGING_IND);
7993
7994 /*
7995 * MM has initiated GPRS Activation. While waiting for SI13 a local reselection
7996 * is triggered in RR because of a better neighbour cell. Since MM initiated GPRS
7997 * is pending; RR should respond by RR_ACTIVATE_CNF and not by RR_ACTIVATE_IND.
7998 */
7999 #ifdef GPRS
8000 if ( GET_STATE(STATE_GPRS) EQ GPRS_ACTIVATED AND
8001 rr_data->sc_data.mm_started EQ MM_ORIGINATED AND
8002 rr_data->sc_data.selection_type EQ CELL_RESELECTION_ON_GPRS_ACT)
8003 {
8004 att_init_cell_selection (mode, MM_ORIGINATED);
8005 }
8006 else
8007 #endif
8008 {
8009 att_init_cell_selection (mode, RR_ORIGINATED);
8010 }
8011 dat_att_null();
8012 #ifdef GPRS
8013 gprs_init_data_cr();
8014 #endif
8015 /*
8016 * stop any reselection related timer.
8017 */
8018 if (rr_data->sc_data.selection_type EQ BACK_FROM_DEDICATED_RLF)
8019 {
8020 /*
8021 * according GSM 5.08, chapter 6.7.2 call re-establishment
8022 * shall be finished latest during 20 seconds (=2*normal
8023 * cell reselection time).
8024 */
8025 TIMERSTART (T_RESELECT, 2*TRESELECT_VALUE);
8026 }
8027 else
8028 {
8029 TIMERSTART (T_RESELECT, TRESELECT_VALUE);
8030 }
8031
8032 /*
8033 * depending on the cell reselection type
8034 */
8035 switch (rr_data->sc_data.selection_type)
8036 {
8037 case CELL_RESELECTION:
8038 case CELL_RESELECTION_RACH:
8039 /*
8040 * exclude serving cell for five seconds
8041 */
8042 set_tnnn (SC_INDEX, 5*ONE_SEC);
8043 break;
8044 case BACK_FROM_DEDICATED:
8045 case BACK_FROM_DEDICATED_RLF:
8046 /*
8047 * remove serving cell from neighbourcell results
8048 */
8049 att_remove_bad_ncell (&rr_data->ms_data.measurement_report);
8050 att_build_back_from_dedicated ();
8051 break;
8052 case CELL_RESELECTION_CR:
8053 /*
8054 * check cell to get back in full service
8055 */
8056 break;
8057 }
8058
8059 EM_CELL_RESEL_STARTED;
8060 /*
8061 * find a suitable cell for cell reselection
8062 */
8063 att_search_cell ();
8064 }
8065
8066 /*
8067 +--------------------------------------------------------------------+
8068 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8069 | STATE : code ROUTINE : att_start_cell_selection |
8070 +--------------------------------------------------------------------+
8071
8072 PURPOSE : The function is called at the beginning of a cell selection.
8073 */
8074
8075 GLOBAL void att_start_cell_selection (BOOL originator, BOOL parallel,
8076 U8 search_mode)
8077 {
8078 GET_INSTANCE_DATA;
8079 TRACE_FUNCTION ("att_start_cell_selection()");
8080
8081
8082 TRACE_EVENT_P2 ("START %sparallel CELL SELECTION %s_ORIGINATED",
8083 parallel?"":"not ",
8084 originator?"MM":"RR");
8085
8086 tstart_tabort(TABORT_VALUE);
8087
8088 rr_data->net_lost = FALSE;
8089 rr_data->cs_data.black_list_search_pending = FALSE;
8090
8091 EM_CELL_SELECTION;
8092
8093 /* Set the current search mode */
8094 CS_SET_CURRENT_SEARCH_MODE(search_mode);
8095
8096 /*
8097 * initialize some variables
8098 */
8099 /* found channel handling */
8100 if(originator EQ MM_ORIGINATED)
8101 {
8102 if(rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH)
8103 cs_get_channel_from_found_list ();
8104 else
8105 cs_clear_channel_from_found_list();
8106 }
8107
8108 att_init_cell_selection (CELL_SELECTION, originator);
8109
8110 /* Reset scan mode */
8111 rr_data->cs_data.scan_mode = CS_FIRST_SCAN_FIRST_ATTEMPT;
8112
8113 /*
8114 * init process and start power measurements
8115 */
8116 #ifdef GPRS
8117 rr_data->gprs_data.use_c31 = FALSE;
8118 #endif
8119 if(!parallel)
8120 {
8121 memset (rr_data->nc_data, 0, 6*sizeof (T_NC_DATA));
8122 cs_set_null ();
8123 }
8124 cs_set_all ();
8125
8126 /*
8127 * Why should a RR caused cell selection forego the helpfully information
8128 * of the neighbor cell description of the last serving cell to speed up
8129 * the selection of the new cell?
8130 * But it is appropriate only for non PARALLEL search!
8131 * Therefore we collect first the (at cs_data) stored cell discription
8132 * and merge it into a channel list (cs_data.bcch_info). As second step
8133 * we use this list to level up the priority of the matching cells after
8134 * the scan execution (cs_mph_power_cnf).
8135 */
8136
8137 #ifdef GPRS
8138 if(att_gprs_is_avail() AND !parallel)
8139 gprs_init_data_cr();
8140 #endif
8141
8142 /* Cell Selection Improvements-LLD section:4.1.3.4.1.3
8143 * This function updates the new search mode based on the current
8144 * dynamic search mode configuration
8145 */
8146 att_check_dynamic_search_mode_config();
8147
8148 cs_start_scan ();
8149
8150 if(!parallel)
8151 {
8152 if( GET_STATE(STATE_ATT) EQ ATT_CS_INIT )
8153 {
8154 att_code_rr_act_cnf();
8155 }
8156 else
8157 {
8158 SET_STATE (STATE_ATT, ATT_CS1);
8159 }
8160 dat_att_null();
8161 }
8162 }
8163
8164 /*
8165 +--------------------------------------------------------------------+
8166 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8167 | STATE : code ROUTINE : att_try_old_cell |
8168 +--------------------------------------------------------------------+
8169
8170 PURPOSE : if no suitable cell has been found during cell reselection
8171 the old serving cell is tried.
8172
8173 */
8174
8175 static void att_try_old_cell (void)
8176 {
8177 GET_INSTANCE_DATA;
8178 UBYTE search_mode =0;
8179 TRACE_FUNCTION ("att_try_old_cell()");
8180
8181 /*
8182 * check whether the old serving cell is possible
8183 */
8184
8185 if (rr_data->nc_data[SC_INDEX].arfcn EQ rr_data->nc_data[CR_INDEX].arfcn)
8186 rr_data->ms_data.old_cell_tried = TRUE;
8187
8188 /* Implements RR Clone findings #8 */
8189 if (! att_cell_barred_status_cr_no_cr (SC_INDEX) AND
8190 ! is_tnnn (SC_INDEX) AND
8191 rr_data->nc_data[SC_INDEX].c1 > 0 AND
8192 rr_data->ms_data.old_cell_tried EQ FALSE)
8193
8194 {
8195 if (rr_data->sc_data.selection_type EQ CELL_RESELECTION_RACH)
8196 {
8197 /*
8198 * go direct back to the old cell after random access failure
8199 */
8200 att_return_to_idle();
8201 }
8202 else
8203 {
8204 /*
8205 * serving cell is possible. Configure layer 1
8206 * to start cell reselection
8207 */
8208 rr_data->ms_data.old_cell_tried = TRUE;
8209 att_start_cr_in_pl(SC_INDEX);
8210 }
8211 }
8212 else
8213 {
8214 /*
8215 * old serving cell is not possible. Then start
8216 * cell selection for recovering.
8217 */
8218 /* Refer Cell Selection Improvements-LLD section:4.1.3.9 */
8219 if(rr_data->ms_data.rr_service EQ FULL_SERVICE)
8220 {
8221 /* RR is in full service and in ATT_IDLE state. Cell reselection started
8222 * and failed. Start Fast search
8223 */
8224 search_mode = FAST_SEARCH_MODE;
8225 }
8226 else
8227 {
8228 if((rr_data->ms_data.rr_service EQ LIMITED_SERVICE) AND
8229 (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH))
8230 {
8231 /* RR is in Limited service and in ATT_IDLE state. The requested service
8232 * by MM is Full service. Cell reselection started and failed.
8233 * Obtain new search mode based on the current search mode.
8234 */
8235 search_mode = cs_get_new_search_mode();
8236 }
8237 else
8238 {
8239 /* RR is in Limited service and in ATT_IDLE state. The requested service
8240 * by MM is Limited service. Cell reselection started and failed.
8241 * Start Normal search
8242 */
8243 search_mode = NORMAL_SEARCH_MODE;
8244 }
8245 }
8246
8247 /* XY:n don't inform GRR , and don't call start_cs_gprs !!!
8248 * we can go here after sending a CR_IND but not being in CS3
8249 */
8250 att_start_cell_selection (RR_ORIGINATED, CS_NOT_PARALLEL,search_mode);
8251 }
8252 }
8253
8254 /*
8255 +--------------------------------------------------------------------+
8256 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8257 | STATE : code ROUTINE : att_mph_identity_req |
8258 +--------------------------------------------------------------------+
8259
8260 PURPOSE : Forwards the mobile identities to Layer 1.
8261
8262 */
8263
8264 GLOBAL void att_mph_identity_req (void)
8265 {
8266 GET_INSTANCE_DATA;
8267 PALLOC (mph_identity_req, MPH_IDENTITY_REQ);
8268
8269 TRACE_FUNCTION ("att_mph_identity_req()");
8270
8271 memset (mph_identity_req, 0, sizeof (T_MPH_IDENTITY_REQ));
8272
8273 switch (rr_data->ms_data.rr_service)
8274 {
8275 case FULL_SERVICE:
8276 /*
8277 * identities are only forwarded in full service
8278 */
8279 if (rr_data->ms_data.imsi_available)
8280 {
8281 /*
8282 * fill in the international mobile identity, if available
8283 */
8284 mph_identity_req->mid.len_imsi = rr_data->ms_data.imsi.c_ident_dig;
8285 memcpy (mph_identity_req->mid.imsi, rr_data->ms_data.imsi.ident_dig,
8286 mph_identity_req->mid.len_imsi);
8287 }
8288
8289 if (rr_data->ms_data.tmsi_available)
8290 {
8291 /*
8292 * fill in the temporary mobile identity, if available
8293 */
8294 mph_identity_req->mid.v_tmsi = TRUE;
8295 mph_identity_req->mid.tmsi = rr_data->ms_data.tmsi_binary;
8296 }
8297 break;
8298 }
8299 #ifdef GPRS
8300 if (rr_data->gprs_data.gprs_indic)
8301 {
8302 att_add_ptmsi (mph_identity_req);
8303 {
8304 PALLOC(ms_id, RRGRR_MS_ID_IND);
8305 ms_id->tmsi = rr_data->ms_data.tmsi_binary;
8306 PSENDX(GRR, ms_id);
8307 }
8308 }
8309 #endif
8310
8311 /*
8312 * send the valid identities to layer 1.
8313 */
8314 PSENDX (PL, mph_identity_req);
8315
8316 }
8317
8318 /*
8319 +--------------------------------------------------------------------+
8320 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8321 | STATE : code ROUTINE : att_start_registration_timer |
8322 +--------------------------------------------------------------------+
8323
8324 PURPOSE : Checks whether to start, to stop or to let run the
8325 registration timer depending on the requested service by MM
8326 and the actual RR service.
8327
8328 */
8329
8330 /*
8331 * Time tables with increasing periods depending on the registration attempt
8332 */
8333 #ifdef TI_PS_FF_AT_P_CMD_CTREG
8334 /* Initialize the table with default values
8335 * All the values are in secs / 10 format
8336 * Ex: T_TEN_SEC = 10 Sec / 10
8337 */
8338 const UBYTE no_service_mode_time [25] =
8339 { T_TEN_SEC, T_TEN_SEC, T_TEN_SEC, T_TEN_SEC,
8340 T_TWENTY_SEC, T_TWENTY_SEC, T_TWENTY_SEC, T_TWENTY_SEC, T_TWENTY_SEC,
8341 T_THIRTY_SEC, T_THIRTY_SEC, T_THIRTY_SEC, T_THIRTY_SEC, T_THIRTY_SEC,
8342 T_SIXTY_SEC, T_SIXTY_SEC, T_SIXTY_SEC, T_SIXTY_SEC, T_SIXTY_SEC,
8343 T_TWO_MIN, T_TWO_MIN, T_TWO_MIN, T_TWO_MIN, T_TWO_MIN,
8344 T_SIX_MIN
8345 };
8346 #else
8347 const T_TIME no_service_mode_time [25] =
8348 { TEN_SEC, TEN_SEC, TEN_SEC, TEN_SEC,
8349 TWENTY_SEC, TWENTY_SEC, TWENTY_SEC, TWENTY_SEC, TWENTY_SEC,
8350 THIRTY_SEC, THIRTY_SEC, THIRTY_SEC, THIRTY_SEC, THIRTY_SEC,
8351 SIXTY_SEC, SIXTY_SEC, SIXTY_SEC, SIXTY_SEC, SIXTY_SEC,
8352 TWO_MIN, TWO_MIN, TWO_MIN, TWO_MIN, TWO_MIN,
8353 SIX_MIN
8354 };
8355 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
8356
8357 #ifdef TI_PS_FF_AT_P_CMD_CTREG
8358 const UBYTE lim_service_mode_time [25] =
8359 { T_TEN_SEC, T_TEN_SEC, T_TEN_SEC, T_TEN_SEC,
8360 T_TWENTY_SEC, T_TWENTY_SEC, T_TWENTY_SEC, T_TWENTY_SEC, T_TWENTY_SEC,
8361 T_THIRTY_SEC, T_THIRTY_SEC, T_THIRTY_SEC, T_THIRTY_SEC, T_THIRTY_SEC,
8362 T_SIXTY_SEC, T_SIXTY_SEC, T_SIXTY_SEC, T_SIXTY_SEC, T_SIXTY_SEC,
8363 T_TWO_MIN, T_TWO_MIN, T_TWO_MIN, T_TWO_MIN, T_TWO_MIN,
8364 T_SIX_MIN
8365 };
8366 #else
8367 const T_TIME lim_service_mode_time [25] =
8368 { TEN_SEC, TEN_SEC, TEN_SEC, TEN_SEC,
8369 TWENTY_SEC, TWENTY_SEC, TWENTY_SEC, TWENTY_SEC, TWENTY_SEC,
8370 THIRTY_SEC, THIRTY_SEC, THIRTY_SEC, THIRTY_SEC, THIRTY_SEC,
8371 SIXTY_SEC, SIXTY_SEC, SIXTY_SEC, SIXTY_SEC, SIXTY_SEC,
8372 TWO_MIN, TWO_MIN, TWO_MIN, TWO_MIN, TWO_MIN,
8373 SIX_MIN
8374 };
8375 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
8376
8377 #ifdef TI_PS_FF_AT_P_CMD_CTREG
8378 /*
8379 * Function used to convert the user given TREG timer values in secs to ms
8380 * Ex: User value TREG value
8381 * 0 1 Sec
8382 * 1 10 Sec
8383 * 2 20 Sec etc
8384 */
8385 T_TIME cast2T_Time(UBYTE tab_val)
8386 {
8387 return (tab_val)? tab_val*10000: 1000;
8388 }
8389 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
8390
8391 GLOBAL void att_start_registration_timer (void)
8392 {
8393 GET_INSTANCE_DATA;
8394 T_TIME status = 0L;
8395
8396 #ifdef TI_PS_FF_AT_P_CMD_CTREG
8397 BOOL ret;
8398 UBYTE tab_val;
8399 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
8400
8401 TRACE_FUNCTION ("att_start_registration_timer()");
8402
8403 /*
8404 * is there a TREG expiry which couldn't be handled yet
8405 * so restart TREG with a short time
8406 */
8407 if (rr_data->treg_pending)
8408 {
8409 TIMERSTART (TREG, ONE_SEC);
8410 rr_data->treg_pending = FALSE;
8411 return;
8412 }
8413 /*
8414 * preparation to avoid the change of a running TREG
8415 */
8416 TIMER_STATUS (rr_handle, TREG, &status);
8417 /*
8418 * depending on the current service of RR
8419 */
8420 switch (rr_data->ms_data.rr_service)
8421 {
8422 case NO_SERVICE:
8423 /*
8424 * RR has no service, so it will try to come back
8425 * to limited or full service after timeout
8426 * set fieldstrength to 0.
8427 */
8428 #ifdef FF_PS_RSSI
8429 RX_SetValue ( 0, RX_QUAL_UNAVAILABLE, RX_ACCE_UNAVAILABLE);
8430 #else
8431 RX_SetValue (0);
8432 #endif
8433 cs_set_all ();
8434 if (status)
8435 return;
8436
8437 if (!IS_TIMER_ACTIVE(TREG))
8438 {
8439 #ifdef TI_PS_HCOMM_CHANGE
8440 PSIGNAL (_hCommDL, DL_TRACE_REQ, NULL);
8441 #else
8442 PSIGNAL (hCommDL, DL_TRACE_REQ, NULL);
8443 #endif /* TI_PS_HCOMM_CHANGE */
8444 }
8445 #ifdef TI_PS_FF_AT_P_CMD_CTREG
8446 ret = cl_shrd_get_treg(RR_MOD_NOSERVICE_TIME,
8447 rr_data->ms_data.reg_counter,
8448 &tab_val);
8449 TRACE_EVENT_P1("Reading of the TREG value is %s",ret? "SUCCESS":"FAILURE");
8450 if (!ret)
8451 {
8452 /* Use default on failure */
8453 tab_val = no_service_mode_time [rr_data->ms_data.reg_counter];
8454 }
8455 if (rr_data->ms_data.reg_counter < 24)
8456 {
8457 rr_data->ms_data.reg_counter++;
8458 }
8459 TIMERSTART (TREG, cast2T_Time(tab_val));
8460 #else
8461 if (rr_data->ms_data.reg_counter < 24)
8462 {
8463 TIMERSTART (TREG, no_service_mode_time [rr_data->ms_data.reg_counter++]);
8464 }
8465 else
8466 {
8467 TIMERSTART (TREG, no_service_mode_time [24]);
8468 }
8469 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
8470 break;
8471 case LIMITED_SERVICE:
8472 /*
8473 * RR has limited service
8474 * The timer is only started if MM has requested Full Service.
8475 */
8476 if (rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH)
8477 {
8478 cs_set_all ();
8479 if (status)
8480 return;
8481 #ifdef TI_PS_FF_AT_P_CMD_CTREG
8482 ret = cl_shrd_get_treg(RR_MOD_LIMSERVICE_TIME,
8483 rr_data->ms_data.reg_counter,
8484 &tab_val);
8485 TRACE_EVENT_P1("Reading of the TREG value is %s",ret? "SUCCESS":"FAILURE");
8486 if (!ret)
8487 {
8488 /* Use default on failure */
8489 tab_val = lim_service_mode_time [rr_data->ms_data.reg_counter];
8490 }
8491 if (rr_data->ms_data.reg_counter < 24)
8492 {
8493 rr_data->ms_data.reg_counter++;
8494 }
8495 TIMERSTART (TREG, cast2T_Time(tab_val));
8496 #else
8497 if (rr_data->ms_data.reg_counter < 24)
8498 {
8499 TIMERSTART (TREG, lim_service_mode_time [rr_data->ms_data.reg_counter++]);
8500 }
8501 else
8502 {
8503 TIMERSTART (TREG, lim_service_mode_time [24]);
8504 }
8505 #endif /* TI_PS_FF_AT_P_CMD_CTREG */
8506 }
8507 break;
8508 case FULL_SERVICE:
8509 /*
8510 * In full service mode, the timer is not started.
8511 */
8512 TIMERSTOP (TREG);
8513 break;
8514 }
8515 }
8516
8517
8518 /*
8519 +--------------------------------------------------------------------+
8520 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8521 | STATE : code ROUTINE : att_set_func |
8522 +--------------------------------------------------------------------+
8523
8524 PURPOSE : Sets the requested MM functionality. If MM requests a
8525 PLMN available search (FUNC_NET_SRCH_BY_MMI) the current
8526 search request must be stored until the PLMN available
8527 search has been finished.
8528
8529 */
8530
8531 GLOBAL void att_set_func (UBYTE func)
8532 {
8533 GET_INSTANCE_DATA;
8534
8535 #if !defined(NTRACE)
8536 TRACE_EVENT_P5 ("att_set_func: func op=%s %scurrent=%s, service:rMM=%s RRs=%s",
8537 _rr_str_FUNC[func],
8538 _rr_str_PARFUNC[rr_data->ms_data.parallel_net_plmn_search_type],
8539 _rr_str_FUNC[rr_data->ms_data.current_plmn_search_type],
8540 _rr_str_FUNC[rr_data->ms_data.req_mm_service],
8541 _rr_str_SERVICE[rr_data->ms_data.rr_service]);
8542
8543 if ((func EQ FUNC_NET_SRCH_BY_MMI) AND
8544 (func NEQ rr_data->ms_data.parallel_net_plmn_search_type))
8545 {
8546 TRACE_EVENT_P2 ("att_set_func: NEW %scurrent=%s",
8547 _rr_str_PARFUNC[func],
8548 _rr_str_FUNC[rr_data->ms_data.current_plmn_search_type]);
8549 }
8550 else if ((func NEQ rr_data->ms_data.current_plmn_search_type) OR
8551 (rr_data->ms_data.parallel_net_plmn_search_type NEQ 0))
8552 {
8553 TRACE_EVENT_P1 ("att_set_func: NEW current=%s", _rr_str_FUNC[func]);
8554 }
8555 #endif /* !NTRACE */
8556
8557 switch (func)
8558 {
8559 case FUNC_LIM_SERV_ST_SRCH:
8560 case FUNC_PLMN_SRCH:
8561 case FUNC_ST_PWR_SCAN:
8562 rr_data->ms_data.parallel_net_plmn_search_type = 0;
8563 rr_data->ms_data.current_plmn_search_type = func;
8564 break;
8565
8566 case FUNC_NET_SRCH_BY_MMI:
8567 rr_data->ms_data.parallel_net_plmn_search_type = func;
8568 break;
8569 }
8570 }
8571
8572 /*
8573 +--------------------------------------------------------------------+
8574 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8575 | STATE : code ROUTINE : att_get_func |
8576 +--------------------------------------------------------------------+
8577
8578 PURPOSE : Requests the MM functionality. If a temporary PLMN available
8579 search request is active (temp_func = FUNC_NET_SRCH_BY_MMI)
8580 this function is returned, else the last one which was
8581 requested by MMI.
8582
8583 */
8584
8585 static UBYTE att_get_func (void)
8586 {
8587 GET_INSTANCE_DATA;
8588 switch (rr_data->ms_data.parallel_net_plmn_search_type)
8589 {
8590 case FUNC_NET_SRCH_BY_MMI:
8591 return (rr_data->ms_data.parallel_net_plmn_search_type);
8592
8593 default:
8594 return (rr_data->ms_data.current_plmn_search_type);
8595 }
8596 }
8597
8598 /*
8599 +--------------------------------------------------------------------+
8600 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8601 | STATE : code ROUTINE : att_clear_parallel_search |
8602 +--------------------------------------------------------------------+
8603
8604 PURPOSE : Resets the temporary requested MM functionality.
8605
8606 */
8607
8608 static void att_clear_parallel_search (void)
8609 {
8610 GET_INSTANCE_DATA;
8611 rr_data->ms_data.parallel_net_plmn_search_type = 0;
8612 }
8613
8614 /*
8615 +--------------------------------------------------------------------+
8616 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8617 | STATE : code ROUTINE : att_init_cr_data |
8618 +--------------------------------------------------------------------+
8619
8620 PURPOSE : The CR index contains the whole data of the new cell.
8621 It is cleared prior to cell reselection
8622 */
8623
8624 GLOBAL void att_init_cr_data (void)
8625 {
8626 GET_INSTANCE_DATA;
8627 /*
8628 * clear sys info bitmap
8629 */
8630 rr_data->cr_data.cd.sys_info_read = NO_SYS_INFO_READ;
8631
8632 /*
8633 * reset BA list from SI 2, 2Bis and 2Ter
8634 */
8635 memset(&rr_data->cr_data.cr_white_list, 0 , sizeof(T_CR_WHITE_LIST));
8636 }
8637
8638 /*
8639 +--------------------------------------------------------------------+
8640 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8641 | STATE : code ROUTINE : att_copy_cr_data |
8642 +--------------------------------------------------------------------+
8643
8644 PURPOSE : The CR index contains the whole data of the new cell.
8645 It shall replace the content of the old serving cell.
8646 The content of the old serving cell is copied to the
8647 column of the new cell (in the neighbour cell area). The
8648 status is set to DECODED.
8649
8650 */
8651
8652 GLOBAL void att_copy_cr_data (void)
8653 {
8654 GET_INSTANCE_DATA;
8655 UBYTE i;
8656
8657 /*
8658 * look for all neighbourcells.
8659 */
8660 for (i=0;i<6;i++)
8661 if (rr_data->nc_data[CR_INDEX].arfcn EQ rr_data->nc_data[i].arfcn)
8662 {
8663 /*
8664 * channel found, then update neighbourcell
8665 */
8666 memcpy (&rr_data->nc_data[i], &rr_data->nc_data[SC_INDEX],
8667 sizeof (T_NC_DATA));
8668 rr_data->nc_data[i].bcch_status = DECODED;
8669 rr_data->old_serving_cell = i;
8670 break;
8671 }
8672
8673 /*
8674 * update SC_INDEX column.
8675 */
8676 memcpy (&rr_data->nc_data[SC_INDEX], &rr_data->nc_data[CR_INDEX],
8677 sizeof (T_NC_DATA));
8678 /*
8679 * implementation problem: must be set for RR originated search
8680 * e.g. limited to full service
8681 */
8682 rr_data->nc_data[SC_INDEX].bcch_status = DECODED;
8683
8684 /*
8685 * fit classmarks depend on the values of 'std' and the new serving cell
8686 */
8687 rr_csf_fit_capability ();
8688 #if defined (REL99) && defined (TI_PS_FF_EMR)
8689 /*When there's no SI-2quater in the reselected cell and in the current
8690 cell the reporting is of enhanced type, we can no longer use these
8691 enhanced parameters. */
8692 /*Reset EMR data and indicate the same to GRR and ALR*/
8693 if ( rr_data->sc_data.emr_data_current.is_data_valid EQ TRUE )
8694 {
8695 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS);
8696 for_set_default_emr_data(&rr_data->sc_data.emr_data_current);
8697 for_send_enh_para(&rr_data->sc_data.emr_data_current);
8698 }
8699 #endif
8700 }
8701
8702 /*
8703 +--------------------------------------------------------------------+
8704 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8705 | STATE : code ROUTINE : att_copy_eplmn_list |
8706 +--------------------------------------------------------------------+
8707
8708 PURPOSE : This function copies the EPLMN list to rr_data global area
8709
8710 */
8711
8712 GLOBAL void att_copy_eplmn_list (T_eq_plmn_list *eq_plmn_list)
8713 {
8714 GET_INSTANCE_DATA;
8715 UBYTE i;
8716
8717 /* List only copied if valid and PLMNs greater than 1 (HPLMN included)
8718 else EPLMN list is marked as invalid */
8719 if(eq_plmn_list->v_eq_plmn)
8720 {
8721 for(i=0;i<RR_EPLMNLIST_SIZE;i++)
8722 {
8723 T_plmn local_copy;
8724 rr_unpack_plmn(&local_copy, eq_plmn_list->eq_plmn, i);
8725 rr_data->ms_data.eq_plmn_list[i] = local_copy; /*Struct copy*/
8726 }
8727
8728 rr_data->ms_data.v_eq_plmn = TRUE;
8729 }
8730 else
8731 {
8732 rr_data->ms_data.v_eq_plmn = FALSE;
8733 memset(&rr_data->ms_data.eq_plmn_list, 0xFF, SIZE_EPLMN);
8734 }
8735 }
8736
8737 /*
8738 +--------------------------------------------------------------------+
8739 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8740 | STATE : code ROUTINE : rr_unpack_plmn |
8741 +--------------------------------------------------------------------+
8742
8743 PURPOSE : Unpacks a PLMN from compressed form to uncompressed form.
8744
8745 */
8746
8747 LOCAL void rr_unpack_plmn (T_plmn *plmn, const UBYTE *packed, USHORT index)
8748 {
8749 index *= UBYTES_PER_PLMN;
8750 plmn->mcc[0] = packed[index] & 0x0f;
8751 plmn->mcc[1] = packed[index] >> 4;
8752 index++;
8753 plmn->mcc[2] = packed[index] & 0x0f;
8754 plmn->mnc[2] = packed[index] >> 4;
8755 index++;
8756 plmn->mnc[0] = packed[index] & 0x0f;
8757 plmn->mnc[1] = packed[index] >> 4;
8758 index++;
8759 if ((plmn->mcc[0] & 0x0F) EQ 0x0F)
8760 plmn->v_plmn = V_PLMN_NOT_PRES;
8761 else
8762 plmn->v_plmn = V_PLMN_PRES;
8763 }
8764
8765 /*
8766 +--------------------------------------------------------------------+
8767 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8768 | STATE : code ROUTINE : att_build_back_from_dedicated |
8769 +--------------------------------------------------------------------+
8770
8771 PURPOSE : A list is build containing the serving cell followed by
8772 the synchronized neighbourcells in decreasing fieldstrenght.
8773 In case of call re-establishment the serving cell is not used.
8774 The list controls the cell reselection after dedicated mode.
8775
8776 */
8777
8778 static void att_build_back_from_dedicated (void)
8779 {
8780 GET_INSTANCE_DATA;
8781 UBYTE i;
8782 T_NC_DATA * rrd;
8783
8784 /*
8785 * update the neighbourcell entries
8786 */
8787 for (i=0;i<6;i++)
8788 {
8789 /*
8790 * clear the data for this neighbourcell
8791 */
8792 memset (&rr_data->nc_data[i], 0, sizeof (T_NC_DATA));
8793 rrd = &rr_data->nc_data[i];
8794 if (rr_data->ms_data.measurement_report.ncells.no_of_ncells > i)
8795 {
8796 /*
8797 * if neighbourcell data is available in the measurement report
8798 * copy the data.
8799 */
8800 rrd->bsic = rr_data->ms_data.measurement_report.ncells.bsic[i];
8801 rrd->arfcn = rr_data->ms_data.measurement_report.ncells.arfcn[i];
8802 rrd->rxlev = rr_data->ms_data.measurement_report.ncells.rx_lev[i];
8803 rrd->bcch_status = NON_DECODED;
8804 rrd->avail_time = 0;
8805 }
8806 else
8807 rrd->bcch_status = EMPTY;
8808 }
8809
8810 /*
8811 * update the serving cell fieldstrength data.
8812 * It is important to make distinction between rxlev of the traffic channel and of the BCCH channel
8813 * for C1 and C2 calculations
8814 */
8815 rr_data->nc_data[SC_INDEX].rxlev = rr_data->ms_data.measurement_report.bcch_rxlev_of_sc;
8816
8817 /*
8818 * implementation problem: must be set to have a defined status.
8819 */
8820 rr_data->nc_data[SC_INDEX].bcch_status = DECODED;
8821 }
8822
8823 /*
8824 +--------------------------------------------------------------------+
8825 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8826 | STATE : code ROUTINE : att_check_network |
8827 +--------------------------------------------------------------------+
8828
8829 PURPOSE : This function is a SW shield for the FTA campaign. Due
8830 to bad cables and public networks with high fieldstrength
8831 some FTA testcases (especially MM testcases with limited
8832 services) fails on our Anite System. To avoid this these
8833 function is a SW shield, excluding all german networks.
8834
8835 This function must be adapted for other countries if needed.
8836
8837 */
8838
8839 GLOBAL UBYTE att_check_network (T_loc_area_ident * lai)
8840 {
8841 GET_INSTANCE_DATA;
8842 UBYTE count=0;
8843 /*
8844 * if a test SIM is inserted and "Software Shielding" is enabled then check mcc value with stored mcc value
8845 * (durig dynamic configuration command shield).The network exists in the list updated using dynamic
8846 * configauration command SHIELD then return FALSE.
8847 */
8848 if ((test_house EQ TRUE) AND (rr_data->dyn_config.mcc_shield.enabled EQ TRUE))
8849 {
8850 for(count=0;count< MAX_MCC_SHIELD;count++)
8851 {
8852 if (lai->mcc[0] EQ rr_data->dyn_config.mcc_shield.mcc[count][0] AND
8853 lai->mcc[1] EQ rr_data->dyn_config.mcc_shield.mcc[count][1] AND
8854 lai->mcc[2] EQ rr_data->dyn_config.mcc_shield.mcc[count][2] )
8855 {
8856 TRACE_EVENT ("att_check_network() returns FALSE");
8857 return FALSE;
8858 }
8859 }
8860 }
8861 return TRUE;
8862 }
8863
8864
8865 /*
8866 +--------------------------------------------------------------------+
8867 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8868 | STATE : code ROUTINE : att_return_to_idle |
8869 +--------------------------------------------------------------------+
8870
8871 PURPOSE : The functions configures PL for idle mode without going
8872 through a complete cell reselection.
8873
8874 */
8875
8876 GLOBAL void att_return_to_idle (void)
8877 {
8878 GET_INSTANCE_DATA;
8879
8880 TIMERSTOP (T_RESELECT);
8881 /*
8882 * configure layer 1
8883 */
8884 #ifdef GPRS
8885 if(att_gprs_cell_has_pbcch())
8886 {
8887 att_gprs_stop_pl();
8888 }
8889 else
8890 {
8891 #endif
8892 att_build_idle_req (SC_INDEX, MODE_CELL_SELECTION);
8893 #ifdef GPRS
8894 }
8895 #endif
8896
8897 SET_STATE (STATE_ATT, ATT_IDLE);
8898 dat_att_cell_selected();
8899 srv_use_stored_prim ();
8900 #ifdef REL99
8901 #ifdef GPRS
8902 /* RR is returning to idle mode. If cbch info was received
8903 * during transfer mode, send it now.
8904 */
8905 if(rr_data->gprs_data.cbch_info_rxvd_in_ptm)
8906 {
8907 rr_data->gprs_data.cbch_info_rxvd_in_ptm = FALSE;
8908 att_config_cbch();
8909 }
8910 #endif
8911 #endif
8912 /*
8913 * Start registration timer if needed
8914 */
8915 att_start_registration_timer ();
8916
8917 rr_data->bcch_error = 0;
8918 }
8919
8920 /*
8921 +--------------------------------------------------------------------+
8922 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8923 | STATE : code ROUTINE : att_notify_stop_plmn_search |
8924 +--------------------------------------------------------------------+
8925
8926 PURPOSE : Network search has to be aborted in lower layer so that
8927 NC monitoring can be resumed when going back to idle mode.
8928 */
8929
8930 GLOBAL void att_notify_stop_plmn_search (UBYTE deactivate_pl)
8931 {
8932 GET_INSTANCE_DATA;
8933 UCHAR state = GET_STATE (STATE_ATT);
8934
8935 TRACE_EVENT_P1("att_notify_stop_plmn_search - %x", rr_data->start_cell_reselection);
8936
8937 if ( rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI OR
8938 (rr_data->ms_data.rr_service EQ LIMITED_SERVICE AND !rr_data->start_cell_reselection) OR
8939 (rr_data->ms_data.rr_service EQ NO_SERVICE AND !rr_data->start_cell_reselection) OR
8940 state EQ ATT_CS1 OR
8941 state EQ ATT_CS2 OR
8942 CS_GET_CURRENT_SEARCH_MODE EQ BLACK_LIST_SEARCH_MODE)
8943 {
8944 PALLOC (mph_sync_req, MPH_SYNC_REQ);
8945
8946 if(deactivate_pl)
8947 mph_sync_req->cs = CS_STOP_PLMN_SEARCH_AND_DEACTIVATE;
8948 else
8949 mph_sync_req->cs = CS_STOP_PLMN_SEARCH;
8950
8951 PSENDX (PL, mph_sync_req);
8952
8953 rr_data->start_cell_reselection = TRUE;
8954
8955 TRACE_EVENT_P1("Start_cell_reselection %d",rr_data->start_cell_reselection);
8956
8957 }
8958 }
8959
8960
8961
8962 /*
8963 +--------------------------------------------------------------------+
8964 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8965 | STATE : code ROUTINE : att_reset_old_lai |
8966 +--------------------------------------------------------------------+
8967
8968 PURPOSE : This function is used to reset old lai parameters
8969 */
8970
8971 GLOBAL void att_reset_old_lai_rac ()
8972 {
8973 GET_INSTANCE_DATA;
8974 rr_data->old_cell_id = NOT_PRESENT_16BIT;
8975 #ifdef GPRS
8976 rr_data->old_rac = NOT_PRESENT_8BIT;
8977 #endif
8978 memset (&rr_data->old_lai, NOT_PRESENT_8BIT, sizeof(T_loc_area_ident));
8979
8980 }
8981
8982 /*
8983 +--------------------------------------------------------------------+
8984 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
8985 | STATE : code ROUTINE : att_copy_old_lai_rac |
8986 +--------------------------------------------------------------------+
8987
8988 PURPOSE : This function is used to copy old lai and rac parameters
8989 */
8990
8991 GLOBAL void att_copy_old_lai_rac (U8 index)
8992 {
8993 GET_INSTANCE_DATA;
8994 memcpy (&rr_data->old_lai, &rr_data->nc_data[index].lai,
8995 sizeof(T_loc_area_ident));
8996 rr_data->old_cell_id = rr_data->nc_data[index].cell_id;
8997 #ifdef GPRS
8998 rr_data->old_rac = rr_data->nc_data[index].rac;
8999 #endif
9000 }
9001
9002 /*
9003 +--------------------------------------------------------------------------------+
9004 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9005 | STATE : code ROUTINE : att_check_dynamic_search_mode_config |
9006 +--------------------------------------------------------------------------------+
9007
9008 PURPOSE : This function updates the new search mode based on the current
9009 dynamic search mode configuration
9010 CSI-LLD section:4.1.3.4.1.8
9011 */
9012
9013 GLOBAL void att_check_dynamic_search_mode_config(void)
9014 {
9015 GET_INSTANCE_DATA;
9016 U8 new_mode = CS_GET_CURRENT_SEARCH_MODE;
9017
9018 TRACE_FUNCTION("att_check_dynamic_search_mode_config()");
9019
9020 TRACE_EVENT_P1("New Search Mode : %d", CS_GET_CURRENT_SEARCH_MODE);
9021
9022 if(new_mode EQ FAST_SEARCH_MODE AND !rr_data->dyn_config.tfast_cs_val)
9023 {
9024 /* If Fast search is disabled, use Normal search */
9025 new_mode = NORMAL_SEARCH_MODE;
9026
9027 TRACE_EVENT("Fast Search is disabled");
9028 }
9029
9030 if(new_mode EQ NORMAL_SEARCH_MODE AND !rr_data->dyn_config.tnormal_cs_val)
9031 {
9032 /* If Normal search is disabled, use Full search */
9033 new_mode = FULL_SEARCH_MODE;
9034
9035 TRACE_EVENT("Normal Search is disabled");
9036 }
9037
9038 if(new_mode NEQ CS_GET_CURRENT_SEARCH_MODE)
9039 TRACE_EVENT_P1("Allowed Search Mode : %d", new_mode);
9040
9041 CS_SET_CURRENT_SEARCH_MODE(new_mode);
9042
9043 }
9044
9045
9046 /*
9047 +--------------------------------------------------------------------+
9048 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9049 | STATE : code ROUTINE : att_get_txpwr_max_cch |
9050 +--------------------------------------------------------------------+
9051
9052 PURPOSE : This function is used to calculate the MAX power used on CCH
9053 */
9054
9055 LOCAL UBYTE att_get_txpwr_max_cch (UBYTE index)
9056 {
9057 GET_INSTANCE_DATA;
9058 UBYTE max_cch = rr_data->nc_data[index].select_para.ms_txpwr_max_cch;
9059 UBYTE dbm_value;
9060
9061 TRACE_FUNCTION("att_get_txpwr_max_cch()");
9062
9063 switch(std)
9064 {
9065 case STD_1800:
9066 case STD_DUAL_EGSM:
9067 case STD_DUAL:
9068 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
9069 case STD_850_1800:
9070 case STD_850_900_1800:
9071 #endif
9072 /* Ref 04.18 Section 10.5.2.35
9073 * Rest Octets IE includes parameters which are used by the mobile station
9074 * for cell selection and reselection purposes. It may also include the
9075 * POWER OFFSET parameter used by DCS 1800 Class 3 MS.
9076 */
9077 if (INRANGE(LOW_CHANNEL_1800,rr_data->nc_data[index].arfcn,HIGH_CHANNEL_1800))
9078 {
9079 /* DCS 1800 */
9080 if (att_get_power() EQ 0x02 AND
9081 rr_data->nc_data[index].c2_par.power_off_ind)
9082 {
9083 TRACE_EVENT(" IDLE_REQ :DCS_PCLASS3");
9084 /* Class 3 & Valid Power offset */
9085 dbm_value = p_control_dcs[max_cch] +
9086 (rr_data->nc_data[index].c2_par.power_off << 1);
9087
9088 /* dbm value is more than 36 return the max cch power level as 29 */
9089 if(dbm_value > 36) return 29;
9090
9091 if(dbm_value NEQ 0)
9092 {
9093 /* map the calculated dbm value to power control value
9094 * Specification : 0505 Section : 4.1.1
9095 */
9096 max_cch = (30 - dbm_value) >= 0 ?
9097 (30 - dbm_value) >> 1 :
9098 (31 - ((dbm_value - 32) >> 1));
9099 }
9100 } /* if att_get_power */
9101 } /* if INRANGE */
9102 break;
9103 default :
9104 break;
9105 } /* switch std */
9106 return max_cch;
9107 }
9108
9109
9110
9111 #if !defined(NTRACE)
9112 /*
9113 +--------------------------------------------------------------------+
9114 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9115 | STATE : code ROUTINE : att_print_mcc_mnc |
9116 +--------------------------------------------------------------------+
9117
9118 PURPOSE : Outputs to trace mcc and mnc arrays
9119
9120 */
9121 /* Implements Measure#32: Row 52,53, 124 & 125 */
9122 GLOBAL void att_print_mcc_mnc (USHORT arfcn, UBYTE *mcc, UBYTE *mnc, T_S2I_STRING titel)
9123 {
9124 TRACE_EVENT_P8 ( "[%d] MCC=%x%x%x MNC=%x%x%x %s",
9125 ((int)arfcn), mcc[0], mcc[1], mcc[2], mnc[0], mnc[1], mnc[2],
9126 S2I_STRING(titel)); /* A valid string is expected */
9127 }
9128
9129 LOCAL void att_print_selection_type (UBYTE selection_type)
9130 {
9131 GET_INSTANCE_DATA;
9132 switch (rr_data->sc_data.selection_type)
9133 {
9134 case CELL_SELECTION:
9135 TRACE_EVENT_WIN ("selection_type=CELL_SELECTION");
9136 break;
9137 case CELL_RESELECTION:
9138 TRACE_EVENT_WIN ("selection_type=CELL_RESELECTION");
9139 break;
9140 case BACK_FROM_DEDICATED:
9141 TRACE_EVENT_WIN ("selection_type=BACK_FROM_DEDICATED");
9142 break;
9143 case CELL_RESELECTION_NC:
9144 TRACE_EVENT_WIN ("selection_type=CELL_RESELECTION_NC");
9145 break;
9146 case BACK_FROM_DEDICATED_RLF:
9147 TRACE_EVENT_WIN ("selection_type=BACK_FROM_DEDICATED_RLF");
9148 break;
9149 case CELL_RESELECTION_RACH:
9150 TRACE_EVENT_WIN ("selection_type=CELL_RESELECTION_RACH");
9151 break;
9152 case CELL_RESELECTION_CR:
9153 TRACE_EVENT_WIN ("selection_type=CELL_RESELECTION_CR");
9154 break;
9155 }
9156 }
9157
9158 /* Implements Measure#32: Row 36, 39 and 40 */
9159 LOCAL void att_print_op (T_op *op, T_S2I_STRING titel)
9160 {
9161 T_S2I_STRING sim, mode;
9162 if (op->v_op)
9163 {
9164 sim = op->sim_ins ? (op->ts ? S2I_STRING("TEST") : S2I_STRING("NORMAL")) : S2I_STRING("NO");
9165 mode = op->m ? S2I_STRING("MAN") : S2I_STRING("AUTO");
9166
9167 TRACE_EVENT_P5 ("%s: SIM=%s mode=%s func=%s service=%s",
9168 S2I_STRING(titel),
9169 S2I_STRING(sim),
9170 S2I_STRING(mode),
9171 S2I_STRING(_rr_str_FUNC[op->func]),
9172 S2I_STRING(_rr_str_SERVICE[op->service]));
9173 }
9174 }
9175 #endif /* !NTRACE */
9176
9177 /*
9178 +--------------------------------------------------------------------+
9179 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9180 | STATE : code ROUTINE : att_set_rr_service_info |
9181 +--------------------------------------------------------------------+
9182
9183 PURPOSE : Copies the RR related service info(service,PLMN,lac,cell_id)
9184 */
9185
9186 GLOBAL void att_set_rr_service_info (void)
9187 {
9188 GET_INSTANCE_DATA;
9189
9190 T_LOC_INFO loc_info;
9191 loc_info.service_mode = rr_data->ms_data.rr_service;
9192 if(rr_data->ms_data.rr_service NEQ NO_SERVICE)
9193 {
9194 loc_info.lac = rr_data->nc_data[SC_INDEX].lai.lac;
9195 loc_info.cell_id = rr_data->nc_data[SC_INDEX].cell_id;
9196 memcpy (loc_info.mcc,rr_data->nc_data[SC_INDEX].lai.mcc,SIZE_MCC);
9197 memcpy (loc_info.mnc,rr_data->nc_data[SC_INDEX].lai.mnc,SIZE_MNC);
9198 }
9199 cl_shrd_set_loc(&loc_info);
9200 }
9201
9202 /*
9203 +--------------------------------------------------------------------+
9204 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9205 | STATE : code ROUTINE : att_set_tim_advance_info |
9206 +--------------------------------------------------------------------+
9207
9208 PURPOSE : Copies the Timing Advance info.ME_STATUS is presently using
9209 only ME_STATUS_IDLE which is not as per the standard.We need to assign
9210 me_status correctly.
9211 */
9212
9213 GLOBAL void att_set_tim_advance_info (void)
9214 {
9215 GET_INSTANCE_DATA;
9216 T_TIM_ADV tim_adv;
9217 tim_adv.me_status = ME_STATUS_IDLE;
9218 tim_adv.tm_adv = rr_data->sc_data.new_ta;
9219 cl_shrd_set_tim_adv(&tim_adv);
9220 }
9221
9222 /*
9223 +--------------------------------------------------------------------+
9224 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9225 | STATE : code ROUTINE : att_func1_opt |
9226 +--------------------------------------------------------------------+
9227
9228 PURPOSE : This function sets the system information read flag of the passed
9229 si_type . It saves the neighbour cell list or Merges it to previously
9230 saved list if available.
9231 */
9232 LOCAL void att_copy_sys_info_2bis_2ter_par(UBYTE index,T_SI_TYPE si_type,
9233 T_LIST *new_2_bis_ter_list, BUF_neigh_cell_desc *neigh_cell_desc,
9234 UBYTE indicate_changes)
9235 {
9236 GET_INSTANCE_DATA;
9237 T_LIST new_list;
9238 T_CELL_DATA *cd;
9239 BOOL modified = FALSE;
9240
9241 USHORT cur_si_type_read; /*Current SI type*/
9242 USHORT oth_si_type_read; /*The other SI type in this function */
9243 USHORT oth_si_to_clean;/*The other SI to clean in this function*/
9244 UCHAR si_type_msg; /* 2BIS or 2TER type msg*/
9245
9246 TRACE_FUNCTION("att_copy_sys_info_2bis_2ter_par()");
9247
9248 switch (index)
9249 {
9250 case SC_INDEX:
9251 case CR_INDEX:
9252 if(si_type EQ SI_TYPE_2BIS)
9253 {
9254 cur_si_type_read = SYS_INFO_2BIS_READ;
9255 oth_si_type_read = SYS_INFO_2TER_READ;
9256 oth_si_to_clean = IND_SI_2TER;
9257 si_type_msg = SYS_INFO_2bis_MSG;
9258
9259 }
9260 else
9261 {
9262 cur_si_type_read = SYS_INFO_2TER_READ;
9263 oth_si_type_read = SYS_INFO_2BIS_READ;
9264 oth_si_to_clean = IND_SI_2BIS;
9265 si_type_msg = SYS_INFO_2ter_MSG;
9266 }
9267 if (index EQ SC_INDEX)
9268 {
9269 cd = &rr_data->sc_data.cd;
9270 if ((cd->sys_info_read & cur_si_type_read) EQ cur_si_type_read)
9271 {
9272 srv_copy_list (&cd->ncell_list, new_2_bis_ter_list, sizeof (T_LIST));
9273 att_clean_buf ((USHORT)(IND_SI_2 | oth_si_to_clean));
9274 cd->sys_info_read &= ~(SYS_INFO_2_READ | oth_si_type_read);
9275 att_check_2ter_read (index);
9276 }
9277 else
9278 srv_merge_list (&cd->ncell_list, new_2_bis_ter_list);
9279 modified = TRUE;
9280 #ifdef GPRS
9281 rr_data->gprs_data.ba_bcch_modified= FALSE;
9282 #endif
9283
9284 }
9285 else
9286 {
9287 cd = &rr_data->cr_data.cd;
9288 /*
9289 * merge 2bis list with the old neighbour cell list
9290 */
9291 srv_copy_list (&new_list, &cd->ncell_list,
9292 sizeof (T_LIST));
9293 srv_merge_list (&new_list, new_2_bis_ter_list);
9294
9295 if (srv_compare_list (&cd->ncell_list, &new_list) EQ FALSE)
9296 {
9297 /*
9298 * both lists are different
9299 */
9300 srv_copy_list (&cd->ncell_list, &new_list, sizeof (T_LIST));
9301 modified = TRUE;
9302 }
9303 }
9304 /* CSI-LLD section:4.1.1.11
9305 * This function Updates the black list with the BA list received in si2bis/ter
9306 */
9307 cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,&cd->ncell_list);
9308
9309 dat_store_neigh_cell_desc (si_type_msg, index,
9310 neigh_cell_desc, &cd->ncell_list);
9311 /*
9312 * Indicate that the system information type 2bis message has been read.
9313 */
9314 att_set_sys_info_read (cur_si_type_read, index);
9315
9316 /*
9317 * forward new neighbour cell list to layer 1
9318 * if changes shall be indicated
9319 */
9320 if (modified AND indicate_changes)
9321 {
9322 att_code_mph_ncell_req (index);
9323 }
9324
9325 break;
9326 }
9327 }
9328
9329
9330
9331 #if defined (REL99) && defined (TI_PS_FF_EMR)
9332 /*
9333 +--------------------------------------------------------------------+
9334 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9335 | STATE : code ROUTINE : attf_send_enh_para_to_alr |
9336 +--------------------------------------------------------------------+
9337
9338 PURPOSE : This function formats and sends a primitive with enhanced measurement
9339 parameters.
9340 */
9341 GLOBAL void attf_send_enh_para_to_alr(UBYTE rep_type, T_enh_para_struct *p_src)
9342 {
9343
9344 PALLOC(p_enh, MPH_ENHPARA_UPDATE_REQ);
9345 TRACE_FUNCTION ("attf_send_enh_para_to_alr");
9346 p_enh->rep_type = rep_type;
9347 p_enh->enh_para = *p_src;
9348 PSENDX(PL,p_enh);
9349 return;
9350 }
9351
9352 /*
9353 +--------------------------------------------------------------------+
9354 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9355 | STATE : code ROUTINE : att_print_mcc_mnc |
9356 +--------------------------------------------------------------------+
9357
9358 PURPOSE : Outputs to trace mcc and mnc arrays
9359
9360 */
9361 LOCAL void att_check_for_si5ter_and_enhpara (UBYTE old_index)
9362 {
9363 GET_INSTANCE_DATA;
9364 T_rr_enh_para *p_temp = &rr_data->sc_data.emr_data_temp;
9365 T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current;
9366
9367 /*we have complete BA(SACCH) list (with or without SI-5 ter ) : we will
9368 discard any enhanced para that are present in previous state which are
9369 aligned to BA(BCCH)*/
9370 if (rr_data->sc_data.enh_para_status EQ ENH_PARA_IDLE )
9371 {
9372 /*The enhanced parameters available are from different state, reset them*/
9373 for_set_default_emr_data(p_temp);
9374 memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS);
9375 for_set_default_emr_data(p_cur);
9376 for_send_enh_para(p_cur);
9377 rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE;
9378 return;
9379 }
9380 if(old_index EQ rr_data->sc_data.ba_index)
9381 {
9382 /*Updation of enhanced cell list for EMR : we can receive
9383 SI-5ter and MI in any random order*/
9384 if ( (rr_data->sc_data.emr_data_temp.is_data_valid EQ TRUE) AND
9385 rr_data->sc_data.emr_data_temp.ba2bsic_map_pending )
9386 for_att_update_ba2bsic_mapping(&rr_data->sc_data.emr_data_temp);
9387 else if ( (rr_data->sc_data.emr_data_current.is_data_valid EQ TRUE) AND
9388 rr_data->sc_data.emr_data_current.ba2bsic_map_pending )
9389 for_att_update_ba2bsic_mapping(&rr_data->sc_data.emr_data_current);
9390
9391 /*When BA(SACCH) is ready, check whether there are enhanced parameters in
9392 temp that needs attention*/
9393 if ( (rr_data->sc_data.enh_para_status EQ ENH_PARA_DEDICATED) AND
9394 (p_temp->is_data_valid EQ TRUE ) )
9395 {
9396 /* This means enhanced parameters were received before BA list - so update
9397 the enhanced list with actual ARFCN and update current EMR data*/
9398 if ( for_update_enh_cell_list( rr_data->act_ncell_list) EQ TRUE)
9399 {
9400 *p_cur = *p_temp;
9401 if (p_cur->ba2bsic_map_pending EQ 0) /*send parameters when there are no more mapping pending*/
9402 for_send_enh_para(p_cur);
9403 }
9404 /*Reset temporary, irrespective of whether updation is succesful or not*/
9405 for_set_default_emr_data(p_temp);
9406 }
9407 else if (p_cur->is_data_valid EQ TRUE AND p_cur->ba2bsic_map_pending EQ 0)
9408 for_send_enh_para(p_cur);
9409 }
9410 else
9411 {
9412 for_set_default_emr_data(p_temp);
9413 for_set_default_emr_data(p_cur);
9414 for_send_enh_para(p_cur);
9415 }
9416 return;
9417 }
9418 #endif
9419
9420 /*
9421 +--------------------------------------------------------------------+
9422 | PROJECT : GSM-PS (6147) MODULE : RR_ATT |
9423 | STATE : code ROUTINE : att_update_std_band_indicator |
9424 +--------------------------------------------------------------------+
9425
9426 PURPOSE : This function updates the std value depending upon the band
9427 indicator value received in the SI1 or SI6 message. band
9428 indicator will be ignored when received in the DCS 1800 or
9429 PCS 1900 frequency band. Depending upon the std value region
9430 will be updated.
9431
9432 */
9433 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
9434 GLOBAL void att_update_std_band_indicator (UBYTE band_indicator)
9435 {
9436 GET_INSTANCE_DATA;
9437 UBYTE band_index = cs_get_band_index (rr_data->nc_data[SC_INDEX].arfcn);
9438 UBYTE freq_bands;
9439 UBYTE new_region = NOT_PRESENT_8BIT;
9440 UBYTE mscr = 0; /* variable to hold msc release version*/
9441
9442 TRACE_FUNCTION ("att_update_std_band_indicator");
9443
9444 get_msc_release_version(&mscr);
9445 TRACE_EVENT_P1("mscr (MSC release) version : 0x%X", mscr);
9446 if (mscr NEQ MSCR_99)
9447 {
9448 TRACE_EVENT ("band indicator received when MSC release is not R99");
9449 TRACE_ERROR ("band indicator received when MSC release is not R99");
9450 return;
9451 }
9452
9453 if ((band_index EQ B_DCS_1800) OR (band_index EQ B_PCS_1900))
9454 {
9455 TRACE_EVENT_P2 ("band indicator %x received in band %x", band_indicator, band_index);
9456 return;
9457 }
9458
9459 rr_csf_get_freq_bands (&freq_bands);
9460 if (band_indicator NEQ NOT_PRESENT_8BIT)
9461 {
9462 if (band_indicator EQ BAND_IND_1800)
9463 {
9464 if ((freq_bands & BAND_DCS_1800) EQ BAND_DCS_1800)
9465 {
9466 if (std EQ STD_DUAL_US)
9467 {
9468 std = STD_850_1800;
9469 new_region = BOTH_REGIONS;
9470 }
9471 else if (std EQ STD_850_900_1900)
9472 {
9473 std = STD_850_900_1800;
9474 new_region = BOTH_REGIONS;
9475 }
9476 }
9477 }
9478 else
9479 {
9480 if ((freq_bands & BAND_PCS_1900) EQ BAND_PCS_1900)
9481 {
9482 if (std EQ STD_DUAL_EGSM)
9483 {
9484 std = STD_900_1900;
9485 new_region = BOTH_REGIONS;
9486 }
9487 else if (std EQ STD_850_900_1800)
9488 {
9489 std = STD_850_900_1900;
9490 new_region = BOTH_REGIONS;
9491 }
9492 }
9493 }
9494 TRACE_EVENT_P1 ("Updated std to %x", std);
9495 }
9496
9497 if (new_region NEQ NOT_PRESENT_8BIT)
9498 rr_data->cs_data.region = new_region;
9499 }
9500 #endif
9501
9502 #endif /* RR_ATTF_C */