comparison src/g23m-gsm/alr/alr_cs.c @ 104:27a4235405c6

src/g23m-gsm: import from LoCosto source
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 04 Oct 2016 18:24:05 +0000
parents
children
comparison
equal deleted inserted replaced
103:76d139c7a25e 104:27a4235405c6
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GSM-PS
4 | Modul : ALR_CS
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This Modul defines the SDL process Cell Selection.
18 +-----------------------------------------------------------------------------
19 */
20
21 #ifndef ALR_CS_C
22 #define ALR_CS_C
23
24 #define ENTITY_PL
25
26 /*==== INCLUDES ===================================================*/
27 #include <string.h>
28 #include <stdlib.h>
29 #include <limits.h>
30 #include "typedefs.h"
31 #include "vsi.h"
32 #include "custom.h"
33 #include "gsm.h"
34 #include "prim.h"
35 #include "pei.h"
36 #include "tok.h"
37
38 #include "pcm.h"
39 #ifdef GPRS
40 #include "alr_gprs.h"
41 #endif
42
43 #include "alr.h"
44 #include "alr_em.h"
45 #include "cl_list.h"
46
47 #if defined (_SIMULATION_)
48 #define TRACING
49 #endif
50
51 #if defined (TRACING)
52 #define ALR_TRACE_CS(a) ALR_TRACE(a)
53 #else
54 #define ALR_TRACE_CS(a)
55 #endif
56
57 #if defined (TRACING)
58
59 #define ALR_TRACE_CS_STD(a1) TRACE_EVENT_P1 ("std %d",a1)
60 #define ALR_TRACE_CS_BSIC_REQ(a,s) TRACE_EVENT_P2 ("BSIC REQ [%u] %d", a, s)
61 #define ALR_TRACE_CS_SYNC_VALID(a,f,t) TRACE_EVENT_P3 ("set new SC[%u],valid block fno:%d,time_al%d",a,f,t)
62
63 #else
64
65 #define ALR_TRACE_CS_STD(std)
66 #define ALR_TRACE_CS_BSIC_REQ(a,s)
67 #define ALR_TRACE_CS_SYNC_VALID(a,f,t)
68
69 #endif
70
71 /*==== EXPORT =====================================================*/
72
73 /*==== PRIVAT =====================================================*/
74
75 /*==== VARIABLES ==================================================*/
76
77 /* Power scan attempts for different search modes */
78 LOCAL const U8 power_scan_attempts[] = {
79 FULL_SEARCH_MODE_ATTEMPTS,
80 NORMAL_SEARCH_MODE_ATTEMPTS,
81 FAST_SEARCH_MODE_ATTEMPTS,
82 BLACK_LIST_SEARCH_MODE_ATTEMPTS
83 };
84
85 /* Power measurements spreading time for different search modes */
86 #if defined(_SIMULATION_)
87 LOCAL const U16 tim_powermeas_value[] = {
88 500,
89 500,
90 100,
91 100
92 };
93 #else
94 LOCAL const U16 tim_powermeas_value[] = {
95 TIM_FULL_SEARCH_POWERMEAS_VAL,
96 TIM_NORMAL_SEARCH_POWERMEAS_VAL,
97 TIM_FAST_SEARCH_POWERMEAS_VAL,
98 TIM_BLACK_LIST_SEARCH_POWERMEAS_VAL
99 };
100 #endif
101
102 LOCAL const int array_band_index[] = {
103 B_GSM_900,
104 B_E_GSM,
105 B_PCS_1900,
106 B_DCS_1800,
107 MAX_NUM_BANDS,
108 MAX_NUM_BANDS,
109 B_GSM_850
110 };
111
112 /*==== FUNCTIONS ==================================================*/
113
114 LOCAL void cs_add_and_sort_channels (void);
115 LOCAL void cs_find_inactive_carriers (T_POWER_MEAS **p_results,
116 U16 p_results_size[2],U8 *std,
117 U8 no_of_attempts, SHORT *min_rxlev);
118 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
119 LOCAL U8 cs_add_whitelist_carriers (U16 p_results_size[2], U8 *std,
120 U8 attempts,
121 SHORT *min_rxlev,
122 T_POWER_MEAS **p_results,
123 U8 no_of_carriers_per_band[4]);
124 #else
125 LOCAL U8 cs_add_whitelist_carriers (U16 p_results_size[2],
126 U8 std, U8 attempts,
127 SHORT *min_rxlev,
128 T_POWER_MEAS *presults,
129 U8 no_of_carriers_per_band[4]);
130 #endif
131 LOCAL BOOL cs_is_in_black_list (U8 region,U16 arfcn);
132 LOCAL U8 cs_restrict_max_carriers_per_band (U16 arfcn, U8 std,
133 U8 no_of_carriers_per_band[4],
134 U16 p_results_size[2], U8 min_rxlev);
135 LOCAL void cs_move_extra_carriers (U8 i_cnf, U8 extra_cnf);
136 LOCAL void cs_reorder_the_extra_carriers (U8 extra_cnf);
137 LOCAL void cs_power_array_swap_arfcn (T_POWER_ARRAY *from,
138 T_POWER_ARRAY *to);
139
140 /*
141 +--------------------------------------------------------------------+
142 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
143 | STATE : code ROUTINE : cs_init |
144 +--------------------------------------------------------------------+
145
146 PURPOSE : Initialize Cell Selection Process.
147 Set state and dynamic allocated RAM area to NULL.
148
149 */
150
151 GLOBAL void cs_init (void)
152 {
153 GET_INSTANCE_DATA;
154 TRACE_FUNCTION ("cs_init()");
155 alr_data->state[STATE_CS] = CS_NULL;
156 memset (&alr_data->cs_data, 0, sizeof (T_CS_DATA));
157 alr_data->cs_data.p_results1 = (T_POWER_MEAS*)&alr_power_meas_result1;
158 alr_data->cs_data.p_results2 = (T_POWER_MEAS*)&alr_power_meas_result2;
159 alr_data->cs_data.search_mode = SM_WIDE_MODE;
160 alr_data->cs_data.sync_fail_count = CS_SYNC_FAIL_COUNT_MAX;
161 alr_data->cs_data.bcch_fail_count = CS_BCCH_FAIL_COUNT_MAX;
162
163 if ( IS_EXT_MEAS_RUNNING ) /*alr_data->cs_data.mph_ext_meas_req NEQ NULL*/
164 {
165 PFREE ( alr_data->cs_data.mph_ext_meas_req );
166 alr_data->cs_data.mph_ext_meas_req = NULL;
167 }
168 }
169
170 /*
171 +--------------------------------------------------------------------+
172 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
173 | STATE : code ROUTINE : cs_get_next_area |
174 +--------------------------------------------------------------------+
175
176 PURPOSE : This returns the next area to scan ('next_area').
177 Also it sets 'std' and 'freq_area' - members of 'cs_data' -
178 depend on given 'freq_bands'.
179 */
180
181 LOCAL UBYTE cs_get_next_area (void)
182 {
183 GET_INSTANCE_DATA;
184 UBYTE next_area;
185
186 if ((alr_data->cs_data.freq_area&ALL_FREQ_AREA) EQ ALL_FREQ_AREA)
187 next_area =
188 (alr_data->cs_data.freq_area&NEXT_AMERICAN_AREA) ? AMERICAN_FREQ_AREA : EUROPEAN_FREQ_AREA;
189 else
190 next_area = alr_data->cs_data.freq_area;
191
192 /*
193 * In the case the members and value arenīt already initialized,
194 * next_area is set to 0
195 */
196 switch (next_area)
197 {
198 default:
199 case EUROPEAN_FREQ_AREA:
200 if ((alr_data->cs_data.std12 & 0x0f) EQ 0) /* not initialized */
201 next_area = 0;
202 break;
203 case AMERICAN_FREQ_AREA:
204 if ((alr_data->cs_data.std12 >> 4) EQ 0) /* not initialized */
205 next_area = 0;
206 break;
207 case 0:
208 break;
209 }
210
211 /*
212 if (next_area)
213 {
214 TRACE_EVENT_P9 ("cs_get_next_area: fb=%02x => cs_std=%u(%u) std12=%02x area=%02x'%c%c' next=%u'%c'",
215 alr_data->cs_data.freq_bands, alr_data->cs_data.std, std,
216 alr_data->cs_data.std12, alr_data->cs_data.freq_area,
217 (alr_data->cs_data.freq_area & EUROPEAN_FREQ_AREA) ? 'E':' ',
218 (alr_data->cs_data.freq_area & AMERICAN_FREQ_AREA) ? 'A':' ',
219 next_area, next_area ? ((next_area EQ AMERICAN_FREQ_AREA) ? 'A':' E') : '?');
220 }
221 */
222 return next_area;
223 }
224
225 /*
226 +--------------------------------------------------------------------+
227 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
228 | STATE : code ROUTINE : cs_get_std_area |
229 +--------------------------------------------------------------------+
230
231 PURPOSE : This returns the frequency band 'std' depend on given
232 'freq_bands'. It also sets the suitable frequency area
233 to the value of a possible given area pointer.
234
235 This function knows only the single and dual frequency
236 band combinations. Triple or quad frequency band
237 combinations leads to return values set to 0.
238 */
239
240 LOCAL UBYTE cs_get_std_area (UBYTE freq_bands, UBYTE *p_area)
241 {
242 UBYTE cs_freq_area;
243 UBYTE cs_std;
244
245 switch (freq_bands)
246 {
247 case BAND_GSM_900:/* single band */
248 cs_freq_area = EUROPEAN_FREQ_AREA;
249 cs_std = STD_900;
250 break;
251 case BAND_DCS_1800:/* single band */
252 cs_freq_area = EUROPEAN_FREQ_AREA;
253 cs_std = STD_1800;
254 break;
255 case BAND_PCS_1900:/* single band */
256 cs_freq_area = AMERICAN_FREQ_AREA;
257 cs_std = STD_1900;
258 break;
259 case BAND_E_GSM:/* extended single band */
260 case BAND_GSM_900|BAND_E_GSM: /* extended single band */
261 cs_freq_area = EUROPEAN_FREQ_AREA;
262 cs_std = STD_EGSM;
263 break;
264 case BAND_GSM_850:/* single band */
265 cs_freq_area = AMERICAN_FREQ_AREA;
266 cs_std = STD_850;
267 break;
268 case BAND_DUAL:/* dual band */
269 cs_freq_area = EUROPEAN_FREQ_AREA;
270 cs_std = STD_DUAL;
271 break;
272 case BAND_DUAL_EXT:/* dual band */
273 cs_freq_area = EUROPEAN_FREQ_AREA;
274 cs_std = STD_DUAL_EGSM;
275 break;
276 case BAND_DUAL_US:/* dual band */
277 cs_freq_area = AMERICAN_FREQ_AREA;
278 cs_std = STD_DUAL_US;
279 break;
280 default:
281 cs_freq_area = 0;
282 cs_std = 0;
283 break;
284 }
285
286 if (p_area)
287 *p_area = cs_freq_area;
288 return cs_std;
289 }
290
291 /*
292 +--------------------------------------------------------------------+
293 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
294 | STATE : code ROUTINE : cs_set_std_area |
295 +--------------------------------------------------------------------+
296
297 PURPOSE : This returns the next area to scan ('next_area').
298 Also it sets 'std' and 'freq_area' - members of 'cs_data' -
299 depend on given 'freq_bands'.
300 This function will be executed at least once (single band) and
301 not more than twice (multiband) per power request.
302 */
303
304 LOCAL UBYTE cs_set_std_area (void)
305 {
306 GET_INSTANCE_DATA;
307 UBYTE next_area;
308 UBYTE cs_freq_bands = alr_data->cs_data.freq_bands;
309 UBYTE cs_std;
310 UBYTE cs_freq_area = alr_data->cs_data.freq_area;
311
312 /*
313 TRACE_EVENT_P1 ("cs_set_std_area(): %s call", cs_freq_area?"second":"first");
314 */
315 if (cs_freq_area & NEXT_AMERICAN_AREA)
316 /*
317 * Initializing before second measurement
318 */
319 next_area = AMERICAN_FREQ_AREA;
320 else
321 next_area = 0;
322
323 if (cs_freq_bands EQ 0)
324 {
325 TRACE_ERROR ("alr_data->cs_data.freq_bands=0 (Invalid value)!");
326 TRACE_ASSERT (cs_freq_bands EQ 0);
327 }
328
329 cs_std = cs_get_std_area(cs_freq_bands, &cs_freq_area);
330 if (cs_std EQ 0)
331 {
332 cs_freq_area = 0;
333 if (cs_freq_bands & BAND_DUAL_EXT)
334 { /* european frequency bands */
335 cs_freq_area |= EUROPEAN_FREQ_AREA;
336 if (next_area EQ 0)
337 next_area = EUROPEAN_FREQ_AREA;
338 }
339 if (cs_freq_bands & BAND_DUAL_US)
340 { /* american frequency bands */
341 cs_freq_area |= AMERICAN_FREQ_AREA;
342 if (next_area EQ 0)
343 next_area = AMERICAN_FREQ_AREA;
344 }
345
346 if (next_area EQ EUROPEAN_FREQ_AREA)
347 {
348 cs_freq_bands &= BAND_DUAL_EXT;
349 }
350 else
351 {
352 cs_freq_bands &= BAND_DUAL_US;
353 cs_freq_area |= NEXT_AMERICAN_AREA;
354 }
355 /*
356 * get the next 'std' depend on the value of 'next_area'
357 */
358 cs_std = cs_get_std_area (cs_freq_bands, NULL);
359 }
360
361 if (next_area EQ 0)
362 next_area = cs_freq_area;
363
364 alr_data->cs_data.freq_area = cs_freq_area;
365 alr_data->cs_data.std = cs_std;
366 TRACE_EVENT_P9 ("cs_set_std_area: fb=%02x => cs_std=%u(%u) std12=%02x area=%02x'%c%c' next=%u'%c'",
367 alr_data->cs_data.freq_bands, alr_data->cs_data.std, std,
368 alr_data->cs_data.std12, alr_data->cs_data.freq_area,
369 (alr_data->cs_data.freq_area & EUROPEAN_FREQ_AREA) ? 'E':' ',
370 (alr_data->cs_data.freq_area & AMERICAN_FREQ_AREA) ? 'A':' ',
371 next_area, next_area ? ((next_area EQ AMERICAN_FREQ_AREA) ? 'A':'E') : '?');
372
373 return next_area;
374 }
375
376 /*
377 +--------------------------------------------------------------------+
378 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
379 | STATE : code ROUTINE : cs_power_array_swap_arfcn|
380 +--------------------------------------------------------------------+
381
382 PURPOSE : This function swaps ARFCN and its RxLev between the
383 locations passed.
384 */
385 LOCAL void cs_power_array_swap_arfcn(T_POWER_ARRAY *ptr1,T_POWER_ARRAY *ptr2)
386 {
387 U16 temp_arfcn;
388 SHORT temp_rxlev;
389
390 temp_arfcn = ptr1->radio_freq;
391 temp_rxlev = ptr1->accum_power_result;
392
393 ptr1->radio_freq = ptr2->radio_freq;
394 ptr1->accum_power_result = ptr2->accum_power_result;
395
396 ptr2->radio_freq = temp_arfcn;
397 ptr2->accum_power_result = temp_rxlev;
398
399 }
400
401 /*
402 +--------------------------------------------------------------------+
403 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
404 | STATE : code ROUTINE : cs_prepare_power_req |
405 +--------------------------------------------------------------------+
406
407 PURPOSE : This prepares the inputs for the power request depending
408 on the frequency areas.
409
410 */
411
412 GLOBAL T_POWER_MEAS* cs_prepare_power_req (void)
413 {
414 GET_INSTANCE_DATA;
415 UBYTE next_area,region;
416 T_POWER_MEAS *power_meas;
417 T_LIST *black_list;
418
419 TRACE_FUNCTION ("cs_prepare_power_req");
420
421 /*
422 * depending on the set frequency area
423 */
424 next_area = cs_get_next_area ();
425
426 if (next_area)
427 { /* members and values are already initialized */
428 switch (next_area)
429 {
430 default:
431 case EUROPEAN_FREQ_AREA:
432 power_meas = alr_data->cs_data.p_results1;
433 alr_data->cs_data.std = alr_data->cs_data.std12&0x0f;
434 break;
435 case AMERICAN_FREQ_AREA:
436 power_meas = alr_data->cs_data.p_results2;
437 alr_data->cs_data.std = alr_data->cs_data.std12>>4;
438 break;
439 }
440
441 TRACE_EVENT_WIN_P4 ("cs_prepare_power_req: cs_std=%u(%02x) next=%u'%c'",
442 alr_data->cs_data.std, alr_data->cs_data.std12,
443 next_area, (next_area EQ AMERICAN_FREQ_AREA) ? 'A':'E');
444
445 }
446 else
447 { /* must be initialize first */
448 int i;
449 int power_array_size;
450 int radio_freq_offset = 1;
451
452 /*
453 * depending on the given frequency bands
454 */
455 next_area = cs_set_std_area ();
456 /*
457 * depending on the just set frequency standard
458 */
459 switch(alr_data->cs_data.std)
460 {
461 case STD_900:
462 power_array_size = MAX_CARRIERS_GSM900;
463 break;
464
465 case STD_EGSM:
466 power_array_size = MAX_CARRIERS_EGSM900;
467 break;
468
469 case STD_1900:
470 power_array_size = MAX_CARRIERS_PCS1900;
471 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
472 radio_freq_offset = 1024;
473 #else
474 radio_freq_offset = 512;
475 #endif
476 break;
477
478 case STD_1800:
479 power_array_size = MAX_CARRIERS_DCS1800;
480 radio_freq_offset = 512;
481 break;
482
483 case STD_DUAL:
484 power_array_size = MAX_CARRIERS_DUAL;
485 break;
486
487 case STD_DUAL_EGSM:
488 power_array_size = MAX_CARRIERS_DUAL_EGSM;
489 break;
490
491 case STD_850:
492 power_array_size = MAX_CARRIERS_GSM850;
493 radio_freq_offset = 128;
494 break;
495
496 case STD_DUAL_US:
497 power_array_size = MAX_CARRIERS_DUAL_US;
498 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
499 radio_freq_offset = 128;
500 #endif
501 break;
502
503 default:
504 power_array_size = 0;
505 break;
506 }
507
508 if (power_array_size)
509 {
510 /*
511 * fill all carriers which shall be measured into the structure
512 * to layer 1.
513 */
514 T_POWER_ARRAY *power_array;
515 USHORT size;
516
517 if ( IS_EXT_MEAS_RUNNING )
518 {
519 power_array_size = alr_data->cs_data.mph_ext_meas_req->num_of_chan;
520 }
521
522 /* depend on the next area get the right T_POWER_MEAS instance */
523 switch (next_area)
524 {
525 default:
526 case EUROPEAN_FREQ_AREA:
527 size = sizeof (T_POWER_MEAS1);
528 power_meas = alr_data->cs_data.p_results1;
529 /*
530 TRACE_EVENT_P1 ("static T_POWER_MEAS(EU): size=%u", sizeof (T_POWER_MEAS1));
531 */
532 memset (alr_data->cs_data.p_results1, 0, sizeof (T_POWER_MEAS));
533
534 /* save value of 'std' for cs_increment_c_channels() */
535 alr_data->cs_data.std12 |= alr_data->cs_data.std & 0x0f;
536 break;
537
538 case AMERICAN_FREQ_AREA:
539 size = sizeof (T_POWER_MEAS2);
540 power_meas = alr_data->cs_data.p_results2;
541 /*
542 TRACE_EVENT_P1 ("static T_POWER_MEAS(USA): size=%u", sizeof (T_POWER_MEAS2));
543 */
544 /* save value of 'std' for cs_increment_c_channels() */
545 alr_data->cs_data.std12 |= (alr_data->cs_data.std << 4);
546 break;
547 }
548
549 memset (power_meas, 0, size);
550
551 TRACE_EVENT_WIN_P8 ("cs_prepare_power_req: cs_std=%u(%u) std12=%02x rf=%u..%u (%u) next=%u'%c'",
552 alr_data->cs_data.std, std, alr_data->cs_data.std12,
553 radio_freq_offset, power_array_size+radio_freq_offset-1,
554 power_array_size,
555 next_area, (next_area EQ AMERICAN_FREQ_AREA) ? 'A':'E');
556
557 power_array = &(power_meas->power_array[0]);
558 memset (power_array, 0, sizeof (T_POWER_ARRAY) * power_array_size);
559 power_meas->power_array_size = power_array_size;
560
561 if ( IS_EXT_MEAS_RUNNING )
562 {
563 USHORT *arfcn = &alr_data->cs_data.mph_ext_meas_req->arfcn[0];
564 for ( i = 0; i < power_array_size; i++, power_array++, arfcn++ )
565 {
566 power_array->radio_freq = ARFCN_TO_L1 ( *arfcn );
567 }
568 }
569 else
570 {
571 if(alr_data->cs_data.p_power_req->search_mode NEQ BLACK_LIST_SEARCH_MODE)
572 {
573 power_array_size += radio_freq_offset;
574 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
575 if (alr_data->cs_data.std EQ STD_EGSM)
576 {
577 for (i=radio_freq_offset; i <= MAX_CARRIERS_GSM900; i++, power_array++)
578 {
579 power_array->radio_freq = (U16)i;
580 }
581 for (i=LOW_CHANNEL_EGSM; i < HIGH_CHANNEL_EGSM; i++, power_array++)
582 {
583 power_array->radio_freq = (U16)i;
584 }
585 power_array->radio_freq = 0x00;
586 power_array++;
587 }
588 else if (alr_data->cs_data.std EQ STD_DUAL)
589 {
590 for (i=radio_freq_offset; i <= MAX_CARRIERS_GSM900; i++, power_array++)
591 {
592 power_array->radio_freq = (U16)i;
593 }
594 for (i=LOW_CHANNEL_1800; i <= HIGH_CHANNEL_1800; i++, power_array++)
595 {
596 power_array->radio_freq = (U16)i;
597 }
598 }
599 else if (alr_data->cs_data.std EQ STD_DUAL_EGSM)
600 {
601 for (i=radio_freq_offset; i <= MAX_CARRIERS_GSM900; i++, power_array++)
602 {
603 power_array->radio_freq = (U16)i;
604 }
605 for (i=LOW_CHANNEL_EGSM; i < HIGH_CHANNEL_EGSM; i++, power_array++)
606 {
607 power_array->radio_freq = (U16)i;
608 }
609 for (i=LOW_CHANNEL_1800; i <= HIGH_CHANNEL_1800; i++, power_array++)
610 {
611 power_array->radio_freq = (U16)i;
612 }
613 power_array->radio_freq = 0x00;
614 power_array++;
615 }
616 else if (alr_data->cs_data.std EQ STD_DUAL_US)
617 {
618 for (i=radio_freq_offset; i <= HIGH_CHANNEL_850; i++, power_array++)
619 {
620 power_array->radio_freq = (U16)i;
621 }
622 for (i=1024; i <= 1322; i++, power_array++)
623 {
624 power_array->radio_freq = (U16)i;
625 }
626 }
627 else
628 {
629 for(i=radio_freq_offset; i < power_array_size; i++, power_array++)
630 {
631 power_array->radio_freq = (U16)i;
632 }
633 }
634 #else
635 for(i=radio_freq_offset; i < power_array_size; i++, power_array++)
636 {
637 power_array->radio_freq = (U16)i;
638 }
639 #endif
640 }
641 else
642 {
643 /* Blacklist search. Fill all Black Listed and "Grey" carriers
644 * sent by RR for L1 measurement
645 */
646 region = srv_get_region_from_std(std);
647 power_meas->power_array_size = 0;
648 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
649 if (region EQ BOTH_REGIONS)
650 {
651 int j;
652 for (j=0; j<MAX_REGIONS; j++)
653 {
654 black_list = (T_LIST*)&alr_data->cs_data.p_power_req->black_list.list[j];
655
656 for(i=CHANNEL_0;i<CHANNEL_0_INTERNAL;i++)
657 {
658 if(srv_get_channel(black_list, i))
659 {
660 power_array->radio_freq = ARFCN_TO_L1 ( i );
661
662 power_meas->power_array_size++;
663 power_array++;
664 }
665 }
666 }
667 }
668 else
669 {
670 #endif
671 black_list = (T_LIST*)&alr_data->cs_data.p_power_req->black_list.list[region];
672
673 for(i=CHANNEL_0;i<CHANNEL_0_INTERNAL;i++)
674 {
675 if(srv_get_channel(black_list, i))
676 {
677 power_array->radio_freq = ARFCN_TO_L1 ( i );
678
679 power_meas->power_array_size++;
680 power_array++;
681 }
682 }
683 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
684 }
685 #endif
686 } /* Black list search */
687 } /* !EXT_MEAS */
688 } /* power_array_size != 0 */
689 else
690 {
691 TRACE_EVENT_P6 ("cs_prepare_power_req: invalid: fb=%02x cs_std=%u area=%02x'%c%c' next='%c'",
692 alr_data->cs_data.freq_bands,
693 alr_data->cs_data.std, alr_data->cs_data.freq_area,
694 (alr_data->cs_data.freq_area & EUROPEAN_FREQ_AREA) ? 'E':' ',
695 (alr_data->cs_data.freq_area & AMERICAN_FREQ_AREA) ? 'A':' ',
696 (next_area EQ AMERICAN_FREQ_AREA) ? 'A':'E');
697 power_meas = NULL;/* invalid values */
698 }
699 }
700 return power_meas;/* do it */
701 }
702
703 /*
704 +--------------------------------------------------------------------+
705 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
706 | STATE : code ROUTINE : cs_power_req |
707 +--------------------------------------------------------------------+
708
709 PURPOSE : This starts measurement of the fieldstrength of all channels.
710
711 */
712
713 GLOBAL void cs_power_req (UBYTE pch_interrupt)
714 {
715 GET_INSTANCE_DATA;
716 /* When Power On alr_data->cs_data.std will be set to 0, which wil be changed later. This is
717 used to find out if it is a first power scan after boot up. MPHC_INIT_L1_REQ will be sent
718 only during first powerv scan. It should not be sent on subsequent power scan */
719 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
720 U8 initial_req = alr_data->cs_data.std;
721 #endif
722
723 TRACE_EVENT_P1 (" p_results1=%08x", alr_data->cs_data.p_results1);
724
725 /* Reset CS data */
726 alr_data->cs_data.std12 = 0;
727 alr_data->cs_data.freq_area = 0;
728 alr_data->cs_data.c_meas = 0;
729 alr_data->cs_data.p_results1->power_array_size = 0;
730 alr_data->cs_data.p_results2->power_array_size = 0;
731
732 cs_prepare_power_req();
733
734 if(IS_EXT_MEAS_RUNNING)
735 {
736 alr_data->cs_data.c_max_meas = power_scan_attempts[FULL_SEARCH_MODE];
737
738 alr_data->cs_data.c_tim_meas = (tim_powermeas_value[FULL_SEARCH_MODE]/
739 power_scan_attempts[FULL_SEARCH_MODE]);
740
741 }
742 else
743 {
744 T_MPH_POWER_REQ* mph_power_req = alr_data->cs_data.p_power_req;
745
746 /* CSI-LLD Section: 4.1.3.4.2.3
747 * Set the number of RF scan attempts and TIM_POWER_MEAS timer value
748 * based on the search mode
749 */
750
751 /* Set the number of RF scan attempts */
752 alr_data->cs_data.c_max_meas =
753 power_scan_attempts[mph_power_req->search_mode];
754
755 /* Set TIM_POWER_MEAS timer value */
756 alr_data->cs_data.c_tim_meas =
757 (tim_powermeas_value[mph_power_req->search_mode] /
758 power_scan_attempts[mph_power_req->search_mode]);
759
760
761 if (((alr_data->cs_data.freq_area & ALL_FREQ_AREA) EQ ALL_FREQ_AREA) AND
762 (mph_power_req->search_mode NEQ BLACK_LIST_SEARCH_MODE))
763 {
764 /* Multiply the number of field strength measurements by 2 */
765 alr_data->cs_data.c_max_meas <<= 1;
766
767 /* Reduce the TIM_POWER_MEAS value by half */
768 alr_data->cs_data.c_tim_meas >>= 1;
769 }
770
771 TRACE_EVENT_P2(" Search Type:[%u] Search Mode:[%u]",
772 mph_power_req->pch_interrupt,
773 mph_power_req->search_mode);
774 }
775
776 /* new state is dependent on necessary of the L1 configuration */
777 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
778 if (!initial_req)
779 #else
780 if ((pch_interrupt EQ PCH_INTERRUPT) OR (alr_data->cs_data.std NEQ std))
781 #endif
782 {
783 SET_STATE (STATE_CS, CS_INIT_L1);
784 }
785 else
786 {
787 SET_STATE (STATE_CS, CS_START_MEASURE);
788 }
789
790 TRACE_EVENT_P2 ("cs_power_req: c_max_meas=%u c_tim_meas=%u",
791 alr_data->cs_data.c_max_meas, alr_data->cs_data.c_tim_meas);
792
793 ma_cs_rxlev_req ();
794 }
795
796 /*
797 +--------------------------------------------------------------------+
798 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
799 | STATE : code ROUTINE : cs_bsic_req |
800 +--------------------------------------------------------------------+
801
802 PURPOSE : Request of RR to search for frequency correction
803 burst and synchron burst.
804
805 */
806
807 GLOBAL void cs_bsic_req (T_MPH_BSIC_REQ * mph_bsic_req)
808 {
809 GET_INSTANCE_DATA;
810 UBYTE cs_std;
811
812 if (mph_bsic_req)
813 {
814 ALR_TRACE_CS_BSIC_REQ(mph_bsic_req->arfcn&ARFCN_MASK, GET_STATE (STATE_CS));
815
816 ALR_EM_BSIC_REQUEST;
817
818 }
819 /*
820 * cs_bsic_req is called from several places with mph_bsic_req EQ NULL
821 */
822
823 switch (GET_STATE (STATE_CS))
824 {
825 case CS_ACTIVE_BCCH:
826 ma_stop_scell_bcch_req ();
827 /*
828 * first stop BCCH reading,
829 * then start like in idle mode if
830 * it is a valid channel number
831 */
832 /*lint -fallthrough*/
833 default:
834 if (mph_bsic_req)
835 {
836 alr_data->cs_data.arfcn = mph_bsic_req->arfcn;
837 cs_std = STD_GET_FROM_ARFCN (mph_bsic_req->arfcn);
838 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
839 alr_data->cs_data.std = cs_std;
840 #else
841 if (cs_std AND (cs_std NEQ alr_data->cs_data.std))
842 { /*
843 * When RR supplies a value of 'std' then init radio band before sync
844 */
845 TRACE_EVENT_WIN_P2("cs_bsic_req: cs_std=%u->%u",
846 alr_data->cs_data.std, cs_std);
847 alr_data->cs_data.std = cs_std;
848 ma_cs_init_l1_req(alr_data->cs_data.std);
849 SET_STATE(STATE_CS, CS_INIT_SYNC);
850 return; /* wait of MPHC_INIT_L1_CON */
851 }
852 #endif
853 }
854 /* If no value of 'std' are supplied, then start sync immediately */
855 /*lint -fallthrough*/
856 case CS_INIT_DONE:
857 #if defined(STOP_SYNC_TASK)
858 if (alr_data->cs_data.sync_active)
859 {
860 /*
861 * stop any synchronisation task
862 */
863 SET_STATE(STATE_CS, CS_STOP_SYNC);
864 ma_cs_stop_network_sync_req();
865 return;/* wait for MPHC_STOP_NETWORK_SYNC_CON */
866 }
867 /*lint -fallthrough*/
868 case CS_STOP_SYNC_DONE:
869 #endif /* STOP_SYNC */
870 /*
871 * start synchronisation
872 * to the frequency correction burst and synchron burst
873 * in layer 1.
874 */
875 TRACE_EVENT_P1 ("NETWORK_SYNC_REQ[%u]", alr_data->cs_data.arfcn&ARFCN_MASK);
876 ma_cs_network_sync_req (ARFCN_STD_TO_L1(alr_data->cs_data.arfcn, alr_data->cs_data.std));
877 SET_STATE(STATE_CS, CS_ACTIVE_SYNC);
878 break;
879 #if defined(STOP_SYNC_TASK)
880 case CS_STOP_SYNC:
881 /* do nothing, wait for MPHC_STOP_NETWORK_SYNC_CON */
882 return;
883 #endif /* STOP_SYNC */
884 }
885 }
886
887 /*
888 +--------------------------------------------------------------------+
889 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
890 | STATE : code ROUTINE : cs_rxlev_ind |
891 +--------------------------------------------------------------------+
892
893 PURPOSE : This is the response from layer 1 for
894 a measurement sample request over all channels.
895
896 */
897
898 GLOBAL void cs_rxlev_ind (T_MPHC_RXLEV_IND* rxlev_ind)
899 {
900 GET_INSTANCE_DATA;
901 #if defined(_SIMULATION_)
902 {
903 /*
904 * special handling for windows simulation. In this case predefined
905 * values are used, because the primitives are too big to be forwarded
906 * via the test interface.
907 */
908 int index = rxlev_ind->shared_ptr;
909
910 memcpy(alr_data->cs_data.p_results1,&tap_rxlev_response_european[index],
911 sizeof(T_POWER_MEAS));
912
913 memcpy(alr_data->cs_data.p_results2,&tap_rxlev_response_american[index],
914 sizeof(T_POWER_MEAS));
915 }
916 #endif /* _SIMULATION_ */
917
918 TRACE_EVENT_P3 ("cs_rxlev_ind(): cs_std=%u c_meas=%u/%u",
919 alr_data->cs_data.std, alr_data->cs_data.c_meas+1, alr_data->cs_data.c_max_meas);
920
921 if ( IS_EXT_MEAS_RUNNING AND alr_data->cs_data.ext_meas_state_pend NEQ CS_NULL )
922 {
923 TIMERSTOP(TIM_POWERMEAS);
924 SET_STATE (STATE_CS, CS_NULL);
925 nc_stop_ext_meas_ind();
926 return;
927 }
928
929 switch (GET_STATE (STATE_CS))
930 {
931 case CS_MEASURED:
932
933 /* increment the number of measurement samples */
934 alr_data->cs_data.c_meas++;
935
936 if (alr_data->cs_data.c_meas EQ alr_data->cs_data.c_max_meas)
937 {
938 /* Allocate memory for MPH_POWER_CNF */
939 PALLOC (mph_power_cnf, MPH_POWER_CNF);
940
941 if (alr_data->cs_data.p_power_cnf)
942 {
943 PFREE (alr_data->cs_data.p_power_cnf);
944 }
945
946 alr_data->cs_data.p_power_cnf = mph_power_cnf;
947
948 memset (alr_data->cs_data.p_power_cnf, 0, sizeof (T_MPH_POWER_CNF));
949
950 TIMERSTOP(TIM_POWERMEAS);
951
952 /* Sort the channels based on their RxLev */
953 cs_add_and_sort_channels ();
954
955 if(!IS_EXT_MEAS_RUNNING)
956 {
957 /* Free MPH_POWER_REQ buffer */
958 PFREE(alr_data->cs_data.p_power_req);
959
960 alr_data->cs_data.p_power_req = NULL;
961 }
962
963 /* Send fieldstrength list to RR */
964 ma_cs_power_cnf (mph_power_cnf);
965
966 /* we are done with power measurements, next comes the BCCH detection */
967 SET_STATE (STATE_CS, CS_NULL);
968
969 alr_data->cs_data.p_power_cnf = NULL;
970
971 ALR_EM_POWER_MEASUREMENT_CONFIRM;
972 }
973 else
974 if (alr_data->cs_data.c_meas < alr_data->cs_data.c_max_meas)
975 {
976 /*
977 * start next sample
978 */
979 if ((alr_data->cs_data.freq_area & ALL_FREQ_AREA) EQ ALL_FREQ_AREA)
980 { /*
981 * toggle radio_band and configure new before the next measurement
982 */
983 TRACE_EVENT_P2 ("cs_rxlev_ind(): area=%02x->%02x",
984 alr_data->cs_data.freq_area,
985 alr_data->cs_data.freq_area^NEXT_AMERICAN_AREA);
986 alr_data->cs_data.freq_area ^= NEXT_AMERICAN_AREA;
987 #ifndef TI_PS_FF_QUAD_BAND_SUPPORT
988 SET_STATE (STATE_CS, CS_INIT_L1);
989 #endif
990 }
991 #ifndef TI_PS_FF_QUAD_BAND_SUPPORT
992 else
993 { /*
994 * start new measurement without new configuration of radio_band
995 */
996 #endif
997 SET_STATE (STATE_CS, CS_START_MEASURE);
998 #ifndef TI_PS_FF_QUAD_BAND_SUPPORT
999 }
1000 #endif
1001 ma_cs_rxlev_req ();
1002 }
1003 break;
1004
1005 default:
1006 break;
1007 }
1008 }
1009
1010 /*
1011 +--------------------------------------------------------------------+
1012 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1013 | STATE : code ROUTINE : cs_network_sync_ind |
1014 +--------------------------------------------------------------------+
1015
1016 PURPOSE : The function handles the result of a search for FCB or SCB.
1017
1018 */
1019
1020 GLOBAL void cs_network_sync_ind (T_MPHC_NETWORK_SYNC_IND* sync_ind)
1021 {
1022 GET_INSTANCE_DATA;
1023 PALLOC (mph_bsic_cnf, MPH_BSIC_CNF);
1024
1025 alr_data->cs_data.sync_active = FALSE;
1026 /*
1027 * The BCCH fail counter has to be reinitialized for every new cell.
1028 */
1029 alr_data->cs_data.bcch_fail_count = CS_BCCH_FAIL_COUNT_MAX;
1030 /*
1031 * copy arfcn, rxlev and bsic
1032 */
1033 mph_bsic_cnf->arfcn = ARFCN_STD_TO_G23(sync_ind->radio_freq, alr_data->cs_data.std);
1034 mph_bsic_cnf->arfcn = STD_ADD_TO_ARFCN(mph_bsic_cnf->arfcn, alr_data->cs_data.std);
1035 /* US_BIT should be used to differentiate an US frequency channel. */
1036 switch (alr_data->cs_data.std)
1037 {
1038 case STD_1900:
1039 case STD_850:
1040 case STD_DUAL_US:
1041 mph_bsic_cnf->arfcn |= US_BIT;
1042 break;
1043 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1044 case STD_850_1800:
1045 case STD_850_900_1800:
1046 if ((mph_bsic_cnf->arfcn >= LOW_CHANNEL_850) && (mph_bsic_cnf->arfcn <= HIGH_CHANNEL_850))
1047 mph_bsic_cnf->arfcn |= US_BIT;
1048 break;
1049 case STD_900_1900:
1050 if ((mph_bsic_cnf->arfcn >= LOW_CHANNEL_1900) && (mph_bsic_cnf->arfcn <= HIGH_CHANNEL_1900))
1051 mph_bsic_cnf->arfcn |= US_BIT;
1052 break;
1053 case STD_850_900_1900:
1054 if (mph_bsic_cnf->arfcn >= HIGH_CHANNEL_900)
1055 mph_bsic_cnf->arfcn |= US_BIT;
1056 break;
1057 #endif
1058 default:
1059 break;
1060 }
1061
1062 /*
1063 * set bsic and result code
1064 */
1065 mph_bsic_cnf->bsic = (UBYTE)(sync_ind->bsic & 63);
1066 mph_bsic_cnf->cs = sync_ind->sb_flag ? CS_NO_ERROR : CS_NO_BCCH_AVAIL;
1067
1068 /* Implements Measure#32: Row 21 and 22 */
1069 if (sync_ind->sb_flag)
1070 {
1071 TRACE_EVENT_P3 ("network_sync_ind:[%u] rf=%u cs_std=%u OK",
1072 mph_bsic_cnf->arfcn&ARFCN_MASK,
1073 sync_ind->radio_freq, alr_data->cs_data.std);
1074 }
1075 else
1076 {
1077 TRACE_EVENT_P3 ("network_sync_ind:[%u] rf=%u cs_std=%u no BCCH avail.",
1078 mph_bsic_cnf->arfcn&ARFCN_MASK,
1079 sync_ind->radio_freq, alr_data->cs_data.std);
1080 }
1081
1082 switch (GET_STATE(STATE_CS))
1083 {
1084 /*
1085 * workarounds for crossing MPHC_STOP_NETWORK_SYNC_REQ and
1086 * MPHC_NETWORK_SYNC_IND:
1087 * It is possible to receive a MPHC_NETWORK_SYNC_IND from layer 1 at the
1088 * same time as sending a MPHC_STOP_NETWORK_SYNC_REQ. The
1089 * MPHC_STOP_NETWORK_SYNC_REQ will be ignored by the layer 1 and no
1090 * STOP_NW_SYNC_CON will be send.
1091 */
1092 case CS_STOP_SYNC:
1093 /* The state CS_STOP_SYNC was set and the MPHC_NETWORK_SYNC_REQ was
1094 * interrupted to clean the way for a new MPHC_NETWORK_SYNC_REQ. A possible
1095 * MPHC_NETWORK_SYNC_IND will be treated as MPHC_STOP_NETWORK_SYNC_CON
1096 * because the result does not matter.
1097 */
1098 SET_STATE (STATE_CS, CS_STOP_SYNC_DONE);
1099 cs_bsic_req(NULL);
1100 /*lint -fallthrough */
1101 default:
1102 /*
1103 * the synchronisation has been broken
1104 */
1105 ALR_TRACE_CS ("MPHC_NETWORK_SYNC_IND ignored");
1106 PFREE (mph_bsic_cnf);
1107 return;
1108 /* break; */
1109
1110 case CS_NW_SYNC_TIMEOUT:
1111 /*
1112 * The state CS_NW_SYNC_TIMEOUT was set and the MPHC_NETWORK_SYNC_REQ was
1113 * interrupted to limit the time for reading the BCCH. A possible
1114 * MPHC_NETWORK_SYNC_IND will be treated normal. Otherwise, no BSIC_CNF
1115 * will be sent to RR, and RR waits forever.
1116 */
1117 SET_STATE(STATE_CS, CS_ACTIVE_SYNC);
1118 /*lint -fallthrough */
1119 case CS_ACTIVE_SYNC:
1120 ma_bsic_cnf (mph_bsic_cnf);
1121 break;
1122 }
1123
1124 #ifdef GPRS
1125 if(alr_data->gprs_data.pcco_active)
1126 {
1127 USHORT index;
1128 /* store data in nc_data.cr_cell */
1129 alr_data->nc_data.cr_cell.ba_arfcn =
1130 ARFCN_TO_G23(sync_ind->radio_freq)&ARFCN_MASK;
1131 alr_data->nc_data.cr_cell.bsic = (UBYTE)(sync_ind->bsic & 63);
1132 alr_data->nc_data.cr_cell.frame_offset = sync_ind->fn_offset;
1133 alr_data->nc_data.cr_cell.time_align = sync_ind->time_alignment;
1134
1135 index = nc_get_index(alr_data->nc_data.cr_cell.ba_arfcn);
1136 if ((index NEQ NOT_PRESENT_16BIT) AND (index NEQ LAST_BSIC_REQ))
1137 {
1138 /*
1139 * update in nc_data also because this data is not valid
1140 * anymore after a network_sync_req and in some special cases
1141 * nc_start_reselect will use the data in nc_data.cell[index]
1142 */
1143 alr_data->nc_data.cell[index].bsic = (UBYTE)(sync_ind->bsic & 63);
1144 alr_data->nc_data.cell[index].frame_offset = sync_ind->fn_offset;
1145 alr_data->nc_data.cell[index].time_align = sync_ind->time_alignment;
1146 }
1147 SET_STATE(STATE_CS, CS_NULL);
1148 return;
1149 }
1150 #endif
1151 if (sync_ind->sb_flag)
1152 {
1153 if (GET_STATE (STATE_CS) EQ CS_ACTIVE_SYNC)
1154 {
1155 USHORT arfcn;
1156 PALLOC(new_scell, MPHC_NEW_SCELL_REQ);
1157
1158 arfcn = ARFCN_STD_TO_G23(sync_ind->radio_freq, alr_data->cs_data.std);
1159 ALR_TRACE_CS_SYNC_VALID(arfcn, sync_ind->fn_offset,
1160 sync_ind->time_alignment);
1161
1162 /* store data in nc_data.cr_cell */
1163 alr_data->nc_data.cr_cell.ba_arfcn =
1164 ARFCN_TO_G23(sync_ind->radio_freq)&ARFCN_MASK;
1165 alr_data->nc_data.cr_cell.bsic = sync_ind->bsic;
1166 alr_data->nc_data.cr_cell.frame_offset = 0;
1167 alr_data->nc_data.cr_cell.time_align = 0;
1168
1169 new_scell->radio_freq = sync_ind->radio_freq;
1170 new_scell->fn_offset = sync_ind->fn_offset;
1171 new_scell->time_alignment = sync_ind->time_alignment;
1172 new_scell->tsc = sync_ind->bsic;
1173
1174 ALR_EM_BSIC_CONFIRM(EM_AVAIL);
1175
1176 /* after successful sync we can use narrow band search mode for
1177 * subsequent syncs.
1178 */
1179 alr_data->cs_data.search_mode = SM_NARROW_MODE;
1180 alr_data->cs_data.sync_fail_count = CS_SYNC_FAIL_COUNT_MAX;
1181
1182 alr_data->sc_band = get_band (arfcn);
1183 ma_new_scell_req(new_scell);
1184 }
1185 }
1186 else
1187 {
1188 ALR_TRACE_CS ("INVALID BLOCK");
1189
1190 ALR_EM_BSIC_CONFIRM(EM_NOT_AVAIL);
1191 /* If there are too many failed sync attempts in a row the AFC value
1192 * in L1 might be screwed up somehow.
1193 */
1194 if(alr_data->cs_data.sync_fail_count EQ 0)
1195 {
1196 alr_data->cs_data.sync_fail_count = CS_SYNC_FAIL_COUNT_MAX;
1197 alr_data->cs_data.search_mode = SM_WIDE_MODE;
1198 }
1199 else
1200 {
1201 alr_data->cs_data.sync_fail_count -= 1;
1202 }
1203
1204 }
1205 SET_STATE(STATE_CS, CS_NULL);
1206 }
1207
1208
1209 /*
1210 +--------------------------------------------------------------------+
1211 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1212 | STATE : code ROUTINE : cs_stop |
1213 +--------------------------------------------------------------------+
1214
1215 PURPOSE : Process signal cs_stop from SDL process
1216 Main_Control. This function stops all cell selection
1217 activities of ALR.
1218
1219 */
1220
1221 GLOBAL void cs_stop (void)
1222 {
1223 GET_INSTANCE_DATA;
1224 switch (GET_STATE (STATE_CS))
1225 {
1226 case CS_ACTIVE_MEASURE:
1227 {
1228 PALLOC (stop_req, MPHC_STOP_RXLEV_REQ);
1229 PSENDX (L1, stop_req);
1230 if ( IS_EXT_MEAS_RUNNING )
1231 {
1232 /* wait for MPHC_RXLEV_IND */
1233 alr_data->cs_data.ext_meas_state_pend = CS_ACTIVE_MEASURE;
1234 }
1235 break;
1236 }
1237 case CS_ACTIVE_SYNC:
1238 {
1239 PALLOC (stop_req, MPHC_STOP_NETWORK_SYNC_REQ);
1240 TIMERSTOP(TIM_NW_SYNC_GUARD);
1241 PSENDX (L1, stop_req);
1242 break;
1243 }
1244 case CS_ACTIVE_BCCH:
1245 /*
1246 * Stop BCCH reading
1247 */
1248 ma_stop_scell_bcch_req ();
1249 break;
1250 default:
1251 break;
1252 }
1253 SET_STATE (STATE_CS, CS_NULL);
1254 }
1255
1256 /*
1257 +--------------------------------------------------------------------+
1258 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1259 | STATE : code ROUTINE : cs_read_scell_bcch |
1260 +--------------------------------------------------------------------+
1261
1262 PURPOSE : Process signal cs_read_scell_bcch from SDL process
1263 Main_Control. This funtion requests reading of the full
1264 serving cell BCCH.
1265
1266 */
1267 GLOBAL void cs_read_scell_bcch (void)
1268 {
1269 GET_INSTANCE_DATA;
1270 /*
1271 * send bcch req
1272 * do full normal BCCH reading(modulus=1,position=0)
1273 */
1274 SET_STATE(STATE_CS, CS_ACTIVE_BCCH);
1275 ma_scell_full_nbcch();
1276 }
1277
1278
1279 /*
1280 +--------------------------------------------------------------------+
1281 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1282 | STATE : code ROUTINE : cs_add_and_sort_channels |
1283 +--------------------------------------------------------------------+
1284
1285 PURPOSE : Accumulate power measurements for all found channels
1286 sorted by highest fieldstrength.
1287 */
1288
1289 LOCAL void cs_add_and_sort_channels (void)
1290 {
1291 GET_INSTANCE_DATA;
1292 T_MPH_POWER_CNF* mph_power_cnf = alr_data->cs_data.p_power_cnf;
1293 T_MPH_POWER_REQ* mph_power_req = alr_data->cs_data.p_power_req;
1294 T_POWER_MEAS *p_results[MAX_REGIONS];
1295 T_POWER_ARRAY *parray, *pbig, *last;
1296 SHORT rxlev, min_rxlev[MAX_NUM_BANDS+1];
1297 /*lint -e644 (Warning -- Variable 'band_index' may not have been initialized) */
1298 UBYTE x, band_index = 0;
1299 /*lint +e644 (Warning -- Variable 'band_index' may not have been initialized) */
1300 U16 i, j, p_results_size[MAX_REGIONS], arfcn;
1301 U8 radio_band_config, std[MAX_REGIONS];
1302 U8 no_of_attempts, region, where_to_add;
1303 U8 i_cnf, extra_cnf, extra_space;
1304 U8 no_of_carriers_per_band[4] = {0, 0, 0, 0}; /* Counter for Multible frequency band in a Region
1305 * Index 0 for GSM_900,
1306 * Index 1 for DCS_1800,
1307 * Index 2 for GSM_850,
1308 * Index 3 for PCS_1900
1309 */
1310 /* Obtain data for European region */
1311 p_results[EUROPEAN_REGION] = alr_data->cs_data.p_results1;
1312 p_results_size[EUROPEAN_REGION] = alr_data->cs_data.p_results1 ?
1313 (alr_data->cs_data.p_results1->power_array_size) : 0;
1314
1315 /* Obtain data for American region */
1316 p_results[AMERICAN_REGION] = alr_data->cs_data.p_results2;
1317 p_results_size[AMERICAN_REGION] = alr_data->cs_data.p_results2 ?
1318 alr_data->cs_data.p_results2->power_array_size : 0;
1319
1320 TRACE_FUNCTION ( "cs_add_and_sort_channels()" );
1321
1322 if (!mph_power_cnf)
1323 {
1324 TRACE_EVENT ("mph_power_cnf EQ NULL");
1325 SET_STATE (STATE_CS, CS_NULL);
1326 return;
1327 }
1328
1329 i_cnf = 0;
1330 extra_cnf = MAX_CHANNELS - 1;
1331 mph_power_cnf->num_of_chan = 0;
1332
1333
1334 /* Set the minimum signal level */
1335 if ( IS_EXT_MEAS_RUNNING )
1336 {
1337 no_of_attempts = power_scan_attempts[FULL_SEARCH_MODE];
1338 for(x=0 ; x<=MAX_NUM_BANDS ; x++ )
1339 min_rxlev[x] = SHRT_MIN + 1;
1340 }
1341 else
1342 {
1343 if (!mph_power_req)
1344 {
1345 TRACE_EVENT ("mph_power_req EQ NULL");
1346 SET_STATE (STATE_CS, CS_NULL);
1347 return;
1348 }
1349
1350 no_of_attempts = power_scan_attempts[mph_power_req->search_mode];
1351 for(x=0 ; x<MAX_NUM_BANDS ; x++ )
1352 min_rxlev[x] = mph_power_req->lower_rxlevel_threshold[x] * no_of_attempts;
1353 /* If the std value cannot be retreived use the
1354 * default lower_rxlev_threshold value of 4
1355 */
1356 min_rxlev[MAX_NUM_BANDS] = LOWER_RXLEV_THRESHOLD;
1357 }
1358
1359 TRACE_EVENT_P5 ("cs_add_and_sort_channels: std12=%02x max=%u/%u a='%c%c'",
1360 alr_data->cs_data.std12,
1361 p_results_size[EUROPEAN_REGION],
1362 p_results_size[AMERICAN_REGION],
1363 (alr_data->cs_data.freq_area & EUROPEAN_FREQ_AREA) ? 'E' : ' ',
1364 (alr_data->cs_data.freq_area & AMERICAN_FREQ_AREA) ? 'A' : ' ');
1365
1366 if ((alr_data->cs_data.freq_area&ALL_FREQ_AREA) EQ ALL_FREQ_AREA)
1367 {
1368 /* use 'std' values saved by cs_prepare_power_req() */
1369 std[EUROPEAN_REGION] = alr_data->cs_data.std12&0x0f;
1370 std[AMERICAN_REGION] = alr_data->cs_data.std12>>4;
1371 }
1372 else
1373 {
1374 /* only one area */
1375 std[EUROPEAN_REGION] = std[AMERICAN_REGION] = alr_data->cs_data.std;
1376 if (alr_data->cs_data.freq_area & EUROPEAN_FREQ_AREA)
1377 p_results_size[AMERICAN_REGION] = 0;
1378 if (alr_data->cs_data.freq_area & AMERICAN_FREQ_AREA)
1379 p_results_size[EUROPEAN_REGION] = 0;
1380 }
1381
1382 if( IS_EXT_MEAS_RUNNING )
1383 {
1384 /*
1385 * According to 3GPP 05 08
1386 * Section "Range of parameter RxLev"
1387 *
1388 * The measured signal level shall be mapped to an RXLEV value between 0 and 63, as follows:
1389 * RXLEV 0 = less than -110 dBm + SCALE.
1390 * RXLEV 1 = -110 dBm + SCALE to -109 dBm + SCALE.
1391 * RXLEV 2 = -109 dBm + SCALE to -108 dBm + SCALE.
1392 * :
1393 * :
1394 * RXLEV 62 = -49 dBm + SCALE to -48 dBm + SCALE.
1395 * RXLEV 63 = greater than -48 dBm + SCALE.
1396 * where SCALE is an offset that is used only in the ENHANCED MEASUREMENT REPORT message,
1397 * otherwise it is set to 0.
1398 */
1399
1400 for(i=0; i < p_results_size[EUROPEAN_REGION]; i++)
1401 if( p_results[EUROPEAN_REGION]->power_array->accum_power_result < 0 )
1402 p_results[EUROPEAN_REGION]->power_array->accum_power_result = 0;
1403
1404 for(i=0; i < p_results_size[AMERICAN_REGION]; i++)
1405 if( p_results[AMERICAN_REGION]->power_array->accum_power_result < 0 )
1406 p_results[AMERICAN_REGION]->power_array->accum_power_result = 0;
1407 }
1408 else
1409 {
1410 /* LLD Section : 4.1.3.4.2
1411 * Find all inactive carriers and add them to MPH_POER_CNF
1412 * Also set the Rxlev of all Black Listed carriers to less than
1413 * Lower_Rxlev_Threshold
1414 */
1415
1416 TRACE_EVENT_P2("BIC->PWR array size, E:%d, A:%d",
1417 p_results_size[0], p_results_size[1]);
1418
1419 cs_find_inactive_carriers(p_results, p_results_size,
1420 std, no_of_attempts,
1421 min_rxlev);
1422
1423 TRACE_EVENT_P2("AIC->PWR array size, E:%d, A:%d",
1424 p_results_size[0], p_results_size[1]);
1425
1426 /*
1427 * If the search mode is BLACK_LIST_SEARCH_MODE no need for sorting
1428 * (based on RXLEV) the carriers (RR will look only for
1429 * inactive carrier list)
1430 */
1431 if(mph_power_req->search_mode EQ BLACK_LIST_SEARCH_MODE)
1432 {
1433 /* Allow measurement indications posting to RR */
1434 SET_STATE(STATE_NC,NC_IDLE);
1435 return;
1436 }
1437
1438 /* Put whitelist carriers at the top of power cnf list */
1439 if(mph_power_req->white_list.white_list_valid)
1440 {
1441 region = mph_power_req->white_list.region;
1442
1443 switch(mph_power_req->white_list.region)
1444 {
1445 case EUROPEAN_REGION :
1446 case AMERICAN_REGION :
1447 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1448 case BOTH_REGIONS:
1449 i_cnf = cs_add_whitelist_carriers(p_results_size, std,
1450 no_of_attempts,
1451 min_rxlev, p_results,
1452 no_of_carriers_per_band);
1453 #else
1454 i_cnf = cs_add_whitelist_carriers(p_results_size,
1455 std[region], no_of_attempts,
1456 min_rxlev, p_results[region],
1457 no_of_carriers_per_band);
1458 #endif
1459 TRACE_EVENT_P5(
1460 "[%c]White list Area (B_GSM_EGSM:%d, B_1800:%d, B_850:%d, B_1900:%d)",
1461 (mph_power_req->white_list.region ? 'A' : 'E'),
1462 no_of_carriers_per_band[0], no_of_carriers_per_band[1],
1463 no_of_carriers_per_band[2], no_of_carriers_per_band[3]);
1464 break;
1465 default :
1466 TRACE_EVENT_P1("Invalid whitelist region:%d",region);
1467 break;
1468 }
1469 } /* white list valid */
1470 else
1471 {
1472 TRACE_EVENT("WL is absent");
1473 }
1474 } /* !ext_meas */
1475
1476 TRACE_EVENT_P3("AWL->PWR array size, E:%d A:%d i_cnf:%d",
1477 p_results_size[0], p_results_size[1],i_cnf);
1478
1479 while (i_cnf < MAX_CHANNELS)
1480 {
1481 pbig=NULL;
1482 rxlev = 0;
1483 radio_band_config = where_to_add =0x00;
1484
1485 /* Loop through both regions */
1486 for (i=0;i<MAX_REGIONS;i++)
1487 {
1488 if((p_results_size[i]) AND (p_results[i] NEQ NULL))
1489 {
1490 parray = p_results[i]->power_array;
1491
1492 for (j=0; j<p_results_size[i]; j++, parray++)
1493 {
1494 arfcn = ARFCN_STD_TO_G23(parray->radio_freq, std[i]);
1495 /*lint -e661 (Warning -- Possible access of out-of-bounds) */
1496 get_band_index_from_arfcn(arfcn, x, std[i]);
1497 if (parray->accum_power_result >= min_rxlev[x] AND parray->accum_power_result > rxlev)
1498 {
1499 pbig = parray;
1500 rxlev = parray->accum_power_result;
1501 radio_band_config = std[i];
1502 region = (U8) i;
1503 band_index = x;
1504 }
1505 /*lint +e661 (Warning -- Possible access of out-of-bounds) */
1506 }
1507 }
1508 }
1509
1510 if( pbig NEQ NULL )
1511 {
1512 arfcn = ARFCN_STD_TO_G23(pbig->radio_freq, radio_band_config);
1513 if (rxlev > (min_rxlev[band_index] -1))
1514 {
1515 /* fill mph_power_cnf */
1516 arfcn = STD_ADD_TO_ARFCN(arfcn, radio_band_config);
1517
1518 /* US_BIT should be used to differentiate an US frequency channel. */
1519 switch (radio_band_config)
1520 {
1521 case STD_1900:
1522 case STD_850:
1523 case STD_DUAL_US:
1524 arfcn |= US_BIT;
1525 break;
1526 default:
1527 break;
1528 }
1529
1530 where_to_add = cs_restrict_max_carriers_per_band(
1531 arfcn&ARFCN_MASK,
1532 radio_band_config,
1533 no_of_carriers_per_band,
1534 p_results_size, min_rxlev[band_index]);
1535
1536 if(where_to_add EQ ADD_AT_THE_TOP)
1537 {
1538 /* First 40 Strongest Cariiers */
1539 mph_power_cnf->arfcn[i_cnf] = arfcn;
1540 mph_power_cnf->rx_lev[i_cnf] = (U8)(rxlev/no_of_attempts);
1541
1542 i_cnf++;
1543 }
1544 else if(where_to_add EQ ADD_AT_THE_BOTTOM)
1545 {
1546 /* Strongest Carriers which fall between 41 to 60 */
1547 if(extra_cnf >= i_cnf)
1548 {
1549 mph_power_cnf->arfcn[extra_cnf] = arfcn;
1550 mph_power_cnf->rx_lev[extra_cnf] = (U8)(rxlev/no_of_attempts);
1551
1552 extra_cnf--;
1553 }
1554 else
1555 {
1556 TRACE_EVENT_P2("MPH_POWER_CNF crossover, i_cnf: %d extra_cnf: %d",
1557 i_cnf, extra_cnf);
1558 }
1559 }
1560
1561 /* After adding a carrier to MPH_POWER_CNF, the particular carrier will be
1562 * replaced by the Last carrier of that region. So that we could avoid
1563 * searching the already added (MPH_POWER_CNF) carrier.
1564 */
1565 if(where_to_add NEQ REACHED_THE_MAXIMUM)
1566 {
1567 last = p_results[region]->power_array + (p_results_size[region]-1);/*lint !e644 region may not have been initialized */
1568
1569 pbig->accum_power_result = min_rxlev[band_index] - 1;
1570
1571 cs_power_array_swap_arfcn(pbig, last);
1572
1573 p_results_size[region]--;
1574 }
1575 else
1576 {
1577 TRACE_EVENT_P4("RTM->PWR array size, E:%d A:%d i_cnf:%d extra_cnf:%d",
1578 p_results_size[0], p_results_size[1],i_cnf,
1579 (MAX_CHANNELS-(extra_cnf+1)));
1580 }
1581 }
1582 }
1583 else
1584 break; /* no level found higher or equal than min_rxlev -> break sort/fill */
1585
1586 }/* while (i_cnf < MAX_CHANNELS) */
1587
1588 mph_power_cnf->num_of_chan = i_cnf;
1589
1590 /* Obtain the number of extra channels(41 to 60) added to
1591 * Power cnf array
1592 */
1593 extra_cnf = MAX_CHANNELS - (extra_cnf+1);
1594
1595 /* Obtain the amount of space available for extra channels
1596 * in power_cnf array
1597 */
1598 extra_space = MAX_CHANNELS - i_cnf;
1599
1600 TRACE_EVENT_P3("After Sorting, i_cnf:%d extra_cnf:%d extra_space:%d",
1601 i_cnf,extra_cnf,(extra_space-extra_cnf));
1602
1603 if(extra_cnf AND extra_space)
1604 {
1605 /* Extra channels are present and space to fit them is also available */
1606 if(extra_space < extra_cnf)
1607 {
1608 /* Some of the extra channels(41 to 60) are overwritten
1609 * Ignore them
1610 */
1611 extra_cnf = extra_space;
1612 }
1613
1614 /* Reordering the carriers(41 to 60) from Strongest to Weakest */
1615 cs_reorder_the_extra_carriers(extra_cnf);
1616
1617 /* Move the extra carriers up in power_cnf array, in case there
1618 * is empty gap between i_cnf and extra_cnf channels
1619 */
1620 if(extra_space > extra_cnf)
1621 cs_move_extra_carriers(i_cnf, extra_cnf);
1622
1623 mph_power_cnf->num_of_chan += extra_cnf;
1624 }
1625
1626 TRACE_EVENT_P5(
1627 "No. of carriers in POWER_CNF:%d (B_GSM_EGSM:%d, B_1800:%d, B_850:%d, B_1900:%d)",
1628 mph_power_cnf->num_of_chan,
1629 no_of_carriers_per_band[0], no_of_carriers_per_band[1],
1630 no_of_carriers_per_band[2], no_of_carriers_per_band[3]);
1631 }
1632
1633
1634
1635 /*
1636 +--------------------------------------------------------------------+
1637 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1638 | STATE : code ROUTINE : get_band |
1639 +--------------------------------------------------------------------+
1640
1641 PURPOSE : The function extracts the frequency band from the given
1642 'arfcn' parameter.
1643 */
1644
1645 GLOBAL UBYTE get_band (USHORT arfcn)
1646 {
1647 UBYTE local_std = STD_GET_FROM_ARFCN(arfcn);
1648 UBYTE sc_band;
1649
1650 if (local_std EQ 0)
1651 local_std = std;
1652
1653 switch (local_std)
1654 {
1655 case STD_900:
1656 sc_band = BAND_GSM_900;
1657 break;
1658
1659 case STD_EGSM:
1660 sc_band = BAND_E_GSM;
1661 break;
1662
1663 case STD_1800:
1664 sc_band = BAND_DCS_1800;
1665 break;
1666
1667 case STD_1900:
1668 sc_band = BAND_PCS_1900;
1669 break;
1670
1671 case STD_850:
1672 sc_band = BAND_GSM_850;
1673 break;
1674
1675 case STD_DUAL:
1676 if (arfcn >= LOW_CHANNEL_1800)
1677 sc_band = BAND_DCS_1800;
1678 else
1679 sc_band = BAND_GSM_900;
1680 break;
1681
1682 case STD_DUAL_EGSM:
1683 if (arfcn >= LOW_CHANNEL_EGSM)
1684 sc_band = BAND_E_GSM;
1685 else if (arfcn >= LOW_CHANNEL_1800)
1686 sc_band = BAND_DCS_1800;
1687 else if (arfcn EQ CHANNEL_0)
1688 sc_band = BAND_E_GSM;
1689 else
1690 sc_band = BAND_GSM_900;
1691 break;
1692
1693 case STD_DUAL_US:
1694 if (arfcn >= LOW_CHANNEL_1900)
1695 sc_band = BAND_PCS_1900;
1696 else
1697 sc_band = BAND_GSM_850;
1698 break;
1699
1700 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1701 case STD_850_1800:
1702 if (arfcn >= LOW_CHANNEL_1800)
1703 sc_band = BAND_DCS_1800;
1704 else
1705 sc_band = BAND_GSM_850;
1706 break;
1707
1708 case STD_900_1900:
1709 if (arfcn >= LOW_CHANNEL_EGSM)
1710 sc_band = BAND_E_GSM;
1711 else if (arfcn >= LOW_CHANNEL_1900)
1712 sc_band = BAND_PCS_1900;
1713 else if (arfcn EQ CHANNEL_0)
1714 sc_band = BAND_E_GSM;
1715 else
1716 sc_band = BAND_GSM_900;
1717 break;
1718
1719 case STD_850_900_1800:
1720 if (arfcn >= LOW_CHANNEL_EGSM)
1721 sc_band = BAND_E_GSM;
1722 else if (arfcn >= LOW_CHANNEL_1800)
1723 sc_band = BAND_DCS_1800;
1724 else if (arfcn EQ CHANNEL_0)
1725 sc_band = BAND_E_GSM;
1726 else if (arfcn >= LOW_CHANNEL_850)
1727 sc_band = BAND_GSM_850;
1728 else
1729 sc_band = BAND_GSM_900;
1730 break;
1731
1732 case STD_850_900_1900:
1733 if (arfcn >= LOW_CHANNEL_EGSM)
1734 sc_band = BAND_E_GSM;
1735 else if (arfcn >= LOW_CHANNEL_1900)
1736 sc_band = BAND_PCS_1900;
1737 else if (arfcn EQ CHANNEL_0)
1738 sc_band = BAND_E_GSM;
1739 else if (arfcn >= LOW_CHANNEL_850)
1740 sc_band = BAND_GSM_850;
1741 else
1742 sc_band = BAND_GSM_900;
1743 break;
1744 #endif
1745
1746 default:
1747 sc_band = 0;
1748 break;
1749 }
1750 /* this trace causes a lot of trace load; switch on only if needed
1751 TRACE_EVENT_P2 ("[%u] sc_band=%02x", arfcn&ARFCN_MASK, sc_band);
1752 */
1753 return sc_band;
1754 }
1755
1756 /*
1757 +--------------------------------------------------------------------+
1758 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1759 | STATE : code ROUTINE : cs_increment_bfc |
1760 +--------------------------------------------------------------------+
1761
1762 PURPOSE : The function increments the BCCH fail counter. This
1763 counter is decremented on every invalid BCCH block read
1764 during CS. It is incremented on evry valid block read on
1765 BCCH during CS. Valid means in this case that there was a
1766 SYS Info decodable in the block on the BCCH. There is a
1767 maximum value to start with and when the counter reaches
1768 0 we switch back to wide band search mode for further
1769 MPHC_NETWORK_SYNC_REQs (if any).
1770 */
1771
1772 GLOBAL void cs_increment_bfc (void)
1773 {
1774 GET_INSTANCE_DATA;
1775 alr_data->cs_data.bcch_fail_count += 1;
1776 if(alr_data->cs_data.bcch_fail_count > CS_BCCH_FAIL_COUNT_MAX)
1777 alr_data->cs_data.bcch_fail_count = CS_BCCH_FAIL_COUNT_MAX;
1778 }
1779
1780
1781 /*
1782 +--------------------------------------------------------------------+
1783 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1784 | STATE : code ROUTINE : cs_decrement_bfc |
1785 +--------------------------------------------------------------------+
1786
1787 PURPOSE : The function decrements the BCCH fail counter. This
1788 counter is decremented on every invalid BCCH block read
1789 during CS. It is incremented on evry valid block read on
1790 BCCH during CS. Valid means in this case that there was a
1791 SYS Info decodable in the block on the BCCH. There is a
1792 maximum value to start with and when the counter reaches
1793 0 we switch back to wide band search mode for further
1794 MPHC_NETWORK_SYNC_REQs (if any).
1795 */
1796
1797 GLOBAL void cs_decrement_bfc (void)
1798 {
1799 GET_INSTANCE_DATA;
1800 if(alr_data->cs_data.bcch_fail_count < 3)
1801 {
1802 alr_data->cs_data.bcch_fail_count = 0;
1803 alr_data->cs_data.search_mode = SM_WIDE_MODE;
1804 }
1805 else
1806 alr_data->cs_data.bcch_fail_count -= 2;
1807
1808 }
1809
1810
1811 /*
1812 +--------------------------------------------------------------------+
1813 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1814 | STATE : code ROUTINE : cs_set_wideband_sync |
1815 +--------------------------------------------------------------------+
1816
1817 PURPOSE : The function sets wide band search mode for further
1818 MPHC_NETWORK_SYNC_REQs (if any).
1819 */
1820
1821 GLOBAL void cs_set_wideband_sync (void)
1822 {
1823 GET_INSTANCE_DATA;
1824 alr_data->cs_data.search_mode = SM_WIDE_MODE;
1825 }
1826
1827 /*
1828 +--------------------------------------------------------------------+
1829 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1830 | STATE : code ROUTINE : cs_is_in_black_list |
1831 +--------------------------------------------------------------------+
1832
1833 PURPOSE : The function checks whether the given carrier is in the
1834 Blacklist or not
1835 CSI-LLD section: 4.1.3.4.2.1
1836 */
1837
1838 LOCAL BOOL cs_is_in_black_list(U8 region,U16 arfcn)
1839 {
1840 GET_INSTANCE_DATA;
1841 BOOL ret = FALSE;
1842
1843 if((region EQ EUROPEAN_REGION) OR (region EQ AMERICAN_REGION))
1844 {
1845 if(alr_data->cs_data.p_power_req->search_mode EQ FULL_SEARCH_MODE)
1846 {
1847 return ret;
1848 }
1849
1850 ret = srv_get_channel((T_LIST*)&alr_data->cs_data.p_power_req->black_list.list[region],
1851 arfcn&ARFCN_MASK);
1852
1853 if(ret)
1854 {
1855 if(srv_get_region_from_std(alr_data->cs_data.std) == region
1856 AND nc_is_in_ba(arfcn&ARFCN_MASK))
1857 {
1858 TRACE_EVENT_P1 ("ARFCN %d found in BA and Black list", arfcn & ARFCN_MASK);
1859 ret = FALSE;
1860 }
1861 }
1862
1863 }
1864 return ret;
1865 }
1866
1867 /*
1868 +--------------------------------------------------------------------+
1869 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1870 | STATE : code ROUTINE : cs_find_inactive_carriers |
1871 +--------------------------------------------------------------------+
1872
1873 PURPOSE : 1. Finds all inactive carriers
1874 2. Sets the RxLev of all Blacklisted carriers to less than
1875 LOWER_RXLEV_THRESHOLD
1876 CSI-LLD Section: 4.1.3.8.2.2.1
1877 CSI-LLD Section: 4.2
1878 */
1879
1880 LOCAL void cs_find_inactive_carriers (T_POWER_MEAS **p_results,
1881 U16 p_results_size[2],U8 *std,
1882 U8 no_of_attempts, SHORT *min_rxlev)
1883 {
1884 GET_INSTANCE_DATA;
1885 T_POWER_ARRAY* parray, *last;
1886 U16 j, arfcn;
1887 U8 i, x=0;
1888 T_MPH_POWER_CNF* mph_power_cnf = alr_data->cs_data.p_power_cnf;
1889
1890 TRACE_FUNCTION("cs_find_inactive_carriers ()");
1891
1892 /* Loop through both regions */
1893 for (i=0;i<MAX_REGIONS;i++)
1894 {
1895 if((p_results_size[i]) AND (p_results[i] NEQ NULL))
1896 {
1897 parray = p_results[i]->power_array;
1898
1899 for (j=0; j<p_results_size[i];)
1900 {
1901 arfcn = ARFCN_STD_TO_G23(parray->radio_freq, std[i]);
1902 /* Pointer to the Last Power array for a particular region */
1903 last = (p_results[i]->power_array + (p_results_size[i]-1));
1904 /*lint -e661 (Warning -- Possible access of out-of-bounds) */
1905 get_band_index_from_arfcn(arfcn, x, std[i]);
1906 if (parray->accum_power_result < min_rxlev[x])
1907 {
1908 /*lint +e661 (Warning -- Possible access of out-of-bounds) */
1909 /* Inactive carrier */
1910 srv_set_channel((T_LIST*)&mph_power_cnf->inactive_carrier_list.list[i],
1911 arfcn&ARFCN_MASK);
1912
1913 /* Replace inactive carrier with the last active carrier */
1914 cs_power_array_swap_arfcn(parray,last);
1915
1916 /* Decrement the power array size to exclude this carrier */
1917 p_results_size[i]--;
1918 }
1919 else if(cs_is_in_black_list(i, (U16)(arfcn&ARFCN_MASK)))
1920 {
1921 /* Carrier is black listed. No need to consider this */
1922 /*lint -e661 (Warning -- Possible access of out-of-bounds) */
1923 parray->accum_power_result = min_rxlev[x]-1;
1924 /*lint +e661 (Warning -- Possible access of out-of-bounds) */
1925 /* Replace inactive carrier with the last active carrier */
1926 cs_power_array_swap_arfcn(parray,last);
1927
1928 /* Decrement the power array size to exclude this carrier */
1929 p_results_size[i]--;
1930
1931 }
1932 else
1933 {
1934 j++, parray++;
1935 }
1936 } /* for size */
1937 } /* if size */
1938 } /* MAX_REGIONS */
1939 }
1940
1941
1942 /*
1943 +--------------------------------------------------------------------+
1944 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
1945 | STATE : code ROUTINE : cs_whitelist_handle |
1946 +--------------------------------------------------------------------+
1947
1948 PURPOSE : This function puts the White carriers at the top of the
1949 MPH_POWER_CNF list
1950 CSI-LLD 4.1.3.4.2.7
1951 */
1952
1953 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1954 LOCAL U8 cs_add_whitelist_carriers(U16 p_results_size[2], U8 *r_std, U8 no_of_attempts,
1955 SHORT *min_rxlev, T_POWER_MEAS **presults,
1956 U8 no_of_carriers_per_band[4])
1957 #else
1958 LOCAL U8 cs_add_whitelist_carriers(U16 p_results_size[2], U8 std, U8 no_of_attempts,
1959 SHORT *min_rxlev,
1960 T_POWER_MEAS *presults,
1961 U8 no_of_carriers_per_band[4])
1962 #endif
1963 {
1964 GET_INSTANCE_DATA;
1965 T_MPH_POWER_CNF* mph_power_cnf = alr_data->cs_data.p_power_cnf;
1966 T_MPH_POWER_REQ* mph_power_req = alr_data->cs_data.p_power_req;
1967 U8 i_cnf,j, where_to_add = DO_NOT_ADD;
1968 U8 region = mph_power_req->white_list.region;
1969 U16 i,arfcn, temp_arfcn;
1970 U8 temp_rxlev;
1971 UBYTE x=0;
1972 T_POWER_ARRAY *parray, *last;
1973 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1974 U8 std, start_region, no_of_regions, k;
1975 #endif
1976
1977 TRACE_FUNCTION ("cs_add_whitelist_carriers()");
1978
1979 i_cnf = 0;
1980
1981 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1982 if (region EQ BOTH_REGIONS)
1983 {
1984 if((!(p_results_size[EUROPEAN_REGION]) OR (presults[EUROPEAN_REGION] EQ NULL)) AND
1985 (!(p_results_size[AMERICAN_REGION]) OR (presults[AMERICAN_REGION] EQ NULL)))
1986 return i_cnf;
1987 }
1988 else if(!(p_results_size[region]) OR (presults EQ NULL))
1989 {
1990 #endif
1991 return i_cnf;
1992 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1993 }
1994 #endif
1995
1996 /* Move the white list carriers to MPH_POWER_CNF array first */
1997 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1998 if (region EQ BOTH_REGIONS)
1999 {
2000 start_region = EUROPEAN_REGION;
2001 no_of_regions = MAX_REGIONS;
2002 }
2003 else if (region EQ EUROPEAN_REGION)
2004 {
2005 start_region = region;
2006 no_of_regions = MAX_REGIONS - 1;
2007 }
2008 else
2009 {
2010 start_region = region;
2011 no_of_regions = MAX_REGIONS;
2012 }
2013
2014 for (k=start_region; k< no_of_regions; k++)
2015 {
2016 std = r_std[k];
2017 parray = presults[k]->power_array;
2018
2019 for (i=0; (i<p_results_size[k] AND i_cnf < 32); )
2020 #else
2021 for (i=0; (i<p_results_size[region] AND i_cnf < 32); )
2022 #endif
2023 {
2024 /* Convert to GSM standard format from L1 format*/
2025 arfcn = ARFCN_STD_TO_G23(parray->radio_freq,std);
2026 /*lint -e661 (Warning -- Possible access of out-of-bounds) */
2027 get_band_index_from_arfcn(arfcn, x, std);
2028 if (parray->accum_power_result > (min_rxlev[x] - 1))
2029 {
2030 /*lint +e661 (Warning -- Possible access of out-of-bounds) */
2031 if(srv_get_channel((T_LIST*)&mph_power_req->white_list.list, arfcn&ARFCN_MASK))
2032 {
2033
2034 /* Channel is present in white list. Add this to top of MPH_POWER_CNF */
2035 arfcn = STD_ADD_TO_ARFCN(arfcn, std);
2036
2037 /* US_BIT should be used to differentiate an US frequency channel. */
2038 switch (std)
2039 {
2040 case STD_1900:
2041 case STD_850:
2042 case STD_DUAL_US:
2043 arfcn |= US_BIT;
2044 break;
2045 default:
2046 break;
2047 }
2048 /*lint -e661 (Warning -- Possible access of out-of-bounds) */
2049 where_to_add = cs_restrict_max_carriers_per_band(arfcn&ARFCN_MASK, std,
2050 no_of_carriers_per_band, p_results_size, min_rxlev[x]);
2051 /*lint +e661 (Warning -- Possible access of out-of-bounds) */
2052 if(where_to_add NEQ DO_NOT_ADD)
2053 {
2054 /* White list carriers are always added at the top */
2055 mph_power_cnf->arfcn[i_cnf] = arfcn;
2056 mph_power_cnf->rx_lev[i_cnf] = (U8)(parray->accum_power_result/no_of_attempts);
2057 i_cnf++;
2058 }
2059 else
2060 {
2061 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2062 TRACE_EVENT_P2("[WL] [DO_NOT_ADD] [%d] : [%c]", arfcn&ARFCN_MASK,
2063 (k ? 'A' :'E'));
2064 #else
2065 TRACE_EVENT_P2("[WL] [DO_NOT_ADD] [%d] : [%c]", arfcn&ARFCN_MASK,
2066 (region ? 'A' :'E'));
2067 #endif
2068 }
2069
2070 /* Exclude this carrier */
2071 parray->accum_power_result = min_rxlev[x]-1;
2072
2073 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2074 last = presults[k]->power_array + (p_results_size[k] - 1);
2075 #else
2076 last = presults->power_array + (p_results_size[region] - 1);
2077 #endif
2078
2079 /* Swapping the current carrier with the last carrier */
2080 cs_power_array_swap_arfcn(parray, last);
2081
2082 /* Decrement the power array counter to exclude the above carrier */
2083 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2084 p_results_size[k]--;
2085 #else
2086 p_results_size[region]--;
2087 #endif
2088
2089 } /* Present in White List */
2090 else
2091 {
2092 i++; parray++;
2093 }
2094 } /* Active Carrier */
2095 else
2096 {
2097 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2098 TRACE_EVENT_P2("[WL] [IA] [%d] : [%c]", parray->radio_freq,
2099 (k ? 'A' :'E'));
2100 #else
2101 TRACE_EVENT_P2("[WL] [IA] [%d] : [%c]", parray->radio_freq,
2102 (region ? 'A' :'E'));
2103 #endif
2104 i++; parray++;
2105 }
2106 } /* i < max */
2107 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
2108 }
2109 #endif
2110
2111 /* Assign the total Number of white list channels */
2112 mph_power_cnf->num_of_white_list_chan = i_cnf;
2113
2114 TRACE_EVENT_P1("[WL] no. of channels : %d ",mph_power_cnf->num_of_white_list_chan);
2115
2116 /*
2117 * Sort the white list carriers added to power_cnf array on the
2118 * basis of their field strength
2119 */
2120 for(i=0; i < i_cnf; i++)
2121 {
2122 for(j=i+1; j<i_cnf; j++)
2123 {
2124 if(mph_power_cnf->rx_lev[i] < mph_power_cnf->rx_lev[j])
2125 {
2126 temp_rxlev = mph_power_cnf->rx_lev[i];
2127 temp_arfcn = mph_power_cnf->arfcn[i];
2128
2129 mph_power_cnf->rx_lev[i] = mph_power_cnf->rx_lev[j];
2130 mph_power_cnf->arfcn[i] = mph_power_cnf->arfcn[j];
2131
2132 mph_power_cnf->rx_lev[j] = temp_rxlev;
2133 mph_power_cnf->arfcn[j] = temp_arfcn;
2134 }
2135 }
2136 }
2137
2138 return (i_cnf);
2139 }
2140
2141 /*
2142 +--------------------------------------------------------------------+
2143 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
2144 | STATE : code ROUTINE : |
2145 | cs_restrict_max_carriers_per_band |
2146 +--------------------------------------------------------------------+
2147 PURPOSE : This function is to handle the Multiple Frequency Bands
2148 in a Region. Will help to add the minimum(40) carriers per
2149 band on top of the power cnf and the remaining(40 to 60)
2150 carriers will be added in at the end (Below the Normal (40)
2151 carriers of all band).
2152 CSI-LLD :
2153 */
2154
2155 U8 cs_restrict_max_carriers_per_band (U16 arfcn, U8 std,
2156 U8 no_of_carriers_per_band[4], U16 p_results_size[2], UBYTE min_rxlev)
2157 {
2158 GET_INSTANCE_DATA;
2159
2160 T_POWER_MEAS *presults;
2161 T_POWER_ARRAY *parray, *last;
2162 U16 i;
2163 U8 index = 0xff,just_reached_the_maximum=FALSE;
2164 U8 region, where_to_add = DO_NOT_ADD;
2165
2166 switch(std)
2167 {
2168 case STD_900 :
2169 case STD_DUAL :
2170 case STD_EGSM :
2171 case STD_DUAL_EGSM :
2172 case STD_1800 :
2173 if(INRANGE (CHANNEL_0, arfcn, HIGH_CHANNEL_900) OR
2174 INRANGE(LOW_CHANNEL_EGSM, arfcn, HIGH_CHANNEL_EGSM))
2175 {
2176 index = 0;
2177 }
2178 else if(INRANGE (LOW_CHANNEL_1800, arfcn, HIGH_CHANNEL_1800))
2179 {
2180 index = 1;
2181 }
2182 else
2183 {
2184 TRACE_ERROR("[European]Invalid Carrier");
2185 return DO_NOT_ADD;
2186 }
2187 region = EUROPEAN_REGION;
2188 break;
2189 case STD_DUAL_US :
2190 case STD_850 :
2191 case STD_1900 :
2192 if(INRANGE (LOW_CHANNEL_850, arfcn, HIGH_CHANNEL_850))
2193 {
2194 index = 2;
2195 }
2196 else if(INRANGE (LOW_CHANNEL_1900, arfcn, HIGH_CHANNEL_1900))
2197 {
2198 index = 3;
2199 }
2200 else
2201 {
2202 TRACE_ERROR("[American]Invalid Carrier");
2203 return DO_NOT_ADD;
2204 }
2205 region = AMERICAN_REGION;
2206 break;
2207 } /* end switch */
2208
2209 if(index < 4)
2210 {
2211 if(no_of_carriers_per_band[index] < MIN_CHANNELS_PER_BAND)
2212 {
2213 /* Increment counter for corresponding band */
2214 no_of_carriers_per_band[index]++;
2215
2216 if(no_of_carriers_per_band[index] EQ MIN_CHANNELS_PER_BAND)
2217 {
2218 TRACE_EVENT_P5(
2219 "[%d]Band, 40 channels added (B_GSM_EGSM%d, B_1800:%d, B_850:%d, B_1900:%d)",
2220 index,
2221 no_of_carriers_per_band[0], no_of_carriers_per_band[1],
2222 no_of_carriers_per_band[2], no_of_carriers_per_band[3]);
2223 }
2224
2225 /* Add at the top of MPH_POWER_CNF list */
2226 where_to_add = ADD_AT_THE_TOP;
2227 }
2228 else if(no_of_carriers_per_band[index] <= MAX_CHANNELS_PER_BAND)
2229 {
2230 /* Increment counter for corresponding band */
2231 no_of_carriers_per_band[index]++;
2232
2233 /* Add at the bottom of MPH_POWER_CNF list */
2234 where_to_add = ADD_AT_THE_BOTTOM;
2235
2236 if(no_of_carriers_per_band[index] EQ (MAX_CHANNELS_PER_BAND + 1))
2237 {
2238 TRACE_EVENT_P5(
2239 "[%d]Band, 60 channels added (B_GSM_EGSM%d, B_1800:%d, B_850:%d, B_1900:%d)",
2240 index,
2241 no_of_carriers_per_band[0], no_of_carriers_per_band[1],
2242 no_of_carriers_per_band[2], no_of_carriers_per_band[3]);
2243
2244 just_reached_the_maximum = TRUE;
2245
2246 where_to_add = REACHED_THE_MAXIMUM;
2247 }
2248 }
2249 else
2250 {
2251 where_to_add = DO_NOT_ADD;
2252 }
2253 }
2254 else
2255 {
2256 TRACE_ERROR("Unknown Band Index");
2257 return DO_NOT_ADD;
2258 } /* if index < 4 */
2259
2260 /* When Max number of channels(60) are added for a particular band,
2261 * all the remaining carriers belonging to that band are excluded from
2262 * further sorting
2263 */
2264 if(just_reached_the_maximum)
2265 {
2266 BOOL exclude;
2267 U16 l3_arfcn;
2268
2269 if (region EQ AMERICAN_REGION)/*lint !e644 region may not have been initialized */
2270 { /* American band */
2271 presults = alr_data->cs_data.p_results2;
2272 }
2273 else
2274 { /* European band */
2275 presults = alr_data->cs_data.p_results1;
2276 }
2277
2278 TRACE_EVENT_P3("[%d]Index, E:%d A:%d",
2279 index, p_results_size[0], p_results_size[1]);
2280
2281 if((presults NEQ NULL) AND (p_results_size[region]))/*lint !e644 region may not have been initialized */
2282 {
2283 for(i=0, parray = presults->power_array; i < p_results_size[region];)
2284 {
2285 exclude = FALSE;
2286 l3_arfcn = ARFCN_STD_TO_G23(parray->radio_freq, std);
2287
2288 switch(index)
2289 {
2290 case 0 :
2291 if(INRANGE (LOW_CHANNEL_900, l3_arfcn, HIGH_CHANNEL_900) OR
2292 INRANGE(LOW_CHANNEL_EGSM, l3_arfcn, HIGH_CHANNEL_EGSM))
2293 {
2294 exclude = TRUE;
2295 }
2296 break;
2297 case 1:
2298 if(INRANGE (LOW_CHANNEL_1800, l3_arfcn, HIGH_CHANNEL_1800))
2299 {
2300 exclude = TRUE;
2301 }
2302 break;
2303 case 2 :
2304 if(INRANGE (LOW_CHANNEL_850, l3_arfcn, HIGH_CHANNEL_850))
2305 {
2306 exclude = TRUE;
2307 }
2308 break;
2309 case 3:
2310 if(INRANGE (LOW_CHANNEL_1900, l3_arfcn, HIGH_CHANNEL_1900))
2311 {
2312 exclude = TRUE;
2313 }
2314 break;
2315 default :
2316 break;
2317 } /* end switch */
2318
2319 if(exclude)
2320 {
2321 last = presults->power_array + (p_results_size[region] - 1); /*lint !e644 region may not have been initialized */
2322
2323 /* Exclude this carrier */
2324 parray->accum_power_result = min_rxlev-1;
2325
2326 /* Swaping the Current carrier with the last carrier */
2327 cs_power_array_swap_arfcn(parray, last);
2328
2329 /* Decrement the power array counter to exclude the above carrier */
2330 p_results_size[region]--;
2331 }
2332 else
2333 {
2334 parray++; i++;
2335 }
2336 } /* power array size */
2337 } /* end if(just_reached_the_maximum */
2338 } /* presults NEQ NULL */
2339
2340 return where_to_add;
2341 }
2342 #endif
2343
2344
2345 /*
2346 +--------------------------------------------------------------------+
2347 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
2348 | STATE : code ROUTINE : cs_reorder_the_extra_carriers |
2349 +--------------------------------------------------------------------+
2350 PURPOSE : Extra Carriers (More than 40 and below 60) are stored at
2351 the bottom of the MPH_POWER_CNF. But these are stored in
2352 ascending order (if you see from the TOP). This needs to
2353 be reordered (means Strongest carrier should go to top).
2354 */
2355
2356 LOCAL void cs_reorder_the_extra_carriers(U8 extra_cnf)
2357 {
2358 GET_INSTANCE_DATA;
2359 T_MPH_POWER_CNF* mph_power_cnf = alr_data->cs_data.p_power_cnf;
2360 U8 i,j,count,max_count,temp_rxlevel;
2361 U16 temp_arfcn;
2362
2363 TRACE_FUNCTION("cs_reorder_the_extra_carriers");
2364
2365 i = MAX_CHANNELS - 1;
2366 j = MAX_CHANNELS - extra_cnf;
2367 max_count = extra_cnf/2;
2368
2369
2370 for(count=0; count < max_count; i--, j++, count++)
2371 {
2372 temp_arfcn = mph_power_cnf->arfcn[i];
2373 temp_rxlevel = mph_power_cnf->rx_lev[i];
2374
2375 mph_power_cnf->arfcn[i] = mph_power_cnf->arfcn[j];
2376 mph_power_cnf->rx_lev[i] = mph_power_cnf->rx_lev[j];
2377
2378 mph_power_cnf->arfcn[j] = temp_arfcn;
2379 mph_power_cnf->rx_lev[j] = temp_rxlevel;
2380
2381 }
2382
2383 }
2384
2385 /*
2386 +--------------------------------------------------------------------+
2387 | PROJECT : GSM-PS (8403) MODULE : ALR_CS |
2388 | STATE : code ROUTINE : |
2389 | cs_move_extra_carriers |
2390 +--------------------------------------------------------------------+
2391 PURPOSE : Extra Carriers (More than 40 and below 60) are stored at
2392 the bottom of the MPH_POWER_CNF. These carriers needs to
2393 be rearranged below the normal (Strangest 40 Carriers)
2394 carriers
2395 */
2396
2397 LOCAL void cs_move_extra_carriers(U8 i_cnf, U8 extra_cnf)
2398 {
2399 GET_INSTANCE_DATA;
2400 T_MPH_POWER_CNF* mph_power_cnf = alr_data->cs_data.p_power_cnf;
2401
2402 /*
2403 * Add the extra carriers below Normal carrier
2404 */
2405 TRACE_FUNCTION("cs_move_extra_carriers");
2406
2407 /* Move the extra carriers below the Normal carriers */
2408 memmove (&mph_power_cnf->arfcn[i_cnf],
2409 &mph_power_cnf->arfcn[MAX_CHANNELS - extra_cnf],
2410 sizeof (mph_power_cnf->arfcn[0]) * (extra_cnf));
2411
2412 memmove (&mph_power_cnf->rx_lev[i_cnf],
2413 &mph_power_cnf->rx_lev[MAX_CHANNELS - extra_cnf],
2414 sizeof (mph_power_cnf->rx_lev[0]) * (extra_cnf));
2415
2416 }
2417