comparison src/g23m-gsm/alr2/alr_cs.c @ 2:3a14ee9a9843

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