comparison g23m-gsm/rr/rr_cs.c @ 0:75a11d740a02

initial import of gsm-fw from freecalypso-sw rev 1033:5ab737ac3ad7
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 09 Jun 2016 00:02:41 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:75a11d740a02
1 /*
2 +-----------------------------------------------------------------------------
3 | Project :
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 Cell Selection
18 | capability of Radio Resource.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef RR_CS_C
23 #define RR_CS_C
24
25 #include "config.h"
26 #include "fixedconf.h"
27 #include "condat-features.h"
28
29 #define ENTITY_RR
30
31 /*==== INCLUDES ===================================================*/
32
33 #include <string.h>
34 #include <stdlib.h>
35 #include <stddef.h> /* offsetof */
36 #include "typedefs.h"
37 #include "pcm.h"
38 #include "pconst.cdg"
39 #include "mconst.cdg"
40 #include "message.h"
41 #include "ccdapi.h"
42 #include "vsi.h"
43 #include "custom.h"
44 #include "gsm.h"
45 #include "prim.h"
46 #include "cnf_rr.h"
47 #include "tok.h"
48 #include "rr.h"
49
50 /*==== EXPORT =====================================================*/
51
52 /*==== PRIVATE ====================================================*/
53 static void cs_remove_co_chan (USHORT arfcn, USHORT co_arfcn);
54 static void cs_remove_co_channels (USHORT arfcn);
55 static UBYTE cs_check_channel (USHORT arfcn);
56 static BOOL cs_sync_next_bsic (void);
57
58
59 /*==== VARIABLES ==================================================*/
60
61 EXTERN UBYTE test_house;
62
63 /*==== FUNCTIONS ==================================================*/
64
65 LOCAL void cs_add_current_network_to_found_list ();
66 LOCAL BOOL cs_check_black_list_criteria(U8 region, U16 arfcn, U8 rxlev);
67 LOCAL BOOL cs_is_in_black_list(U8 region, U16 arfcn);
68 LOCAL BOOL cs_is_in_white_list(U8 region, U16 arfcn);
69 LOCAL U8 cs_get_sync_fail_counter(U8 region, U16 arfcn);
70 LOCAL void cs_reset_sync_fail_counter(U8 region, U16 arfcn);
71 LOCAL void cs_inc_sync_fail_counter(U8 region, U16 arfcn);
72 LOCAL void cs_use_white_list_info(U8 num_of_chan);
73 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
74 LOCAL UBYTE cs_update_std_ffs (UBYTE new_std);
75 #else
76 LOCAL UBYTE get_band_index(USHORT arfcn);
77 #endif
78
79
80 /*
81 * -------------------------------------------------------------------
82 * Procedures
83 * -------------------------------------------------------------------
84 */
85
86 /*
87 * The cell selection process bases on attributes for each channel
88 * of the power campaign. This attributes are defined by a bitmap
89 *
90 * Bit 1 0 priority
91 * ---------------------------------
92 * 0 0 low priority
93 * 0 1 mid priority
94 * 1 0 high priority
95 * 1 1 reserved
96 *
97 * The selection of a cell for synchronisation depends on
98 * the priority and the fieldstrength. It will be the cell
99 * selected, which is not checked yet, has the highest
100 * priority and the highest fieldstrength.
101 *
102 * Bit 2 reserved
103 *
104 * Bit 3 checked flag
105 * ---------------------------------
106 * 0 cell is not checked
107 * 1 cell is checked
108 *
109 * The flag indicates whether a cell is already checked or not.
110 *
111 * Bit 4 detected flag
112 * ---------------------------------
113 * 0 bcch is not detected
114 * 1 bcch is checked
115 *
116 * The flag indicates whether a BCCH is detected or not.
117 *
118 * Bit 5 emergency cell flag
119 * ---------------------------------
120 * 0 emergency services possible
121 * 1 emergency services not possible
122 *
123 * The flag indicates whether emergency services are possible or not.
124 *
125 * Bit 6 low priority cell flag
126 * ---------------------------------
127 * 0 no low priority cell
128 * 1 low priority cell
129 *
130 * The flag indicates whether a cell has a low priority or not.
131 *
132 * Bit 8 BCCH info list flag
133 * ---------------------------------
134 * 0 not member of the BCCH info list
135 * 1 member of the BCCH info list
136 *
137 * The flag indicates whether a cell is member of the BCCH information
138 * list or not.
139 */
140
141 /*
142 +--------------------------------------------------------------------+
143 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
144 | STATE : code ROUTINE : cs_init_process |
145 +--------------------------------------------------------------------+
146
147 PURPOSE : Initialisation of the cell selection process.
148 Called from 'pei_init' exclusively and rr_deactivate.
149
150 */
151
152 GLOBAL void cs_init_process (void)
153 {
154 GET_INSTANCE_DATA;
155 TRACE_FUNCTION ("cs_init_process()");
156
157 /*
158 * set the state and clear all variables.
159 */
160 SET_STATE (STATE_CELL_SEL, CS_NULL);
161 memset (&rr_data->cs_data, 0, sizeof (&rr_data->cs_data));
162
163 rr_data->cs_data.arfcn_sc = NOT_PRESENT_16BIT;
164 rr_data->cs_data.arfcn_cr = NOT_PRESENT_16BIT;
165
166 /* CSI-LLD section:4.1.1.11 */
167 rr_data->cs_data.initial_plmn_search = INITIAL_PLMN_SEARCH_NOT_ACTIVE;
168
169 /* In all simulation testcases written prior to cell selection
170 * improvements feature, US_BIT and STD values were not set in
171 * the ARFCN field
172 */
173 #if !defined (_SIMULATION_)
174 rr_data->cs_data.region = NOT_PRESENT_8BIT;
175 #endif
176
177 rr_data->cs_data.white_list.last_sc_arfcn = NOT_PRESENT_16BIT;
178 rr_data->cs_data.white_list.region = NOT_PRESENT_8BIT;
179 TRACE_EVENT_P1("white_list_region %d", rr_data->cs_data.white_list.region);
180
181 rr_data->start_cell_reselection = TRUE;
182 TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection);
183
184 /* Dynamic configuration parameters */
185 rr_data->dyn_config.bl_cs_en = TRUE;
186 rr_data->dyn_config.tfast_cs_val = TFAST_CS_VALUE;
187 rr_data->dyn_config.tnormal_cs_val = TNORMAL_CS_VALUE;
188 rr_data->dyn_config.lim_ser_nps_delay= DELAY_NON_PAR_SEARCH_LIM_SER;
189
190 #if defined(_SIMULATION_FFS_)
191 rr_csf_ffs_init();
192 #endif
193 }
194
195 /*
196 +--------------------------------------------------------------------+
197 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
198 | STATE : code ROUTINE : cs_set_bcch_info |
199 +--------------------------------------------------------------------+
200
201 PURPOSE : The function merges bcch information from SIM to White list
202 database
203 CSI-LLD - 4.1.2.2.1
204 */
205
206 GLOBAL void cs_set_bcch_info (T_bcch_info * sim_bcch_info)
207 {
208 GET_INSTANCE_DATA;
209 T_LIST tmp_list;
210 BUF_neigh_cell_desc cd;
211
212 TRACE_FUNCTION ("cs_set_bcch_info()");
213
214 /* Check for availability of sim_bcch_info data */
215 if(cs_check_region(rr_data->cs_data.white_list.region) AND
216 (sim_bcch_info NEQ NULL))
217 {
218 if(sim_bcch_info->v_bcch)
219 {
220 /* Store the sim_bcch_info data to white_list structure */
221 memcpy(cd.b_neigh_cell_desc,sim_bcch_info->bcch,BA_BITMAP_SIZE);
222 cd.o_neigh_cell_desc = 0;
223 cd.l_neigh_cell_desc = NCELL_DESC_BIT_LEN;
224
225 /* Merge BCCH info into white list */
226 for_create_channel_list((T_f_range *)&cd,&tmp_list);
227 srv_merge_list(&rr_data->cs_data.white_list.list,&tmp_list);
228 }
229 }
230 }
231
232 /*
233 +--------------------------------------------------------------------+
234 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
235 | STATE : code ROUTINE : cs_clear_white_list |
236 +--------------------------------------------------------------------+
237
238 PURPOSE : The function clears the bcch information (neigbour cell
239 description) of sys info 2, 2bis and 2ter stored in RAM
240 and FFS.
241 CSI-LLD - 4.1.2.2.6
242 */
243
244 GLOBAL void cs_clear_white_list(U8 clr_bcch_info)
245 {
246 GET_INSTANCE_DATA;
247 TRACE_FUNCTION ("cs_clear_white_list()");
248
249 if (clr_bcch_info & CLR_WHITE_LIST_SIM)
250 {
251 dat_send_bcchinfo_mm (NULL);
252
253 TRACE_EVENT ("White List: SIM cleared");
254 }
255
256 if (clr_bcch_info & CLR_WHITE_LIST_RAM)
257 {
258 rr_data->cs_data.arfcn_sc = NOT_PRESENT_16BIT;
259 rr_data->cs_data.arfcn_cr = NOT_PRESENT_16BIT;
260
261 memset(&rr_data->cs_data.white_list, 0 , sizeof(T_CS_WHITE_LIST));
262
263 rr_data->cs_data.white_list.last_sc_arfcn = NOT_PRESENT_16BIT;
264 rr_data->cs_data.white_list.region = NOT_PRESENT_8BIT;
265
266 TRACE_EVENT ("White List: RAM cleared");
267 }
268
269 #if defined (_SIMULATION_FFS_)
270 if (clr_bcch_info & CLR_WHITE_LIST_FFS)
271 {
272 T_CS_WHITE_LIST white_list;
273 memset(&white_list,0,sizeof(T_CS_WHITE_LIST));
274
275 rr_data->cs_data.white_list.region = NOT_PRESENT_8BIT;
276 rr_data->cs_data.white_list.last_sc_arfcn = NOT_PRESENT_16BIT;
277
278 rr_csf_write_white_list(&white_list);
279
280 TRACE_EVENT ("White List: FFS cleared");
281 }
282 #endif /* _SIMULATION_FFS_ */
283 }
284
285
286 #if defined (_SIMULATION_FFS_)
287 /*
288 +--------------------------------------------------------------------+
289 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
290 | STATE : code ROUTINE : cs_store_white_list |
291 +--------------------------------------------------------------------+
292
293 PURPOSE : The function stores while list information to FFS.
294 CSI-LLD - 4.1.2.2.3
295 */
296
297 GLOBAL void cs_store_white_list (void)
298 {
299 GET_INSTANCE_DATA;
300 /* Store the white List to FFS */
301 rr_csf_write_white_list(&rr_data->cs_data.white_list);
302 }
303 #endif /*_SIMULATION_FFS_*/
304
305 /*
306 +--------------------------------------------------------------------+
307 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
308 | STATE : code ROUTINE : cs_use_white_list_info |
309 +--------------------------------------------------------------------+
310
311 PURPOSE : The function uses the stored white list information and
312 increases the priority of these channels.
313 CSI-LLD - 4.1.2.2.8
314 */
315
316 LOCAL void cs_use_white_list_info(U8 num_of_chan)
317 {
318 GET_INSTANCE_DATA;
319 U8 i, priority;
320
321 TRACE_FUNCTION ("cs_use_white_list_info()");
322
323 /* Boot Time: If white list is invalidated by the second activate_req,
324 * decrease priority of white list carriers in power_cnf
325 */
326 priority = (cs_check_region(rr_data->cs_data.white_list.region)) ?
327 CS_HIGH_PRIORITY : CS_LOW_PRIORITY ;
328
329 for (i=0;i<num_of_chan;i++)
330 {
331 /*
332 * Power cnf always contains White list carriers at the top
333 */
334 rr_data->cs_data.attributes [i] = priority;
335
336 TRACE_EVENT_P3 ("Whie List: change prio of [%d]%u to 0x%02x",
337 rr_data->cs_data.arfcn[i]&ARFCN_MASK,
338 i, rr_data->cs_data.attributes [i]);
339 }
340 }
341
342 /*
343 +--------------------------------------------------------------------+
344 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
345 | STATE : code ROUTINE : cs_set_all |
346 +--------------------------------------------------------------------+
347
348 PURPOSE : The function clears all attributes and all stored BCCH
349 information.
350
351 */
352
353 GLOBAL void cs_set_all (void)
354 {
355 GET_INSTANCE_DATA;
356 TRACE_FUNCTION ("cs_set_all()");
357
358 /*
359 * clear all attributes
360 */
361 memset (&rr_data->cs_data.attributes, 0, sizeof (rr_data->cs_data.attributes));
362 }
363
364 /*
365 +--------------------------------------------------------------------+
366 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
367 | STATE : code ROUTINE : cs_set_freq_band |
368 +--------------------------------------------------------------------+
369
370 PURPOSE : This function sets the frequency band bit mask.
371
372 */
373
374 GLOBAL UBYTE cs_get_freq_band (UBYTE pch_interrupt)
375 {
376 UBYTE freq_bands;
377
378 rr_csf_get_freq_bands (&freq_bands);
379
380 if (!pch_interrupt)
381 {
382 /*
383 * Power measurements without PCH interruption => PLMN search
384 * ----------------------------------------------------------
385 * In this case we use the found and set value of 'std' for the frequency
386 * area to mask out not available frequencies from 'freq_bands'.
387 * Use only frequencies of the current area.
388 */
389 switch (std)
390 {
391 case STD_900:
392 freq_bands &= BAND_GSM_900;
393 break;
394 case STD_EGSM:
395 freq_bands &= BAND_E_GSM; /* BAND_GSM_900|BAND_E_GSM */
396 break;
397 case STD_1900:
398 freq_bands &= BAND_PCS_1900;
399 break;
400 case STD_1800:
401 freq_bands &= BAND_DCS_1800;
402 break;
403 case STD_DUAL:
404 freq_bands &= BAND_DUAL; /* BAND_GSM_900|BAND_DCS_1800 */
405 break;
406 case STD_DUAL_EGSM:
407 freq_bands &= BAND_DUAL_EXT; /* BAND_GSM_900|BAND_E_GSM|BAND_DCS_1800 */
408 break;
409 case STD_850:
410 freq_bands &= BAND_GSM_850;
411 break;
412 case STD_DUAL_US:
413 freq_bands &= BAND_DUAL_US; /* BAND_GSM_850|BAND_PCS_1900 */
414 break;
415 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
416 case STD_850_1800:
417 freq_bands &= BAND_850_1800; /* BAND_GSM_850|BAND_DCS_1800 */
418 break;
419 case STD_900_1900:
420 freq_bands &= BAND_900_1900; /* BAND_E_GSM|BAND_PCS_1900 */
421 break;
422 case STD_850_900_1800:
423 freq_bands &= BAND_850_900_1800; /* BAND_E_GSM|BAND_GSM_850|BAND_DCS_1800 */
424 break;
425 case STD_850_900_1900:
426 freq_bands &= BAND_850_900_1900; /* BAND_GSM_850|BAND_E_GSM|BAND_PCS_1900 */
427 break;
428 #endif
429 }
430 }
431 return freq_bands;
432 }
433
434 /*
435 +--------------------------------------------------------------------+
436 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
437 | STATE : code ROUTINE : get_band_index |
438 +--------------------------------------------------------------------+
439
440 PURPOSE : The function extracts the frequency band index from the given
441 'arfcn' parameter.
442 */
443
444 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
445 GLOBAL UBYTE cs_get_band_index (USHORT arfcn)
446 #else
447 GLOBAL UBYTE get_band_index (USHORT arfcn)
448 #endif
449 {
450 UBYTE local_std = STD_GET_FROM_ARFCN(arfcn);
451 UBYTE sc_band;
452
453 if(local_std EQ STD_NOT_PRESENT)
454 {
455 /* Parallel search case */
456 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
457 local_std = std;
458 #else
459 local_std = std_bands[std-1];
460 #endif
461 }
462
463 switch (local_std)
464 {
465 case STD_900:
466 sc_band = B_GSM_900;
467 break;
468
469 case STD_EGSM:
470 sc_band = B_E_GSM;
471 break;
472
473 case STD_1800:
474 sc_band = B_DCS_1800;
475 break;
476
477 case STD_1900:
478 sc_band = B_PCS_1900;
479 break;
480
481 case STD_850:
482 sc_band = B_GSM_850;
483 break;
484
485 case STD_DUAL:
486 if (arfcn >= LOW_CHANNEL_1800)
487 sc_band = B_DCS_1800;
488 else
489 sc_band = B_GSM_900;
490 break;
491
492 case STD_DUAL_EGSM:
493 if (arfcn >= LOW_CHANNEL_EGSM)
494 sc_band = B_E_GSM;
495 else if (arfcn >= LOW_CHANNEL_1800)
496 sc_band = B_DCS_1800;
497 else if (arfcn EQ CHANNEL_0)
498 sc_band = B_E_GSM;
499 else
500 sc_band = B_GSM_900;
501 break;
502
503 case STD_DUAL_US:
504 if (arfcn >= LOW_CHANNEL_1900)
505 sc_band = B_PCS_1900;
506 else
507 sc_band = B_GSM_850;
508 break;
509
510 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
511 case STD_850_1800:
512 if (arfcn >= LOW_CHANNEL_1800)
513 sc_band = B_DCS_1800;
514 else
515 sc_band = B_GSM_850;
516 break;
517
518 case STD_900_1900:
519 if (arfcn >= LOW_CHANNEL_EGSM)
520 sc_band = B_E_GSM;
521 else if (arfcn >= LOW_CHANNEL_1900)
522 sc_band = B_PCS_1900;
523 else if (arfcn EQ CHANNEL_0)
524 sc_band = B_E_GSM;
525 else
526 sc_band = B_GSM_900;
527 break;
528
529 case STD_850_900_1800:
530 if (arfcn >= LOW_CHANNEL_EGSM)
531 sc_band = B_E_GSM;
532 else if (arfcn >= LOW_CHANNEL_1800)
533 sc_band = B_DCS_1800;
534 else if (arfcn EQ CHANNEL_0)
535 sc_band = B_E_GSM;
536 else if (arfcn >= LOW_CHANNEL_850)
537 sc_band = B_GSM_850;
538 else
539 sc_band = B_GSM_900;
540 break;
541
542 case STD_850_900_1900:
543 if (arfcn >= LOW_CHANNEL_EGSM)
544 sc_band = B_E_GSM;
545 else if (arfcn >= LOW_CHANNEL_1900)
546 sc_band = B_PCS_1900;
547 else if (arfcn EQ CHANNEL_0)
548 sc_band = B_E_GSM;
549 else if (arfcn >= LOW_CHANNEL_850)
550 sc_band = B_GSM_850;
551 else
552 sc_band = B_GSM_900;
553 break;
554 #endif
555
556 default:
557 sc_band = MAX_NUM_BANDS;
558 break;
559 }
560 /* this trace causes a lot of trace load; switch on only if needed
561 TRACE_EVENT_P3 (" [%u] std=%02x, sc_band=%02x", arfcn&ARFCN_MASK, local_std, sc_band);
562 */
563 return sc_band;
564 }
565
566 /*
567 +--------------------------------------------------------------------+
568 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
569 | STATE : code ROUTINE : cs_start_scan |
570 +--------------------------------------------------------------------+
571
572 PURPOSE : This function starts the scanning. The power measurements
573 are triggered. Power measurements means that layer 1
574 performs fieldstrength measurements on all carriers and
575 sends a list of the best to RR back for FB/SB scanning and
576 BCCH reading. There are two variants: with or without
577 paging channel (PCH) interruption. If RR is already in
578 idle mode, scanning without PCH interruption is performed,
579 that means the MS is pageable during that time.
580
581 */
582
583 GLOBAL void cs_start_scan ()
584 {
585 GET_INSTANCE_DATA;
586 U16 arfcn;
587 U8 i=0;
588 U8 region;
589 PALLOC (mph_power_req, MPH_POWER_REQ);/* T_MPH_POWER_REQ */
590
591 TRACE_FUNCTION ("cs_start_scan()");
592
593 memset(mph_power_req,0,sizeof(T_MPH_POWER_REQ ));
594
595 TIMERSTOP (TREG);
596 rr_data->cs_data.act_index = NOT_PRESENT_8BIT;
597
598 switch (GET_STATE (STATE_CELL_SEL))
599 {
600 case CS_NULL:
601 case CS_NULL_ACTIVE:
602 /*
603 * start power measurements with PCH interruption
604 */
605 mph_power_req->pch_interrupt = PCH_INTERRUPT;
606 rr_data->first_meas_received = FALSE;
607 rr_data->resel_pending = FALSE;
608 rr_data->c_ncell_bcch = NOT_INITIALISED;
609 rr_data->cs_data.all_freq_area = FALSE;
610 /* In all simulation testcases written prior to cell selection
611 * improvements feature, US_BIT and STD values were not set in
612 * the ARFCN field
613 */
614 #if !defined (_SIMULATION_)
615 rr_data->cs_data.region = NOT_PRESENT_8BIT;
616 #endif
617
618 dat_att_null ();
619 SET_STATE (STATE_CELL_SEL, CS_NULL_ACTIVE);
620
621 /* stop possibly parallel search and allow start of cell reselection */
622 att_notify_stop_plmn_search (FALSE);
623 break;
624
625 case CS_IDLE:
626 case CS_IDLE_ACTIVE:
627 /*
628 * start power measurements without PCH interruption.
629 */
630 mph_power_req->pch_interrupt = NO_PCH_INTERRUPT;
631 SET_STATE (STATE_CELL_SEL, CS_IDLE_ACTIVE);
632
633 /* indicate suspend state of nc monitoring in lower layer */
634 rr_data->start_cell_reselection = FALSE;
635 TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection);
636 break;
637
638 default:
639 break;
640 }
641
642 #ifndef TI_PS_FF_QUAD_BAND_SUPPORT
643 mph_power_req->freq_bands = cs_get_freq_band (mph_power_req->pch_interrupt);
644 #endif
645
646 /* CSI-LLD : 4.1.3.4.1.4 */
647 /* Set the new search mode */
648 mph_power_req->search_mode = CS_GET_CURRENT_SEARCH_MODE;
649
650 /* Set Lower Rxlev threshold */
651 memcpy( mph_power_req->lower_rxlevel_threshold, rr_data->dyn_config.lower_rxlev_thr, MAX_NUM_BANDS*sizeof(UBYTE));
652
653 /* Copy the black list information */
654 for(i=0;i<MAX_REGIONS;i++)
655 {
656 srv_copy_list ((T_LIST *)&mph_power_req->black_list.list[i],
657 &rr_data->cs_data.black_list.list[i],sizeof(T_LIST));
658 }
659
660 /* In case of Black List search, include "grey" carriers also
661 * in the Black list while sending to ALR
662 */
663 if(CS_GET_CURRENT_SEARCH_MODE EQ BLACK_LIST_SEARCH_MODE)
664 {
665 TRACE_EVENT(" Black_List_Search_Started");
666
667 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
668 mph_power_req->freq_bands = cs_get_freq_band (FALSE);
669 #endif
670
671 region = rr_data->cs_data.region;
672
673 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
674 if (region EQ BOTH_REGIONS)
675 {
676 for (i=0; i<MAX_REGIONS; i++)
677 {
678 for(arfcn=CHANNEL_0;arfcn<CHANNEL_0_INTERNAL;arfcn++)
679 {
680 /* Since Black List search is always a parallel search, "grey" carriers
681 * belonging to the current region only have to be added
682 */
683 if(cs_get_sync_fail_counter(i,arfcn))
684 srv_set_channel((T_LIST*)&mph_power_req->black_list.list[i],arfcn);
685 }
686 }
687 }
688 else
689 {
690 #endif
691 for(arfcn=CHANNEL_0;arfcn<CHANNEL_0_INTERNAL;arfcn++)
692 {
693 /* Since Black List search is always a parallel search, "grey" carriers
694 * belonging to the current region only have to be added
695 */
696 if(cs_get_sync_fail_counter(region,arfcn))
697 srv_set_channel((T_LIST*)&mph_power_req->black_list.list[region],arfcn);
698 }
699 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
700 }
701 #endif
702 }
703 else
704 {
705 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
706 mph_power_req->freq_bands = cs_get_freq_band (TRUE);
707 #endif
708
709 TRACE_EVENT_P9 ( "White List:[%d]Reg,[%d]Arfcn, MCC/MNC r=%x%x%x/%x%x%x/%d",
710 rr_data->cs_data.white_list.region,
711 rr_data->cs_data.white_list.last_sc_arfcn,
712 rr_data->cs_data.white_list.last_sc_lac.mcc[0],
713 rr_data->cs_data.white_list.last_sc_lac.mcc[1],
714 rr_data->cs_data.white_list.last_sc_lac.mcc[2],
715 rr_data->cs_data.white_list.last_sc_lac.mnc[0],
716 rr_data->cs_data.white_list.last_sc_lac.mnc[1],
717 rr_data->cs_data.white_list.last_sc_lac.mnc[2],
718 rr_data->cs_data.white_list.last_sc_lac.lac);
719
720 /* Copy white list information
721 * White list cannot be used, when the region it belongs to, is not known
722 * or its PLMN ID does not match with the requested PLMN
723 */
724 if((!cs_check_region(rr_data->cs_data.white_list.region)) OR
725 ((rr_data->ms_data.req_mm_service NEQ FUNC_PLMN_SRCH) AND
726 (GET_STATE(STATE_ATT) NEQ ATT_CS_INIT)) OR
727 ((rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH) AND
728 (!dat_plmn_equal_req(rr_data->cs_data.white_list.last_sc_lac.mcc,
729 rr_data->cs_data.white_list.last_sc_lac.mnc,
730 rr_data->ms_data.plmn.mcc,
731 rr_data->ms_data.plmn.mnc))))
732 {
733 TRACE_EVENT("White List is not used");
734 }
735 else
736 {
737 /* Copy the white list information */
738 srv_copy_list((T_LIST*)&mph_power_req->white_list.list,
739 &rr_data->cs_data.white_list.list,sizeof (T_LIST));
740
741 /* Set the region */
742 mph_power_req->white_list.region = rr_data->cs_data.white_list.region;
743
744 /* White list is valid */
745 mph_power_req->white_list.white_list_valid = TRUE;
746 }
747 }
748
749 /* Handle the search mode timers based on the new search mode */
750 cs_handle_search_mode_timer(CS_GET_CURRENT_SEARCH_MODE);
751
752 /*
753 * reset the time for net search to finish
754 * a PLMN available search during 35 seconds.
755 */
756 if( rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI)
757 TIMERSTART(T_PLMN_SEARCH, T_PLMN_SEARCH_VALUE);
758
759 /*
760 * start power measurements in layer 1.
761 */
762 TRACE_EVENT_P2 ("cs_start_scan(): freq_bands=%02x Search Mode = %d",
763 mph_power_req->freq_bands,mph_power_req->search_mode);
764
765 PSENDX (PL, mph_power_req);
766 }
767
768 /*
769 +--------------------------------------------------------------------+
770 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
771 | STATE : code ROUTINE : cs_start_sync |
772 +--------------------------------------------------------------------+
773
774 PURPOSE : Start the synchronisation to FB/SB without power measurements.
775 Synchronisation to the frequency correction burst (FB) followed
776 by a synchronisation to the synchron burst (SB) is carried
777 out by layer 1. It means that the MS is synchronised to the
778 base station and then able to read the BCCH to check the cell.
779
780 */
781
782 GLOBAL void cs_start_sync (void)
783 {
784 GET_INSTANCE_DATA;
785 UBYTE i;
786
787 TRACE_FUNCTION ("cs_start_sync()");
788
789 /* While scanning for limited service, we scan all carriers */
790 if((CS_GET_PREVIOUS_SEARCH_MODE NEQ FAST_SEARCH_MODE) AND
791 (rr_data->cs_data.scan_mode EQ CS_SECOND_SCAN))
792 {
793 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
794 /*
795 * reset check bit for all channels
796 */
797 rr_data->cs_data.attributes[i] &= CS_NON_CHECKED_BITS;
798 }
799
800 if (cs_sync_next_bsic () EQ FALSE)
801 {
802 /*
803 * indicate the end of scanning to attachment process
804 */
805 TIMERSTOP(T_PLMN_SEARCH);
806 att_no_bsic_ind ();
807 }
808 else
809 {
810 /*
811 * Another FB/SB scan is requested
812 */
813 SET_STATE (STATE_CELL_SEL, CS_IDLE_ACTIVE);
814 }
815 }
816
817
818 /*
819 +--------------------------------------------------------------------+
820 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
821 | STATE : code ROUTINE : cs_del_list |
822 +--------------------------------------------------------------------+
823
824 PURPOSE : A list of carriers (neighbourcell list) is used to speed up
825 the cell selection process. All members of the list and the
826 list of the power campaign are set to low priority.
827
828 */
829
830 GLOBAL void cs_del_list (T_LIST *list)
831 {
832 GET_INSTANCE_DATA;
833 UBYTE i;
834
835 TRACE_FUNCTION ("cs_del_list()");
836
837 /*
838 * for all cells of the power campaign list
839 */
840
841 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
842 {
843 /*
844 * if they are member of the given list and not just checked
845 */
846 if (srv_get_channel (list, (USHORT)(rr_data->cs_data.arfcn[i]&ARFCN_MASK)) AND
847 rr_data->cs_data.act_index NEQ i)
848 {
849 /*
850 * set to low priority
851 */
852 rr_data->cs_data.attributes [i] &= CS_SET_TO_LOW_PRIORITY;
853 /*TRACE_EVENT_P1("[%u] del from list",rr_data->cs_data.arfcn[i]);*/
854 }
855 }
856 }
857
858 /*
859 +--------------------------------------------------------------------+
860 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
861 | STATE : code ROUTINE : cs_set_list |
862 +--------------------------------------------------------------------+
863
864 PURPOSE : A list of carriers (neighbourcell list) is used to speed up
865 the cell selection process. All members of the list and the
866 list of the power campaign are set to high priority.
867
868
869 */
870
871 GLOBAL void cs_set_list (T_LIST *list)
872 {
873 GET_INSTANCE_DATA;
874 UBYTE i;
875
876 TRACE_FUNCTION ("cs_set_list()");
877
878 /*
879 * Not in the test house
880 */
881 if (rr_data->cell_test_operation OR
882 dat_test_sim_available ())
883 return;
884
885 /*
886 * for all channels in the power campaign list
887 */
888 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
889 {
890 /*
891 * if they are also member of the given list
892 */
893 if (srv_get_channel (list, (USHORT)(rr_data->cs_data.arfcn[i]&ARFCN_MASK)))
894 {
895 /*
896 * set to high priority
897 */
898 rr_data->cs_data.attributes [i] &= CS_SET_TO_LOW_PRIORITY;
899 rr_data->cs_data.attributes [i] += CS_HIGH_PRIORITY;
900 }
901 }
902 }
903
904 /*
905 +--------------------------------------------------------------------+
906 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
907 | STATE : code ROUTINE : cs_def_list |
908 +--------------------------------------------------------------------+
909
910 PURPOSE : Checks whether a member of the list has the requested
911 attributes (e.g. emergency or low priority cell)
912
913 */
914
915 GLOBAL UBYTE cs_def_list (UBYTE attribute)
916 {
917 GET_INSTANCE_DATA;
918 UBYTE i;
919 UBYTE result = FALSE;
920
921 TRACE_FUNCTION ("cs_def_list()");
922
923 /*
924 * for all channels of the power campaign list
925 */
926 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
927 {
928 /*
929 * check only cells which have high/mid priority
930 */
931 if ((rr_data->cs_data.attributes [i] & CS_CHECK_FLAG) EQ 0 AND
932 (rr_data->cs_data.attributes [i] & CS_PRIORITY) NEQ 0)
933 /*
934 * channel is not checked yet, so it is possible that
935 * the channel has this attribute
936 */
937 {
938 rr_data->cs_data.attributes [i] = CS_MID_PRIORITY;
939 result = TRUE;
940 }
941
942 /*
943 * check the attribute of the cell. If an attribute
944 * like emergency or low priority cell is set, the channel
945 * has been checked.
946 */
947 if (rr_data->cs_data.attributes[i] & attribute)
948 {
949 /*
950 * channel has this attribute, then set priority to high
951 */
952 rr_data->cs_data.attributes [i] &= CS_SET_TO_LOW_PRIORITY;
953 rr_data->cs_data.attributes [i] += CS_HIGH_PRIORITY;
954
955 /* reset check bit for this channel */
956 rr_data->cs_data.attributes[i] &= CS_NON_CHECKED_BITS;
957 result = TRUE;
958 }
959 }
960
961 return result;
962 }
963
964 /*
965 +--------------------------------------------------------------------+
966 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
967 | STATE : code ROUTINE : cs_sync_next |
968 +--------------------------------------------------------------------+
969
970 PURPOSE : The function starts the next FB/SB synchronisation request.
971 It selects the channel with the highest priority and field-
972 strength which is not checked yet.
973
974 */
975
976 GLOBAL BOOL cs_sync_next (void)
977 {
978 GET_INSTANCE_DATA;
979 TRACE_FUNCTION ("cs_sync_next()");
980
981 /*
982 * no further channel is possible
983 */
984 if (cs_sync_next_bsic () EQ FALSE)
985 {
986 /*
987 * stop any timer which controls cell selection
988 */
989 TIMERSTOP (T_RESELECT);
990 SET_STATE (STATE_CELL_SEL, CS_IDLE);
991
992 /*
993 * indicate end of search to attachment process
994 */
995 TIMERSTOP(T_PLMN_SEARCH);
996 att_no_bsic_ind ();
997
998 return FALSE;
999 }
1000
1001 return TRUE;
1002 }
1003
1004 /*
1005 +--------------------------------------------------------------------+
1006 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1007 | STATE : code ROUTINE : cs_sync_next_bsic |
1008 +--------------------------------------------------------------------+
1009
1010 PURPOSE : The function looks for the next candidate for a FB/SB
1011 sync request. The channel is not checked yet, has the
1012 highest priority and the highest fieldstrength.
1013 Return TRUE if another MPH_BSIC_REQ is sent.
1014 */
1015
1016 static BOOL cs_sync_next_bsic (void)
1017 {
1018 GET_INSTANCE_DATA;
1019 UBYTE i;
1020 UBYTE x = NOT_PRESENT_8BIT;
1021
1022 TRACE_FUNCTION ("cs_sync_next_bsic()");
1023
1024 /*
1025 * try to use 'found channel' from previous cell selection
1026 */
1027
1028 if( rr_data->found_channel NEQ NOT_PRESENT_16BIT )
1029 {
1030 for ( i = 0; i < rr_data->cs_data.max_arfcn; i++ )
1031 {
1032 if ( ((rr_data->cs_data.arfcn[i] & ARFCN_MASK) EQ
1033 (rr_data->found_channel & ARFCN_MASK)) AND
1034 ((rr_data->cs_data.arfcn[i] & US_BIT) EQ
1035 (rr_data->found_channel & US_BIT)) AND
1036 (rr_data->cs_data.attributes[i] & CS_CHECK_FLAG) EQ 0)
1037 {
1038 TRACE_EVENT ( "rr_found_channel in CS_DATA" );
1039 rr_data->found_channel = NOT_PRESENT_16BIT;
1040 x = i;
1041 break;
1042 }
1043 }
1044 }
1045
1046 /*
1047 * for all channels of the power campaign list
1048 */
1049 if ( x EQ NOT_PRESENT_8BIT )
1050 {
1051 for ( i=0; i < rr_data->cs_data.max_arfcn; i++ )
1052 {
1053 if ((rr_data->cs_data.attributes[i] & CS_CHECK_FLAG) EQ 0)
1054 {
1055 /*
1056 * channel is not checked yet
1057 */
1058 if (x EQ NOT_PRESENT_8BIT)
1059 {
1060 /*
1061 * first channel which is not checked yet
1062 */
1063 x = i;
1064
1065 /* High priority cell. Start sync */
1066 if((rr_data->cs_data.attributes[i] & CS_PRIORITY) EQ CS_HIGH_PRIORITY)
1067 break;
1068 }
1069 else
1070 {
1071 if ((rr_data->cs_data.attributes[i] & CS_PRIORITY) >
1072 (rr_data->cs_data.attributes[x] & CS_PRIORITY))
1073 {
1074 /*
1075 * new channel has higher priority
1076 */
1077 x = i;
1078 }
1079 }
1080 } /* CS_CHECK FLAG */
1081 } /* i < max_arfcn */
1082 } /* x NEQ NOT_PRESENT_8BIT */
1083
1084 if (x NEQ NOT_PRESENT_8BIT)
1085 {
1086 rr_data->cs_data.act_index = x;
1087
1088 if ((rr_data->ms_data.rr_service NEQ NO_SERVICE) AND
1089 (rr_data->cs_data.arfcn[x] EQ rr_data->nc_data[SC_INDEX].arfcn))
1090 {
1091 /*
1092 * Synchronization request for serving cell.
1093 * No need to send MPH_BSIC_REQ as we are already synchronized to
1094 * serving cell, instead fake MPH_BSIC_CNF.
1095 */
1096 PALLOC (mph_bsic_cnf, MPH_BSIC_CNF); /* T_MPH_BSIC_CNF */
1097 mph_bsic_cnf->arfcn = rr_data->cs_data.arfcn[x];
1098 mph_bsic_cnf->bsic = rr_data->nc_data[SC_INDEX].bsic;
1099 mph_bsic_cnf->cs = CS_NO_ERROR;
1100 if (srv_store_prim ((T_PRIM *)D2P(mph_bsic_cnf)))
1101 {
1102 TRACE_EVENT ("Shortcut for sync to SC taken");
1103 USE_STORED_ENTRIES();
1104 return TRUE;
1105 }
1106 else
1107 {
1108 /* In the unlikely event that we could not store the primitive */
1109 PFREE (mph_bsic_cnf);
1110 }
1111 }
1112 else
1113 {
1114
1115 /*
1116 *start BSIC Reading;For fast search, the first scan is only on reasonably strong carriers.i.e carrires with rxlev>MEDIUM_RXLEV_THRESHOLD
1117 *This is as per the cell selection improvements document. Hence dont send BSIC request on white listed low power carrires for first scan.
1118 *(OMAPS00109145)*/
1119 if( (rr_data->cs_data.previous_search_mode EQ FAST_SEARCH_MODE) AND (rr_data->cs_data.scan_mode NEQ CS_SECOND_SCAN) AND ( rr_data->cs_data.rxlev[x]<MEDIUM_RXLEV_THRESHOLD))
1120 return FALSE;
1121 else
1122 {
1123 PALLOC (mph_bsic_req, MPH_BSIC_REQ);
1124
1125 mph_bsic_req->arfcn = rr_data->cs_data.arfcn[x];
1126
1127 TRACE_EVENT_P3 ("BSIC REQ[%u]%u a=0x%x",
1128 rr_data->cs_data.arfcn[x] & ARFCN_MASK,
1129 x, rr_data->cs_data.attributes[x]);
1130
1131 PSENDX (PL, mph_bsic_req);
1132 }
1133 return TRUE;
1134 }
1135 }
1136 else
1137 return FALSE;
1138 }
1139
1140 /*
1141 +--------------------------------------------------------------------+
1142 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1143 | STATE : code ROUTINE : cs_set_null |
1144 +--------------------------------------------------------------------+
1145
1146 PURPOSE : Initialize the cell selection process.
1147
1148 */
1149
1150 GLOBAL void cs_set_null (void)
1151 {
1152 GET_INSTANCE_DATA;
1153 TRACE_FUNCTION ("cs_set_null()");
1154
1155 SET_STATE (STATE_CELL_SEL, CS_NULL);
1156 }
1157
1158 /*
1159 +--------------------------------------------------------------------+
1160 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1161 | STATE : code ROUTINE : cs_set_stop_active |
1162 +--------------------------------------------------------------------+
1163
1164 PURPOSE : The function resets the state of the cell selection
1165 process to an non-active state.
1166
1167 */
1168
1169 GLOBAL void cs_set_stop_active (void)
1170 {
1171 GET_INSTANCE_DATA;
1172 TRACE_FUNCTION ("cs_set_stop_active()");
1173
1174 switch (GET_STATE(STATE_CELL_SEL))
1175 {
1176 case CS_NULL:
1177 case CS_NULL_ACTIVE:
1178 SET_STATE (STATE_CELL_SEL, CS_NULL);
1179 break;
1180 case CS_IDLE:
1181 case CS_IDLE_ACTIVE:
1182 SET_STATE (STATE_CELL_SEL, CS_IDLE);
1183 break;
1184 }
1185 }
1186
1187 /*
1188 +--------------------------------------------------------------------+
1189 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1190 | STATE : code ROUTINE : cs_set_attributes |
1191 +--------------------------------------------------------------------+
1192
1193 PURPOSE : The function sets an attribute for a channel (e.g.
1194 emergency or low priority cell).
1195
1196 */
1197
1198 GLOBAL void cs_set_attributes (UBYTE attribute, USHORT arfcn)
1199 {
1200 GET_INSTANCE_DATA;
1201 UBYTE i;
1202
1203 TRACE_FUNCTION ("cs_set_attributes()");
1204
1205 /*
1206 * for all channels of the power campaign list
1207 */
1208 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
1209 {
1210 /*
1211 * if it is the given channel number, set the attributes.
1212 */
1213 if ((rr_data->cs_data.arfcn[i]&ARFCN_MASK) EQ arfcn)
1214 rr_data->cs_data.attributes [i] |= attribute;
1215 }
1216 }
1217
1218 /*
1219 +--------------------------------------------------------------------+
1220 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1221 | STATE : code ROUTINE : cs_set_rxlev |
1222 +--------------------------------------------------------------------+
1223
1224 PURPOSE : Updating of a fieldstrength value in the list of the
1225 power campaign.
1226
1227 */
1228
1229 GLOBAL void cs_set_rxlev (UBYTE rxlev, USHORT arfcn)
1230 {
1231 GET_INSTANCE_DATA;
1232 UBYTE i;
1233
1234 TRACE_FUNCTION ("cs_set_rxlev()");
1235
1236 /*
1237 * for all channels in the power campaign list
1238 */
1239 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
1240 {
1241 /*
1242 * if it is the given channel number, update the fieldstrength.
1243 */
1244 if ((rr_data->cs_data.arfcn[i]&ARFCN_MASK) EQ arfcn)
1245 rr_data->cs_data.rxlev [i] = rxlev;
1246 }
1247 }
1248
1249 /*
1250 +--------------------------------------------------------------------+
1251 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1252 | STATE : code ROUTINE : cs_clear_attributes |
1253 +--------------------------------------------------------------------+
1254
1255 PURPOSE : The function clears an attribute for a channel (e.g.
1256 emergency or low priority cell).
1257
1258 */
1259
1260 GLOBAL void cs_clear_attributes (UBYTE attribute, USHORT arfcn)
1261 {
1262 GET_INSTANCE_DATA;
1263 UBYTE i;
1264
1265 TRACE_FUNCTION ("cs_clear_attributes()");
1266
1267 /*
1268 * for all channels in the power campaign list
1269 */
1270 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
1271 {
1272 /*
1273 * if it is the given channel number, clear the attributes.
1274 */
1275 if ((rr_data->cs_data.arfcn[i]&ARFCN_MASK) EQ arfcn)
1276 rr_data->cs_data.attributes [i] &= ~attribute;
1277 }
1278 }
1279
1280 /*
1281 +--------------------------------------------------------------------+
1282 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1283 | STATE : code ROUTINE : cs_mph_power_cnf |
1284 +--------------------------------------------------------------------+
1285
1286 PURPOSE : The result of a power request to layer 1. Layer 1 returns
1287 a list of up to 40 GSM 900 + 40 DCS 1800 channels to RR.
1288
1289 */
1290
1291 GLOBAL void cs_mph_power_cnf (T_MPH_POWER_CNF * mph_power_cnf)
1292 {
1293 GET_INSTANCE_DATA;
1294 UBYTE i,j,rxlev;
1295 USHORT mask = 0xFFFF; /* no mask */
1296 U8 x;
1297 BOOL copy = TRUE;
1298
1299 TRACE_FUNCTION ("cs_mph_power_cnf()");
1300
1301 if(GET_STATE(STATE_ATT) EQ ATT_CS_INIT )
1302 {
1303 if( !srv_store_prim ((T_PRIM *)D2P(mph_power_cnf)) )
1304 {
1305 /*
1306 * primitive storing failed
1307 */
1308 PFREE (mph_power_cnf);
1309 SET_STATE(STATE_CELL_SEL, CS_NULL);
1310 SET_STATE(STATE_ATT, ATT_NULL);
1311 }
1312 else
1313 {
1314 /*
1315 * Boot Time: Do not store primitive for more than 10 s in case
1316 * of quick registration. If the second activate_req does not
1317 * come before this time move to ATT_NULL.
1318 * The T_RESELECT timer is used for a different purpose here.
1319 */
1320 TIMERSTART(T_RESELECT, TRESELECT_VALUE);
1321 }
1322 return;
1323 }
1324
1325 TRACE_EVENT_P1 ("mph_power_cnf: %u freq.", mph_power_cnf->num_of_chan);
1326
1327 for (i = 0; i < mph_power_cnf->num_of_chan; i++)
1328 {
1329 TRACE_EVENT_P3("[%4u] std=%u rx_lev=%2u",
1330 mph_power_cnf->arfcn[i]&ARFCN_MASK,
1331 STD_GET_FROM_ARFCN(mph_power_cnf->arfcn[i]),
1332 mph_power_cnf->rx_lev[i]);
1333 }
1334
1335 /* Remove the inactive carriers from Black List */
1336 if((CS_GET_CURRENT_SEARCH_MODE EQ BLACK_LIST_SEARCH_MODE) OR
1337 (mph_power_cnf->num_of_chan))
1338 {
1339 /* In case of "Full", "Normal" and "Fast" search modes, remove
1340 * inactive carriers from Black List, only when there is atleast
1341 * one strong carrier in that area
1342 */
1343 cs_rem_inactive_carriers_from_bl(mph_power_cnf);
1344 }
1345
1346 if(CS_GET_CURRENT_SEARCH_MODE NEQ BLACK_LIST_SEARCH_MODE)
1347 {
1348 /* Update previous search mode */
1349 CS_SET_PREVIOUS_SEARCH_MODE(CS_GET_CURRENT_SEARCH_MODE);
1350
1351 switch (GET_STATE(STATE_CELL_SEL))
1352 {
1353 case CS_IDLE_ACTIVE:
1354 /* We will start parallel scan in 2 cases
1355 1. After HPLMN timer expiry
1356 2. After TREG timer expiry
1357 In these both cases don't mask out std and US_BIT
1358 */
1359 #ifndef TI_PS_FF_QUAD_BAND_SUPPORT
1360 mask = ARFCN_MASK; /* for parallel search mask out 'std' and US_BIT. */
1361 #endif
1362 /*lint -fallthrough*/
1363 case CS_NULL_ACTIVE:
1364 /*
1365 * copy channel list from layer 1, set the number
1366 * of entries in the list
1367 */
1368 rr_data->cs_data.max_arfcn = mph_power_cnf->num_of_chan;
1369
1370 /*
1371 * for all channels coming from layer 1
1372 */
1373 for (i=0,j=0;i<mph_power_cnf->num_of_chan;i++)
1374 {
1375 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1376 x = cs_get_band_index(mph_power_cnf->arfcn[i]);
1377 #else
1378 x = get_band_index(mph_power_cnf->arfcn[i]);
1379 #endif
1380
1381 /* for OMAPS00109145, in which the I-Sample is not camping on to the agilent ,once down link failure is
1382 occured on current cell and at power levels < -100dB, this is because in the fast search mode we are not
1383 considering the low rxlev carriers. So this modification is required in order to come back to the network
1384 even after a down link failure has happened and if another BCCH carrer of less power become active and available
1385 for the mobile to camp */
1386
1387 rxlev = rr_data->dyn_config.lower_rxlev_thr[x];
1388 copy = TRUE;
1389
1390 if((i >= mph_power_cnf->num_of_white_list_chan) AND
1391 (mph_power_cnf->rx_lev[i] < rxlev))
1392
1393 {
1394 copy = FALSE;
1395 }
1396
1397 /*
1398 * check against band restrictions
1399 */
1400 if (copy AND cs_check_channel ((USHORT)(mph_power_cnf->arfcn[i]&ARFCN_MASK)))
1401 {
1402 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1403 /* For parallel search mask serving cell */
1404 if ((GET_STATE(STATE_CELL_SEL) EQ CS_IDLE_ACTIVE) AND (rr_data->nc_data[SC_INDEX].arfcn EQ (mph_power_cnf->arfcn[i]&ARFCN_MASK)))
1405 rr_data->cs_data.arfcn[j] = mph_power_cnf->arfcn[i]&ARFCN_MASK;
1406 else
1407 #endif
1408 rr_data->cs_data.arfcn[j] = mph_power_cnf->arfcn[i]&mask;
1409 rr_data->cs_data.rxlev[j] = mph_power_cnf->rx_lev[i];
1410 /*
1411 * set initial to middle priority
1412 */
1413 rr_data->cs_data.attributes [j++] = CS_MID_PRIORITY;
1414 }
1415 else
1416 {
1417 /*
1418 * a cell is not copied due to band restrictions
1419 */
1420 rr_data->cs_data.max_arfcn--;
1421 }
1422 }
1423
1424 TRACE_EVENT_P2("No_chan > [%d]min_rxlev copied:%d",rxlev,rr_data->cs_data.max_arfcn);
1425
1426 /* Increase the priority of white list carriers */
1427 if(rr_data->cs_data.max_arfcn )
1428 cs_use_white_list_info(mph_power_cnf->num_of_white_list_chan);
1429
1430 /*
1431 * add actual PLMN to the found list, if available
1432 */
1433 if (rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI AND
1434 GET_STATE(STATE_ATT) EQ ATT_IDLE AND
1435 (!rr_data->net_lost))
1436 cs_add_current_network_to_found_list ();
1437
1438 /*
1439 * Select channel with the highest fieldstrength and priority
1440 * and start BSIC scanning, else send signal that no further
1441 * channel is available
1442 */
1443 if (cs_sync_next_bsic () EQ FALSE)
1444 {
1445 SET_STATE (STATE_CELL_SEL, CS_IDLE);
1446 TIMERSTOP(T_PLMN_SEARCH);
1447 att_no_bsic_ind ();
1448 }
1449 else
1450 {
1451 SET_STATE (STATE_CELL_SEL, CS_IDLE_ACTIVE);
1452 }
1453
1454 /*
1455 * CS power measurements may be used to reorder arfcns'n in
1456 * MPH_NEIGHBOURCELL_REQ while TCSVALID is running
1457 */
1458 TIMERSTART(TCSVALID, THIRTY_SEC);
1459 break;
1460 }
1461 } /* NEQ black list search */
1462 else
1463 {
1464
1465 /* Stop the parallel PLMN search */
1466 att_notify_stop_plmn_search(FALSE);
1467
1468 SET_STATE (STATE_CELL_SEL, CS_IDLE);
1469
1470 /* Black list search is a temporary search. It is not used
1471 * in deciding the next search. Hence we need to update current search
1472 * mode when Black List search is over */
1473 CS_SET_CURRENT_SEARCH_MODE(CS_GET_PREVIOUS_SEARCH_MODE);
1474
1475
1476 } /* Black list search */
1477
1478 PFREE (mph_power_cnf);
1479 srv_use_stored_prim ();
1480 }
1481
1482 /*
1483 +--------------------------------------------------------------------+
1484 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1485 | STATE : code ROUTINE : cs_mph_bsic_cnf |
1486 +--------------------------------------------------------------------+
1487
1488 PURPOSE : The response of a FB/SB synchronisation request from layer 1.
1489
1490 */
1491
1492 GLOBAL void cs_mph_bsic_cnf (T_MPH_BSIC_CNF * mph_bsic_cnf)
1493 {
1494 GET_INSTANCE_DATA;
1495 U8 local_region;
1496 U16 local_arfcn;
1497
1498 TRACE_FUNCTION ("cs_mph_bsic_cnf()");
1499
1500 switch (GET_STATE (STATE_CELL_SEL))
1501 {
1502 case CS_IDLE_ACTIVE:
1503 if (mph_bsic_cnf->cs EQ CS_NO_ERROR)
1504 {
1505 UBYTE new_std = STD_GET_FROM_ARFCN(mph_bsic_cnf->arfcn);
1506 /*
1507 * FB / SB is decoded, cell has the attributes
1508 * BCCH detected and checked
1509 */
1510 /*
1511 * reset std from the current MPH_BSIC_CNF(only if it is non-zero)
1512 */
1513 TRACE_EVENT_P2("reset std: new_std = %d, old_std = %d", new_std, std);
1514 if(new_std)
1515 {
1516 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1517 UBYTE new_region;
1518
1519 std = cs_update_std_ffs (new_std);
1520 new_region = srv_get_region_from_std(std);
1521 TRACE_EVENT_P1("update std: new_std = %d", std);
1522 #else
1523 UBYTE new_region = srv_get_region_from_std(new_std);
1524
1525 std = new_std;
1526 #endif
1527
1528 /* Both American and European bands are detected in the current
1529 * region. Following TREG timer expiry in Limited Service state,
1530 * non-parallel search will be issued
1531 * CSI-LLD section:4.3
1532 */
1533 if(rr_data->cs_data.region NEQ NOT_PRESENT_8BIT)
1534 {
1535 if(rr_data->cs_data.region NEQ new_region)
1536 {
1537 rr_data->cs_data.all_freq_area = TRUE;
1538 TRACE_EVENT("all_freq_area : 1");
1539 }
1540 }
1541
1542 /* CSI-LLD section:4.1.1.3.12
1543 * This stores region in rr_data base by extracting from std
1544 */
1545 rr_data->cs_data.region = new_region;
1546 }
1547 /*
1548 * remove co channels
1549 */
1550 if (test_house EQ FALSE)
1551 cs_remove_co_channels ((USHORT)(mph_bsic_cnf->arfcn&ARFCN_MASK));
1552
1553 rr_data->cs_data.attributes [rr_data->cs_data.act_index] |=
1554 (CS_CHECK_FLAG | CS_BCCH_READ);
1555
1556 /* CSI-LLD section:4.1.1.11
1557 * Synchronisation succeeded. Remove the carrier from black list
1558 */
1559 cs_del_from_black_list(rr_data->cs_data.region,
1560 (U16)(mph_bsic_cnf->arfcn&ARFCN_MASK));
1561
1562 att_bsic_ind ((USHORT)(mph_bsic_cnf->arfcn&ARFCN_MASK),
1563 rr_data->cs_data.rxlev [rr_data->cs_data.act_index],
1564 mph_bsic_cnf->bsic);
1565 }
1566 else
1567 {
1568 /*
1569 * FB / SB is not decoded, cell has the attributes
1570 * BCCH not detected and checked
1571 */
1572 rr_data->cs_data.attributes [rr_data->cs_data.act_index] |= CS_CHECK_FLAG;
1573
1574 /* Extract region information */
1575
1576 local_arfcn = rr_data->cs_data.arfcn[rr_data->cs_data.act_index];
1577
1578 if(STD_GET_FROM_ARFCN(local_arfcn) NEQ STD_NOT_PRESENT)
1579 {
1580 /* During Non-Parallel search, region information is available
1581 * in ARFCN
1582 */
1583 local_region = CS_GET_REGION_FROM_FREQ(local_arfcn);
1584 }
1585 else
1586 {
1587 /* Parallel search case */
1588 local_region = srv_get_region_from_std(std);
1589 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1590 if (local_region EQ BOTH_REGIONS)
1591 local_region = srv_get_region_from_std_arfcn (std, local_arfcn);
1592 #endif
1593 }
1594
1595 /* CSI-LLD section:4.1.1.6
1596 * Sync failed. Add the carrier to Black list
1597 */
1598 cs_add_to_black_list(local_region,
1599 (U16)(local_arfcn),
1600 rr_data->cs_data.rxlev[rr_data->cs_data.act_index]);
1601
1602 /* CSI-LLD section:4.1.1.11
1603 * Set the BLACK LIST attribute flag for this carrier
1604 */
1605 if(rr_data->cs_data.initial_plmn_search EQ INITIAL_PLMN_SEARCH_ACTIVE)
1606 {
1607 CS_SET_BLACK_LIST_FLAG(rr_data->cs_data.act_index);
1608 }
1609
1610 if (cs_sync_next_bsic () EQ FALSE)
1611 {
1612 TIMERSTOP(T_PLMN_SEARCH);
1613 SET_STATE (STATE_CELL_SEL, CS_IDLE);
1614 att_no_bsic_ind (); /* stop in RR */
1615 }
1616 }
1617 break;
1618
1619 #ifdef GPRS
1620 case CS_CCO:
1621 SET_STATE (STATE_CELL_SEL, CS_IDLE);
1622 if (rr_data->gprs_data.cr_pbcch_active OR rr_data->gprs_data.cr_pcco_active)
1623 {
1624 /*
1625 * a Packet Cell Change Order for a cell which
1626 * is not in the BA list has been requested by the NW
1627 */
1628 if (mph_bsic_cnf->cs EQ CS_NO_ERROR AND
1629 (mph_bsic_cnf->arfcn&ARFCN_MASK) EQ rr_data->gprs_data.arfcn AND
1630 mph_bsic_cnf->bsic EQ rr_data->gprs_data.bsic )
1631 {
1632 /*
1633 * PL successfuly sycnhronized to the cell
1634 * now RR will do a normal Cell Reselection
1635 */
1636 memset (&rr_data->nc_data[CR_INDEX],
1637 0,
1638 sizeof (T_NC_DATA));
1639 rr_data->nc_data[CR_INDEX].arfcn = mph_bsic_cnf->arfcn&ARFCN_MASK;
1640 rr_data->nc_data[CR_INDEX].bsic = mph_bsic_cnf->bsic;
1641
1642 /* CSI-LLD section:4.1.1.11
1643 * Synchronisation succeeded. Remove the carrier from black list
1644 */
1645 cs_del_from_black_list(rr_data->cs_data.region,
1646 (U16)(mph_bsic_cnf->arfcn&ARFCN_MASK));
1647
1648 if( rr_data->gprs_data.cr_pbcch_active )
1649 att_start_cell_reselection_pbcch(MODE_CELL_RESELECTION);
1650 else
1651 {
1652 att_init_cell_selection(CELL_RESELECTION, RR_ORIGINATED);
1653 rr_data->dyn_config.fcr = 0;
1654 rr_data->dyn_config.scr = 0;
1655 rr_data->bcch_error = 0;
1656 rr_data->pag_rec = FALSE;
1657 srv_clear_stored_prim (MPH_PAGING_IND);
1658 gprs_init_data_cr();
1659 dat_att_null();
1660 SET_STATE (STATE_ATT, ATT_CS3);
1661 att_build_idle_req (CR_INDEX, MODE_CELL_RESELECTION);
1662 }
1663 }
1664 else
1665 {
1666 /*
1667 * PL did not sycnhronize to the cell
1668 * inform GRR and wait for a CR_REQ(CR_REQ) with
1669 * the old cell and return to it
1670 */
1671 PALLOC(gprs_ind, RRGRR_GPRS_SI13_IND);
1672 rr_data->gprs_data.cr_pbcch_active = FALSE;
1673
1674 gprs_ind->cause = GPRS_CELL_NOT_SUITABLE;
1675 gprs_ind->serving_cell_info.bcch_arfcn = rr_data->gprs_data.arfcn;
1676 gprs_ind->serving_cell_info.bcch_bsic = rr_data->gprs_data.bsic;
1677
1678 TRACE_EVENT_P4 ("cs=%u C[%d] bsic=%u #%u",
1679 gprs_ind->cause,
1680 gprs_ind->serving_cell_info.bcch_arfcn,
1681 gprs_ind->serving_cell_info.bcch_bsic,
1682 __LINE__);
1683
1684 PSENDX(GRR, gprs_ind);
1685 /* wait for CR_REQ for old cell */
1686 }
1687 }
1688 else
1689 if (mph_bsic_cnf->cs EQ CS_NO_ERROR AND
1690 (mph_bsic_cnf->arfcn&ARFCN_MASK) EQ rr_data->gprs_data.arfcn AND
1691 mph_bsic_cnf->bsic EQ rr_data->gprs_data.bsic )
1692 {
1693 rr_data->gprs_data.tbf_est = TBF_EST_CCO;
1694
1695 rr_data->nc_data[CR_INDEX].arfcn = rr_data->gprs_data.arfcn;
1696 rr_data->nc_data[CR_INDEX].rxlev = 0;
1697 rr_data->nc_data[CR_INDEX].bsic = rr_data->gprs_data.bsic;
1698
1699 att_init_cr_data();
1700 TIMERSTART (T_RESELECT, TRESELECT_VALUE);
1701 rr_data->nc_data[CR_INDEX].bcch_error = 0;
1702 srv_clear_list (&rr_data->cr_data.cd.ncell_list);
1703 SET_STATE (STATE_ATT, ATT_CS2);
1704
1705 /* CSI-LLD section:4.1.1.11
1706 * Synchronisation succeeded. Remove the carrier from black list
1707 */
1708 cs_del_from_black_list(rr_data->cs_data.region,
1709 (U16)(mph_bsic_cnf->arfcn&ARFCN_MASK));
1710 /* wait for System Information Messages */
1711 }
1712 else /* initiate switch back to old cell */
1713 {
1714 dat_code_mph_old_chan_req();
1715
1716 PFREE ( rr_data->gprs_data.dl_data_ind );
1717 rr_data->gprs_data.dl_data_ind = NULL;
1718
1719 rr_data->gprs_data.reconn_cause = RRC_PROT_UNSPECIFIED;
1720 rr_data->gprs_data.cco_need_reconnect_cnf = FALSE;
1721 SET_STATE (STATE_DAT, DAT_CCO_3);
1722 }
1723 break;
1724
1725 case CS_XMEAS:
1726
1727 /* enter result in rr_data->gprs_data.rrgrr_ext_meas_cnf, call att_ext_meas_next_bsic */
1728
1729 {
1730 UBYTE bsic = mph_bsic_cnf->bsic;
1731 T_GPRS_DATA *gprs_data = &rr_data->gprs_data;
1732 T_RRGRR_EXT_MEAS_REQ *rrgrr_ext_meas_req = gprs_data->rrgrr_ext_meas_req;
1733
1734
1735 if ( rrgrr_ext_meas_req->report_type EQ REP_TYPE_1 OR /* "6 strongest carriers independent of BSIC decoding or not" */
1736 rrgrr_ext_meas_req->report_type EQ REP_TYPE_2 AND /* "BSICs for 6 carriers with decoded BSIC with allowed NCC" */
1737 mph_bsic_cnf->cs EQ CS_NO_ERROR AND
1738 (rrgrr_ext_meas_req->ncc_permitted & (1 << ((bsic>>3) & 0x07)))) /* check for "NCC allowed" */
1739 {
1740 T_RRGRR_EXT_MEAS_CNF *rrgrr_ext_meas_cnf = gprs_data->rrgrr_ext_meas_cnf;
1741 T_MPH_EXT_MEAS_CNF *mph_ext_meas_cnf = gprs_data->mph_ext_meas_cnf;
1742 UBYTE n = gprs_data->mph_ext_meas_num;
1743 USHORT arfcn = mph_ext_meas_cnf->arfcn[n];
1744 UBYTE rx_lev = mph_ext_meas_cnf->rx_lev[n];
1745 UBYTE idx = rr_ext_meas_idx ( arfcn );
1746 UBYTE k = rrgrr_ext_meas_cnf->c_xmeas_res++;
1747 T_xmeas_res *xmeas_res = &rrgrr_ext_meas_cnf-> xmeas_res[k];
1748
1749 /*
1750 * Function att_ext_meas_next_bsic checks for the maximum number of elements in the
1751 * array rrgrr_ext_meas_cnf->xmeas_res. Therefore this check is not performed here.
1752 */
1753
1754 xmeas_res->arfcn_idx.arfcn = arfcn;
1755 xmeas_res->arfcn_idx.idx = idx;
1756 xmeas_res->rxlev = rx_lev;
1757 if (mph_bsic_cnf->cs EQ CS_NO_ERROR)
1758 xmeas_res->bsic = bsic;
1759 else
1760 xmeas_res->bsic = RRGRR_INVALID_BSIC;
1761 }
1762 }
1763
1764 rr_data->gprs_data.mph_ext_meas_num++;
1765 att_ext_meas_next_bsic();
1766 break;
1767 #endif
1768 default:
1769 break;
1770 }
1771 PFREE (mph_bsic_cnf);
1772 }
1773
1774
1775 /*
1776 +--------------------------------------------------------------------+
1777 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1778 | STATE : code ROUTINE : cs_get_channel_from_found_list |
1779 +--------------------------------------------------------------------+
1780
1781 PURPOSE : If a network available list was created in former times
1782 (found_plmn / found_channel) and one of this networks is
1783 requested, the associated channel is stored to give it
1784 high priority to speed up cell selection.
1785
1786 */
1787 GLOBAL void cs_get_channel_from_found_list ()
1788 {
1789 GET_INSTANCE_DATA;
1790 UBYTE i;
1791 T_FOUND_ELEMENT * found;
1792
1793 TRACE_FUNCTION ("cs_get_channel_from_found_list()");
1794
1795 /*
1796 * initialise the local variable
1797 */
1798 rr_data->found_channel = NOT_PRESENT_16BIT;
1799
1800 /*
1801 * for all PLMNs stored in the found list
1802 */
1803 found = &rr_data->sc_data.found[0];
1804 for (i=0; i<rr_data->sc_data.found_entries; i++, found++)
1805 {
1806 /*
1807 * if the network in the found list is equal to the PLMN requested by MM,
1808 * set the found channel
1809 */
1810 /* Implements Measure#32: Row 124 */
1811 att_print_mcc_mnc(found->arfcn, found->plmn.mcc, found->plmn.mnc, S2I_STRING("list"));
1812 if (dat_plmn_equal_req (found->plmn.mcc,
1813 found->plmn.mnc,
1814 rr_data->ms_data.plmn.mcc,
1815 rr_data->ms_data.plmn.mnc))
1816 {
1817 rr_data->found_channel = found->arfcn;
1818
1819 /* Embed region information in the found channel arfcn */
1820 if(found->region EQ AMERICAN_REGION)
1821 rr_data->found_channel |= US_BIT;
1822 /* Implements Measure#32: Row 125 */
1823 att_print_mcc_mnc(found->arfcn, found->plmn.mcc, found->plmn.mnc, S2I_STRING("found_channel"));
1824 return;
1825 }
1826 }
1827 }
1828
1829 /*
1830 +--------------------------------------------------------------------+
1831 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1832 | STATE : code ROUTINE : cs_clear_channel_from_found_list |
1833 +--------------------------------------------------------------------+
1834
1835 PURPOSE : If a network available list was created in former times
1836 (found_plmn / rr_found_channel) and one of this networks is
1837 requested, the associated channel is stored to give it
1838 high priority to speed up cell selection. This function
1839 clear the stored data if a network or limited search is
1840 started.
1841
1842 */
1843
1844 GLOBAL void cs_clear_channel_from_found_list (void)
1845 {
1846 GET_INSTANCE_DATA;
1847 /*
1848 * initialize the found channel number
1849 */
1850 rr_data->found_channel = NOT_PRESENT_16BIT;
1851 }
1852
1853 /*
1854 +--------------------------------------------------------------------+
1855 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1856 | STATE : code ROUTINE : cs_remove_co_channels |
1857 +--------------------------------------------------------------------+
1858
1859 PURPOSE : If a channel x fails and the channels x-1 and x+1 have
1860 a fieldstrength difference greater 9 dB, it is not necessary
1861 to try on this cells. Sense of this is to speed up search.
1862
1863 */
1864
1865 static void cs_remove_co_channels (USHORT arfcn)
1866 {
1867 /*
1868 * depending on the channel number. Some extra cases
1869 * for channel numbers on the boarders of the frequency Band
1870 */
1871 switch (arfcn)
1872 {
1873 case CHANNEL_0:
1874 /*
1875 * E-GSM channel 0 has no co-channels
1876 */
1877 break;
1878
1879 /*
1880 * all LOW channel boarders
1881 */
1882 case LOW_CHANNEL_850:
1883 case LOW_CHANNEL_900:
1884 case LOW_CHANNEL_1800:
1885 case LOW_CHANNEL_EGSM:
1886 cs_remove_co_chan (arfcn, (USHORT)(arfcn+1));
1887 break;
1888
1889 /*
1890 * all HIGH channel boarders
1891 */
1892 case HIGH_CHANNEL_1900:
1893 if (std NEQ STD_1900 AND std NEQ STD_DUAL_US)
1894 {
1895 cs_remove_co_chan (arfcn, (USHORT)(arfcn+1));/* DCS 1800 */
1896 }
1897 /*lint -fallthrough*/
1898 case HIGH_CHANNEL_850:
1899 case HIGH_CHANNEL_900:
1900 case HIGH_CHANNEL_1800:
1901 case HIGH_CHANNEL_EGSM-1:
1902 cs_remove_co_chan (arfcn, (USHORT)(arfcn-1));
1903 break;
1904
1905 default:
1906 /*
1907 * all other channels inside the frequency bands
1908 */
1909 cs_remove_co_chan (arfcn, (USHORT)(arfcn+1));
1910 cs_remove_co_chan (arfcn, (USHORT)(arfcn-1));
1911 break;
1912 }
1913 }
1914
1915
1916 /*
1917 +--------------------------------------------------------------------+
1918 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1919 | STATE : code ROUTINE : cs_remove_co_chan |
1920 +--------------------------------------------------------------------+
1921
1922 PURPOSE : if co_chan - chan has a fieldstrength difference greater
1923 9 dBm, remove the channel.
1924
1925 */
1926
1927 static void cs_remove_co_chan (USHORT arfcn, USHORT co_arfcn)
1928 {
1929 GET_INSTANCE_DATA;
1930 UBYTE index_arfcn = NOT_PRESENT_8BIT;
1931 UBYTE index_co_arfcn = NOT_PRESENT_8BIT;
1932 UBYTE i;
1933 SHORT rxlev_arfcn;
1934 SHORT rxlev_co_arfcn;
1935 USHORT *p_arfcn;
1936 TRACE_FUNCTION ("cs_remove_co_chan()");
1937
1938 /*
1939 * calculate the index in the power campaign list
1940 * for the channel
1941 */
1942 p_arfcn = rr_data->cs_data.arfcn;
1943 for (i=0; i<rr_data->cs_data.max_arfcn; i++)
1944 {
1945 if (arfcn EQ (p_arfcn[i]&ARFCN_MASK))
1946 {
1947 index_arfcn = i;
1948 break;
1949 }
1950 }
1951 /*
1952 * if the channel is not inside the list,
1953 * then nothing is to compare else get the
1954 * fieldstrength.
1955 */
1956 if (index_arfcn EQ NOT_PRESENT_8BIT)
1957 return;
1958
1959 /*
1960 * calculate the index in the power campaign list
1961 * for the co-channel
1962 */
1963 for (i=0;i<rr_data->cs_data.max_arfcn;i++)
1964 {
1965 if (co_arfcn EQ (p_arfcn[i]&ARFCN_MASK))
1966 {
1967 index_co_arfcn = i;
1968 break;
1969 }
1970 }
1971 /*
1972 * if the co-channel is not inside the list,
1973 * then nothing is to compare else get the
1974 * fieldstrength.
1975 */
1976 if (index_co_arfcn EQ NOT_PRESENT_8BIT)
1977 return;
1978
1979 rxlev_arfcn = (SHORT)rr_data->cs_data.rxlev [index_arfcn];
1980 rxlev_co_arfcn = (SHORT)rr_data->cs_data.rxlev [index_co_arfcn];
1981
1982 /*
1983 * if the difference is > 9 dBm,
1984 * set to low priority.
1985 */
1986 if ((rxlev_arfcn - rxlev_co_arfcn) > 9)
1987 {
1988 rr_data->cs_data.attributes [index_co_arfcn] &= CS_SET_TO_LOW_PRIORITY;
1989 }
1990 }
1991
1992 /*
1993 +---------------------------------------------------------------------+
1994 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
1995 | STATE : code ROUTINE : cs_add_current_network .... |
1996 +---------------------------------------------------------------------+
1997
1998 PURPOSE : Adds the current PLMN to the found list if available.
1999
2000 */
2001 LOCAL void cs_add_current_network_to_found_list (void)
2002 {
2003 GET_INSTANCE_DATA;
2004 T_loc_area_ident *lai = &rr_data->nc_data[SC_INDEX].lai;
2005
2006 TRACE_FUNCTION ("cs_add_current_network_to_found_list()");
2007
2008 switch (rr_data->ms_data.rr_service)
2009 {
2010 case LIMITED_SERVICE:
2011 case FULL_SERVICE:
2012 /*
2013 * The mobile was in full service
2014 * Add this PLMN to the list of found PLMN
2015 * and clean power measurement list.
2016 */
2017 if (! att_plmn_in_found_list (lai->mcc, lai->mnc) AND
2018 rr_data->sc_data.found_entries < MAX_PLMN)
2019 {
2020 att_save_found_plmn (
2021 &rr_data->sc_data.found[rr_data->sc_data.found_entries],
2022 lai->mcc, lai->mnc,
2023 rr_data->nc_data[SC_INDEX].arfcn,
2024 rr_data->nc_data[SC_INDEX].rxlev, lai->lac, 0);
2025 rr_data->sc_data.found_entries++;
2026 }
2027 /*
2028 * Consider only high priority cells to speed up search
2029 */
2030 cs_del_list (&rr_data->sc_data.cd.ncell_list);
2031 break;
2032 }
2033 }
2034
2035 /*
2036 +--------------------------------------------------------------------+
2037 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2038 | STATE : code ROUTINE : cs_check_channel |
2039 +--------------------------------------------------------------------+
2040
2041 PURPOSE : Depending on the settings (default, GSM 900, DCS 1800)
2042 all non-interesting channels are removed.
2043
2044 */
2045 static UBYTE cs_check_channel (USHORT arfcn)
2046 {
2047 GET_INSTANCE_DATA;
2048 /*
2049 * TRACE_FUNCTION ("cs_check_channel")
2050 */
2051 {
2052 switch (rr_data->dyn_config.set_band)
2053 {
2054 case 0:
2055 /*
2056 * default behaviour
2057 */
2058 return TRUE;
2059
2060 case 1:
2061 /*
2062 * set to GSM 900
2063 */
2064 /*
2065 if (arfcn <= LOW_CHANNEL_900 OR
2066 arfcn >= HIGH_CHANNEL_900)
2067 */
2068 if (INRANGE(LOW_CHANNEL_900,arfcn,HIGH_CHANNEL_900))
2069 return FALSE;
2070 else
2071 return TRUE;
2072
2073 case 2:
2074 /*
2075 * set to DCS 1800
2076 */
2077 /*
2078 if (arfcn >= LOW_CHANNEL_1800 AND
2079 arfcn <= HIGH_CHANNEL_1800)
2080 */
2081 if (INRANGE(LOW_CHANNEL_1800,arfcn,HIGH_CHANNEL_1800))
2082 return TRUE;
2083 else
2084 return FALSE;
2085 }
2086 }
2087 return TRUE;
2088 }
2089
2090 /*
2091 +----------------------------------------------------------------------+
2092 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2093 | STATE : code ROUTINE : cs_check_region |
2094 +----------------------------------------------------------------------+
2095
2096 PURPOSE : This routine validates the region
2097 Cell Selection Improvements-LLD section:4.1.1.2
2098 */
2099
2100 GLOBAL BOOL cs_check_region(U8 region)
2101 {
2102 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2103 if((region EQ EUROPEAN_REGION) OR (region EQ AMERICAN_REGION) OR (region EQ BOTH_REGIONS))
2104 #else
2105 if((region EQ EUROPEAN_REGION) OR (region EQ AMERICAN_REGION))
2106 #endif
2107 {
2108 return TRUE;
2109 }
2110 else
2111 {
2112 TRACE_ERROR("Invalid region");
2113 return FALSE;
2114 }
2115 }
2116
2117 /*
2118 +----------------------------------------------------------------------+
2119 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2120 | STATE : code ROUTINE : cs_validate_arfcn_index |
2121 +----------------------------------------------------------------------+
2122
2123 PURPOSE : This routine validates the ARFCN index
2124 Cell Selection Improvements-LLD section:4.1.1.2
2125 */
2126
2127 GLOBAL BOOL cs_check_arfcn_range(U16 arfcn)
2128 {
2129 if(arfcn EQ CHANNEL_0)
2130 arfcn = CHANNEL_0_INTERNAL;
2131
2132 if((arfcn > CHANNEL_0) AND (arfcn <= CHANNEL_0_INTERNAL))
2133 {
2134 return TRUE;
2135 }
2136 else
2137 {
2138 TRACE_ERROR("Invalid ARFCN");
2139 return FALSE;
2140 }
2141 }
2142
2143 /*
2144 +----------------------------------------------------------------------+
2145 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2146 | STATE : code ROUTINE : cs_inc_sync_fail_counter |
2147 +----------------------------------------------------------------------+
2148
2149 PURPOSE : This routine increments the sync fail counter value for GSM
2150 carrier. Seperate counters are maintained for European and
2151 American regions.The size of SFC counter is 4 bits. As a
2152 result two carriers are accommodated in one byte. This function
2153 first converts the ARFCN range from 1-1023 to 0-511 format and
2154 increments the SFC accordingly. The SFC format is shown below
2155
2156 CSI-LLD section:4.1.1.5.9
2157
2158 ------------------------------------------
2159 | Index | MSB 4 bits | LSB 4 bits |
2160 ------------------------------------------
2161 | 0 | ARFCN : 2 | ARFCN : 1 |
2162 ------------------------------------------
2163 | 1 | ARFCN : 4 | ARFCN 3 |
2164 ------------------------------------------
2165 | - | - | - |
2166 ------------------------------------------
2167 | - | - | - |
2168 ------------------------------------------
2169 | 510 | ARFCN : 1022 | ARFCN: 1021 |
2170 ------------------------------------------
2171 | 511 | ARFCN : 0 | ARFCN :1023 |
2172 -----------------------------------------
2173 ARFCN: 0 = CHANNEL_0_INTERNAL
2174
2175 */
2176
2177 LOCAL void cs_inc_sync_fail_counter(U8 region, U16 arfcn)
2178 {
2179 GET_INSTANCE_DATA;
2180 U16 index=0;
2181 U8 inc = 0;
2182
2183 if(!cs_check_region(region))
2184 return;
2185
2186 if(!cs_check_arfcn_range((U16)(arfcn & ARFCN_MASK)))
2187 return;
2188
2189 if(arfcn EQ CHANNEL_0)
2190 arfcn = CHANNEL_0_INTERNAL;
2191
2192 /* Convert ARFCN range to 0-511 from 1-1023 range */
2193 index = ((arfcn & ARFCN_MASK) -1) >> 1;
2194
2195 if(arfcn & 0x01)
2196 {
2197 /* Increment LSB 4 bits for odd ARFCN */
2198 inc = 0x01;
2199 }
2200 else
2201 {
2202 /* Increment MSB 4 bits for even ARFCN */
2203 inc = 0x10;
2204 }
2205
2206 /* Increment the synchronisation counter */
2207 rr_data->cs_data.black_list.sfc[region][index] += inc;
2208
2209 TRACE_EVENT_P3("[%d]Reg,[%d]Arfcn, SFC = 0x%x",
2210 region,
2211 arfcn,
2212 rr_data->cs_data.black_list.sfc[region][index]);
2213 }
2214
2215 /*
2216 +----------------------------------------------------------------------+
2217 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2218 | STATE : code ROUTINE : cs_reset_sync_fail_counter |
2219 +----------------------------------------------------------------------+
2220
2221 PURPOSE : This routine resets the synchronisation fail counter value of
2222 GSM carrier.
2223 Seperate counters are maintained for European and American
2224 regions.The size of SFC counter is 4 bits. As a result two
2225 carriers are accommodated in one byte. This function
2226 first converts the ARFCN range from 1-1023 to 0-511 format and
2227 increments the SFC accordingly.The SFC format is shown below
2228
2229 CSI-LLD section:4.1.1.5.10
2230
2231 ------------------------------------------
2232 | Index | MSB 4 bits | LSB 4 bits |
2233 ------------------------------------------
2234 | 0 | ARFCN : 2 | ARFCN : 1 |
2235 ------------------------------------------
2236 | 1 | ARFCN : 4 | ARFCN 3 |
2237 ------------------------------------------
2238 | - | - | - |
2239 ------------------------------------------
2240 | - | - | - |
2241 ------------------------------------------
2242 | 510 | ARFCN : 1022 | ARFCN: 1021 |
2243 ------------------------------------------
2244 | 511 | ARFCN : 0 | ARFCN :1023 |
2245 -----------------------------------------
2246 ARFCN: 0 = CHANNEL_0_INTERNAL
2247 */
2248
2249 LOCAL void cs_reset_sync_fail_counter(U8 region, U16 arfcn)
2250 {
2251 GET_INSTANCE_DATA;
2252 USHORT index=0;
2253
2254 if(!cs_check_region(region))
2255 return;
2256
2257 if(!cs_check_arfcn_range((U16)(arfcn & ARFCN_MASK)))
2258 return;
2259
2260 if(arfcn EQ CHANNEL_0)
2261 arfcn = CHANNEL_0_INTERNAL;
2262
2263 /* Convert ARFCN range to 0-511 from 1-1023 range */
2264 index = ((arfcn & ARFCN_MASK) -1) >> 1;
2265
2266 if(arfcn & 0x01)
2267 {
2268 /* Reset LSB 4 bits for odd ARFCN */
2269 rr_data->cs_data.black_list.sfc[region][index] &=0xf0;
2270 }
2271 else
2272 {
2273 /* Reset MSB 4 bits for even ARFCN */
2274 rr_data->cs_data.black_list.sfc[region][index] &=0x0f;
2275 }
2276
2277 TRACE_EVENT_P2("SFC reset for [%d]Reg,[%d]Arfcn",region,arfcn);
2278 }
2279
2280 /*
2281 +----------------------------------------------------------------------+
2282 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2283 | STATE : code ROUTINE : cs_get_sync_fail_counter |
2284 +----------------------------------------------------------------------+
2285
2286 PURPOSE : This function returns the SFC counter of GSM carriers
2287 Seperate counters are maintained for European and American
2288 regions.The size of SFC counter is 4 bits. As a result two
2289 carriers are accommodated in one byte. This function
2290 first converts the ARFCN range from 1-1023 to 0-511 format and
2291 increments the SFC accordingly.The SFC format is shown below
2292
2293 CSI-LLD section:4.1.1.5.11
2294
2295 ------------------------------------------
2296 | Index | MSB 4 bits | LSB 4 bits |
2297 ------------------------------------------
2298 | 0 | ARFCN : 2 | ARFCN : 1 |
2299 ------------------------------------------
2300 | 1 | ARFCN : 4 | ARFCN 3 |
2301 ------------------------------------------
2302 | - | - | - |
2303 ------------------------------------------
2304 | - | - | - |
2305 ------------------------------------------
2306 | 510 | ARFCN : 1022 | ARFCN: 1021 |
2307 ------------------------------------------
2308 | 511 | ARFCN : 0 | ARFCN :1023 |
2309 -----------------------------------------
2310 ARFCN: 0 = CHANNEL_0_INTERNAL
2311 */
2312
2313 LOCAL U8 cs_get_sync_fail_counter(U8 region, U16 arfcn)
2314 {
2315 GET_INSTANCE_DATA;
2316 USHORT index=0;
2317 UBYTE sfc_count=0;
2318
2319 if(!cs_check_region(region))
2320 return sfc_count;
2321
2322 if(!cs_check_arfcn_range((U16)(arfcn & ARFCN_MASK)))
2323 return sfc_count;
2324
2325 if(arfcn EQ CHANNEL_0)
2326 arfcn = CHANNEL_0_INTERNAL;
2327
2328 /* Convert to 0-511 range from 1-1024 range */
2329 index = ((arfcn & ARFCN_MASK) -1) >> 1;
2330
2331 if(arfcn & 0x01)
2332 {
2333 /* obtain LSB 4 bits for odd ARFCN */
2334 sfc_count = (rr_data->cs_data.black_list.sfc[region][index] & 0x0f);
2335 }
2336 else
2337 {
2338 /* obtain MSB 4 bits for even ARFCN */
2339 sfc_count = (rr_data->cs_data.black_list.sfc[region][index] & 0xf0) >> 4;
2340 }
2341
2342 return sfc_count;
2343 }
2344
2345 /*
2346 +--------------------------------------------------------------------+
2347 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2348 | STATE : code ROUTINE : cs_add_to_black_list |
2349 +--------------------------------------------------------------------+
2350
2351 PURPOSE : This function is used to add GSM channels to "Black List".
2352 The function checks the "Black List" criteria before adding
2353 it to the list. This function is called whenever MS fails
2354 to synchronize to a GSM channel.
2355 CSI-LLD section:4.1.1.5.5
2356 */
2357
2358 GLOBAL void cs_add_to_black_list(U8 region, U16 arfcn, U8 rxlev)
2359 {
2360 GET_INSTANCE_DATA;
2361 U16 local_arfcn = arfcn & ARFCN_MASK;
2362
2363 TRACE_FUNCTION("cs_add_to_black_list()");
2364
2365 /* "Region" and "arfcn" are used to index "Black List" database
2366 * Check whether they are within proper range
2367 */
2368 if(!cs_check_region(region))
2369 return;
2370
2371 if(!cs_check_arfcn_range(local_arfcn))
2372 return;
2373
2374 /* Check Black List criteria */
2375 if(cs_check_black_list_criteria(region,arfcn,rxlev))
2376 {
2377 /* Add the channel to Black List */
2378 srv_set_channel(&rr_data->cs_data.black_list.list[region],local_arfcn);
2379
2380 /* Reset the sync fail counter for this channel. So that when this
2381 * carrier is removed from BL(BA_MA list), counter will start from zero
2382 * again
2383 */
2384 cs_reset_sync_fail_counter(region, local_arfcn);
2385
2386 TRACE_EVENT_P2("[%d]Reg[%d]Arfcn added to BL",region,local_arfcn);
2387 }
2388 }
2389
2390 /*
2391 +--------------------------------------------------------------------+
2392 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2393 | STATE : code ROUTINE : cs_del_from_black_list |
2394 +--------------------------------------------------------------------+
2395
2396 PURPOSE : This routine removes the arfcn from black list and resets the sync
2397 fail counter for that arfcn
2398 CSI-LLD section:4.1.1.5.6
2399 */
2400
2401 GLOBAL void cs_del_from_black_list(U8 region, U16 arfcn)
2402 {
2403 GET_INSTANCE_DATA;
2404 USHORT local_arfcn = arfcn & ARFCN_MASK;
2405 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2406 UBYTE i;
2407 #endif
2408
2409 TRACE_FUNCTION("cs_del_from_black_list()");
2410
2411 /* "Region" and "arfcn" are used to index "Black List" database
2412 * Check whether they are within proper range
2413 */
2414 if(!cs_check_region(region))
2415 return;
2416
2417 if(!cs_check_arfcn_range(local_arfcn))
2418 return;
2419
2420 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2421 if (region EQ BOTH_REGIONS)
2422 {
2423 for (i=0; i<MAX_REGIONS; i++)
2424 {
2425 if(srv_get_channel(&rr_data->cs_data.black_list.list[i],local_arfcn))
2426 {
2427 /* Remove the channel from Black List */
2428 srv_unset_channel(&rr_data->cs_data.black_list.list[i],local_arfcn);
2429
2430 /* Reset the sync fail counter for this channel */
2431 cs_reset_sync_fail_counter(i, local_arfcn);
2432
2433 TRACE_EVENT_P2("ARFCN:%d Region:%d deleted from BL",local_arfcn,i);
2434 }
2435 }
2436 }
2437 else
2438 {
2439 #endif
2440 if(srv_get_channel(&rr_data->cs_data.black_list.list[region],local_arfcn))
2441 {
2442 /* Remove the channel from Black List */
2443 srv_unset_channel(&rr_data->cs_data.black_list.list[region],local_arfcn);
2444
2445 /* Reset the sync fail counter for this channel */
2446 cs_reset_sync_fail_counter(region, local_arfcn);
2447
2448 TRACE_EVENT_P2("ARFCN:%d Region:%d deleted from BL",local_arfcn,region);
2449 }
2450 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2451 }
2452 #endif
2453 }
2454
2455 /*
2456 +--------------------------------------------------------------------+
2457 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2458 | STATE : code ROUTINE : cs_clear_black_list |
2459 +--------------------------------------------------------------------+
2460
2461 PURPOSE : This function is used to clear "Black List" database.
2462 The function clears the "Black List" database from
2463 1) Only RAM
2464 2) Only FFS
2465 3) Both RAM and FFS.
2466
2467 This function is called in the following cases
2468 1) In response to "ERASE_BL" dynamic configuration command
2469 2) After Initial PLMN search based on its outcome
2470
2471 CSI-LLD section:4.1.1.5.1
2472 */
2473
2474 GLOBAL void cs_clear_black_list(U8 erase_type)
2475 {
2476 GET_INSTANCE_DATA;
2477 TRACE_FUNCTION ("cs_clear_black_list()");
2478
2479 /* clear Black List from RAM */
2480 if(erase_type & CLR_BLACK_LIST_RAM)
2481 {
2482 memset(&rr_data->cs_data.black_list,0,sizeof(T_CS_BLACK_LIST));
2483
2484 TRACE_EVENT ("Black List: RAM cleared");
2485 }
2486
2487 /* Clear Black List from FFS */
2488 #if defined(_SIMULATION_FFS_)
2489 if(erase_type & CLR_BLACK_LIST_FFS)
2490 {
2491 T_LIST local_black_list[MAX_REGIONS];
2492
2493 memset(&local_black_list[0],0,MAX_REGIONS*sizeof(T_LIST));
2494
2495 rr_csf_write_black_list(&local_black_list[0]);
2496
2497 TRACE_EVENT ("Black List: FFS cleared");
2498 }
2499 #endif
2500
2501 }
2502
2503 /*
2504 +--------------------------------------------------------------------+
2505 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2506 | STATE : code ROUTINE : cs_remove_BA_MA_from_black_list|
2507 +--------------------------------------------------------------------+
2508
2509 PURPOSE : This function is used to remove the GSM channels present
2510 in MA and BA lists from the "Black List". The function
2511 deletes these channels from the "Black List" and also
2512 resets their SFC counter to zero. This function is called
2513 whenever MS receives BA and MA list information in any RR
2514 message.
2515 CSI-LLD section:4.1.1.5.7
2516 */
2517
2518 GLOBAL void cs_remove_BA_MA_from_black_list(U8 region, T_LIST *source_list)
2519 {
2520 GET_INSTANCE_DATA;
2521
2522 TRACE_FUNCTION("cs_remove_BA_MA_from_black_list()");
2523
2524 /* "Region" is to index "Black List" database
2525 * Check whether it is within proper range
2526 */
2527 if(!cs_check_region(region))
2528 return;
2529
2530 if(source_list NEQ NULL)
2531 {
2532 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2533 if (region EQ BOTH_REGIONS)
2534 {
2535 cs_remove_BA_MA_from_black_list(EUROPEAN_REGION,source_list);
2536 cs_remove_BA_MA_from_black_list(AMERICAN_REGION,source_list);
2537 }
2538 else
2539 #endif
2540 srv_unmask_list(&rr_data->cs_data.black_list.list[region],source_list);
2541
2542 TRACE_EVENT("BL updated with BA/MA/Inactive carrier list");
2543 }
2544 }
2545
2546
2547 /*
2548 +--------------------------------------------------------------------+
2549 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2550 | STATE : code ROUTINE : cs_rem_inactive_carriers_from_bl|
2551 +--------------------------------------------------------------------+
2552
2553 PURPOSE : This function is used to remove the inactive carriers from
2554 the "Black List". This is done whenever the mobile changes
2555 LA/RA
2556 Cell Selection Improvements-LLD section:4.1.1.3.4
2557 */
2558
2559 GLOBAL void cs_rem_inactive_carriers_from_bl(T_MPH_POWER_CNF *mph_power_cnf)
2560 {
2561
2562 TRACE_FUNCTION("cs_remove_inactive_from_black_list");
2563
2564 /* Remove the inactive carriers from Black list for European region */
2565 cs_remove_BA_MA_from_black_list(EUROPEAN_REGION,
2566 (T_LIST *)&mph_power_cnf->inactive_carrier_list.list[EUROPEAN_REGION]);
2567
2568 /* Remove the inactive carriers from Black list for American region */
2569 cs_remove_BA_MA_from_black_list(AMERICAN_REGION,
2570 (T_LIST *)&mph_power_cnf->inactive_carrier_list.list[AMERICAN_REGION]);
2571 }
2572
2573
2574 /*
2575 +--------------------------------------------------------------------+
2576 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2577 | STATE : code ROUTINE : cs_is_in_black_list |
2578 +--------------------------------------------------------------------+
2579
2580 PURPOSE : This routine checks whether a carrier is already part of Black
2581 list or not
2582 CSI-LLD section:4.1.1.5.12
2583 */
2584
2585 LOCAL BOOL cs_is_in_black_list(U8 region, U16 arfcn)
2586 {
2587 GET_INSTANCE_DATA;
2588 U8 status;
2589
2590 status = srv_get_channel((T_LIST*)&rr_data->cs_data.black_list.list[region],
2591 (USHORT)arfcn & ARFCN_MASK);
2592
2593 TRACE_EVENT_P3("[%d]Reg[%d]Arfcn, BL status:%d",region,arfcn,status);
2594
2595 return status;
2596 }
2597
2598 /*
2599 +--------------------------------------------------------------------+
2600 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2601 | STATE : code ROUTINE : cs_is_in_white_list |
2602 +--------------------------------------------------------------------+
2603
2604 PURPOSE : This routine checks whether a carrier is part of White
2605 list or not
2606 CSI-LLD section:4.1.2.2.7
2607 */
2608
2609 LOCAL BOOL cs_is_in_white_list(U8 region, U16 arfcn)
2610 {
2611 GET_INSTANCE_DATA;
2612 U8 status = FALSE;
2613
2614 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2615 if((rr_data->cs_data.white_list.region EQ BOTH_REGIONS) OR
2616 (region EQ rr_data->cs_data.white_list.region))
2617 #else
2618 if(region EQ rr_data->cs_data.white_list.region)
2619 #endif
2620 {
2621 status = srv_get_channel(&rr_data->cs_data.white_list.list,
2622 ((U16)arfcn & ARFCN_MASK));
2623 }
2624
2625 TRACE_EVENT_P3("[%d]Reg[%d]Arfcn, WL status:%d", region,arfcn,status);
2626
2627 return status;
2628 }
2629
2630 /*
2631 +---------------------------------------------------------------------+
2632 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2633 | STATE : code ROUTINE : cs_check_black_list_criteria|
2634 +---------------------------------------------------------------------+
2635
2636 PURPOSE : This function checks the criteria for adding a GSM channel
2637 to "Black List". GSM channels are added to "Black List" only
2638 after they satisfy this criteria.
2639 CSI-LLD section:4.1.1.5.13
2640 */
2641
2642 LOCAL BOOL cs_check_black_list_criteria(U8 region,U16 arfcn,U8 rxlev)
2643 {
2644 GET_INSTANCE_DATA;
2645 UBYTE band_index;
2646 U16 local_arfcn = arfcn&ARFCN_MASK;
2647 TRACE_FUNCTION("cs_check_black_list_criteria()");
2648
2649 /* Check if the carrier is already present in the black list */
2650 if(cs_is_in_black_list(region, local_arfcn))
2651 return FALSE;
2652
2653 /* Check if the carrier is present in White List */
2654 if(cs_is_in_white_list(region, local_arfcn))
2655 return FALSE;
2656
2657 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2658 band_index = cs_get_band_index(arfcn);
2659 #else
2660 band_index = get_band_index(arfcn);
2661 #endif
2662 /* RxLev of carrier is above upper threshold. Add the carrier
2663 * to Black List immediately
2664 */
2665 if(rxlev >= rr_data->dyn_config.upper_rxlev_thr[band_index])
2666 {
2667 return TRUE;
2668 }
2669
2670 /* Reasonably strong carrier. Add to Black List only if its sync fail
2671 * counter criteria is satisfied
2672 */
2673 if((rxlev >= rr_data->dyn_config.medium_rxlev_thr[band_index]) AND
2674 (rxlev < rr_data->dyn_config.upper_rxlev_thr[band_index]))
2675 {
2676 cs_inc_sync_fail_counter(region, local_arfcn);
2677
2678 if(cs_get_sync_fail_counter(region, local_arfcn) >= MAX_SYNC_FAILURES)
2679 {
2680 return TRUE;
2681 }
2682 }
2683 return FALSE;
2684 }
2685
2686 /*
2687 +----------------------------------------------------------------+
2688 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2689 | STATE : code ROUTINE : cs_update_black_list |
2690 +----------------------------------------------------------------+
2691
2692 PURPOSE : This function is used to update "Black List" database
2693 after initial PLMN search.It first clears the current
2694 "Black list" database from RAM and then adds some cells
2695 to "Black List" according to the current attrib-utes
2696 array values(BLACK_LIST_FLAG) of the Initial PLMN
2697 selection process. This function is called un-der the
2698 following cases
2699 1.MS enters Limited or No service after Initial PLMN search
2700 2.MS enters Full service in a different Location area
2701 from where it is switched off after initial PLMN search
2702 CSI-LLD section:4.1.1.5.8
2703 */
2704
2705 GLOBAL void cs_update_black_list(void)
2706 {
2707 GET_INSTANCE_DATA;
2708
2709 U8 update_black_list = FALSE;
2710 U8 i, region;
2711
2712 TRACE_FUNCTION("cs_update_black_list()");
2713
2714 /* If the outcome of first FUNC_PLMN_SEARCH is not full service.
2715 * Erase the Black List
2716 */
2717 if((rr_data->ms_data.req_mm_service EQ FUNC_PLMN_SRCH AND
2718 rr_data->ms_data.rr_service NEQ FULL_SERVICE))
2719 {
2720 update_black_list = TRUE;
2721 }
2722
2723 TRACE_EVENT_P8 ( "Old [%d]SC MCC/MNC r=%x%x%x/%x%x%x/%d",
2724 rr_data->cs_data.white_list.last_sc_arfcn,
2725 rr_data->cs_data.white_list.last_sc_lac.mcc[0],
2726 rr_data->cs_data.white_list.last_sc_lac.mcc[1],
2727 rr_data->cs_data.white_list.last_sc_lac.mcc[2],
2728 rr_data->cs_data.white_list.last_sc_lac.mnc[0],
2729 rr_data->cs_data.white_list.last_sc_lac.mnc[1],
2730 rr_data->cs_data.white_list.last_sc_lac.mnc[2],
2731 rr_data->cs_data.white_list.last_sc_lac.lac);
2732
2733 TRACE_EVENT_P8 ( "New [%d]SC MCC/MNC r=%x%x%x/%x%x%x/%d",
2734 rr_data->nc_data[SC_INDEX].arfcn,
2735 rr_data->nc_data[SC_INDEX].lai.mcc[0],
2736 rr_data->nc_data[SC_INDEX].lai.mcc[1],
2737 rr_data->nc_data[SC_INDEX].lai.mcc[2],
2738 rr_data->nc_data[SC_INDEX].lai.mnc[0],
2739 rr_data->nc_data[SC_INDEX].lai.mnc[1],
2740 rr_data->nc_data[SC_INDEX].lai.mnc[2],
2741 rr_data->nc_data[SC_INDEX].lai.lac);
2742
2743 /* If the current serving cell belongs to a different Location area.
2744 * Erase the Black List
2745 */
2746 if((rr_data->ms_data.rr_service EQ FULL_SERVICE) AND
2747 ((rr_data->cs_data.white_list.last_sc_arfcn EQ NOT_PRESENT_16BIT) OR
2748 (!dat_plmn_equal_req(rr_data->cs_data.white_list.last_sc_lac.mcc,
2749 rr_data->cs_data.white_list.last_sc_lac.mnc,
2750 rr_data->nc_data[SC_INDEX].lai.mcc,
2751 rr_data->nc_data[SC_INDEX].lai.mnc)) OR
2752 (rr_data->cs_data.white_list.last_sc_lac.lac NEQ
2753 rr_data->nc_data[SC_INDEX].lai.lac)))
2754 {
2755 update_black_list = TRUE;
2756 }
2757
2758 if(update_black_list)
2759 {
2760 /* Erase the current Black List */
2761 cs_clear_black_list(CLR_BLACK_LIST_RAM);
2762
2763 for(i=0;i<rr_data->cs_data.max_arfcn;i++)
2764 {
2765 if(CS_GET_BLACK_LIST_FLAG(i))
2766 {
2767 /* Obtain the region */
2768 region = CS_GET_REGION_FROM_FREQ(rr_data->cs_data.arfcn[i]);
2769
2770 cs_add_to_black_list(region,
2771 (USHORT)(rr_data->cs_data.arfcn[i]),
2772 rr_data->cs_data.rxlev[i]);
2773 }
2774 } /* i < max_arfcn */
2775
2776 TRACE_EVENT("BL updated after inital PLMN search");
2777 }
2778 }
2779
2780 /*
2781 +----------------------------------------------------------------------+
2782 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2783 | STATE : code ROUTINE : cs_store_black_list |
2784 +----------------------------------------------------------------------+
2785
2786 PURPOSE : This is a wrapper function for storing "Black List"
2787 information to FFS . This in turn calls
2788 rr_csf_write_black_list( ) to store "Black List" to FFS.
2789 This function is called during power off.
2790 CSI-LLD section:4.1.1.5.2
2791 */
2792
2793 GLOBAL void cs_store_black_list(void)
2794 {
2795 GET_INSTANCE_DATA;
2796 #if defined(_SIMULATION_FFS_)
2797 rr_csf_write_black_list(&rr_data->cs_data.black_list.list[0]);
2798 #endif
2799 }
2800
2801 /*
2802 +----------------------------------------------------------------------+
2803 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2804 | STATE : code ROUTINE : cs_get_new_search_mode |
2805 +----------------------------------------------------------------------+
2806
2807 PURPOSE : This routine returns the new search mode depending on the timer
2808 active and the previous search mode
2809 CSI-LLD section:4.1.3.4.1.1
2810 */
2811
2812 GLOBAL U8 cs_get_new_search_mode(void)
2813 {
2814 GET_INSTANCE_DATA;
2815 TRACE_FUNCTION("cs_get_new_search_mode()");
2816
2817 if(IS_TIMER_ACTIVE(T_FAST_CS))
2818 {
2819 /* Fast search timer is active */
2820 return FAST_SEARCH_MODE;
2821 }
2822
2823 if(IS_TIMER_ACTIVE(T_NORMAL_CS))
2824 {
2825 /* Normal search timer is active */
2826 return NORMAL_SEARCH_MODE;
2827 }
2828
2829 TRACE_EVENT_P1("Previous Search Mode : %d",
2830 rr_data->cs_data.previous_search_mode);
2831
2832 if((rr_data->cs_data.previous_search_mode EQ FULL_SEARCH_MODE)
2833 OR (rr_data->cs_data.previous_search_mode EQ FAST_SEARCH_MODE))
2834 {
2835 return NORMAL_SEARCH_MODE;
2836 }
2837
2838 if(rr_data->cs_data.previous_search_mode EQ NORMAL_SEARCH_MODE)
2839 {
2840 return FULL_SEARCH_MODE;
2841 }
2842
2843 return FULL_SEARCH_MODE;
2844 }
2845 /*
2846 +----------------------------------------------------------------------+
2847 | PROJECT : GSM-PS (8403) MODULE : RR_CS |
2848 | STATE : code ROUTINE : cs_handle_search_mode_timer |
2849 +----------------------------------------------------------------------+
2850
2851 PURPOSE : This routine handles the timers for the new search modes
2852 CSI-LLD section:4.1.3.4.1.2
2853 */
2854 GLOBAL void cs_handle_search_mode_timer(U8 search_mode)
2855 {
2856 GET_INSTANCE_DATA;
2857 TRACE_FUNCTION("cs_handle_search_mode_timer()");
2858
2859 if((search_mode EQ FAST_SEARCH_MODE) AND (rr_data->dyn_config.tfast_cs_val))
2860 {
2861 if(!IS_TIMER_ACTIVE(T_FAST_CS))
2862 {
2863 TIMERSTART (T_FAST_CS,rr_data->dyn_config.tfast_cs_val);
2864 }
2865 }
2866
2867 if((search_mode EQ NORMAL_SEARCH_MODE) AND (rr_data->dyn_config.tnormal_cs_val))
2868 {
2869 if(!IS_TIMER_ACTIVE(T_NORMAL_CS))
2870 {
2871 TIMERSTART (T_NORMAL_CS, rr_data->dyn_config.tnormal_cs_val);
2872 }
2873 }
2874
2875 if(search_mode EQ FULL_SEARCH_MODE)
2876 {
2877 if(rr_data->sc_data.mm_started EQ MM_ORIGINATED AND
2878 rr_data->ms_data.req_mm_service NEQ FUNC_NET_SRCH_BY_MMI)
2879 {
2880 TIMERSTOP(T_FAST_CS);
2881 TIMERSTOP(T_NORMAL_CS);
2882 }
2883 }
2884 }
2885
2886 /*
2887 +--------------------------------------------------------------------+
2888 | PROJECT : GSM-PS (6147) MODULE : RR_CS |
2889 | STATE : code ROUTINE : cs_update_std_ffs |
2890 +--------------------------------------------------------------------+
2891
2892 PURPOSE : This function updates the std value depending upon the
2893 frequency band support by MS. Frequncy band support is
2894 available in the FFS.
2895
2896 */
2897 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2898 LOCAL UBYTE cs_update_std_ffs (UBYTE new_std)
2899 {
2900 UBYTE freq_bands;
2901
2902 rr_csf_get_freq_bands (&freq_bands);
2903 switch (new_std)
2904 {
2905 case STD_DUAL_EGSM:
2906 if ((freq_bands & BAND_GSM_850) EQ BAND_GSM_850)
2907 {
2908 return STD_850_900_1800;
2909 }
2910 break;
2911 case STD_DUAL_US:
2912 if ((freq_bands & BAND_GSM_900) EQ BAND_GSM_900)
2913 {
2914 return STD_850_900_1900;
2915 }
2916 break;
2917 default:
2918 TRACE_EVENT_P1 ("wrong std for updation using FFS %x", new_std);
2919 }
2920 return new_std;
2921 }
2922 #endif
2923 #endif