FreeCalypso > hg > fc-selenite
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 */ |