comparison src/g23m-gprs/grr/grr_csf.c @ 1:d393cd9bb723

src/g23m-*: initial import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Sun, 15 Jul 2018 04:40:46 +0000
parents
children
comparison
equal deleted inserted replaced
0:b6a5e36de839 1:d393cd9bb723
1 /*
2 +-----------------------------------------------------------------------------
3 | Project : GPRS (8441)
4 | Modul : GRR
5 +-----------------------------------------------------------------------------
6 | Copyright 2002 Texas Instruments Berlin, AG
7 | All rights reserved.
8 |
9 | This file is confidential and a trade secret of Texas
10 | Instruments Berlin, AG
11 | The receipt of or possession of this file does not convey
12 | any rights to reproduce or disclose its contents or to
13 | manufacture, use, or sell anything it may describe, in
14 | whole, or in part, without the specific written consent of
15 | Texas Instruments Berlin, AG.
16 +-----------------------------------------------------------------------------
17 | Purpose : This module implements local functions for service CS of
18 | entity GRR.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef GRR_CSF_C
23 #define GRR_CSF_C
24 #endif
25
26 #define ENTITY_GRR
27
28 /*==== INCLUDES =============================================================*/
29
30 #include <stdio.h>
31 #include <string.h>
32 #include "typedefs.h" /* to get Condat data types */
33 #include "vsi.h" /* to get a lot of macros */
34 #include "macdef.h"
35 #include "gprs.h"
36 #include "gsm.h" /* to get a lot of macros */
37 #include "ccdapi.h" /* to get CCD API */
38 #include "cnf_grr.h" /* to get cnf-definitions */
39 #include "mon_grr.h" /* to get mon-definitions */
40 #include "prim.h" /* to get the definitions of used SAP and directions */
41 #include "message.h"
42 #include "grr.h" /* to get the global entity definitions */
43 #include "grr_f.h"
44 #include "grr_ctrls.h"
45 #include "grr_meass.h"
46 #include "grr_csf.h"
47 #include "grr_em.h" /*for Engineering mode*/
48
49
50 /*==== CONST ================================================================*/
51 #if defined (REL99) AND defined (TI_PS_FF_EMR)
52 /*
53 * Bitmasks
54 */
55 #define BIT_0 0x01
56 #define BIT_1 0x02
57 #define BIT_2 0x04
58 #define BIT_3 0x08
59 #define BIT_4 0x10
60 #define BIT_5 0x20
61 #define BIT_6 0x40
62 #define BIT_7 0x80
63 #endif
64
65 T_NC_DATA* nc_data = NULL; /* pointer to neighbour cell data */
66
67 const SHORT p_res_off[32] = { -52, /* 0 -> -52 dB */
68 -48, /* 1 -> -48 dB */
69 -44, /* 2 -> -44 dB */
70 -40, /* 3 -> -40 dB */
71 -36, /* 4 -> -36 dB */
72 -32, /* 5 -> -32 dB */
73 -28, /* 6 -> -28 dB */
74 -24, /* 7 -> -24 dB */
75 -20, /* 8 -> -20 dB */
76 -16, /* 9 -> -16 dB */
77 -12, /* 10 -> -12 dB */
78 -10, /* 11 -> -10 dB */
79 - 8, /* 12 -> - 8 dB */
80 - 6, /* 13 -> - 6 dB */
81 - 4, /* 14 -> - 4 dB */
82 - 2, /* 15 -> - 2 dB */
83 0, /* 16 -> 0 dB */
84 2, /* 17 -> 2 dB */
85 4, /* 18 -> 4 dB */
86 6, /* 19 -> 6 dB */
87 8, /* 20 -> 8 dB */
88 10, /* 21 -> 10 dB */
89 12, /* 22 -> 12 dB */
90 16, /* 23 -> 16 dB */
91 20, /* 24 -> 20 dB */
92 24, /* 25 -> 24 dB */
93 28, /* 26 -> 28 dB */
94 32, /* 27 -> 32 dB */
95 36, /* 28 -> 36 dB */
96 40, /* 29 -> 40 dB */
97 44, /* 30 -> 44 dB */
98 48 /* 31 -> 48 dB */
99 };
100
101 #if defined (REL99) AND defined (TI_PS_FF_EMR)
102 /*
103 PURPOSE : checks whether the network colour code (ncc) is member
104 of the ncc permitted field.
105 */
106 LOCAL const UBYTE ncc_bit_mask[8] =
107 {
108 BIT_0, BIT_1, BIT_2, BIT_3,
109 BIT_4, BIT_5, BIT_6, BIT_7
110 };
111 #endif
112
113 #define NC_MODE_LEN 1
114 #define NC_RXLEV_SCELL_LEN 6
115 #define NC_IF_SCELL_LEN 6
116 #define NC_NUM_OF_MEAS_LEN 3
117 #define NC_FREQ_N_LEN 6
118 #define NC_BSIC_N_LEN 6
119 #define NC_RXLEV_N_LEN 6
120
121 #if defined (REL99) AND defined (TI_PS_FF_EMR)
122 #define BA_USED_LEN 1
123 #define BA_USED_3G_LEN 1
124 #define PSI3_CM_LEN 2
125 #define PMO_USED_LEN 1
126 #endif
127
128 #define GET_NC_RPT_PRD(x) ((0x01<<(x))*480) /* multiple of 480 ms */
129
130 #define CS_PERIOD_1_SEC 217 /* 1 second defined by */
131 /* multiplies of TDMA frames */
132 #define MAX_SYNC_FAILED_CNT 3
133
134 #if defined (REL99) AND defined (TI_PS_FF_EMR)
135 #define INRANGE(min, x, max) ((unsigned)(x-min) <= (max-min))
136 #endif
137
138 #ifdef _TARGET_
139
140 #define MIN_RXLEV_FOR_SIX_STRGST 4 /* minimum RXLEV value of neighbour cells */
141 /* which shall be considered for cell */
142 /* re-selection decision */
143 #endif /* #ifdef _TARGET_ */
144
145 #define RXLEV_ACRCY 1000
146 #define RXLEV_MAX_NBR ((T_RXLEV_DATA_NBR)(~((T_RXLEV_DATA_NBR)0)))
147 #define RXLEV_AVG_INVALID 0xFF
148
149 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
150 #define CHECK_DUAL_BANDS (std EQ STD_DUAL OR std EQ STD_DUAL_EGSM OR \
151 std EQ STD_DUAL_US OR std EQ STD_850_1800 OR \
152 std EQ STD_900_1900 OR std EQ STD_850_900_1800 OR \
153 std EQ STD_850_900_1900)
154 #endif
155
156 /*==== GLOBAL VARS ===========================================================*/
157
158 #if defined (REL99) AND defined (TI_PS_FF_EMR)
159 EXTERN BOOL use_ba_gprs;
160 #endif
161
162 /*==== LOCAL VARS ===========================================================*/
163
164 /*==== PRIVATE FUNCTIONS ====================================================*/
165
166 LOCAL void cs_trace_nc_mval_lst ( void );
167 LOCAL void cs_init_nc_mval ( T_NC_MVAL *mval );
168 LOCAL void cs_reorg_nc_mval_lst ( void );
169
170
171 LOCAL BOOL cs_build_meas_rpt ( T_U_MEAS_REPORT *u_meas_report );
172
173 LOCAL BOOL cs_process_serving_cell_data
174 ( UBYTE *rxlev_scell, UBYTE *v_i_scell,
175 UBYTE *i_scell, UBYTE *used_bits,
176 BOOL *rsc_avail, BOOL *isc_avail );
177
178 #if defined (REL99) AND defined (TI_PS_FF_EMR)
179 LOCAL void cs_build_enh_sorted_strng_arfcn_list
180 (T_ENH_STRNG_ARFCN_LIST *f_bin );
181 /*
182 LOCAL UBYTE cs_sort_arfcns_into_bins
183 ( T_ENH_STRNG_ARFCN_LIST *p_s_bin,
184 T_ENH_STRNG_ARFCN_LIST *p_m_bin,
185 T_ENH_STRNG_ARFCN_LIST *p_r_bin);*/
186 LOCAL UBYTE cs_sort_arfcns_into_bins
187 ( T_ENH_STRNG_ARFCN_LIST *p_s_bin,
188 T_ENH_STRNG_ARFCN_LIST *p_r_bin);
189 LOCAL void cs_sort_store_in_desc_order_rxlev
190 ( T_ENH_STRNG_ARFCN_LIST *p_bin,
191 T_ENH_STRNG_ARFCN_LIST *p_f_bin);
192 LOCAL BOOL cs_build_enh_meas_rpt( T_U_ENHNC_MEAS_REPORT *u_enh_meas_report );
193
194 LOCAL BOOL cs_fill_nc_enh_meas_results
195 (T_nc_meas_rep_enh *nc_meas_rep_enh);
196 LOCAL void cs_form_enh_cell_list (void );
197 LOCAL void cs_form_ba_bcch_enh_cell_list
198 (void );
199 LOCAL void cs_nc_sort_and_update_emr_info
200 (void );
201 LOCAL void cs_nc_sort_cells_into_bins
202 (T_ENH_BIN *p_sbin,T_ENH_BIN *p_mbin,
203 T_ENH_BIN *p_rbin );
204 LOCAL void cs_nc_sort_and_store_meas_results
205 (T_ENH_BIN *p_bin, UBYTE nbr_rpt );
206 LOCAL void cs_nc_update_rest_bin
207 (T_ENH_BIN *p_rbin,
208 T_ENH_BIN *p_bin, UBYTE nbr_rpt );
209 LOCAL UBYTE cs_get_band_index_for_emr
210 (USHORT arfcn);
211 LOCAL UBYTE cs_nc_scale_rxlev (void);
212 #endif
213
214 LOCAL void cs_build_nc_freq_list
215 ( T_SC_DATABASE *db );
216 LOCAL void cs_find_strongest_with_status
217 ( UBYTE *count,
218 UBYTE *index,
219 UBYTE select_status,
220 UBYTE maximum,
221 UBYTE limitation );
222 LOCAL void cs_consider_multiband
223 ( UBYTE *count,
224 UBYTE *index,
225 UBYTE select_status,
226 UBYTE maximum );
227 LOCAL BOOL cs_update_strongest ( UBYTE cnt_strgst,
228 UBYTE cnt_candid,
229 UBYTE *index,
230 ULONG fn_offset );
231 LOCAL void cs_start_t3158 ( T_TIME time );
232 LOCAL void cs_set_cnt_nc_six ( UBYTE strgst,
233 UBYTE candid );
234 LOCAL T_TIME cs_get_nc_rpt_prd_idle
235 ( void );
236
237 LOCAL void cs_copy_rxlev_from_avg( UBYTE rxlev_avg,
238 T_CELL *cell );
239 LOCAL void cs_reuse_old_cell_rxlev (void);
240 #if defined (REL99) AND defined (TI_PS_FF_EMR)
241 LOCAL void cs_build_ba_bcch_nc_freq_list ();
242 #endif
243
244 /*
245 +------------------------------------------------------------------------------
246 | Function : cs_set_cnt_nc_six
247 +------------------------------------------------------------------------------
248 | Description :
249 |
250 | Parameters :
251 |
252 +------------------------------------------------------------------------------
253 */
254 LOCAL void cs_set_cnt_nc_six ( UBYTE strgst, UBYTE candid )
255 {
256 TRACE_FUNCTION( "cs_set_cnt_nc_six" );
257
258 #if defined FF_EOTD
259 grr_data->db.cnt_nc_six.strgst = MINIMUM( CS_MAX_STRONG_CARRIER_CR, strgst );
260 #else /* #if defined FF_EOTD */
261 grr_data->db.cnt_nc_six.strgst = strgst;
262 #endif /* #if defined FF_EOTD */
263
264 grr_data->db.cnt_nc_six.candid = candid;
265
266 } /* cs_set_cnt_nc_six() */
267
268 /*
269 +------------------------------------------------------------------------------
270 | Function : cs_build_meas_rpt
271 +------------------------------------------------------------------------------
272 | Description : This function ...
273 |
274 | Parameters : u_meas_report - Pointer to measurement report
275 |
276 +------------------------------------------------------------------------------
277 */
278 LOCAL BOOL cs_build_meas_rpt ( T_U_MEAS_REPORT *u_meas_report )
279 {
280 T_NC_ORDER nc_ord = cs_get_network_ctrl_order( TRUE );
281 BOOL pbcch_present = grr_is_pbcch_present( );
282 UBYTE used_bits;
283 /* bits currently used for the measurement report */
284 UBYTE next_meas_bits = 0;
285 /* bits used for the next element of the */
286 /* measurement result list */
287 BOOL is_first_instance;
288
289 T_CS_MEAS_DATA *nmeas = &grr_data->cs_meas;
290 T_nc_meas_rep *ncmeas_rep = &u_meas_report->nc_meas_rep;
291 T_nc_meas_s1 *p_mrpt;
292 T_ncell_info *ncell;
293 T_NC_MVAL *mval;
294 UBYTE return_value;
295 BOOL rsc_avail = FALSE;
296 BOOL isc_avail = FALSE;
297 #if defined (REL99) AND defined (TI_PS_FF_EMR)
298 UBYTE psi3_cm = grr_get_psi3_cm();
299 #endif
300 TRACE_FUNCTION( "cs_build_meas_rpt" );
301
302 /* process message type */
303 used_bits = PMR_MSG_TYPE_LEN;
304 u_meas_report->msg_type = U_MEAS_REPORT_c;
305
306 /* process TLLI */
307 used_bits += PMR_TLLI_LEN;
308 grr_set_buf_tlli( &u_meas_report->tlli_value, grr_get_tlli( ) );
309
310 /* process PSI5 change mark */
311 used_bits += PMR_FLAG_LEN;
312
313 if( pbcch_present EQ FALSE OR
314 grr_data->db.nc_ref_lst.param EQ &psc_db->nc_ms.ncmeas.param )
315 {
316 u_meas_report->v_psi5_cm = FALSE;
317 }
318 else if( grr_data->db.nc_ref_lst.param EQ &psc_db->nc_cw.param )
319 {
320 used_bits += PMR_PSI5_CHNGE_MRK_LEN;
321
322 u_meas_report->v_psi5_cm = TRUE;
323 u_meas_report->psi5_cm = psc_db->psi5_params.psi5_change_mark;
324 }
325 else
326 {
327 TRACE_ERROR( "cs_build_meas_rpt no valid data set" );
328 return( FALSE );
329 }
330
331 /* process flags */
332 used_bits += PMR_FLAG_LEN;
333 u_meas_report->flag = 0;
334 u_meas_report->v_nc_meas_rep = TRUE;
335 u_meas_report->v_xmeas_rep = FALSE;
336
337 #if defined (REL99) AND defined (TI_PS_FF_EMR)
338 /*if(psc_db->network_rel NEQ BSS_NW_REL_97)*/
339 {
340 used_bits += PMR_FLAG_LEN;
341 u_meas_report->v_release_99_str_pmr = TRUE;
342
343 used_bits += PMR_FLAG_LEN;
344 u_meas_report->release_99_str_pmr.v_meas_rep_3g_str = FALSE;
345
346 used_bits += PMR_FLAG_LEN;
347 u_meas_report->release_99_str_pmr.v_ba_psi3_str = TRUE;
348
349 used_bits += PMO_IND_USED_LEN;
350 u_meas_report->release_99_str_pmr.ba_psi3_str.pmo_ind_used = psc_db->nc_ms.pmo_ind;
351
352 /* 1 bit for u_meas_report->ba_psi3_str.flag */
353 used_bits += PMR_FLAG_LEN;
354
355 /* process BA used, PSI3 change mark and PMO used */
356 if( pbcch_present EQ FALSE )
357 {
358 TRACE_EVENT_P1("pbcch_present %d", pbcch_present);
359 u_meas_report->release_99_str_pmr.ba_psi3_str.flag = FALSE;
360
361 u_meas_report->release_99_str_pmr.ba_psi3_str.v_ba_ind_used = TRUE;
362 u_meas_report->release_99_str_pmr.ba_psi3_str.v_ba_ind_used_3g = TRUE;
363
364 used_bits += PMR_BA_IND_USED_LEN;
365 u_meas_report->release_99_str_pmr.ba_psi3_str.ba_ind_used = psc_db->ba_ind;
366
367 /* Add 1 bit for ba_ind_used_3g */
368 u_meas_report->release_99_str_pmr.ba_psi3_str.ba_ind_used_3g = 0;
369 used_bits += PMR_BA_IND_USED_LEN;
370 }
371 else
372 {
373 u_meas_report->release_99_str_pmr.ba_psi3_str.flag = TRUE;
374
375 u_meas_report->release_99_str_pmr.ba_psi3_str.v_psi3_cm = TRUE;
376
377 used_bits += PMR_PSI3_CHNGE_MRK_LEN;
378 u_meas_report->release_99_str_pmr.ba_psi3_str.psi3_cm = psi3_cm;
379 }
380 }
381 #endif
382
383 /* process NC mode */
384 used_bits += NC_MODE_LEN;
385
386 switch( nc_ord )
387 {
388 case NC_NC1: ncmeas_rep->nc_mode = NCMODE_NC1; break;
389 case NC_NC2: ncmeas_rep->nc_mode = NCMODE_NC2; break;
390
391 default: TRACE_ERROR( "cs_build_meas_rpt no valid NC mode" ); return( FALSE );
392 }
393
394 /* process serving cell data - rxlev and ilev */
395
396 return_value =
397 cs_process_serving_cell_data(&ncmeas_rep->rxlev_scell,
398 &ncmeas_rep->v_i_scell,
399 &ncmeas_rep->i_scell, &used_bits,
400 &rsc_avail, &isc_avail);
401 if((return_value EQ FALSE) AND (rsc_avail EQ FALSE))
402 return(FALSE);
403
404
405 /* process NC measurement results */
406 used_bits += NC_NUM_OF_MEAS_LEN;
407 ncmeas_rep->num_nc_meas = 0;
408 ncmeas_rep->c_nc_meas_s1 = 0;
409 is_first_instance = nmeas->pmr_snd_ref EQ 0 ? TRUE : FALSE;
410
411 do
412 {
413 /* calculate estimated length of next measurement result */
414 if( nmeas->pmr_snd_ref >= grr_data->db.cnt_nc_six.candid )
415 {
416 mval = NULL;
417 ncell = NULL;
418 }
419 else
420 {
421 mval = &grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[nmeas->pmr_snd_ref].idx];
422
423 next_meas_bits = NC_FREQ_N_LEN + NC_RXLEV_N_LEN + PMR_FLAG_LEN;
424
425 if( mval->sync_info.sync.status EQ STAT_SYNC_OK )
426 {
427 UBYTE ncell_idx = 0;
428
429 ncell = grr_get_ncell_info( mval->arfcn, mval->sync_info.bsic );
430
431 while( ncell_idx < grr_data->db.nc_ref_lst.number AND
432 ncell EQ NULL )
433 {
434 ncell = grr_data->db.nc_ref_lst.info[ncell_idx];
435
436 if( ncell->arfcn NEQ mval->arfcn OR
437 NC_GET_TYPE( ncell->info_src ) NEQ INFO_TYPE_BA_BCCH )
438 {
439 ncell = NULL;
440 }
441
442 ncell_idx++;
443 }
444
445 if( ncell NEQ NULL )
446 {
447 next_meas_bits = NC_FREQ_N_LEN + NC_RXLEV_N_LEN + PMR_FLAG_LEN;
448
449 if( NC_GET_TYPE( ncell->info_src ) EQ INFO_TYPE_BA_BCCH )
450 {
451 next_meas_bits += NC_BSIC_N_LEN;
452 }
453 }
454 }
455 else
456 {
457 ncell = NULL;
458 }
459 }
460
461 if( ncell NEQ NULL AND mval NEQ NULL)
462 {
463 if( BIT_UL_CTRL_BLOCK_CONTENTS - used_bits >= next_meas_bits )
464 {
465 /* copy next measurement result to measurement report */
466
467 ncmeas_rep->num_nc_meas++;
468 ncmeas_rep->c_nc_meas_s1++;
469 used_bits += next_meas_bits;
470 p_mrpt = &ncmeas_rep->nc_meas_s1[ncmeas_rep->c_nc_meas_s1 - 1];
471
472 p_mrpt->freq_n = ncell->index;
473 p_mrpt->rxlev_n = mval->rxlev_avg;
474
475 if( NC_GET_TYPE( ncell->info_src ) EQ INFO_TYPE_BA_BCCH )
476 {
477 p_mrpt->bsic = mval->sync_info.bsic;
478 p_mrpt->v_bsic = TRUE;
479 }
480 else
481 {
482 p_mrpt->v_bsic = FALSE;
483 }
484
485 nmeas->pmr_snd_ref++;
486 }
487 else
488 {
489 mval = NULL;
490 }
491 }
492 else
493 {
494 nmeas->pmr_snd_ref++;
495 }
496
497 }
498 while( mval NEQ NULL );
499
500 return( is_first_instance OR ncmeas_rep->num_nc_meas );
501
502
503 } /* cs_build_meas_rpt() */
504
505 /*
506 +------------------------------------------------------------------------------
507 | Function : cs_is_meas_reporting
508 +------------------------------------------------------------------------------
509 | Description : This function ...
510 |
511 | Parameters : ...
512 |
513 +------------------------------------------------------------------------------
514 */
515 GLOBAL UBYTE cs_is_meas_reporting ( void )
516 {
517 T_NC_ORDER ctrl_order = cs_get_network_ctrl_order( TRUE );
518
519 TRACE_FUNCTION( "cs_is_meas_reporting" );
520
521 return( ctrl_order EQ NC_NC1 OR ctrl_order EQ NC_NC2 );
522
523 } /* cs_is_meas_reporting() */
524
525 #if defined (REL99) AND defined (TI_PS_FF_EMR)
526 /*
527 +------------------------------------------------------------------------------
528 | Function : cs_is_enh_meas_reporting
529 +------------------------------------------------------------------------------
530 | Description : This function is used to check whether enhanced measurement
531 | reporting is to be done.
532 |
533 | Parameters : returns TRUE if ENH reporting is to be done
534 |
535 +------------------------------------------------------------------------------
536 */
537 GLOBAL BOOL cs_is_enh_meas_reporting ( void )
538 {
539 BOOL return_value = FALSE;
540
541 TRACE_FUNCTION( "cs_is_enh_meas_reporting" );
542
543 if ( cs_is_meas_reporting() AND
544 (grr_data->db.nc_ref_lst.enh_param->rept_type EQ REPORT_TYPE_ENH_REP) )
545 {
546 return_value = TRUE;
547 }
548
549 return( return_value );
550 } /* cs_is_enh_meas_reporting() */
551 #endif
552
553 /*
554 +------------------------------------------------------------------------------
555 | Function : cs_build_nc_freq_list
556 +------------------------------------------------------------------------------
557 | Description :
558 |
559 | Parameters : db - pointer to serving cell database
560 |
561 +------------------------------------------------------------------------------
562 */
563 LOCAL void cs_build_nc_freq_list ( T_SC_DATABASE *db )
564 {
565 UBYTE i, j, k; /* used for counting */
566 UBYTE act_idx; /* index of actual processed reference list entry */
567 BOOL is_removed;
568 BOOL is_overwritten;
569
570 T_ncell_info *info_ref_lst;
571 T_ncell_info *info_prev = ( db->nc_cw.list.number EQ 0 ?
572 NULL :
573 &db->nc_cw.list.info[db->nc_cw.list.number-1] );
574 T_ncell_info *info_curr;
575 T_INFO_SRC info_src = 0;
576
577 TRACE_FUNCTION( "cs_build_nc_freq_list" );
578
579 /*
580 * add neighbour cell information of BA(GPRS) to reference list
581 * in case they are not removed
582 */
583 for( i = 0; i < db->nc_cw.list.number; i++ )
584 {
585 /*
586 * looking for entry with correct index,
587 * they are no longer sorted with increasing number
588 */
589 k = 0;
590
591 while( k < db->nc_cw.list.number AND i NEQ db->nc_cw.list.info[k].index )
592 {
593 k++;
594 }
595
596 if( db->nc_cw.list.info[k].arfcn EQ psc_db->pbcch.bcch.arfcn )
597 {
598 /* remove the serving cell from the neighbour cell reference list */
599 is_removed = TRUE;
600 }
601 else
602 {
603 for( j = 0, is_removed = FALSE;
604 j < db->nc_ms.rfreq.number AND is_removed EQ FALSE;
605 j++ )
606 {
607 if( db->nc_cw.list.info[k].index EQ db->nc_ms.rfreq.idx[j] )
608 {
609 is_removed = TRUE;
610 }
611 }
612 }
613
614 if( is_removed EQ FALSE )
615 {
616 if( !( db->nc_cw.list.info[k].v_cr_par EQ FALSE AND
617 NC_GET_TYPE( db->nc_cw.list.info[k].info_src ) NEQ INFO_TYPE_BA_BCCH AND
618 cs_get_network_ctrl_order( TRUE ) NEQ NC_NC2 )
619 AND
620 !( db->nc_cw.list.info[k].cr_par.cell_ba ) )
621 {
622 grr_data->db.nc_ref_lst.info[grr_data->db.nc_ref_lst.number] =
623 &db->nc_cw.list.info[k];
624 grr_data->db.nc_ref_lst.number++;
625 }
626 else
627 {
628
629 #if !defined (NTRACE)
630
631 if( grr_data->cs.v_crp_trace EQ TRUE )
632 {
633 TRACE_EVENT_P2( "cs_build_nc_freq_list 1: not added to NC_REF_LST %d %d",
634 db->nc_cw.list.info[k].arfcn, db->nc_cw.list.info[k].bsic );
635 }
636
637 #endif /* #if !defined (NTRACE) */
638
639 }
640 }
641 else
642 {
643
644 #if !defined (NTRACE)
645
646 if( grr_data->cs.v_crp_trace EQ TRUE )
647 {
648 TRACE_EVENT_P2( "cs_build_nc_freq_list 2: not added to NC_REF_LST %d %d",
649 db->nc_cw.list.info[k].arfcn, db->nc_cw.list.info[k].bsic );
650 }
651
652 #endif /* #if !defined (NTRACE) */
653
654
655 }
656 }
657
658 /*
659 * add/overwrite neighbour cell information to/of reference list
660 */
661 i = 0;
662
663 while( ( info_curr = grr_get_next_bigger_ncell_param
664 ( &db->nc_ms.ncmeas.list, info_src ) ) NEQ NULL )
665 {
666 j = 0;
667 is_overwritten = FALSE;
668
669 while( j < grr_data->db.nc_ref_lst.number AND is_overwritten EQ FALSE )
670 {
671 info_ref_lst = grr_data->db.nc_ref_lst.info[j];
672
673 if( NC_GET_TYPE( info_ref_lst->info_src ) NEQ INFO_TYPE_BA_BCCH AND
674 info_ref_lst->v_cr_par EQ TRUE AND
675 info_curr->v_cr_par EQ TRUE AND
676 info_ref_lst->bsic EQ info_curr->bsic AND
677 info_ref_lst->arfcn EQ info_curr->arfcn )
678 {
679 is_overwritten = TRUE;
680 }
681 else
682 {
683 j++;
684 }
685 }
686
687 /*
688 * calculate the index of the reference list entry
689 * which shall be used for further processing
690 */
691 if( is_overwritten EQ FALSE )
692 {
693 if( grr_data->db.nc_ref_lst.number < MAX_NR_OF_NCELL )
694 {
695 act_idx = grr_data->db.nc_ref_lst.number;
696 }
697 else
698 {
699 TRACE_ERROR( "cs_build_nc_freq_list: reference list full" );
700 return;
701 }
702 }
703 else
704 {
705 act_idx = j;
706 }
707
708
709 if(
710 !( info_curr->v_cr_par EQ FALSE AND
711 NC_GET_TYPE( info_curr->info_src ) NEQ INFO_TYPE_BA_BCCH AND
712 cs_get_network_ctrl_order( TRUE ) NEQ NC_NC2 )
713 AND
714 !( info_curr->cr_par.cell_ba )
715 AND
716 ( info_curr->arfcn NEQ psc_db->pbcch.bcch.arfcn )
717 )
718 {
719 /*
720 * add/overwrite reference list entry
721 */
722 grr_data->db.nc_ref_lst.info[act_idx] = info_curr;
723 grr_data->db.nc_ref_lst.number++;
724
725 /* process cell selection parameter */
726 grr_restore_cs_param
727 ( info_curr, info_prev, (UBYTE)( db->nc_cw.list.number + i ) );
728
729
730 if( info_curr->v_cr_par EQ TRUE )
731 {
732 info_prev = info_curr;
733 }
734 }
735 else
736 {
737
738 #if !defined (NTRACE)
739
740 if( grr_data->cs.v_crp_trace EQ TRUE )
741 {
742 TRACE_EVENT_P2( "cs_build_nc_freq_list 3: not added to NC_REF_LST %d %d",
743 info_curr->arfcn, info_curr->bsic );
744 }
745
746 #endif /* #if !defined (NTRACE) */
747
748 info_curr->index = db->nc_cw.list.number + i;
749 }
750
751 info_src = info_curr->info_src;
752
753 i++;
754 }
755
756 #if !defined (NTRACE)
757
758 if( grr_data->cs.v_crp_trace EQ TRUE )
759 {
760 UBYTE read;
761 USHORT crp_s;
762 ULONG crp[4];
763 T_ncell_info *info;
764
765 crp[0] = ( ( ULONG )psc_db->pbcch.bcch.arfcn << 16 );
766 crp[0] |= ( ( ULONG )psc_db->pbcch.bcch.bsic << 8 );
767 crp[0] |= ( ULONG )psc_db->scell_par.cell_ba;
768
769 crp[1] = ( ( ULONG )psc_db->scell_par.exc_acc << 24 );
770 crp[1] |= ( ( ULONG )psc_db->scell_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min << 16 );
771 crp[1] |= ( ( ULONG )psc_db->scell_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch << 8 );
772
773 if( psc_db->scell_par.cr_par_1.v_hcs_par )
774 {
775 crp[1] |= ( ULONG )psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class;
776 crp_s = ( ( USHORT )psc_db->scell_par.cr_par_1.hcs_par.gprs_hcs_thr << 8 );
777 }
778 else
779 {
780 crp[1] |= ( ULONG )0xFF;
781 crp_s = ( ( USHORT )0xFF << 8 );
782 }
783
784 crp_s |= ( ULONG )psc_db->scell_par.multi_band_rep;
785
786 TRACE_EVENT_P3( "SCELL %08X%08X%04X", crp[0], crp[1], crp_s );
787
788 for( read = 0; read < grr_data->db.nc_ref_lst.number; read++ )
789 {
790 info = grr_data->db.nc_ref_lst.info[read];
791
792 crp[0] = ( ( ULONG )info->arfcn << 16 );
793 crp[0] |= ( ( ULONG )info->bsic << 8 );
794
795 if( info->v_cr_par )
796 {
797 crp[0] |= ( ULONG )info->cr_par.cell_ba;
798
799 crp[1] = ( ( ULONG )info->cr_par.exc_acc << 24 );
800 crp[1] |= ( ( ULONG )info->cr_par.same_ra_scell << 16 );
801 crp[1] |= ( ( ULONG )info->cr_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min << 8 );
802 crp[1] |= ( ULONG )info->cr_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch;
803
804 crp[2] = ( ( ULONG )info->cr_par.cr_offset.gprs_temp_offset << 24 );
805 crp[2] |= ( ( ULONG )info->cr_par.cr_offset.gprs_penalty_time << 16 );
806 crp[2] |= ( ( ULONG )info->cr_par.gprs_resel_off << 8 );
807
808 if( grr_data->db.nc_ref_lst.info[read]->cr_par.cr_par_1.v_hcs_par )
809 {
810 crp[2] |= ( ULONG )info->cr_par.cr_par_1.hcs_par.gprs_prio_class;
811 crp[3] = ( ( ULONG )info->cr_par.cr_par_1.hcs_par.gprs_hcs_thr << 24 );
812 }
813 else
814 {
815 crp[2] |= ( ULONG )0xFF;
816 crp[3] = ( ( ULONG )0xFF << 24 );
817 }
818
819 if( info->cr_par.v_si13_pbcch )
820 {
821 if( info->cr_par.si13_pbcch.v_si13_location )
822 {
823 crp[3] |= ( ( ULONG )info->cr_par.si13_pbcch.si13_location << 16 );
824 crp[3] |= ( ( ULONG )0xFF << 8 );
825 crp[3] |= ( ULONG )0xFF;
826 }
827 else
828 {
829 crp[3] |= ( ( ULONG )0xFF << 16 );
830 crp[3] |= ( ( ULONG )info->cr_par.si13_pbcch.pbcch_location << 8 );
831 crp[3] |= ( ULONG )info->cr_par.si13_pbcch.psi1_repeat_period;
832 }
833 }
834 else
835 {
836 crp[3] |= ( ULONG )0xFFFFFF;
837 }
838 }
839 else
840 {
841 crp[1] |= ( ULONG )0xFF;
842 crp[2] = ( ULONG )0xFFFFFFFF;
843 crp[3] = ( ULONG )0xFFFFFFFF;
844 }
845
846 TRACE_EVENT_P5( "NC_REF_LST[%d] %08X%08X%08X%08X",
847 read, crp[0], crp[1], crp[2], crp[3] );
848 }
849 }
850
851 #endif /* #if !defined (NTRACE) */
852
853 }/* cs_build_nc_freq_list */
854
855 /*
856 +------------------------------------------------------------------------------
857 | Function : cs_reorg_nc_mval_lst
858 +------------------------------------------------------------------------------
859 | Description :
860 |
861 | Parameters :
862 |
863 +------------------------------------------------------------------------------
864 */
865 LOCAL void cs_reorg_nc_mval_lst ( void )
866 {
867 BOOL scell_restored = FALSE;
868 UBYTE mval_idx;
869 UBYTE nc_idx;
870 T_NC_MVAL *nc_mval;
871 T_ncell_info *ncell_info;
872
873 TRACE_FUNCTION( "cs_reorg_nc_mval_lst" );
874
875 for( mval_idx = 0; mval_idx < MAX_NR_OF_NC_MVAL; mval_idx++ )
876 {
877 /*
878 * check whether measured values can be reused
879 */
880
881 nc_mval = &grr_data->db.nc_mval_list.nc_mval[mval_idx];
882
883 if( nc_mval->status NEQ NC_MVAL_STAT_NONE )
884 {
885 /*
886 * only used entries shall be considered
887 */
888
889 if( psc_db->pbcch.bcch.arfcn EQ nc_mval->arfcn AND
890 psc_db->pbcch.bcch.arfcn NEQ RRGRR_INVALID_ARFCN )
891 {
892 /*
893 * remove the measured values from the serving cell,
894 * this cell will not be used for cell re-selection
895 */
896 cs_init_nc_mval( nc_mval );
897 }
898 else
899 {
900 ncell_info = grr_get_ncell_info( nc_mval->arfcn, RRGRR_INVALID_BSIC );
901
902 if( ncell_info EQ NULL )
903 {
904 /*
905 * cell is not on the neighbor cell list,
906 * keep the measured values until RR informs GRR,
907 * but do not use them
908 */
909 nc_mval->status = NC_MVAL_STAT_PENDING;
910 nc_mval->rla_p.stat = CS_RLA_P_NOT_AVAIL;
911 }
912 else
913 {
914 /*
915 * cell is on the neighbor cell list,
916 * re-activate the measured values
917 */
918 nc_mval->status = NC_MVAL_STAT_ASSIGNED;
919 }
920
921 if( grr_data->db.old_scell.arfcn EQ nc_mval->arfcn AND
922 grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN )
923 {
924 /*
925 * in case the old serving cell is on the measured values list,
926 * keep the results for further use
927 */
928 scell_restored = TRUE;
929
930 nc_mval->sync_info.bsic = grr_data->db.old_scell.bsic;
931 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
932 nc_mval->sync_info.sync.sync_failed_cnt = 0;
933 }
934 }
935 }
936 }
937
938 for( nc_idx = 0; nc_idx < grr_data->db.nc_ref_lst.number; nc_idx++ )
939 {
940 nc_mval = grr_get_nc_mval( grr_data->db.nc_ref_lst.info[nc_idx]->arfcn,
941 RRGRR_INVALID_BSIC, &mval_idx );
942
943 if( nc_mval EQ NULL )
944 {
945 nc_mval =
946 grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &mval_idx );
947
948 if( nc_mval NEQ NULL )
949 {
950 nc_mval->status = NC_MVAL_STAT_ASSIGNED;
951 nc_mval->arfcn = grr_data->db.nc_ref_lst.info[nc_idx]->arfcn;
952
953 if( grr_data->db.old_scell.arfcn EQ nc_mval->arfcn AND
954 grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN )
955 {
956 scell_restored = TRUE;
957
958 nc_mval->sync_info.bsic = grr_data->db.old_scell.bsic;
959 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
960 nc_mval->sync_info.sync.sync_failed_cnt = 0;
961
962 TRACE_EVENT_P2( "cs_reorg_nc_mval_lst: old SCELL on new NCELL list (1) %d %d",
963 grr_data->db.nc_ref_lst.info[nc_idx]->arfcn,
964 grr_data->db.nc_ref_lst.info[nc_idx]->bsic );
965 }
966 }
967 else
968 {
969 TRACE_EVENT_P1( "cs_reorg_nc_mval_lst: nc_mval EQ NULL (1) %d",
970 RRGRR_INVALID_ARFCN );
971 }
972 }
973 else
974 {
975 if( grr_data->db.old_scell.arfcn EQ nc_mval->arfcn AND
976 grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN )
977 {
978 scell_restored = TRUE;
979
980 nc_mval->status = NC_MVAL_STAT_ASSIGNED;
981 nc_mval->sync_info.bsic = grr_data->db.old_scell.bsic;
982 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
983 nc_mval->sync_info.sync.sync_failed_cnt = 0;
984
985 TRACE_EVENT_P2( "cs_reorg_nc_mval_lst: old SCELL on new NCELL list (2) %d %d",
986 grr_data->db.nc_ref_lst.info[nc_idx]->arfcn,
987 grr_data->db.nc_ref_lst.info[nc_idx]->bsic );
988 }
989 }
990 }
991
992 if( scell_restored EQ FALSE AND
993 grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN )
994 {
995 nc_mval =
996 grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &mval_idx );
997
998 if( nc_mval NEQ NULL )
999 {
1000 nc_mval->status = NC_MVAL_STAT_PENDING;
1001 nc_mval->arfcn = grr_data->db.old_scell.arfcn;
1002 nc_mval->sync_info.bsic = grr_data->db.old_scell.bsic;
1003 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
1004 nc_mval->sync_info.sync.sync_failed_cnt = 0;
1005 }
1006 else
1007 {
1008 TRACE_EVENT_P1( "cs_reorg_nc_mval_lst: nc_mval EQ NULL (2) %d",
1009 RRGRR_INVALID_ARFCN );
1010 }
1011 }
1012
1013 grr_data->cs.is_mval_initialized = FALSE;
1014
1015 cs_trace_nc_mval_lst( );
1016
1017 }/* cs_reorg_nc_mval_lst */
1018
1019 /*==== PUBLIC FUNCTIONS =====================================================*/
1020 /*
1021 +------------------------------------------------------------------------------
1022 | Function : cs_grr_init
1023 +------------------------------------------------------------------------------
1024 | Description : The function cs_grr_init() .... name change becauce there is a
1025 | function in cs_init in TIL.
1026 |
1027 | Parameters : void
1028 |
1029 +------------------------------------------------------------------------------
1030 */
1031 GLOBAL void cs_grr_init ( void )
1032 {
1033 TRACE_FUNCTION( "cs_grr_init" );
1034
1035 grr_data->cs.gmm_state = STANDBY_STATE;
1036 grr_data->cs.last_cr = 0;
1037 grr_data->cs.reselect_cause = CS_RESELECT_CAUSE_CS_NORMAL;
1038 grr_data->cs.is_mval_initialized = FALSE;
1039 grr_data->cs.nc_sync_rep_pd = 0;
1040
1041 #if !defined (NTRACE)
1042
1043 grr_data->cs.v_crp_trace = FALSE;
1044
1045 #endif /* #if !defined (NTRACE) */
1046
1047 grr_init_ncmeas_extd_struct( &psc_db->nc_ms, FALSE );
1048 cs_init_nc_ref_list( &grr_data->db.nc_ref_lst );
1049 cs_init_nc_mval_lst( );
1050
1051 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1052 /* Initialize Enhanced Measurement parameters and list */
1053 grr_init_enh_param(&psc_db->enh_ms, TRUE);
1054 grr_init_enh_cell_list();
1055 #endif
1056
1057 grr_data->cs_meas.pmr_snd_ref = 0;
1058 grr_data->cs_meas.packet_mode = PACKET_MODE_NULL;
1059
1060 nc_data = &grr_data->nc_data;
1061
1062 cs_reset_all_cell_results( );
1063
1064 grr_data->cs.list_id = 0;
1065 grr_data->cs.stop_req = FALSE;
1066
1067 nc_data->c_cell = 0;
1068
1069 grr_data->cs.cr_meas_mode = CS_CRMM_BA_GPRS;
1070 grr_data->cs.cr_meas_update = FALSE;
1071 grr_data->cs.last_assignment_id = 0;
1072
1073
1074 INIT_STATE( CS_MEAS, CS_MEAS_NULL );
1075 INIT_STATE( CS, CS_NULL );
1076 } /* cs_grr_init() */
1077
1078 /*
1079 +------------------------------------------------------------------------------
1080 | Function : cs_process_cc_order
1081 +------------------------------------------------------------------------------
1082 | Description : The function cs_process_cc_order() ....
1083 |
1084 | Parameters : d_cell_chan_order - Pointer to packet cell change order message
1085 |
1086 +------------------------------------------------------------------------------
1087 */
1088 GLOBAL void cs_process_cc_order ( T_nc_meas_par *nc_meas_par,
1089 UBYTE v_nc_freq_list,
1090 T_nc_freq_list *nc_freq_list
1091 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1092 , UBYTE v_enh_meas_param_pcco,
1093 T_enh_meas_param_pcco *enh_meas_param_pcco
1094 #endif
1095 )
1096 {
1097 TRACE_FUNCTION( "cs_process_cc_order" );
1098
1099 grr_init_ncmeas_extd_struct( &pcr_db->nc_ms, FALSE );
1100
1101 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1102 /* Initialize Enhanced Measurement parameters */
1103 grr_init_enh_param(&pcr_db->enh_ms, TRUE);
1104 #endif
1105
1106 /*
1107 * process the NC measurement parameter
1108 *
1109 * only one instance of PCCO, store data in final location
1110 */
1111 grr_prcs_nc_param_struct ( &pcr_db->nc_ms.ncmeas.param,
1112 nc_meas_par,
1113 0 );
1114
1115 /* For PCCO the paramater obtained in PCCO should be applied immediately
1116 Sec 5.6.1 Spec 4.60 */
1117 grr_data->db.nc_ref_lst.param = &pcr_db->nc_ms.ncmeas.param;
1118
1119 /*
1120 * process NC_FREQUENCY_LIST
1121 *
1122 * only one instance of PCCO, store data in final location
1123 */
1124 grr_prcs_nc_freq_list ( &pcr_db->nc_ms.ncmeas.list,
1125 &pcr_db->nc_ms.rfreq,
1126 v_nc_freq_list,
1127 nc_freq_list,
1128 INFO_TYPE_PCCO,
1129 0 );
1130
1131 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1132 /*
1133 * process the ENH measurement parameter
1134 *
1135 * only one instance of PCCO, store data in final location
1136 */
1137 if(v_enh_meas_param_pcco)
1138 {
1139 grr_prcs_enh_param_pcco ( pcr_db, enh_meas_param_pcco );
1140 }
1141 #endif
1142
1143 } /* cs_process_cc_order() */
1144
1145 /*
1146 +------------------------------------------------------------------------------
1147 | Function : cs_calc_cr_criterion
1148 +------------------------------------------------------------------------------
1149 | Description : The function cs_calc_cr_criterion() ....
1150 |
1151 | Parameters : dummy - description of parameter dummy
1152 |
1153 +------------------------------------------------------------------------------
1154 */
1155 GLOBAL void cs_calc_cr_criterion ( T_CR_CRITERIONS *cr_crit,
1156 USHORT arfcn,
1157 T_rla_p *rla_p,
1158 T_CR_PAR_1 *cr_par_1 )
1159 {
1160 T_MS_PWR_CAP mspc;
1161 SHORT A, B;
1162
1163 TRACE_FUNCTION( "cs_calc_cr_criterion" );
1164
1165 /* C1 = A - MAX(B,0) */
1166 /* A = RLA_P - GPRS_RXLEV_ACCESS_MIN */
1167 /* B = GPRS_MS_TXPWR_MAX_CCH - P */
1168 /* P = max MS RF output power */
1169
1170 /* C31 = RLA_P(s) - HCS_THR(s) (serving cell) */
1171 /* C31 = RLA_P(n) - HCS_THR(n) - TO(n)*L(n) (neighbour cell) */
1172 /* TO(n) = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) ) */
1173 /* L(n) = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1174 /* 1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1175
1176 /* C32(s) = C1(s) */
1177 /* C32(n) = C1(n) + GPRS_RESELECT OFFSET(n) - TO(n)*(1-L(n)) */
1178 /* TO(n) = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) ) */
1179 /* L(n) = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1180 /* 1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1181 /* H(n) = 0 for x < 0 */
1182 /* 1 for x >= 0 */
1183 /* T(n) = ????? */
1184
1185 grr_get_ms_pwr_cap( arfcn, grr_data->meas.pwr_offset, &mspc );
1186
1187 /*
1188 * calculate cell re-selection criteria acc. GSM05.08,
1189 * chapter 10.1.2 for the serving/neighbour cell
1190 */
1191
1192 /* intermediate results for serving/neighbour cell */
1193 A = (SHORT)rla_p->lev - (SHORT)cr_par_1->cr_pow_par.gprs_rxlev_access_min;
1194 B = mspc.p_control[cr_par_1->cr_pow_par.gprs_ms_txpwr_max_cch] - mspc.p[mspc.ms_power];
1195
1196 /* path loss criterion for serving/neighbour cell */
1197 cr_crit->c1 = A - MAXIMUM( B, 0 );
1198
1199 /* signal threshold criterion for serving/neighbour cell */
1200 cr_crit->c31 = ( SHORT )rla_p->lev;
1201
1202 if( cr_par_1->v_hcs_par )
1203 {
1204 cr_crit->c31 -= ( 2 * cr_par_1->hcs_par.gprs_hcs_thr );
1205 }
1206
1207 /* cell ranking criterion for serving/neighbour cell */
1208 cr_crit->c32 = cr_crit->c1;
1209
1210 } /* cs_calc_cr_criterion() */
1211
1212 /*
1213 +------------------------------------------------------------------------------
1214 | Function : cs_calc_params
1215 +------------------------------------------------------------------------------
1216 | Description : The function cs_calc_params() ....
1217 |
1218 | Parameters : dummy - description of parameter dummy
1219 |
1220 +------------------------------------------------------------------------------
1221 */
1222 GLOBAL void cs_calc_params ( void )
1223 {
1224 BOOL prio_cr = FALSE;
1225 UBYTE h;
1226 UBYTE i, prios, prion, strgst = 0xFF;
1227 T_ncell_info *ncell_info;
1228 T_NC_MVAL *nc_mval;
1229
1230 TRACE_FUNCTION( "cs_calc_params" );
1231
1232 /* C1 = A - MAX(B,0) */
1233 /* A = RLA_P - GPRS_RXLEV_ACCESS_MIN */
1234 /* B = GPRS_MS_TXPWR_MAX_CCH - P */
1235 /* P = max MS RF output power */
1236
1237 /* C31 = RLA_P(s) - HCS_THR(s) (serving cell) */
1238 /* C31 = RLA_P(n) - HCS_THR(n) - TO(n)*L(n) (neighbour cell) */
1239 /* TO(n) = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) ) */
1240 /* L(n) = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1241 /* 1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1242
1243 /* C32(s) = C1(s) */
1244 /* C32(n) = C1(n) + GPRS_RESELECT OFFSET(n) - TO(n)*(1-L(n)) */
1245 /* TO(n) = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) ) */
1246 /* L(n) = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1247 /* 1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s) */
1248 /* H(n) = 0 for x < 0 */
1249 /* 1 for x >= 0 */
1250 /* T(n) = ????? */
1251
1252 cs_calc_cr_criterion( &grr_data->db.scell_info.cr_crit,
1253 psc_db->pbcch.bcch.arfcn,
1254 &grr_data->db.scell_info.rla_p,
1255 &psc_db->scell_par.cr_par_1 );
1256
1257 /* priority class for serving cell */
1258 prios = ( psc_db->scell_par.cr_par_1.v_hcs_par ) ?
1259 psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class : 0;
1260
1261 /*
1262 * calculate cell re-selection criteria acc. GSM05.08,
1263 * chapter 10.1.2 for the neighbour cells
1264 */
1265 for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
1266 {
1267 h = FALSE;
1268 nc_mval = &grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx];
1269
1270 if( nc_mval->sync_info.sync.status EQ STAT_SYNC_OK )
1271 {
1272 ncell_info =
1273 grr_get_ncell_info( nc_mval->arfcn, nc_mval->sync_info.bsic );
1274
1275 if( ncell_info NEQ NULL )
1276 {
1277 cs_calc_cr_criterion( &grr_data->db.nc_six_strgst[i].cr_crit,
1278 ncell_info->arfcn,
1279 &nc_mval->rla_p,
1280 &ncell_info->cr_par.cr_par_1 );
1281
1282 /* cell ranking criterion for neighbour cell, add GPRS_RESELECT_OFFSET */
1283
1284 /*
1285 * if the parameter C32_QUAL is set, positive GPRS_RESELECT_OFFSET values
1286 * shall only be applied to the neighbour cell with the highest RLA_P value
1287 * of those cells for which C32 is compared.
1288 *
1289 * calculation part 1
1290 */
1291 if( psc_db->gen_cell_par.c32_qual EQ FALSE OR
1292 p_res_off[ncell_info->cr_par.gprs_resel_off] < 0 )
1293 {
1294 grr_data->db.nc_six_strgst[i].cr_crit.c32 +=
1295 p_res_off[ncell_info->cr_par.gprs_resel_off];
1296 }
1297
1298 /* priority class of neighbour cell */
1299 prion = ( ncell_info->cr_par.cr_par_1.v_hcs_par ) ?
1300 ncell_info->cr_par.cr_par_1.hcs_par.gprs_prio_class : 0;
1301
1302 /* check whether GPRS_TEMPORARY_OFFSET shall be considered */
1303 if( (ULONG)( ( ncell_info->cr_par.cr_offset.gprs_penalty_time + 1 ) *
1304 10 * CS_PERIOD_1_SEC ) > grr_data->db.nc_six_strgst[i].avail_time )
1305 {
1306 h = TRUE;
1307 }
1308
1309 /*
1310 * cell ranking and signal threshold criterion for neighbour cell,
1311 * subtract GPRS_TEMPORARY_OFFSET
1312 */
1313 if( h )
1314 {
1315 SHORT *criterion;
1316
1317 if( prios NEQ prion )
1318 {
1319 criterion = &grr_data->db.nc_six_strgst[i].cr_crit.c31;
1320 }
1321 else
1322 {
1323 criterion = &grr_data->db.nc_six_strgst[i].cr_crit.c32;
1324 }
1325
1326 if( ncell_info->cr_par.cr_offset.gprs_temp_offset EQ
1327 GPRS_TEMPORARY_OFFSET_INFINITY )
1328 {
1329 *criterion = CS_SMALLEST_SHORT_VALUE;
1330 }
1331 else
1332 {
1333 *criterion -= 10 * ncell_info->cr_par.cr_offset.gprs_temp_offset;
1334 }
1335 }
1336
1337 /*
1338 * cell ranking and signal threshold criterion for neighbour cell,
1339 * subtract RA_RESELECT_HYSTERESIS and/or GPRS_CELL_RESELECT_HYSTERESIS
1340 */
1341 if( !ncell_info->cr_par.same_ra_scell )
1342 {
1343 grr_data->db.nc_six_strgst[i].cr_crit.c32 -=
1344 2 * psc_db->gen_cell_par.ra_re_hyst;
1345 }
1346 else if( grr_data->cs.gmm_state NEQ STANDBY_STATE )
1347 {
1348 grr_data->db.nc_six_strgst[i].cr_crit.c32 -=
1349 2 * psc_db->gen_cell_par.gprs_c_hyst;
1350
1351 if( psc_db->gen_cell_par.c31_hyst )
1352 {
1353 grr_data->db.nc_six_strgst[i].cr_crit.c31 -=
1354 2 * psc_db->gen_cell_par.gprs_c_hyst;
1355 }
1356 }
1357
1358 /*
1359 * in case a cell re-selection occured within the
1360 * previous 15 seconds, subtract 5 dB
1361 */
1362 if(grr_t_status( T15_SEC_CC ) > 0)
1363 {
1364 grr_data->db.nc_six_strgst[i].cr_crit.c32 -= 5;
1365 }
1366 }
1367 else
1368 {
1369 grr_data->db.nc_six_strgst[i].cr_crit.c1 = -2;
1370 grr_data->db.nc_six_strgst[i].cr_crit.c31 = -2;
1371 grr_data->db.nc_six_strgst[i].cr_crit.c32 = -2;
1372 }
1373 }
1374 else
1375 {
1376 grr_data->db.nc_six_strgst[i].cr_crit.c1 = -1;
1377 grr_data->db.nc_six_strgst[i].cr_crit.c31 = -1;
1378 grr_data->db.nc_six_strgst[i].cr_crit.c32 = -1;
1379 }
1380 }
1381
1382 /*
1383 * calculate the correct neighbour cell for adding positive
1384 * GPRS_RESELECT_OFFSET values to C32 in case C32_QUAL is set
1385 */
1386 if( psc_db->gen_cell_par.c32_qual EQ TRUE )
1387 {
1388 /*
1389 * check whether priorized cell re-selection should be performed
1390 */
1391 for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
1392 {
1393 if( grr_data->db.nc_six_strgst[i].cr_crit.c31 >= 0 )
1394 {
1395 prio_cr = TRUE;
1396 }
1397 }
1398
1399 if( grr_data->db.scell_info.cr_crit.c31 >= 0 )
1400 {
1401 prio_cr = TRUE;
1402 }
1403
1404 /* find out the strongest neighbour cell */
1405 for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
1406 {
1407 if( ( prio_cr AND grr_data->db.nc_six_strgst[i].cr_crit.c31 >= 0 ) OR
1408 ( !prio_cr ) )
1409 {
1410 if( strgst EQ 0xFF OR
1411 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].rla_p.lev >
1412 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[strgst].idx].rla_p.lev )
1413 {
1414 strgst = i;
1415 }
1416 }
1417 }
1418
1419 if( strgst NEQ 0xFF )
1420 {
1421 nc_mval = &grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[strgst].idx];
1422
1423 if( nc_mval->sync_info.sync.status EQ STAT_SYNC_OK )
1424 {
1425 ncell_info =
1426 grr_get_ncell_info( nc_mval->arfcn, nc_mval->sync_info.bsic );
1427
1428 if( ncell_info NEQ NULL )
1429 {
1430 /*
1431 * if the parameter C32_QUAL is set, positive GPRS_RESELECT_OFFSET values
1432 * shall only be applied to the neighbour cell with the highest RLA_P value
1433 * of those cells for which C32 is compared.
1434 *
1435 * calculation part 2
1436 */
1437
1438 if( p_res_off[ncell_info->cr_par.gprs_resel_off] > 0 )
1439 {
1440 grr_data->db.nc_six_strgst[strgst].cr_crit.c32 +=
1441 p_res_off[ncell_info->cr_par.gprs_resel_off];
1442 }
1443 }
1444 }
1445 }
1446 }
1447
1448 /*
1449 * perform some tracing
1450 */
1451
1452 #if !defined (NTRACE)
1453
1454 if( grr_data->cs.v_crp_trace EQ TRUE )
1455 {
1456 /* trace the C1 criterion */
1457 for( i = grr_data->db.cnt_nc_six.strgst; i < CS_MAX_STRONG_CARRIER; i++ )
1458 {
1459 grr_data->db.nc_six_strgst[i].cr_crit.c1 = 0;
1460 }
1461
1462 TRACE_EVENT_P7
1463 (
1464 "C1 : %6d %6d %6d %6d %6d %6d %6d",
1465 grr_data->db.scell_info.cr_crit.c1,
1466 grr_data->db.nc_six_strgst[0].cr_crit.c1,
1467 grr_data->db.nc_six_strgst[1].cr_crit.c1,
1468 grr_data->db.nc_six_strgst[2].cr_crit.c1,
1469 grr_data->db.nc_six_strgst[3].cr_crit.c1,
1470 grr_data->db.nc_six_strgst[4].cr_crit.c1,
1471 grr_data->db.nc_six_strgst[5].cr_crit.c1
1472 );
1473
1474 /* trace the C31 criterion */
1475 for( i = grr_data->db.cnt_nc_six.strgst; i < CS_MAX_STRONG_CARRIER; i++ )
1476 {
1477 grr_data->db.nc_six_strgst[i].cr_crit.c31 = 0;
1478 }
1479
1480 TRACE_EVENT_P7
1481 (
1482 "C31 : %6d %6d %6d %6d %6d %6d %6d",
1483
1484 grr_data->db.scell_info.cr_crit.c31,
1485 grr_data->db.nc_six_strgst[0].cr_crit.c31,
1486 grr_data->db.nc_six_strgst[1].cr_crit.c31,
1487 grr_data->db.nc_six_strgst[2].cr_crit.c31,
1488 grr_data->db.nc_six_strgst[3].cr_crit.c31,
1489 grr_data->db.nc_six_strgst[4].cr_crit.c31,
1490 grr_data->db.nc_six_strgst[5].cr_crit.c31
1491 );
1492
1493 /* trace the C32 criterion */
1494 for( i = grr_data->db.cnt_nc_six.strgst; i < CS_MAX_STRONG_CARRIER; i++ )
1495 {
1496 grr_data->db.nc_six_strgst[i].cr_crit.c32 = 0;
1497 }
1498
1499 TRACE_EVENT_P7
1500 (
1501 "C32 : %6d %6d %6d %6d %6d %6d %6d",
1502 grr_data->db.scell_info.cr_crit.c32,
1503 grr_data->db.nc_six_strgst[0].cr_crit.c32,
1504 grr_data->db.nc_six_strgst[1].cr_crit.c32,
1505 grr_data->db.nc_six_strgst[2].cr_crit.c32,
1506 grr_data->db.nc_six_strgst[3].cr_crit.c32,
1507 grr_data->db.nc_six_strgst[4].cr_crit.c32,
1508 grr_data->db.nc_six_strgst[5].cr_crit.c32
1509 );
1510 }
1511
1512 #endif /* #if !defined (NTRACE) */
1513
1514 } /* cs_calc_params() */
1515
1516 /*
1517 +------------------------------------------------------------------------------
1518 | Function : cs_store_meas_values
1519 +------------------------------------------------------------------------------
1520 | Description : The function cs_store_meas_values() saves the received
1521 | rla_p values in the grr database
1522 |
1523 | Parameters : ...
1524 |
1525 +------------------------------------------------------------------------------
1526 */
1527 GLOBAL void cs_store_meas_values ( void )
1528 {
1529 UBYTE i, j; /* used for counting */
1530
1531 USHORT arfcn;
1532
1533 T_rla_p rla_p;
1534
1535 TRACE_FUNCTION( "cs_store_meas_values" );
1536
1537 /*
1538 * store the first value as serving cell
1539 */
1540 grr_data->db.scell_info.rla_p.stat =
1541 cs_get_rla_p( &nc_data->cell[0].rla_p_data,
1542 &grr_data->db.scell_info.rla_p.lev );
1543
1544 if( grr_data->db.scell_info.rla_p.stat NEQ CS_RLA_P_NOT_AVAIL )
1545 {
1546 #ifdef FF_PS_RSSI
1547 RX_SetValue( grr_data->db.scell_info.rla_p.lev,
1548 RX_QUAL_UNAVAILABLE,
1549 psc_db->scell_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min);
1550 #else
1551 RX_SetValue( grr_data->db.scell_info.rla_p.lev );
1552 #endif
1553 }
1554
1555 /*
1556 * store the next values as neighbour cells
1557 */
1558 for( j = 1; j < nc_data->c_cell; j++ )
1559 {
1560 i = 0;
1561 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1562 arfcn = nc_data->cell[j].arfcn;
1563 #else
1564 arfcn = grr_l1_arfcn_to_g23( nc_data->cell[j].arfcn );
1565 #endif
1566 rla_p.stat = cs_get_rla_p( &nc_data->cell[j].rla_p_data, &rla_p.lev );
1567
1568 while( i < MAX_NR_OF_NC_MVAL AND
1569 grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ arfcn )
1570
1571 {
1572 i++;
1573 }
1574
1575 if( i < MAX_NR_OF_NC_MVAL )
1576 {
1577 grr_data->db.nc_mval_list.nc_mval[i].rla_p = rla_p;
1578 }
1579 }
1580 } /* cs_store_meas_values() */
1581
1582 /*
1583 +------------------------------------------------------------------------------
1584 | Function : cs_store_rxlev_values
1585 +------------------------------------------------------------------------------
1586 | Description : The function cs_store_rxlev_values()
1587 |
1588 | Parameters : ...
1589 |
1590 +------------------------------------------------------------------------------
1591 */
1592 GLOBAL void cs_store_rxlev_values ( void )
1593 {
1594 UBYTE i, j; /* used for counting */
1595
1596 USHORT arfcn;
1597
1598 TRACE_FUNCTION( "cs_store_rxlev_values" );
1599
1600 /*
1601 * store the first value as serving cell
1602 */
1603 grr_data->db.scell_info.rxlev_avg =
1604 cs_get_rxlev_avg( &nc_data->cell[0].rxlev_data );
1605
1606 /*
1607 * store the next values as neighbour cells
1608 */
1609 for( j = 1; j < nc_data->c_cell; j++ )
1610 {
1611 i = 0;
1612 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1613 arfcn = nc_data->cell[j].arfcn;
1614 #else
1615 arfcn = grr_l1_arfcn_to_g23( nc_data->cell[j].arfcn );
1616 #endif
1617
1618 while( i < MAX_NR_OF_NC_MVAL AND
1619 grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ arfcn )
1620
1621 {
1622 i++;
1623 }
1624
1625 if( i < MAX_NR_OF_NC_MVAL )
1626 {
1627 grr_data->db.nc_mval_list.nc_mval[i].rxlev_avg =
1628 cs_get_rxlev_avg( &nc_data->cell[j].rxlev_data );
1629 }
1630 }
1631 } /* cs_store_rxlev_values() */
1632
1633 /*
1634 +------------------------------------------------------------------------------
1635 | Function : cs_find_strongest
1636 +------------------------------------------------------------------------------
1637 | Description : The function cs_find_strongest() finds out the six strongest
1638 | neighbour cells and stores their indices in an array.
1639 |
1640 | Parameters : cnt_strgst - number of strongest carriers
1641 | cnt_candid - number of strongest plus candidate carriers
1642 | index - index of carriers
1643 | status - status of carriers
1644 |
1645 +------------------------------------------------------------------------------
1646 */
1647 GLOBAL BOOL cs_find_strongest ( ULONG fn_offset )
1648 {
1649 UBYTE cnt_strgst;
1650 UBYTE cnt_candid;
1651 UBYTE index[CS_MAX_STRONG_CARRIER];
1652
1653 UBYTE max_nc_excl_sc_band = 0; /* maximum number of reported neighbour */
1654 /* cells that should be not in the band */
1655 /* of the serving cell */
1656
1657 TRACE_FUNCTION( "cs_find_strongest" );
1658
1659 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1660 if( CHECK_DUAL_BANDS EQ TRUE)
1661 #else
1662 if( std EQ STD_DUAL OR std EQ STD_DUAL_EGSM OR std EQ STD_DUAL_US )
1663 #endif
1664 {
1665 switch( psc_db->scell_par.multi_band_rep )
1666 {
1667 case GRR_MULTIBAND_REPORTING_1: max_nc_excl_sc_band = 1; break;
1668 case GRR_MULTIBAND_REPORTING_2: max_nc_excl_sc_band = 2; break;
1669 case GRR_MULTIBAND_REPORTING_3: max_nc_excl_sc_band = 3; break;
1670 default : max_nc_excl_sc_band = 0; break;
1671 }
1672 }
1673
1674 /*
1675 * look for strongest neighbour cells with a valid RLA_P value,
1676 * these are used for cell re-selection only
1677 */
1678 cnt_strgst = 0;
1679
1680 cs_consider_multiband
1681 ( &cnt_strgst, index, CS_RLA_P_VALID, max_nc_excl_sc_band );
1682
1683 /*
1684 * look for strongest neighbour cells with a RLA_P which is not valid
1685 * but available and add them to the remaining storage areas in the list
1686 * of strongest neighbour cells, these are used for checking the BSIC
1687 * in advance, these cells may become a valid RLA_P value soon
1688 */
1689 cnt_candid = cnt_strgst;
1690
1691 if( cnt_candid < CS_MAX_STRONG_CARRIER )
1692 {
1693 cs_consider_multiband
1694 ( &cnt_candid, index, CS_RLA_P_NOT_VALID, max_nc_excl_sc_band );
1695 }
1696
1697 return(cs_update_strongest( cnt_strgst, cnt_candid, index, fn_offset ));
1698 } /* cs_find_strongest() */
1699
1700 /*
1701 +------------------------------------------------------------------------------
1702 | Function : cs_consider_multiband
1703 +------------------------------------------------------------------------------
1704 | Description :
1705 |
1706 | Parameters :
1707 |
1708 +------------------------------------------------------------------------------
1709 */
1710 LOCAL void cs_consider_multiband ( UBYTE *count,
1711 UBYTE *index,
1712 UBYTE select_status,
1713 UBYTE maximum )
1714 {
1715 TRACE_FUNCTION( "cs_consider_multiband" );
1716
1717 if( maximum NEQ 0 )
1718 {
1719 /*
1720 * A maximum of zero means that normal reporting of the six strongest
1721 * cell irrespective of the band used should be performed.
1722 *
1723 * A maximum greater zero means that multi band reporting should be
1724 * performed, so the MS shall report the strongest cells in each of the
1725 * frequency bands in the BA list, excluding the frequency band of the
1726 * serving cell. The remaining positions shall be used for reporting of
1727 * the cells in the band of the serving cell.
1728 */
1729 cs_find_strongest_with_status
1730 ( count, index, select_status, maximum, CS_EXCLUDE_SC_BAND );
1731
1732 cs_find_strongest_with_status
1733 ( count, index, select_status,
1734 (UBYTE)( CS_MAX_STRONG_CARRIER - maximum ), CS_ONLY_SC_BAND );
1735 }
1736
1737 if( *count < CS_MAX_STRONG_CARRIER )
1738 {
1739 cs_find_strongest_with_status
1740 ( count, index, select_status,
1741 (UBYTE)( CS_MAX_STRONG_CARRIER - *count ), CS_NO_BAND_LIMITATION );
1742 }
1743 } /* cs_consider_multiband() */
1744
1745 /*
1746 +------------------------------------------------------------------------------
1747 | Function : cs_find_strongest_with_status
1748 +------------------------------------------------------------------------------
1749 | Description : The function cs_find_strongest_with_status() finds out the
1750 | six strongest neighbour cells with a specific status and
1751 | stores their indices in an array.
1752 |
1753 | Parameters : count - number of strongest carriers
1754 | index - index of carriers
1755 | status - status of carriers
1756 | select_status - status which should be used for selection
1757 |
1758 |
1759 +------------------------------------------------------------------------------
1760 */
1761 LOCAL void cs_find_strongest_with_status ( UBYTE *count,
1762 UBYTE *index,
1763 UBYTE select_status,
1764 UBYTE maximum,
1765 UBYTE limitation )
1766 {
1767 UBYTE strgst_idx; /* used for counting */
1768 UBYTE mval_idx; /* used for counting */
1769 UBYTE k; /* used for counting */
1770 BOOL cells_left = TRUE; /* indicates whether there are more cells */
1771 /* which may belong to the strongest */
1772 SHORT max_rla_p; /* next maximum RLA_P value */
1773 UBYTE idx_next_max; /* index of the cell with the next max. */
1774 /* RLA_P value */
1775 BOOL one_of_six_flag; /* indicates whether a cell already */
1776 /* belongs to the strongest */
1777 BOOL limit; /* indicator for limitation precedence */
1778 BOOL scell_is_high_band; /* serving cell is in DCS or PCS band */
1779 BOOL ncell_is_high_band; /* neighbour cell is in DCS or PCS band */
1780 UBYTE max_found_cell = MINIMUM( *count + maximum, CS_MAX_STRONG_CARRIER );
1781 /* maximum number of strongest neighbour */
1782 /* cells that should be found after */
1783 /* leaving this function */
1784 USHORT low_channel;
1785 USHORT high_channel;
1786
1787 T_NC_MVAL *nc_mval;
1788
1789 TRACE_FUNCTION( "cs_find_strongest_with_status" );
1790
1791 #ifdef TI_PS_FF_QUAD_BAND_SUPPORT
1792 if( std EQ STD_DUAL_US OR std EQ STD_900_1900 OR
1793 std EQ STD_850_900_1900 )
1794 #else
1795 if( std EQ STD_DUAL_US )
1796 #endif
1797 {
1798 low_channel = LOW_CHANNEL_1900;
1799 high_channel = HIGH_CHANNEL_1900;
1800 }
1801 else
1802 {
1803 low_channel = LOW_CHANNEL_1800;
1804 high_channel = HIGH_CHANNEL_1800;
1805 }
1806
1807 for( strgst_idx = *count;
1808 strgst_idx < max_found_cell AND cells_left;
1809 strgst_idx++ )
1810 {
1811 max_rla_p = -1;
1812 idx_next_max = 0xFF;
1813
1814 for( mval_idx = 0; mval_idx < MAX_NR_OF_NC_MVAL; mval_idx++ )
1815 {
1816 nc_mval = &grr_data->db.nc_mval_list.nc_mval[mval_idx];
1817
1818 if( nc_mval->status EQ NC_MVAL_STAT_ASSIGNED )
1819 {
1820 one_of_six_flag = FALSE;
1821
1822 for( k = 0; k < *count AND one_of_six_flag EQ FALSE; k++ )
1823 {
1824 if( mval_idx EQ index[k] )
1825 {
1826 one_of_six_flag = TRUE;
1827 }
1828 }
1829
1830 if( one_of_six_flag EQ FALSE AND
1831 nc_mval->rla_p.stat EQ select_status AND
1832
1833 #ifdef _TARGET_
1834 nc_mval->rla_p.lev >= MIN_RXLEV_FOR_SIX_STRGST AND
1835 #endif /* #ifdef _TARGET_ */
1836
1837 nc_mval->rla_p.lev > max_rla_p )
1838 {
1839 switch( limitation )
1840 {
1841 default:
1842 TRACE_ASSERT( limitation EQ CS_NO_BAND_LIMITATION OR
1843 limitation EQ CS_EXCLUDE_SC_BAND OR
1844 limitation EQ CS_ONLY_SC_BAND );
1845
1846 /*lint -fallthrough*/
1847
1848 /*
1849 * fallthrough statement inserted to pass lint process,
1850 * error 644: (Warning -- limit may not have been initialized)
1851 */
1852
1853 case( CS_NO_BAND_LIMITATION ):
1854 limit = FALSE;
1855 break;
1856
1857 case( CS_EXCLUDE_SC_BAND ):
1858 scell_is_high_band =
1859 ( psc_db->pbcch.bcch.arfcn >= low_channel AND
1860 psc_db->pbcch.bcch.arfcn <= high_channel );
1861
1862 ncell_is_high_band =
1863 ( nc_mval->arfcn >= low_channel AND
1864 nc_mval->arfcn <= high_channel );
1865
1866 limit = ( scell_is_high_band EQ ncell_is_high_band );
1867 break;
1868
1869 case( CS_ONLY_SC_BAND ):
1870 scell_is_high_band =
1871 ( psc_db->pbcch.bcch.arfcn >= low_channel AND
1872 psc_db->pbcch.bcch.arfcn <= high_channel );
1873
1874 ncell_is_high_band =
1875 ( nc_mval->arfcn >= low_channel AND
1876 nc_mval->arfcn <= high_channel );
1877
1878 limit = ( scell_is_high_band NEQ ncell_is_high_band );
1879 break;
1880 }
1881
1882 /*
1883 * limitation may take precedence,
1884 * do not consider neighbour cell in case
1885 */
1886 if( limit EQ FALSE )
1887 {
1888 max_rla_p = nc_mval->rla_p.lev;
1889 idx_next_max = mval_idx;
1890 }
1891 }
1892 }
1893 }
1894
1895 if( idx_next_max EQ 0xFF )
1896 {
1897 cells_left = FALSE;
1898 }
1899 else
1900 {
1901 index[strgst_idx] = idx_next_max;
1902
1903 (*count)++;
1904 }
1905 }
1906 } /* cs_find_strongest_with_status() */
1907
1908 /*
1909 +------------------------------------------------------------------------------
1910 | Function : cs_update_strongest
1911 +------------------------------------------------------------------------------
1912 | Description : The function cs_update_strongest() updates the list of the
1913 | strongest neighbour cells stored in the database.
1914 |
1915 | Parameters : cnt_strgst - number of strongest carriers
1916 | cnt_candid - number of strongest plus candidate carriers
1917 | index - index of carriers
1918 | status - status of carriers
1919 | fn_offset - frame number offset
1920 |
1921 +------------------------------------------------------------------------------
1922 */
1923 LOCAL BOOL cs_update_strongest ( UBYTE cnt_strgst,
1924 UBYTE cnt_candid,
1925 UBYTE *index,
1926 ULONG fn_offset )
1927 {
1928 UBYTE i, j; /* used for counting */
1929 ULONG avail_time[CS_MAX_STRONG_CARRIER];
1930 /* used to store the times when a cell becomes first */
1931 /* a cell of the strongest carriers for a possible */
1932 /* rearrangment of the list of the strongest carriers */
1933
1934 T_NC_SIX_STRGST *six_strgst;
1935 T_NC_SIX_STRGST *six_candid;
1936
1937 BOOL has_changed = ( grr_data->db.cnt_nc_six.candid NEQ cnt_candid );
1938
1939
1940 TRACE_FUNCTION( "cs_update_strongest" );
1941
1942 memset( avail_time, 0, sizeof( avail_time ) );
1943
1944 for( i = 0; i < cnt_candid; i++ )
1945 {
1946 /*
1947 * check whether cell is already inserted in list of strongest carrier
1948 */
1949 six_strgst = NULL;
1950 six_candid = NULL;
1951 j = 0;
1952
1953 while( j < grr_data->db.cnt_nc_six.candid AND
1954 six_strgst EQ NULL AND
1955 six_candid EQ NULL )
1956 {
1957 six_candid = &grr_data->db.nc_six_strgst[j];
1958
1959 if( index[i] EQ six_candid->idx )
1960 {
1961 if( j < grr_data->db.cnt_nc_six.strgst )
1962 {
1963 six_strgst = six_candid;
1964 }
1965 }
1966 else
1967 {
1968 six_candid = NULL;
1969
1970 j++;
1971 }
1972 }
1973
1974
1975 if( six_strgst NEQ NULL )
1976 {
1977 if( six_strgst->avail_time <=
1978 ( GPRS_PENALTY_TIME_MAX + 1 ) * 10 * CS_PERIOD_1_SEC )
1979 {
1980 /*
1981 * the time how long the cell is already inserted
1982 * is stored up to a limited period
1983 */
1984 avail_time[i] = six_strgst->avail_time + fn_offset;
1985 }
1986 else
1987 {
1988 avail_time[i] = six_strgst->avail_time;
1989 }
1990 }
1991 else
1992 {
1993 if( six_candid EQ NULL )
1994 {
1995 has_changed = TRUE;
1996 }
1997
1998 if( grr_data->db.old_scell.arfcn EQ
1999 grr_data->db.nc_mval_list.nc_mval[index[i]].arfcn AND
2000 grr_data->db.old_scell.bsic EQ
2001 grr_data->db.nc_mval_list.nc_mval[index[i]].sync_info.bsic )
2002 {
2003 /* for the old serving cell timer T shall always set to status expired */
2004 avail_time[i] =
2005 ( ( GPRS_PENALTY_TIME_MAX + 1 ) * 10 * CS_PERIOD_1_SEC ) + 1;
2006 }
2007
2008 }
2009 }
2010
2011 for( i = 0; i < cnt_candid; i++ )
2012 {
2013 grr_data->db.nc_six_strgst[i].idx = index[i];
2014 grr_data->db.nc_six_strgst[i].avail_time = avail_time[i];
2015
2016 /*
2017 * every time a new list of strongest carriers is build-up
2018 * the parameter mode should be set to CS_MODE_IDLE.
2019 */
2020 grr_data->db.nc_six_strgst[i].mode = CS_MODE_IDLE;
2021 }
2022
2023 cs_set_cnt_nc_six( cnt_strgst, cnt_candid );
2024
2025 /*
2026 * perform some tracing
2027 */
2028
2029 #if !defined (NTRACE)
2030
2031 if( grr_data->cs.v_crp_trace EQ TRUE )
2032 {
2033 /* trace the ARFCN */
2034 {
2035 USHORT arfcn[CS_MAX_STRONG_CARRIER];
2036
2037 memset( arfcn, RRGRR_INVALID_ARFCN, sizeof( arfcn ) );
2038
2039 for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
2040 {
2041 arfcn[i] =
2042 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].arfcn;
2043 }
2044
2045 TRACE_EVENT_P7
2046 (
2047 "ARFCN: %6d %6d %6d %6d %6d %6d %6d",
2048 psc_db->pbcch.bcch.arfcn,
2049 arfcn[0], arfcn[1], arfcn[2], arfcn[3], arfcn[4], arfcn[5]
2050 );
2051 }
2052
2053 /* trace the BSIC */
2054 {
2055 USHORT bsic[CS_MAX_STRONG_CARRIER];
2056
2057 memset( bsic, RRGRR_INVALID_BSIC, sizeof( bsic ) );
2058
2059 for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
2060 {
2061 bsic[i] =
2062 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].sync_info.bsic;
2063 }
2064
2065 TRACE_EVENT_P7
2066 (
2067 "BSIC : %6d %6d %6d %6d %6d %6d %6d",
2068 psc_db->pbcch.bcch.bsic,
2069 bsic[0], bsic[1], bsic[2], bsic[3], bsic[4], bsic[5]
2070 );
2071 }
2072
2073 /* trace the RLA_P */
2074 {
2075 UBYTE rla_p[CS_MAX_STRONG_CARRIER];
2076 UBYTE rxlev_avg[CS_MAX_STRONG_CARRIER];
2077
2078 memset( rla_p, 0, sizeof( rla_p ) );
2079 memset( rxlev_avg, 0, sizeof( rxlev_avg ) );
2080
2081 for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
2082 {
2083 rla_p[i] =
2084 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].rla_p.lev;
2085
2086
2087 rxlev_avg[i] =
2088 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].rxlev_avg;
2089
2090 }
2091
2092 TRACE_EVENT_P7
2093 (
2094 "RLA_P: %6d %6d %6d %6d %6d %6d %6d",
2095 grr_data->db.scell_info.rla_p.lev,
2096 rla_p[0], rla_p[1], rla_p[2], rla_p[3], rla_p[4], rla_p[5]
2097 );
2098
2099 TRACE_EVENT_P7
2100 (
2101 "RXLEV_AVG: %6d %6d %6d %6d %6d %6d %6d",
2102 grr_data->db.scell_info.rxlev_avg,
2103 rxlev_avg[0], rxlev_avg[1], rxlev_avg[2], rxlev_avg[3], rxlev_avg[4], rxlev_avg[5]
2104 );
2105
2106 }
2107
2108 /* trace the synchronisation status */
2109 {
2110 UBYTE sync_stat[CS_MAX_STRONG_CARRIER];
2111
2112 memset( sync_stat, 0xFF, sizeof( sync_stat ) );
2113
2114 for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
2115 {
2116 sync_stat[i] =
2117 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].sync_info.sync.status;
2118 }
2119
2120 TRACE_EVENT_P6
2121 (
2122 "SYNC : %6d %6d %6d %6d %6d %6d",
2123 sync_stat[0], sync_stat[1], sync_stat[2],
2124 sync_stat[3], sync_stat[4], sync_stat[5]
2125 );
2126 }
2127 }
2128
2129 #endif /* #if !defined (NTRACE) */
2130
2131 return( has_changed );
2132
2133 } /* cs_update_strongest() */
2134
2135 /*
2136 +------------------------------------------------------------------------------
2137 | Function : cs_compare_bsic
2138 +------------------------------------------------------------------------------
2139 | Description : The function cs_compare_bsic() compares the indicated BSIC
2140 | with the stored BSICs
2141 |
2142 | Parameters : rrgrr_check_bsic_ind - pointer to primitive
2143 |
2144 +------------------------------------------------------------------------------
2145 */
2146 GLOBAL void cs_compare_bsic ( T_RRGRR_NCELL_SYNC_IND *rrgrr_check_bsic_ind )
2147 {
2148 UBYTE i = 0;
2149 UBYTE j;
2150 UBYTE nc_mval_idx;
2151 T_NC_MVAL *nc_mval;
2152
2153
2154 TRACE_FUNCTION( "cs_compare_bsic" );
2155
2156
2157
2158 while( i < RRGRR_MAX_RSLT_NCELL_SYNC_IND AND
2159 rrgrr_check_bsic_ind->sync_result[i].arfcn NEQ RRGRR_INVALID_ARFCN )
2160 {
2161 if( ( nc_mval = grr_get_nc_mval( rrgrr_check_bsic_ind->sync_result[i].arfcn,
2162 RRGRR_INVALID_BSIC, &nc_mval_idx ) ) NEQ NULL )
2163 {
2164 switch( rrgrr_check_bsic_ind->sync_result[i].sb_flag )
2165 {
2166 case( SB_FOUND ):
2167 nc_mval->sync_info.bsic = rrgrr_check_bsic_ind->sync_result[i].bsic;
2168 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
2169 nc_mval->sync_info.sync.sync_failed_cnt = 0;
2170 break;
2171
2172 case( NO_SB_FOUND ):
2173 nc_mval->sync_info.bsic = RRGRR_INVALID_BSIC;
2174
2175 if( nc_mval->sync_info.sync.sync_failed_cnt EQ MAX_SYNC_FAILED_CNT )
2176 {
2177 nc_mval->sync_info.sync.status = STAT_SYNC_NONE;
2178 nc_mval->sync_info.sync.sync_failed_cnt = 0;
2179
2180 j=0;
2181 while( j < grr_data->nc_data.c_cell AND
2182 grr_data->nc_data.cell[j].arfcn NEQ
2183 nc_mval->arfcn )
2184 {
2185 j++;
2186 }
2187
2188 if( j < grr_data->nc_data.c_cell )
2189 {
2190 cs_reset_meas_result( &grr_data->nc_data.cell[j] );
2191 }
2192
2193 }
2194 else
2195 {
2196 nc_mval->sync_info.sync.status = STAT_SYNC_FAILED;
2197 nc_mval->sync_info.sync.sync_failed_cnt += 1;
2198 }
2199 break;
2200
2201 case( SB_UNKNOWN ):
2202 if( nc_mval->status EQ NC_MVAL_STAT_PENDING )
2203 {
2204 cs_init_nc_mval( nc_mval );
2205 }
2206 else
2207 {
2208 nc_mval->sync_info.bsic = RRGRR_INVALID_BSIC;
2209 nc_mval->sync_info.sync.status = STAT_SYNC_NONE;
2210 nc_mval->sync_info.sync.sync_failed_cnt = 0;
2211 }
2212 break;
2213 }
2214 }
2215
2216 if( nc_mval EQ NULL )
2217 {
2218 if( ( nc_mval = grr_get_nc_mval( RRGRR_INVALID_ARFCN,
2219 RRGRR_INVALID_BSIC,
2220 &nc_mval_idx ) ) NEQ NULL )
2221 {
2222 switch( rrgrr_check_bsic_ind->sync_result[i].sb_flag )
2223 {
2224 case( SB_FOUND ):
2225 nc_mval->status = NC_MVAL_STAT_PENDING;
2226 nc_mval->arfcn = rrgrr_check_bsic_ind->sync_result[i].arfcn;
2227 nc_mval->sync_info.bsic = rrgrr_check_bsic_ind->sync_result[i].bsic;
2228 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
2229 nc_mval->sync_info.sync.sync_failed_cnt = 0;
2230
2231 grr_data->cs.is_mval_initialized = FALSE;
2232 break;
2233
2234 case( NO_SB_FOUND ):
2235 nc_mval->status = NC_MVAL_STAT_PENDING;
2236 nc_mval->arfcn = rrgrr_check_bsic_ind->sync_result[i].arfcn;
2237 nc_mval->sync_info.bsic = RRGRR_INVALID_BSIC;
2238 nc_mval->sync_info.sync.status = STAT_SYNC_FAILED;
2239 nc_mval->sync_info.sync.sync_failed_cnt = 0;
2240
2241 grr_data->cs.is_mval_initialized = FALSE;
2242 break;
2243
2244 case( SB_UNKNOWN ):
2245 TRACE_EVENT_P1( "cs_compare_bsic: SB_UNKNOWN for %d which is not on measured values list, e.g. after GRR suspension",
2246 rrgrr_check_bsic_ind->sync_result[i].arfcn );
2247 break;
2248 }
2249 }
2250 else
2251 {
2252 TRACE_EVENT_P1( "cs_compare_bsic: no free entry for measured values found %d",
2253 rrgrr_check_bsic_ind->sync_result[i].arfcn );
2254 }
2255 }
2256
2257 #ifdef _SIMULATION_
2258
2259 TRACE_EVENT_P3( "BSIC: %d %d %d",
2260 rrgrr_check_bsic_ind->sync_result[i].arfcn,
2261 rrgrr_check_bsic_ind->sync_result[i].sb_flag,
2262 rrgrr_check_bsic_ind->sync_result[i].bsic );
2263
2264 #endif /* #ifdef _SIMULATION_ */
2265
2266 i++;
2267 }
2268
2269 cs_trace_nc_mval_lst( );
2270
2271 } /* cs_compare_bsic() */
2272
2273
2274
2275
2276 /*
2277 +------------------------------------------------------------------------------
2278 | Function : cs_get_best_cell
2279 +------------------------------------------------------------------------------
2280 | Description : The function cs_get_best_cell() checks the start of
2281 | cell reselection.
2282 | Is a criterion fulfilled for cell reselction, then reading of
2283 | best neighbourcell is started.
2284 |
2285 | Parameters :
2286 |
2287 +------------------------------------------------------------------------------
2288 */
2289 GLOBAL void cs_get_best_cell ( T_NC_SIX_STRGST **nc, T_scell_info **sc )
2290 {
2291 UBYTE strgst_idx;
2292 UBYTE i;
2293 T_NC_SIX_STRGST *next_cell;
2294 BOOL c31_bc; /* best neighbour cell priorized */
2295 BOOL c31_nc; /* next neighbour cell priorized */
2296 BOOL c31_sc; /* serving cell priorized */
2297 T_ncell_info *ncell_best; /* best neighbour cell */
2298 T_ncell_info *ncell_next; /* next neighbour cell */
2299 T_NC_MVAL *mval_best; /* measured values for best neighbour cell */
2300 T_NC_MVAL *mval_next; /* measured values for next neighbour cell */
2301
2302 TRACE_FUNCTION( "cs_get_best_cell" );
2303
2304 /*
2305 * start cell reselection if:
2306 *
2307 * 1. C1 for the serving cell falls below zero: C1 < 0
2308 *
2309 * 2. A non-serving cell is evaluated to be better than the serving cell.
2310 *
2311 * a) The best cell is the cell with the highest value of C32 among those
2312 * cells that have the highest PRIOROTY_CLASS among those that fulfill
2313 * the criterion C31 >= 0.
2314 *
2315 * Interpretation: If C31 is fulfilled, take cells with highest
2316 * priority and then select the cell with highest
2317 * C32 value.
2318 *
2319 * b) The best cell is the cell with the highest value of C32 among all
2320 * cells if no cell fulfill the criterion C31 >= 0.
2321 *
2322 * Interpretation: If C31 is not fulfilled, take the cell with the
2323 * highest C32 value.
2324 *
2325 * NOTE: When selecting a neighbour cell to be the new serving cell,
2326 * C1 criterion of that cell shall be taken into account.
2327 */
2328
2329 /*
2330 * set default results
2331 */
2332 *sc = NULL;
2333 *nc = NULL;
2334 mval_best = NULL;
2335 strgst_idx = 0xFF;
2336
2337 if( grr_data->cs.is_upd_ncell_stat_needed )
2338 {
2339 TRACE_EVENT( "cs_get_best_cell: is_upd_ncell_stat_needed EQ TRUE" );
2340
2341 return;
2342 }
2343
2344 if(
2345 (
2346 grr_data->db.scell_info.rla_p.stat NEQ CS_RLA_P_VALID
2347 )
2348 OR
2349 (
2350 grr_data->db.scell_info.rla_p.stat EQ CS_RLA_P_VALID AND
2351 grr_data->db.scell_info.cr_crit.c1 >= 0 AND
2352 grr_data->db.scell_info.cell_barred EQ FALSE
2353 )
2354 )
2355 {
2356 *sc = &grr_data->db.scell_info;
2357 }
2358
2359 /*
2360 * search the best neighbour cell,
2361 * this cell should not be used for a cell re-selection attempt before
2362 */
2363 for( i = 0;
2364 i < grr_data->db.cnt_nc_six.strgst AND *nc EQ NULL;
2365 i++ )
2366 {
2367 *nc = &grr_data->db.nc_six_strgst[i];
2368 mval_best = &grr_data->db.nc_mval_list.nc_mval[(*nc)->idx];
2369 strgst_idx = i;
2370
2371 if( (*nc)->mode NEQ CS_MODE_IDLE OR
2372 mval_best->sync_info.sync.status NEQ STAT_SYNC_OK OR
2373 (*nc)->cr_crit.c1 < 0 )
2374 {
2375 *nc = NULL;
2376 mval_best = NULL;
2377 strgst_idx = 0xFF;
2378 }
2379 }
2380
2381 /*
2382 * if no best neighbour cell was found inform the caller
2383 */
2384 if( *nc EQ NULL OR mval_best EQ NULL )
2385 {
2386 return;
2387 }
2388
2389 ncell_best =
2390 grr_get_ncell_info( mval_best->arfcn, mval_best->sync_info.bsic );
2391
2392 if( ncell_best EQ NULL )
2393 {
2394 TRACE_EVENT( "cs_get_best_cell: ncell_best EQ NULL" );
2395 *nc = NULL;
2396 strgst_idx = 0xFF;
2397
2398 return;
2399 }
2400
2401 /*
2402 * check whether best neighbour cell is priorized
2403 */
2404 c31_bc = ( (*nc)->cr_crit.c31 >= 0 AND
2405 ncell_best->cr_par.cr_par_1.v_hcs_par EQ TRUE );
2406
2407 #if !defined (NTRACE)
2408
2409 if( grr_data->cs.v_crp_trace EQ TRUE )
2410 {
2411 TRACE_EVENT_P4( "cs_get_best_cell: ncell_best %d %d %d %d",
2412 mval_best->arfcn,
2413 mval_best->sync_info.bsic,
2414 c31_bc,
2415 ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class );
2416 }
2417
2418 #endif /* #if !defined (NTRACE) */
2419
2420 /*
2421 * look for a better neighbour cell
2422 */
2423 for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
2424 {
2425 next_cell = &grr_data->db.nc_six_strgst[i];
2426 mval_next = &grr_data->db.nc_mval_list.nc_mval[next_cell->idx];
2427
2428 if( next_cell->mode EQ CS_MODE_IDLE AND
2429 next_cell NEQ *nc AND
2430 mval_next->sync_info.sync.status EQ STAT_SYNC_OK AND
2431 next_cell->cr_crit.c1 >= 0 )
2432 {
2433 ncell_next =
2434 grr_get_ncell_info( mval_next->arfcn, mval_next->sync_info.bsic );
2435
2436 if( ncell_next EQ NULL )
2437 {
2438 TRACE_EVENT( "cs_get_best_cell: ncell_next EQ NULL" );
2439
2440 *nc = NULL;
2441 strgst_idx = 0xFF;
2442
2443 return;
2444 }
2445
2446 /*
2447 * check whether next neighbour cell is priorized
2448 */
2449 c31_nc = ( next_cell->cr_crit.c31 >= 0 AND
2450 ncell_next->cr_par.cr_par_1.v_hcs_par EQ TRUE );
2451
2452 #if !defined (NTRACE)
2453
2454 if( grr_data->cs.v_crp_trace EQ TRUE )
2455 {
2456 TRACE_EVENT_P4( "cs_get_best_cell: ncell_next %d %d %d %d",
2457 mval_next->arfcn,
2458 mval_next->sync_info.bsic,
2459 c31_nc,
2460 ncell_next->cr_par.cr_par_1.hcs_par.gprs_prio_class );
2461 }
2462
2463 #endif /* #if !defined (NTRACE) */
2464
2465 if( c31_bc AND
2466 c31_nc AND
2467 (
2468 ( ncell_next->cr_par.cr_par_1.hcs_par.gprs_prio_class EQ
2469 ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class AND
2470 next_cell->cr_crit.c32 > (*nc)->cr_crit.c32 )
2471 OR
2472 ( ncell_next->cr_par.cr_par_1.hcs_par.gprs_prio_class >
2473 ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class )
2474 )
2475 )
2476 {
2477 /*
2478 * priorized cell reselection must be done
2479 */
2480 *nc = next_cell;
2481 ncell_best = ncell_next;
2482 strgst_idx = i;
2483 }
2484 else if ( !c31_bc )
2485 {
2486 /*
2487 * check whether next neighbour cell is priorized
2488 */
2489 if( c31_nc )
2490 {
2491 /*
2492 * first priorized cell found
2493 */
2494 c31_bc = TRUE;
2495 *nc = next_cell;
2496 ncell_best = ncell_next;
2497 strgst_idx = i;
2498 }
2499 else if ( next_cell->cr_crit.c32 > (*nc)->cr_crit.c32 )
2500 {
2501 /*
2502 * until now, no priorized cell found
2503 */
2504 *nc = next_cell;
2505 ncell_best = ncell_next;
2506 strgst_idx = i;
2507 }
2508 }
2509 }
2510 }
2511
2512 /*
2513 * check whether serving cell is priorized
2514 */
2515 c31_sc = ( grr_data->db.scell_info.cr_crit.c31 >= 0 AND
2516 psc_db->scell_par.cr_par_1.v_hcs_par EQ TRUE );
2517
2518 #if !defined (NTRACE)
2519
2520 if( grr_data->cs.v_crp_trace EQ TRUE )
2521 {
2522 TRACE_EVENT_P3( "cs_get_best_cell: scell %d %d %d",
2523 *sc, c31_sc,
2524 psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class );
2525 }
2526
2527 #endif /* #if !defined (NTRACE) */
2528
2529 /*
2530 * check whether cell reselection must be done
2531 */
2532 if(
2533 (
2534 *sc EQ NULL
2535 )
2536 OR
2537 (
2538 c31_bc AND
2539 c31_sc AND
2540 (
2541 ( ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class EQ
2542 psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class AND
2543 (*nc)->cr_crit.c32 > grr_data->db.scell_info.cr_crit.c32 )
2544 OR
2545 ( ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class >
2546 psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class )
2547 )
2548 )
2549 OR
2550 (
2551 !c31_bc AND
2552 !c31_sc AND
2553 (*nc)->cr_crit.c32 > grr_data->db.scell_info.cr_crit.c32
2554 )
2555 OR
2556 (
2557 c31_bc AND
2558 !c31_sc
2559 )
2560 )
2561 {
2562 *sc = NULL;
2563 }
2564 else
2565 {
2566 *nc = NULL;
2567 strgst_idx = 0xFF;
2568 }
2569
2570 #if !defined (NTRACE)
2571
2572 if( grr_data->cs.v_crp_trace EQ TRUE )
2573 {
2574 TRACE_EVENT_P3( "cs_get_best_cell: strong/candid %d %d %d",
2575 grr_data->db.cnt_nc_six.strgst,
2576 grr_data->db.cnt_nc_six.candid,
2577 strgst_idx );
2578 }
2579
2580 #endif /* #if !defined (NTRACE) */
2581
2582 } /* cs_get_best_cell() */
2583
2584
2585 /*
2586 +------------------------------------------------------------------------------
2587 | Function : cs_get_network_ctrl_order
2588 +------------------------------------------------------------------------------
2589 | Description : The NETWORK_CONTROL_ORDER values NC1 and NC2 shall only apply
2590 | in Ready state. In Standby state, the MS shall always use
2591 | normal MS control independent of the ordered NC mode.
2592 |
2593 | Parameters :
2594 |
2595 +------------------------------------------------------------------------------
2596 */
2597 GLOBAL T_NC_ORDER cs_get_network_ctrl_order ( BOOL consider_gmm_state )
2598 {
2599 T_NC_ORDER ctrl_order = NC_NC0;
2600
2601 TRACE_FUNCTION( "cs_get_network_ctrl_order" );
2602
2603 if( grr_data->nc2_on )
2604 {
2605 if(
2606 (
2607 (
2608 consider_gmm_state EQ TRUE AND
2609 grr_data->cs.gmm_state EQ READY_STATE
2610 )
2611 OR
2612 (
2613 consider_gmm_state EQ FALSE
2614 )
2615 )
2616 AND
2617 (
2618 grr_data->db.nc_ref_lst.param NEQ NULL
2619 )
2620 )
2621 {
2622 ctrl_order = grr_data->db.nc_ref_lst.param->ctrl_order;
2623 }
2624 }
2625
2626 #ifdef _SIMULATION_
2627
2628 TRACE_EVENT_P2( "NETWORK_CONTROL_ORDER: %d, GMM_STATE: %d",
2629 grr_data->db.nc_ref_lst.param EQ NULL ?
2630 ctrl_order : grr_data->db.nc_ref_lst.param->ctrl_order,
2631 grr_data->cs.gmm_state );
2632
2633 #endif /* #ifdef _SIMULATION_ */
2634
2635 return( ctrl_order );
2636
2637 } /* cs_get_network_ctrl_order() */
2638
2639 /*
2640 +------------------------------------------------------------------------------
2641 | Function : cs_reset_nc_change_mark
2642 +------------------------------------------------------------------------------
2643 | Description :
2644 |
2645 | Parameters : void
2646 |
2647 +------------------------------------------------------------------------------
2648 */
2649 GLOBAL void cs_reset_nc_change_mark ( T_SC_DATABASE *db )
2650 {
2651 TRACE_FUNCTION( "cs_reset_nc_change_mark" );
2652
2653 db->nc_cw.list.chng_mrk.curr = 0;
2654 db->nc_cw.list.chng_mrk.prev = 0;
2655 db->nc_cw.param.chng_mrk.curr = 0;
2656 db->nc_cw.param.chng_mrk.prev = 0;
2657 db->nc_ms.ncmeas.list.chng_mrk.curr = 0;
2658 db->nc_ms.ncmeas.list.chng_mrk.prev = 0;
2659 db->nc_ms.ncmeas.param.chng_mrk.curr = 0;
2660 db->nc_ms.ncmeas.param.chng_mrk.prev = 0;
2661
2662 } /* cs_reset_nc_change_mark() */
2663
2664 /*
2665 +------------------------------------------------------------------------------
2666 | Function : cs_get_cr_meas_mode
2667 +------------------------------------------------------------------------------
2668 | Description : The function cs_get_cr_meas_mode() returns the cell
2669 | re-selection measurement mode used in context of TBF
2670 | establishment.
2671 |
2672 | Parameters : void
2673 |
2674 +------------------------------------------------------------------------------
2675 */
2676 GLOBAL UBYTE cs_get_cr_meas_mode ( void )
2677 {
2678 TRACE_FUNCTION( "cs_get_cr_meas_mode" );
2679
2680 return( grr_is_pbcch_present() ? CS_CRMM_BA_GPRS : CS_CRMM_BA_BCCH );
2681 } /* cs_get_cr_meas_mode() */
2682
2683 /*
2684 +------------------------------------------------------------------------------
2685 | Function : cs_send_cr_meas_req
2686 +------------------------------------------------------------------------------
2687 | Description : The function cs_send_cr_meas_req() sends the cell reselection
2688 | measurement request to L1 (MPHP_CR_MEAS_REQ)
2689 |
2690 | Parameters : dummy - description of parameter dummy
2691 |
2692 +------------------------------------------------------------------------------
2693 */
2694 GLOBAL void cs_send_cr_meas_req ( UBYTE del_meas_rslt )
2695 {
2696 BOOL is_pbcch_present = grr_is_pbcch_present( );
2697 UBYTE i, j,number_of_frequencies;
2698 BOOL is_existing;
2699 BOOL v_cs_par[MAX_NR_OF_NCELL];
2700 T_NC_ORDER nc_ord = cs_get_network_ctrl_order( TRUE );
2701 T_NC_REF_LIST *nc_list = &grr_data->db.nc_ref_lst;
2702
2703 TRACE_FUNCTION( "cs_send_cr_meas_req" );
2704
2705 {
2706 /*
2707 * first value represents the arfcn of the serving cell
2708 */
2709 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2710 grr_data->nc_data.cell[0].arfcn = psc_db->pbcch.bcch.arfcn;
2711 #else
2712 grr_data->nc_data.cell[0].arfcn = grr_g23_arfcn_to_l1( psc_db->pbcch.bcch.arfcn );
2713 #endif
2714 number_of_frequencies = 1;
2715
2716 memset( v_cs_par, ( is_pbcch_present ? FALSE : TRUE ), sizeof( v_cs_par ) );
2717
2718 for( i = 0; i < nc_list->number; i++ )
2719 {
2720 if( is_pbcch_present )
2721 {
2722 v_cs_par[i] |= nc_list->info[i]->v_cr_par;
2723 }
2724
2725 for( j = i + 1, is_existing = FALSE;
2726 j < nc_list->number AND is_existing EQ FALSE;
2727 j++ )
2728 {
2729 if( nc_list->info[j]->arfcn EQ nc_list->info[i]->arfcn )
2730 {
2731 is_existing = TRUE;
2732
2733 if( is_pbcch_present )
2734 {
2735 v_cs_par[j] |= nc_list->info[i]->v_cr_par;
2736 }
2737 }
2738 }
2739
2740 if( !is_existing AND
2741 ( nc_ord EQ NC_NC2 OR ( nc_ord NEQ NC_NC2 AND v_cs_par[i] ) ) )
2742 {
2743 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2744 grr_data->nc_data.cell[number_of_frequencies].arfcn = nc_list->info[i]->arfcn;
2745 #else
2746 grr_data->nc_data.cell[number_of_frequencies].arfcn =
2747 grr_g23_arfcn_to_l1( nc_list->info[i]->arfcn );
2748 #endif
2749 number_of_frequencies++;
2750 }
2751 }
2752
2753 if( del_meas_rslt EQ CS_DELETE_MEAS_RSLT )
2754 {
2755 cs_reuse_old_cell_rxlev( );
2756 }
2757 grr_data->nc_data.c_cell = number_of_frequencies;
2758 cs_req_cr_meas( );
2759 }
2760 } /* cs_send_cr_meas_req() */
2761
2762 /*
2763 +------------------------------------------------------------------------------
2764 | Function : cs_send_cr_meas_stop_req
2765 +------------------------------------------------------------------------------
2766 | Description : The function cs_send_cr_meas_stop_req() sends the cell
2767 | reselection measurement stop request to L1
2768 | (MPHP_CR_MEAS_STOP_REQ)
2769 |
2770 | Parameters : dummy - description of parameter dummy
2771 |
2772 +------------------------------------------------------------------------------
2773 */
2774 GLOBAL void cs_send_cr_meas_stop_req ( void )
2775 {
2776 TRACE_FUNCTION( "cs_send_cr_meas_stop_req" );
2777
2778
2779 grr_data->nc_data.c_cell = 0;
2780 grr_data->cs.cr_meas_mode = cs_get_cr_meas_mode( );
2781 cs_stop_cr_meas( );
2782
2783 } /* cs_send_cr_meas_stop_req() */
2784
2785 /*
2786 +------------------------------------------------------------------------------
2787 | Function : cs_send_update_ba_req
2788 +------------------------------------------------------------------------------
2789 | Description : The function cs_send_update_ba_req() updates the BA(BCCH) list
2790 | by passing the lists of added and removed frequencies.
2791 |
2792 | Parameters :
2793 |
2794 +------------------------------------------------------------------------------
2795 */
2796 GLOBAL void cs_send_update_ba_req ( T_SC_DATABASE *db )
2797 {
2798 UBYTE i, j; /* used for counting */
2799 BOOL is_found;
2800 T_add_freq_list *afreq;
2801 T_ncell_info *ncinfo;
2802 T_NC_ORDER ctrl_order = cs_get_network_ctrl_order( FALSE );
2803
2804 TRACE_FUNCTION( "cs_send_update_ba_req" );
2805
2806 {
2807 PALLOC( rrgrr_upd_ba_req, RRGRR_UPDATE_BA_REQ );
2808
2809 /* process cell type */
2810 rrgrr_upd_ba_req->cell_type = SYNC_SCELL;
2811
2812 /* process NC mode */
2813 switch( ctrl_order )
2814 {
2815 case NC_NC2: rrgrr_upd_ba_req->nc_mode = NC2_USED; break;
2816 case NC_RESET: rrgrr_upd_ba_req->nc_mode = NC_RESET; break;
2817 default : rrgrr_upd_ba_req->nc_mode = NC2_NOT_USED; break;
2818 }
2819
2820 /* process list of removed frequencies */
2821 if( db->nc_ms.rfreq.number > RRGRR_BA_LIST_SIZE )
2822 {
2823 TRACE_ERROR ( "Number of removed frequencies > RRGRR_BA_LIST_SIZE" );
2824 }
2825
2826 i = 0;
2827 while( i < db->nc_ms.rfreq.number AND i < RRGRR_BA_LIST_SIZE )
2828 {
2829 j = 0;
2830 is_found = FALSE;
2831 while( j < db->nc_cw.list.number AND is_found EQ FALSE )
2832 {
2833 if( db->nc_cw.list.info[j].index EQ db->nc_ms.rfreq.idx[i] )
2834 {
2835 is_found = TRUE;
2836 }
2837 else
2838 {
2839 j++;
2840 }
2841 }
2842
2843 if( is_found EQ TRUE )
2844 {
2845 rrgrr_upd_ba_req->rm_freq_list[i].arfcn = db->nc_cw.list.info[j].arfcn;
2846 rrgrr_upd_ba_req->rm_freq_list[i].bsic = db->nc_cw.list.info[j].bsic;
2847 }
2848 else
2849 {
2850 TRACE_ERROR( "Removed frequency cannot be found in nc_cw structure" );
2851 }
2852
2853 i++;
2854 }
2855
2856 if( i < RRGRR_BA_LIST_SIZE )
2857 {
2858 rrgrr_upd_ba_req->rm_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
2859 rrgrr_upd_ba_req->rm_freq_list[i].bsic = RRGRR_INVALID_BSIC;
2860 }
2861
2862 #ifdef _SIMULATION_
2863
2864 i++;
2865 while( i < RRGRR_BA_LIST_SIZE )
2866 {
2867 rrgrr_upd_ba_req->rm_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
2868 rrgrr_upd_ba_req->rm_freq_list[i].bsic = RRGRR_INVALID_BSIC;
2869 i++;
2870 }
2871
2872 #endif /* #ifdef _SIMULATION_ */
2873
2874 /* process list of added frequencies */
2875 if( db->nc_ms.ncmeas.list.number > RRGRR_BA_LIST_SIZE )
2876 {
2877 TRACE_ERROR ( "Number of added frequencies > RRGRR_BA_LIST_SIZE" );
2878 }
2879
2880 i = 0;
2881 while( i < db->nc_ms.ncmeas.list.number AND i < RRGRR_BA_LIST_SIZE )
2882 {
2883 afreq = &rrgrr_upd_ba_req->add_freq_list[i];
2884 ncinfo = &db->nc_ms.ncmeas.list.info[i];
2885
2886 afreq->arfcn = ncinfo->arfcn;
2887 afreq->bsic = ncinfo->bsic;
2888
2889 if( ncinfo->v_cr_par EQ TRUE )
2890 {
2891 afreq->v_cr_par = TRUE;
2892
2893 afreq->cr_par.cell_bar_access_2 = ncinfo->cr_par.cell_ba;
2894 afreq->cr_par.exc_acc = ncinfo->cr_par.exc_acc;
2895 afreq->cr_par.same_ra_as_serving_cell = ncinfo->cr_par.same_ra_scell;
2896 afreq->cr_par.gprs_rxlev_access_min = ncinfo->cr_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min;
2897 afreq->cr_par.gprs_ms_txpwr_max_cch = ncinfo->cr_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch;
2898 afreq->cr_par.gprs_temporary_offset = ncinfo->cr_par.cr_offset.gprs_temp_offset;
2899 afreq->cr_par.gprs_penalty_time = ncinfo->cr_par.cr_offset.gprs_penalty_time;
2900 afreq->cr_par.gprs_reselect_offset = ncinfo->cr_par.gprs_resel_off;
2901 afreq->cr_par.priority_class = ncinfo->cr_par.cr_par_1.hcs_par.gprs_prio_class;
2902 afreq->cr_par.hcs_thr = ncinfo->cr_par.cr_par_1.hcs_par.gprs_hcs_thr;
2903 afreq->cr_par.si13_location = SI13_LOC_INVALID;
2904 afreq->cr_par.pbcch_location = PBCCH_LOC_INVALID;
2905 afreq->cr_par.psi1_repeat_period = PSI1_RPT_PRD_INVALID;
2906
2907 if( ncinfo->cr_par.v_si13_pbcch )
2908 {
2909 if( ncinfo->cr_par.si13_pbcch.v_si13_location )
2910 {
2911 afreq->cr_par.si13_location = ncinfo->cr_par.si13_pbcch.si13_location;
2912 }
2913 else
2914 {
2915 afreq->cr_par.pbcch_location = ncinfo->cr_par.si13_pbcch.pbcch_location;
2916 afreq->cr_par.psi1_repeat_period = ncinfo->cr_par.si13_pbcch.psi1_repeat_period - 1;
2917 }
2918 }
2919 }
2920 else
2921 {
2922 afreq->v_cr_par = FALSE;
2923 }
2924
2925 i++;
2926 }
2927
2928 if( i < RRGRR_BA_LIST_SIZE )
2929 {
2930 rrgrr_upd_ba_req->add_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
2931 rrgrr_upd_ba_req->add_freq_list[i].bsic = RRGRR_INVALID_BSIC;
2932 }
2933
2934 #ifdef _SIMULATION_
2935
2936 i++;
2937 while( i < RRGRR_BA_LIST_SIZE )
2938 {
2939 rrgrr_upd_ba_req->add_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
2940 rrgrr_upd_ba_req->add_freq_list[i].bsic = RRGRR_INVALID_BSIC;
2941 i++;
2942 }
2943
2944 #endif /* #ifdef _SIMULATION_ */
2945
2946 PSEND( hCommRR, rrgrr_upd_ba_req );
2947 }
2948 } /* cs_send_update_ba_req() */
2949
2950 /*
2951 +------------------------------------------------------------------------------
2952 | Function : cs_send_meas_rep_req
2953 +------------------------------------------------------------------------------
2954 | Description : The function cs_send_meas_rep_req() updates RR with cause
2955 | NC_START_MEAS or NC_REPORT_MEAS or NC_STOP_MEAS.
2956 |
2957 | Parameters : NC_START_MEAS - start the measurement
2958 | NC_REPORT_MEAS - report the measurement
2959 | NC_STOP_MEAS - stop the measurement
2960 |
2961 +------------------------------------------------------------------------------
2962 */
2963 GLOBAL void cs_send_meas_rep_req ( UBYTE cause )
2964 {
2965 TRACE_FUNCTION( "cs_send_meas_rep_req" );
2966
2967 {
2968 PALLOC( rrgrr_meas_rep_req, RRGRR_MEAS_REP_REQ );
2969
2970 rrgrr_meas_rep_req->meas_cause = grr_data->cs_meas.nc_meas_cause = cause;
2971
2972 PSEND( hCommRR, rrgrr_meas_rep_req );
2973 }
2974 } /* cs_send_meas_rep_req() */
2975
2976 /*
2977 +------------------------------------------------------------------------------
2978 | Function : cs_store_meas_rep_cnf
2979 +------------------------------------------------------------------------------
2980 | Description : ...
2981 |
2982 | Parameters : ...
2983 |
2984 +------------------------------------------------------------------------------
2985 */
2986 GLOBAL void cs_store_meas_rep_cnf ( T_RRGRR_MEAS_REP_CNF *rrgrr_meas_rep_cnf )
2987 {
2988 UBYTE i; /* used for counting */
2989 UBYTE mval_idx;
2990 T_NC_MVAL *mval;
2991
2992 TRACE_FUNCTION( "cs_store_meas_rep_cnf" );
2993
2994 /*
2995 * store the first value as serving cell
2996 */
2997 grr_data->db.scell_info.rxlev_avg = rrgrr_meas_rep_cnf->meas_res[0].rxlev;
2998
2999 /*
3000 * store the next values as neighbour cells
3001 */
3002 cs_init_nc_mval_lst( );
3003
3004 for( i = 1;
3005 i < RRGRR_MEAS_REP_LIST_SIZE AND
3006 rrgrr_meas_rep_cnf->meas_res[i].arfcn NEQ RRGRR_INVALID_ARFCN;
3007 i++ )
3008 {
3009 mval = grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &mval_idx );
3010
3011 if( mval NEQ NULL )
3012 {
3013 mval->status = NC_MVAL_STAT_ASSIGNED;
3014 mval->arfcn = rrgrr_meas_rep_cnf->meas_res[i].arfcn;
3015 mval->rla_p.stat = CS_RLA_P_VALID;
3016 mval->rla_p.lev =
3017 mval->rxlev_avg = rrgrr_meas_rep_cnf->meas_res[i].rxlev;
3018 mval->sync_info.bsic = rrgrr_meas_rep_cnf->meas_res[i].bsic;
3019 mval->sync_info.sync.status = STAT_SYNC_OK;
3020
3021 grr_data->cs.is_mval_initialized = FALSE;
3022 }
3023 else
3024 {
3025 TRACE_EVENT_P2( "No free entry for measured value found: %d %d",
3026 rrgrr_meas_rep_cnf->meas_res[i].arfcn,
3027 rrgrr_meas_rep_cnf->meas_res[i].bsic );
3028 }
3029 }
3030 } /* cs_store_meas_rep_cnf() */
3031
3032 /*
3033 +------------------------------------------------------------------------------
3034 | Function : cs_build_strongest
3035 +------------------------------------------------------------------------------
3036 | Description : ...
3037 |
3038 | Parameters : ...
3039 |
3040 +------------------------------------------------------------------------------
3041 */
3042 GLOBAL void cs_build_strongest ( void )
3043 {
3044 UBYTE i;
3045 UBYTE count = 0;
3046 UBYTE index[CS_MAX_STRONG_CARRIER];
3047
3048 TRACE_FUNCTION( "cs_build_strongest" );
3049
3050 cs_find_strongest_with_status
3051 ( &count, index, CS_RLA_P_VALID,
3052 (UBYTE)( CS_MAX_STRONG_CARRIER - count ), CS_NO_BAND_LIMITATION );
3053
3054 for( i = 0; i < count; i++ )
3055 {
3056 grr_data->db.nc_six_strgst[i].idx = index[i];
3057 }
3058
3059 cs_set_cnt_nc_six( count, count );
3060
3061 } /* cs_build_strongest() */
3062
3063 /*
3064 +------------------------------------------------------------------------------
3065 | Function : cs_send_meas_rpt
3066 +------------------------------------------------------------------------------
3067 | Description : This function ...
3068 |
3069 | Parameters : void
3070 |
3071 +------------------------------------------------------------------------------
3072 */
3073 GLOBAL BOOL cs_send_meas_rpt ( BOOL perform_init )
3074 {
3075 BOOL rpt_snd;
3076 T_U_MEAS_REPORT meas_rpt;
3077
3078 TRACE_FUNCTION( "cs_send_meas_rpt" );
3079
3080 if( perform_init EQ TRUE )
3081 {
3082 grr_data->cs_meas.pmr_snd_ref = 0;
3083 }
3084
3085 memset(&meas_rpt, 0, sizeof(T_U_MEAS_REPORT));
3086
3087 rpt_snd = cs_build_meas_rpt( &meas_rpt );
3088
3089 if( rpt_snd EQ TRUE )
3090 {
3091 sig_cs_ctrl_meas_report( &meas_rpt );
3092 }
3093
3094 return( rpt_snd );
3095 } /* cs_send_meas_rpt() */
3096
3097
3098 /*
3099 +------------------------------------------------------------------------------
3100 | Function : cs_start_t_reselect
3101 +------------------------------------------------------------------------------
3102 | Description : ...
3103 |
3104 | Parameters : void
3105 |
3106 +------------------------------------------------------------------------------
3107 */
3108 GLOBAL void cs_start_t_reselect ( void )
3109 {
3110 TRACE_FUNCTION( "cs_start_t_reselect" );
3111
3112 if( grr_t_status( T_RESELECT ) EQ 0 )
3113 {
3114 vsi_t_start( GRR_handle, T_RESELECT, T_RESELECT_VALUE );
3115
3116 TRACE_EVENT( "Timer T_RESELECT started" );
3117 }
3118 } /* cs_start_t_reselect() */
3119
3120 /*
3121 +------------------------------------------------------------------------------
3122 | Function : cs_stop_t_reselect
3123 +------------------------------------------------------------------------------
3124 | Description : ...
3125 |
3126 | Parameters : void
3127 |
3128 +------------------------------------------------------------------------------
3129 */
3130 GLOBAL void cs_stop_t_reselect ( void )
3131 {
3132 TRACE_FUNCTION( "cs_stop_t_reselect" );
3133
3134 if( grr_t_status( T_RESELECT ) NEQ 0 )
3135 {
3136 vsi_t_stop( GRR_handle, T_RESELECT );
3137
3138 TRACE_EVENT( "Timer T_RESELECT stopped" );
3139 }
3140 } /* cs_stop_t_reselect() */
3141
3142 /*
3143 +------------------------------------------------------------------------------
3144 | Function : cs_process_t3158
3145 +------------------------------------------------------------------------------
3146 | Description : ...
3147 |
3148 | Parameters : void
3149 |
3150 +------------------------------------------------------------------------------
3151 */
3152 GLOBAL void cs_process_t3158 ( void )
3153 {
3154 T_TIME reporting_period;
3155 T_TIME time_to_go;
3156 BOOL tmr_3158_rng_le_rp = FALSE;
3157
3158 TRACE_FUNCTION( "cs_process_t3158" );
3159
3160 if( cs_is_meas_reporting( ) )
3161 /* Implies NC measurement conditions are satisfied. May mean Enhanced
3162 measurement conditions are also satisfied */
3163 {
3164 switch( grr_data->cs_meas.packet_mode )
3165 {
3166 case( PACKET_MODE_PIM ):
3167 case( PACKET_MODE_PAM ):
3168 reporting_period = cs_get_nc_rpt_prd_idle( );
3169 break;
3170
3171 case( PACKET_MODE_PTM ):
3172 /*
3173 * In packet transfer mode, the reporting period is indicated in
3174 * NC_REPORTING_PERIOD_T.
3175 */
3176 reporting_period =
3177 GET_NC_RPT_PRD( grr_data->db.nc_ref_lst.param->rep_per_t );
3178 break;
3179
3180 default:
3181 if( GET_STATE( CS ) EQ CS_CR_NETWORK )
3182 {
3183 /*
3184 * In case timer T3158 expires during processing of Packet Cell Change
3185 * Order, the timer should be re-started and not stopped at all.
3186 */
3187 reporting_period = cs_get_nc_rpt_prd_idle( );
3188 }
3189 else
3190 {
3191 reporting_period = 0;
3192 }
3193 break;
3194 }
3195
3196 time_to_go = grr_t_status( T3158 );
3197
3198 if( time_to_go > 0 )
3199 {
3200 if( time_to_go > reporting_period )
3201 {
3202 cs_stop_t3158( );
3203
3204 if( grr_is_pbcch_present( ) EQ FALSE AND
3205 grr_data->cs_meas.nc_meas_cause NEQ NC_STOP_MEAS )
3206 {
3207 cs_send_meas_rep_req ( NC_STOP_MEAS );
3208 }
3209 }
3210 else
3211 {
3212 tmr_3158_rng_le_rp = TRUE;
3213 }
3214 }
3215
3216 if( reporting_period NEQ 0 )
3217 {
3218 if( tmr_3158_rng_le_rp EQ FALSE )
3219 {
3220 cs_reset_all_rxlev_results( );
3221 cs_start_t3158( reporting_period );
3222 /*
3223 * Start rx_lev averaging when NC=1 or NC=2 in ALR
3224 */
3225 if( grr_is_pbcch_present( ) EQ FALSE AND
3226 grr_data->cs_meas.nc_meas_cause EQ NC_STOP_MEAS )
3227 {
3228 cs_send_meas_rep_req ( NC_START_MEAS ) ;
3229 }
3230 }
3231 }
3232 else
3233 {
3234 cs_reset_all_rxlev_results( );
3235 }
3236 }
3237 else
3238 {
3239 cs_reset_all_rxlev_results( );
3240 cs_stop_t3158( );
3241 /*
3242 * Stop rx_lev averaging when NC=1 or NC=2 in ALR
3243 */
3244 if( grr_is_pbcch_present( ) EQ FALSE AND
3245 grr_data->cs_meas.nc_meas_cause NEQ NC_STOP_MEAS )
3246 {
3247 cs_send_meas_rep_req ( NC_STOP_MEAS );
3248 }
3249 }
3250 } /* cs_process_t3158() */
3251
3252 /*
3253 +------------------------------------------------------------------------------
3254 | Function : cs_start_t3158
3255 +------------------------------------------------------------------------------
3256 | Description :
3257 |
3258 | Parameters :
3259 |
3260 +------------------------------------------------------------------------------
3261 */
3262 LOCAL void cs_start_t3158 ( T_TIME time )
3263 {
3264 TRACE_FUNCTION( "cs_start_t3158" );
3265
3266 vsi_t_start( GRR_handle, T3158, time );
3267
3268 TRACE_EVENT_P1( "T3158: %d", time );
3269
3270 } /* cs_start_t3158() */
3271
3272 /*
3273 +------------------------------------------------------------------------------
3274 | Function : cs_stop_t3158
3275 +------------------------------------------------------------------------------
3276 | Description :
3277 |
3278 | Parameters :
3279 |
3280 +------------------------------------------------------------------------------
3281 */
3282 GLOBAL void cs_stop_t3158 ( void )
3283 {
3284 TRACE_FUNCTION( "cs_stop_t3158" );
3285
3286 if( grr_t_status( T3158 ) > 0 )
3287 {
3288 vsi_t_stop( GRR_handle, T3158 );
3289
3290 TRACE_EVENT( "T3158 stopped" );
3291 }
3292 } /* cs_stop_t3158() */
3293
3294 /*
3295 +------------------------------------------------------------------------------
3296 | Function : cs_cancel_meas_report
3297 +------------------------------------------------------------------------------
3298 | Description : ...
3299 |
3300 | Parameters : void
3301 |
3302 +------------------------------------------------------------------------------
3303 */
3304 GLOBAL void cs_cancel_meas_report ( void )
3305 {
3306 TRACE_FUNCTION( "cs_cancel_meas_report" );
3307
3308 switch( GET_STATE( CS_MEAS ) )
3309 {
3310 case CS_MEAS_REP_REQ:
3311 SET_STATE( CS_MEAS, CS_NULL );
3312 break;
3313 case CS_MEAS_PMR_SENDING:
3314 sig_cs_ctrl_cancel_meas_report( );
3315 break;
3316 default:
3317 /* do nothing */
3318 break;
3319 }
3320 } /* cs_cancel_meas_report() */
3321
3322 /*
3323 +------------------------------------------------------------------------------
3324 | Function : cs_build_nc_ref_list
3325 +------------------------------------------------------------------------------
3326 | Description :
3327 |
3328 | Parameters : db - pointer to serving cell database
3329 |
3330 +------------------------------------------------------------------------------
3331 */
3332 GLOBAL void cs_build_nc_ref_list ( T_SC_DATABASE *db, BOOL is_dsf )
3333 {
3334 TRACE_FUNCTION( "cs_build_nc_ref_list" );
3335
3336 cs_init_nc_ref_list( &grr_data->db.nc_ref_lst );
3337
3338 if(
3339 grr_data->cs.gmm_state EQ READY_STATE AND
3340 is_dsf EQ FALSE AND
3341 (
3342 db->nc_ms.ncmeas.param.ctrl_order EQ NC_NC0 OR
3343 db->nc_ms.ncmeas.param.ctrl_order EQ NC_NC1 OR
3344 db->nc_ms.ncmeas.param.ctrl_order EQ NC_NC2
3345 )
3346 )
3347 {
3348 grr_data->db.nc_ref_lst.param = &db->nc_ms.ncmeas.param;
3349
3350 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3351 grr_data->db.nc_ref_lst.enh_param = &db->enh_ms;
3352 #endif
3353 }
3354 else if( db->nc_cw.param.ctrl_order EQ NC_NC0 OR
3355 db->nc_cw.param.ctrl_order EQ NC_NC1 OR
3356 db->nc_cw.param.ctrl_order EQ NC_NC2 )
3357 {
3358 grr_data->db.nc_ref_lst.param = &db->nc_cw.param;
3359
3360 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3361 grr_data->db.nc_ref_lst.enh_param = &db->enh_cw;
3362 #endif
3363 }
3364
3365 cs_build_nc_freq_list( db );
3366 cs_reorg_nc_mval_lst( );
3367
3368 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3369 if( !grr_is_pbcch_present() AND
3370 grr_data->db.nc_ref_lst.enh_param->rept_type EQ REPORT_TYPE_ENH_REP)
3371 {
3372 cs_init_ba_bcch_nc_ref_list();
3373 cs_build_ba_bcch_nc_freq_list();
3374 }
3375 #endif
3376
3377 }/* cs_build_nc_ref_list */
3378
3379 /*
3380 +------------------------------------------------------------------------------
3381 | Function : cs_init_nc_ref_list
3382 +------------------------------------------------------------------------------
3383 | Description :
3384 |
3385 | Parameters : list - pointer to NC measurement pointer list
3386 |
3387 +------------------------------------------------------------------------------
3388 */
3389 GLOBAL void cs_init_nc_ref_list ( T_NC_REF_LIST *list )
3390 {
3391 TRACE_FUNCTION( "cs_init_nc_ref_list" );
3392
3393 list->number = 0;
3394 list->param = NULL;
3395
3396 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3397 list->enh_param = NULL;
3398 #endif
3399
3400 }/* cs_init_nc_ref_list */
3401
3402
3403 /*
3404 +------------------------------------------------------------------------------
3405 | Function : cs_init_nc_mval_lst
3406 +------------------------------------------------------------------------------
3407 | Description :
3408 |
3409 | Parameters :
3410 |
3411 +------------------------------------------------------------------------------
3412 */
3413 GLOBAL void cs_init_nc_mval_lst ( void )
3414 {
3415 UBYTE i;
3416
3417 TRACE_FUNCTION( "cs_init_nc_mval_lst" );
3418
3419 if( grr_data->cs.is_mval_initialized EQ FALSE )
3420 {
3421 for( i = 0; i < MAX_NR_OF_NC_MVAL; i++ )
3422 {
3423 cs_init_nc_mval( &grr_data->db.nc_mval_list.nc_mval[i] );
3424 }
3425
3426 grr_data->cs.is_mval_initialized = TRUE;
3427
3428 #if !defined (NTRACE)
3429
3430 if( grr_data->cs.v_crp_trace EQ TRUE )
3431 {
3432 TRACE_EVENT( "cs_init_nc_mval_lst: now initialized" );
3433 }
3434
3435 #endif /* #if !defined (NTRACE) */
3436
3437 }
3438 else
3439 {
3440
3441 #if !defined (NTRACE)
3442
3443 if( grr_data->cs.v_crp_trace EQ TRUE )
3444 {
3445 TRACE_EVENT( "cs_init_nc_mval_lst: already initialized" );
3446 }
3447
3448 #endif /* #if !defined (NTRACE) */
3449
3450 }
3451 }/* cs_init_nc_mval_lst */
3452
3453 /*
3454 +------------------------------------------------------------------------------
3455 | Function : cs_init_nc_mval
3456 +------------------------------------------------------------------------------
3457 | Description :
3458 |
3459 | Parameters : mval - pointer to NC measured value
3460 |
3461 +------------------------------------------------------------------------------
3462 */
3463 LOCAL void cs_init_nc_mval ( T_NC_MVAL *mval )
3464 {
3465 TRACE_FUNCTION( "cs_init_nc_mval" );
3466
3467 mval->arfcn = RRGRR_INVALID_ARFCN;
3468 mval->sync_info.bsic = RRGRR_INVALID_BSIC;
3469 mval->sync_info.sync.status = STAT_SYNC_NONE;
3470 mval->sync_info.sync.sync_failed_cnt = 0;
3471 mval->rla_p.stat = CS_RLA_P_NOT_AVAIL;
3472 mval->rxlev_avg = RXLEV_AVG_INVALID;
3473 mval->status = NC_MVAL_STAT_NONE;
3474 }/* cs_init_nc_mval */
3475
3476
3477 /*
3478 +------------------------------------------------------------------------------
3479 | Function : cs_update_bsic
3480 +------------------------------------------------------------------------------
3481 | Description :
3482 |
3483 | Parameters :
3484 |
3485 +------------------------------------------------------------------------------
3486 */
3487 GLOBAL void cs_update_bsic ( void )
3488 {
3489 UBYTE i
3490 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3491 ,j, k
3492 #endif
3493 ;
3494 /* used for counting */
3495 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3496 UBYTE i_max,rtd_index,rtd_count;
3497 #else
3498 UBYTE i_max;
3499 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3500
3501
3502 TRACE_FUNCTION( "cs_update_bsic" );
3503
3504 i = 0;
3505 i_max = MINIMUM( grr_data->db.cnt_nc_six.candid, CS_MAX_STRONG_CARRIER );
3506 i_max = MINIMUM( i_max, RRGRR_MAX_ARFCN_NCELL_SYNC_REQ );
3507
3508 if( i_max NEQ 0 )
3509 {
3510 PALLOC( rrgrr_check_bsic_req, RRGRR_NCELL_SYNC_REQ );
3511
3512 while( i < i_max )
3513 {
3514 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3515 rrgrr_check_bsic_req->ncell_sync_list[i].arfcn = grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].arfcn;
3516 #else
3517 rrgrr_check_bsic_req->arfcn[i] = grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].arfcn;
3518 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3519
3520
3521 i++;
3522 }
3523 #if defined (REL99) AND defined (TI_PS_FF_EMR)
3524 /* Extend the ARFCN list only if ENH reporting is requested */
3525 if(cs_is_enh_meas_reporting())
3526 {
3527 T_ENH_STRNG_ARFCN_LIST f_bin;/* Stores the ARFCN-RXLEV pair in descending
3528 order of RXLEV */
3529 BOOL found; /* Will be set, if ARFCN in f_bin is found in NC_MVAL */
3530
3531 memset(&f_bin, 0, sizeof(T_ENH_STRNG_ARFCN_LIST));
3532
3533 /* Form a ARFCN-RXLEV pair list in descending order of RXLEV */
3534 cs_build_enh_sorted_strng_arfcn_list(&f_bin);
3535
3536 /* Fill the NCELL_SYNC_REQ with ARFCNs from the above list. This list
3537 will be filled without disturbing the six strongest cells for
3538 cell reselection or PMR. The request for SYNC is now done for a
3539 max of 12 cells with 1st few cells upto a max of six for cell
3540 reselection and the remaining will be filled with ARFCNs from
3541 the ENH list in the order of serving band, multiband and the rest
3542 contains the excess from the above bands, each group containing
3543 cells in descending order of RXLEV */
3544 j = 0;
3545 while(i_max < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ AND j < f_bin.num)
3546 {
3547 found = FALSE;
3548 for(k = 0; k < grr_data->db.cnt_nc_six.candid; k++)
3549 {
3550 if(f_bin.meas[j].arfcn EQ
3551 grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[k].idx].arfcn)
3552 {
3553 found = TRUE;
3554 break;
3555 }
3556 }
3557
3558 if(!found)
3559 {
3560 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3561 rrgrr_check_bsic_req->ncell_sync_list[i_max].arfcn = f_bin.meas[j].arfcn;
3562 #else
3563 rrgrr_check_bsic_req->arfcn[i_max] = f_bin.meas[j].arfcn;
3564 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3565
3566 i_max++;
3567 }
3568 j++;
3569 }
3570 }
3571
3572 if( i_max < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
3573 {
3574 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3575 rrgrr_check_bsic_req->ncell_sync_list[i_max].arfcn = RRGRR_INVALID_ARFCN;
3576 #else
3577 rrgrr_check_bsic_req->arfcn[i_max] = RRGRR_INVALID_ARFCN;
3578 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3579 } /*if*/
3580 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3581 i=0;
3582 while (i < i_max)
3583 {
3584 j = 0;
3585 rtd_count = 0;
3586 /*More than 3 RTD values is not acceptable */
3587 while( j < grr_data->db.nc_ref_lst.number AND rtd_count < MAX_NUM_OF_RTD_VALUES )
3588 {
3589 /* Check the NC ARFCN in the BA-list to get the index of that ARFCN in BA-list*/
3590 if(rrgrr_check_bsic_req->ncell_sync_list[i].arfcn EQ (grr_data->db.nc_ref_lst.info[j])->arfcn)
3591 {
3592 /* Pickup the right RTD value for that ARFCN */
3593 rtd_index = (grr_data->db.nc_ref_lst.info[j])->index;
3594 /*Maximum number of ncell is 32 if it exceeds then store RTD_NOT_AVAILABLE for that ARFCN*/
3595 if(rtd_index < MAX_NR_OF_NCELL AND psc_db->rtd[rtd_index] NEQ RTD_NOT_AVAILABLE )
3596 {
3597 rrgrr_check_bsic_req->ncell_sync_list[i].v_rtd = 1;
3598 rrgrr_check_bsic_req->ncell_sync_list[i].rtd[rtd_count] = psc_db->rtd[rtd_index];
3599 rtd_count++;
3600 }/*if*/
3601 } /*if*/
3602 j++;
3603 } /*while*/
3604 rrgrr_check_bsic_req->ncell_sync_list[i].c_rtd = rtd_count;
3605 i++;
3606 } /*while*/
3607 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3608
3609
3610 #ifdef _SIMULATION_
3611
3612 i_max = i_max + 1;
3613 while( i_max < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
3614 {
3615 #if defined (TI_PS_FF_RTD) AND defined (REL99)
3616 rrgrr_check_bsic_req->ncell_sync_list[i_max].arfcn = RRGRR_INVALID_ARFCN;
3617 #else
3618 rrgrr_check_bsic_req->arfcn[i_max] = RRGRR_INVALID_ARFCN;
3619 #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
3620
3621 i_max++;
3622 }
3623 #endif
3624 #else
3625
3626 if( i < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
3627 {
3628 rrgrr_check_bsic_req->arfcn[i] = RRGRR_INVALID_ARFCN;
3629 }
3630
3631 #ifdef _SIMULATION_
3632
3633 i = i + 1;
3634 while( i < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
3635 {
3636 rrgrr_check_bsic_req->arfcn[i] = RRGRR_INVALID_ARFCN;
3637 i++;
3638 }
3639
3640 #endif /* #ifdef _SIMULATION_ */
3641
3642 #endif /* REL99 AND TI_PS_FF_EMR */
3643
3644 rrgrr_check_bsic_req->sync_type = SYNC_INITIAL;
3645 PSEND( hCommRR, rrgrr_check_bsic_req );
3646 }
3647 }/* cs_update_bsic */
3648
3649
3650 /*
3651 +------------------------------------------------------------------------------
3652 | Function : cs_find_candidate
3653 +------------------------------------------------------------------------------
3654 | Description :
3655 |
3656 | Parameters :
3657 |
3658 +------------------------------------------------------------------------------
3659 */
3660 GLOBAL BOOL cs_find_candidate ( void )
3661 {
3662 BOOL is_new_candidate = FALSE;
3663 T_scell_info *sc;
3664
3665 TRACE_FUNCTION( "cs_find_candidate" );
3666
3667 if( grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_ABNORMAL AND
3668 psc_db->gen_cell_par.rab_acc_re EQ GRR_RA_RETRY_DISABLED )
3669 {
3670 grr_data->db.cr_cell = NULL;
3671
3672 #if !defined (NTRACE)
3673
3674 if( grr_data->cs.v_crp_trace EQ TRUE )
3675 {
3676 TRACE_EVENT( "no candidate found, RA retry bit for abnormal cell re-selection not set" );
3677 }
3678
3679 #endif /* #if !defined (NTRACE) */
3680
3681 }
3682 else if( grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_SCELL )
3683 {
3684 if( cs_create_cr_cell( psc_db->pbcch.bcch.arfcn,
3685 psc_db->pbcch.bcch.bsic ) NEQ NULL )
3686 {
3687
3688 #if !defined (NTRACE)
3689
3690 if( grr_data->cs.v_crp_trace EQ TRUE )
3691 {
3692 TRACE_EVENT( "serving cell found as candidate" );
3693 }
3694
3695 #endif /* #if !defined (NTRACE) */
3696
3697 /*
3698 * the cell re-selection process will be started
3699 */
3700 is_new_candidate = TRUE;
3701 }
3702 }
3703 else
3704 {
3705 cs_get_best_cell( &grr_data->db.cr_cell, &sc );
3706
3707 if( grr_data->db.cr_cell NEQ NULL )
3708 {
3709
3710 #if !defined (NTRACE)
3711
3712 if( grr_data->cs.v_crp_trace EQ TRUE )
3713 {
3714 TRACE_EVENT( "candidate found" );
3715 }
3716
3717 #endif /* #if !defined (NTRACE) */
3718
3719 /*
3720 * the cell re-selection process will be started
3721 */
3722 is_new_candidate = TRUE;
3723 }
3724 else if( sc NEQ NULL )
3725 {
3726
3727 #if !defined (NTRACE)
3728
3729 if( grr_data->cs.v_crp_trace EQ TRUE )
3730 {
3731 TRACE_EVENT( "no candidate found, serving cell good" );
3732 }
3733
3734 #endif /* #if !defined (NTRACE) */
3735
3736 /*
3737 * the serving cell becomes good again or is still good
3738 */
3739 cs_stop_t_reselect( );
3740 }
3741 else
3742 {
3743
3744 #if !defined (NTRACE)
3745
3746 if( grr_data->cs.v_crp_trace EQ TRUE )
3747 {
3748 TRACE_EVENT( "no candidate found, serving cell bad" );
3749 }
3750
3751 #endif /* #if !defined (NTRACE) */
3752
3753 /*
3754 * the serving cell becomes bad but
3755 * no suitable neighbour cell is available
3756 */
3757 cs_start_t_reselect( );
3758 }
3759 }
3760
3761 return( is_new_candidate );
3762 }/* cs_find_candidate */
3763
3764 /*
3765 +------------------------------------------------------------------------------
3766 | Function : cs_cr_decision
3767 +------------------------------------------------------------------------------
3768 | Description :
3769 |
3770 | Parameters :
3771 |
3772 +------------------------------------------------------------------------------
3773 */
3774 GLOBAL BOOL cs_cr_decision ( T_CRDM mode )
3775 {
3776 T_NC_ORDER ctrl_order;
3777 BOOL cr_initiated = FALSE;
3778
3779 TRACE_FUNCTION( "cs_cr_decision" );
3780
3781 switch( mode )
3782 {
3783 case( CRDM_T_RESELECT ):
3784 sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
3785
3786 cr_initiated = TRUE;
3787 break;
3788
3789 case( CRDM_CR_CTRL ):
3790 ctrl_order = cs_get_network_ctrl_order( TRUE );
3791
3792 if( ctrl_order EQ NC_NC0 OR
3793 ctrl_order EQ NC_NC1 OR
3794 grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_SCELL OR
3795 ( grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_DL_SIG_FAIL AND
3796 ctrl_order EQ NC_NC2 ) )
3797 {
3798 /*
3799 * Only in case the NETWORK_CONTROL_ORDER is either equal to
3800 * NC0 or NC1 the MS shall perform automomous cell re-selection
3801 */
3802
3803 if( cs_find_candidate( ) )
3804 {
3805 sig_cs_ctrl_new_candidate( grr_data->cs.reselect_cause );
3806 }
3807 else
3808 {
3809 sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
3810 }
3811 }
3812 else
3813 {
3814 sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
3815 }
3816
3817 cr_initiated = TRUE;
3818 break;
3819
3820 case( CRDM_CR_INITIAL ):
3821 ctrl_order = cs_get_network_ctrl_order( TRUE );
3822
3823 if( ctrl_order EQ NC_NC0 OR ctrl_order EQ NC_NC1 )
3824 {
3825 /*
3826 * Only in case the NETWORK_CONTROL_ORDER is either equal to
3827 * NC0 or NC1 the MS shall perform automomous cell re-selection
3828 */
3829
3830 grr_data->db.cr_cell = NULL;
3831
3832 cs_calc_params( );
3833
3834 if( cs_find_candidate( ) )
3835 {
3836 sig_cs_ctrl_new_candidate( grr_data->cs.reselect_cause );
3837
3838 cr_initiated = TRUE;
3839 }
3840 }
3841 break;
3842
3843 case( CRDM_CR_CONT ):
3844 if( cs_find_candidate( ) )
3845 {
3846 sig_cs_ctrl_new_candidate( grr_data->cs.reselect_cause );
3847 }
3848 else
3849 {
3850 sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
3851 }
3852
3853 cr_initiated = TRUE;
3854 break;
3855
3856 default:
3857 TRACE_ASSERT( mode EQ CRDM_T_RESELECT OR
3858 mode EQ CRDM_CR_CTRL OR
3859 mode EQ CRDM_CR_INITIAL OR
3860 mode EQ CRDM_CR_CONT );
3861 break;
3862 }
3863
3864 if( cr_initiated EQ TRUE )
3865 {
3866 TRACE_EVENT_P2( "cs_cr_decision: mode %d, reselect_cause %d",
3867 mode, grr_data->cs.reselect_cause );
3868 }
3869
3870 return( cr_initiated );
3871
3872 }/* cs_cr_decision */
3873
3874
3875
3876
3877
3878 /*
3879 +------------------------------------------------------------------------------
3880 | Function : cs_trace_nc_mval_lst
3881 +------------------------------------------------------------------------------
3882 | Description :
3883 |
3884 | Parameters : void
3885 |
3886 +------------------------------------------------------------------------------
3887 */
3888 LOCAL void cs_trace_nc_mval_lst ( void )
3889 {
3890
3891 #if !defined (NTRACE)
3892
3893 UBYTE read, write;
3894 USHORT arfcn[8];
3895 UBYTE bsic[8];
3896 T_NC_MVAL_STATUS status[8];
3897 T_RXLEV_AVG rxlev_avg[8];
3898 UBYTE rla_p_lev[8];
3899 UBYTE rla_p_stat[8];
3900
3901
3902 TRACE_FUNCTION( "cs_trace_nc_mval_lst" );
3903
3904 if( grr_data->cs.v_crp_trace EQ TRUE )
3905 {
3906 memset( arfcn, 0xFF, sizeof( arfcn ) );
3907 memset( bsic, 0xFF, sizeof( bsic ) );
3908 memset( status, 0xFF, sizeof( status ) );
3909 memset( rxlev_avg, 0xFF, sizeof( rxlev_avg ) );
3910 memset( rla_p_lev, 0xFF, sizeof( rla_p_lev ) );
3911 memset( rla_p_stat, 0xFF, sizeof( rla_p_stat ) );
3912
3913 write = 0;
3914
3915 for( read = 0; read < MAX_NR_OF_NC_MVAL; read++ )
3916 {
3917 if( grr_data->db.nc_mval_list.nc_mval[read].status NEQ NC_MVAL_STAT_NONE )
3918 {
3919 arfcn[write] = grr_data->db.nc_mval_list.nc_mval[read].arfcn;
3920 bsic[write] = grr_data->db.nc_mval_list.nc_mval[read].sync_info.bsic;
3921 status[write] = grr_data->db.nc_mval_list.nc_mval[read].status;
3922 rla_p_lev [write] = grr_data->db.nc_mval_list.nc_mval[read].rla_p.lev;
3923 rla_p_stat [write] = grr_data->db.nc_mval_list.nc_mval[read].rla_p.stat;
3924 rxlev_avg [write] = grr_data->db.nc_mval_list.nc_mval[read].rxlev_avg;
3925
3926 write++;
3927 }
3928
3929 if( write EQ 8 )
3930 {
3931 TRACE_EVENT_P8
3932 ( "NC_MVAL_LIST ARFCN: %5d %5d %5d %5d %5d %5d %5d %5d",
3933 arfcn[0], arfcn[1], arfcn[2], arfcn[3],
3934 arfcn[4], arfcn[5], arfcn[6], arfcn[7] );
3935
3936 TRACE_EVENT_P8
3937 ( "NC_MVAL_LIST BSIC: %5d %5d %5d %5d %5d %5d %5d %5d",
3938 bsic[0], bsic[1], bsic[2], bsic[3],
3939 bsic[4], bsic[5], bsic[6], bsic[7] );
3940
3941 TRACE_EVENT_P8
3942 ( "NC_MVAL_LIST STATUS: %5d %5d %5d %5d %5d %5d %5d %5d",
3943 status[0], status[1], status[2], status[3],
3944 status[4], status[5], status[6], status[7] );
3945
3946 TRACE_EVENT_P8
3947 ( "NC_MVAL_LIST T_RXLEV_AVG: %5d %5d %5d %5d %5d %5d %5d %5d",
3948 rxlev_avg[0], rxlev_avg[1], rxlev_avg[2], rxlev_avg[3],
3949 rxlev_avg[4], rxlev_avg[5], rxlev_avg[6], rxlev_avg[7] );
3950
3951 TRACE_EVENT_P8
3952 ( "NC_MVAL_LIST rla_p.stat: %5d %5d %5d %5d %5d %5d %5d %5d",
3953 rla_p_stat[0], rla_p_stat[1], rla_p_stat[2], rla_p_stat[3],
3954 rla_p_stat[4], rla_p_stat[5], rla_p_stat[6], rla_p_stat[7] );
3955
3956 TRACE_EVENT_P8
3957 ( "NC_MVAL_LIST rla_p.lev: %5d %5d %5d %5d %5d %5d %5d %5d",
3958 rla_p_lev[0], rla_p_lev[1], rla_p_lev[2], rla_p_lev[3],
3959 rla_p_lev[4], rla_p_lev[5], rla_p_lev[6], rla_p_lev[7] );
3960
3961 memset( arfcn, 0xFF, sizeof( arfcn ) );
3962 memset( bsic, 0xFF, sizeof( bsic ) );
3963 memset( status, 0xFF, sizeof( status ) );
3964 memset( rxlev_avg, 0xFF, sizeof( rxlev_avg ) );
3965 memset( rla_p_lev, 0xFF, sizeof( rla_p_lev ) );
3966 memset( rla_p_stat, 0xFF, sizeof( rla_p_stat ) );
3967
3968 write = 0;
3969 }
3970 }
3971
3972 if( write NEQ 0 )
3973 {
3974 TRACE_EVENT_P8
3975 ( "NC_MVAL_LIST ARFCN: %5d %5d %5d %5d %5d %5d %5d %5d",
3976 arfcn[0], arfcn[1], arfcn[2], arfcn[3],
3977 arfcn[4], arfcn[5], arfcn[6], arfcn[7] );
3978
3979 TRACE_EVENT_P8
3980 ( "NC_MVAL_LIST BSIC: %5d %5d %5d %5d %5d %5d %5d %5d",
3981 bsic[0], bsic[1], bsic[2], bsic[3],
3982 bsic[4], bsic[5], bsic[6], bsic[7] );
3983
3984 TRACE_EVENT_P8
3985 ( "NC_MVAL_LIST STATUS: %5d %5d %5d %5d %5d %5d %5d %5d",
3986 status[0], status[1], status[2], status[3],
3987 status[4], status[5], status[6], status[7] );
3988
3989 TRACE_EVENT_P8
3990 ( "NC_MVAL_LIST T_RXLEV_AVG: %5d %5d %5d %5d %5d %5d %5d %5d",
3991 rxlev_avg[0], rxlev_avg[1], rxlev_avg[2], rxlev_avg[3],
3992 rxlev_avg[4], rxlev_avg[5], rxlev_avg[6], rxlev_avg[7] );
3993
3994 TRACE_EVENT_P8
3995 ( "NC_MVAL_LIST rla_p.stat: %5d %5d %5d %5d %5d %5d %5d %5d",
3996 rla_p_stat[0], rla_p_stat[1], rla_p_stat[2], rla_p_stat[3],
3997 rla_p_stat[4], rla_p_stat[5], rla_p_stat[6], rla_p_stat[7] );
3998
3999 TRACE_EVENT_P8
4000 ( "NC_MVAL_LIST rla_p.lev: %5d %5d %5d %5d %5d %5d %5d %5d",
4001 rla_p_lev[0], rla_p_lev[1], rla_p_lev[2], rla_p_lev[3],
4002 rla_p_lev[4], rla_p_lev[5], rla_p_lev[6], rla_p_lev[7] );
4003 }
4004 }
4005
4006 #endif /* #if !defined (NTRACE) */
4007
4008 } /* cs_trace_nc_mval_lst( ) */
4009
4010
4011 /*
4012 +------------------------------------------------------------------------------
4013 | Function : cs_stop_cr_meas
4014 +------------------------------------------------------------------------------
4015 | Description : The function cs_stop_cr_meas () ....
4016 |
4017 | Parameters : void
4018 |
4019 +------------------------------------------------------------------------------
4020 */
4021 GLOBAL void cs_stop_cr_meas( void )
4022 {
4023 TRACE_FUNCTION( "cs_stop_cr_meas" );
4024
4025 switch( grr_data->cs.cr_meas_mode )
4026 {
4027 case( CS_CRMM_BA_GPRS ):
4028 if( grr_data->cs.stop_req EQ FALSE )
4029 {
4030 PALLOC( mphp_cr_meas_stop_req, MPHP_CR_MEAS_STOP_REQ );
4031
4032 #if 0
4033
4034 /*
4035 * the timing for the MPHP_CR_MEAS_STOP_CON is not correct on
4036 * layer 1 side, so we are no longer consider the confirmation
4037 */
4038
4039 grr_data->cs.stop_req = TRUE;
4040
4041 #endif /* #if 0 */
4042
4043 PSEND( hCommL1, mphp_cr_meas_stop_req );
4044 }
4045 break;
4046 case( CS_CRMM_BA_BCCH ):
4047 grr_data->cs.cr_meas_update = FALSE;
4048 break;
4049 }
4050 } /* cs_stop_cr_meas() */
4051
4052
4053 /*
4054 +------------------------------------------------------------------------------
4055 | Function : cs_req_cr_meas
4056 +------------------------------------------------------------------------------
4057 | Description : The function cs_req_cr_meas () ....
4058 |
4059 | Parameters : void
4060 |
4061 +------------------------------------------------------------------------------
4062 */
4063 GLOBAL void cs_req_cr_meas ( void )
4064 {
4065 TRACE_FUNCTION( "cs_req_cr_meas" );
4066
4067 if( nc_data->c_cell NEQ 0 )
4068 {
4069 if( grr_data->cs_meas.packet_mode NEQ PACKET_MODE_PTM )
4070 {
4071 PALLOC( mphp_cr_meas_req, MPHP_CR_MEAS_REQ );
4072
4073 cs_fill_cr_meas_req( mphp_cr_meas_req, grr_data->cs.list_id );
4074
4075 grr_data->cs.list_id++;
4076
4077 PSEND( hCommL1, mphp_cr_meas_req );
4078 }
4079 else
4080 {
4081 PALLOC( mphp_tcr_meas_req, MPHP_TCR_MEAS_REQ );
4082
4083 grr_data->cs.last_assignment_id++;
4084 grr_data->cs.cr_meas_update = TRUE;
4085
4086 cs_fill_cr_meas_req( (T_MPHP_CR_MEAS_REQ*)mphp_tcr_meas_req,
4087 grr_data->cs.last_assignment_id );
4088
4089 PSEND( hCommL1, mphp_tcr_meas_req );
4090 }
4091
4092 grr_data->cs.stop_req = FALSE;
4093 }
4094 } /* cs_req_cr_meas() */
4095
4096
4097 /*
4098 +------------------------------------------------------------------------------
4099 | Function : cs_fill_cr_meas_req
4100 +------------------------------------------------------------------------------
4101 | Description : ...
4102 |
4103 | Parameters : prim - Pointer to primitive buffer
4104 |
4105 +------------------------------------------------------------------------------
4106 */
4107 GLOBAL void cs_fill_cr_meas_req ( T_MPHP_CR_MEAS_REQ *prim, UBYTE id )
4108 {
4109 UBYTE i; /* used for counting */
4110
4111 TRACE_FUNCTION( "cs_fill_cr_meas_req" );
4112
4113 prim->nb_carrier = nc_data->c_cell;
4114 prim->list_id = id;
4115
4116 for( i = 0; i < nc_data->c_cell; i++ )
4117 {
4118 #if defined (REL99) AND defined (TI_PS_FF_EMR)
4119 prim->carrier_list[i] = grr_g23_arfcn_to_l1(nc_data->cell[i].arfcn);
4120 #else
4121 prim->carrier_list[i] = nc_data->cell[i].arfcn;
4122 #endif
4123 }
4124
4125 #ifdef _SIMULATION_
4126
4127 for( i = nc_data->c_cell; i < MPHP_NUMC_BA_GPRS_SC; i++ )
4128 {
4129 prim->carrier_list[i] = 0xFFFF;
4130 }
4131
4132 #endif /* #ifdef _SIMULATION_ */
4133
4134 } /* cs_fill_cr_meas_req() */
4135
4136
4137 /*
4138 +------------------------------------------------------------------------------
4139 | Function : cs_reset_all_cell_results
4140 +------------------------------------------------------------------------------
4141 | Description : The function cs_reset_all_cell_results() ....
4142 |
4143 | Parameters : void
4144 |
4145 +------------------------------------------------------------------------------
4146 */
4147 GLOBAL void cs_reset_all_cell_results ( void )
4148 {
4149 UBYTE i; /* used for counting */
4150
4151 TRACE_FUNCTION( "cs_reset_all_cell_results" );
4152
4153 for( i = 0; i < MPHP_NUMC_BA_GPRS_SC; i++ )
4154 {
4155 cs_reset_meas_result( &nc_data->cell[i] );
4156 }
4157 } /* cs_reset_all_cell_results () */
4158
4159 /*
4160 +------------------------------------------------------------------------------
4161 | Function : cs_reset_all_rxlev_results
4162 +------------------------------------------------------------------------------
4163 | Description : The function cs_reset_all_rxlev_results() ....
4164 |
4165 | Parameters : ...
4166 |
4167 +------------------------------------------------------------------------------
4168 */
4169 GLOBAL void cs_reset_all_rxlev_results ( void )
4170 {
4171 UBYTE i; /* used for counting */
4172
4173 TRACE_FUNCTION( "cs_reset_all_rxlev_results" );
4174
4175 for( i = 0; i < MPHP_NUMC_BA_GPRS_SC; i++ )
4176 {
4177 nc_data->cell[i].rxlev_data.acc = 0;
4178 nc_data->cell[i].rxlev_data.nbr = 0;
4179 }
4180 } /* cs_reset_all_rxlev_results () */
4181
4182 /*
4183 +------------------------------------------------------------------------------
4184 | Function : cs_reset_meas_result
4185 +------------------------------------------------------------------------------
4186 | Description : The function cs_reset_meas_result() ....
4187 |
4188 | Parameters : ...
4189 |
4190 +------------------------------------------------------------------------------
4191 */
4192 GLOBAL void cs_reset_meas_result ( T_CELL *cell )
4193 {
4194 T_RLA_P_DATA *rla_p_data = &cell->rla_p_data;
4195 T_RXLEV_DATA *rxlev_data = &cell->rxlev_data;
4196
4197 UBYTE i; /* used for counting */
4198
4199 TRACE_FUNCTION( "cs_reset_meas_result" );
4200 TRACE_EVENT_P2( "cs_reset_meas_result arfcn =%ld LOI=%ld",cell->arfcn,rla_p_data->loi );
4201
4202 rla_p_data->loi = CS_IDX_NOT_USED;
4203 rla_p_data->ovrflw = FALSE;
4204
4205 for( i = 0; i < CS_MAX_MEAS_RSLT; i++ )
4206 {
4207 rla_p_data->meas[i].cnt = 0;
4208 rla_p_data->meas[i].acc = 0;
4209 rla_p_data->meas[i].rpt_prd = 0;
4210 }
4211
4212 rxlev_data->acc = 0;
4213 rxlev_data->nbr = 0;
4214 } /* cs_reset_meas_result () */
4215
4216 /*
4217 +------------------------------------------------------------------------------
4218 | Function : cs_fill_meas_rslt
4219 +------------------------------------------------------------------------------
4220 | Description : ...
4221 |
4222 | Parameters : ...
4223 |
4224 +------------------------------------------------------------------------------
4225 */
4226 GLOBAL void cs_fill_meas_rslt ( T_MPHP_CR_MEAS_IND *mphp_cr_meas_ind,
4227 T_MPHP_TCR_MEAS_IND *mphp_tcr_meas_ind )
4228 {
4229 T_RLA_P_DATA *rla_p_data;
4230 T_RXLEV_DATA *rxlev_data;
4231
4232 T_RXLEV_DATA_NBR del_nbr;
4233
4234 UBYTE i;
4235 UBYTE index = 0;
4236 BOOL ovrflw = FALSE;
4237
4238 UBYTE cnt;
4239 SHORT acc;
4240 USHORT rpt_prd;
4241
4242 TRACE_FUNCTION( "cs_fill_meas_rslt" );
4243
4244 if( mphp_cr_meas_ind NEQ NULL )
4245 {
4246 rpt_prd = mphp_cr_meas_ind->reporting_period;
4247 }
4248 else
4249 {
4250 rpt_prd = CS_RPT_PRD_PTM;
4251 }
4252
4253 /*
4254 * Process all data relevant for RLA_P derivation
4255 */
4256
4257 for( i = 0; i < nc_data->c_cell; i++ )
4258 {
4259 rla_p_data = &nc_data->cell[i].rla_p_data;
4260 rxlev_data = &nc_data->cell[i].rxlev_data;
4261
4262 if( mphp_cr_meas_ind NEQ NULL )
4263 {
4264 cnt = 1;
4265 if((signed char)mphp_cr_meas_ind->p_ncell_meas[i].rxlev <0)
4266 {
4267 acc = 0;
4268 }
4269 else
4270 {
4271 acc = (signed char)mphp_cr_meas_ind->p_ncell_meas[i].rxlev;
4272 }
4273 }
4274 else
4275 {
4276 cnt = mphp_tcr_meas_ind->acc_nbr[i];
4277 if((SHORT)mphp_tcr_meas_ind->acc_level[i] <0)
4278 {
4279 acc = 0;
4280 }
4281 else
4282 {
4283 acc = mphp_tcr_meas_ind->acc_level[i];
4284 }
4285 }
4286
4287 if( rla_p_data->loi NEQ CS_IDX_NOT_USED )
4288 {
4289 if( rla_p_data->loi EQ CS_MAX_MEAS_RSLT - 1 )
4290 {
4291 ovrflw = TRUE;
4292 }
4293 else
4294 {
4295 index = rla_p_data->loi + 1;
4296 }
4297 }
4298
4299 if( cnt EQ 0 )
4300 {
4301 if( rla_p_data->meas[index].cnt EQ 0 )
4302 {
4303 rla_p_data->meas[index].rpt_prd += rpt_prd;
4304 }
4305 else
4306 {
4307 rla_p_data->meas[index].cnt = 0;
4308 rla_p_data->meas[index].acc = 0;
4309 rla_p_data->meas[index].rpt_prd = rpt_prd;
4310 }
4311 }
4312 else
4313 {
4314 rla_p_data->meas[index].cnt = cnt;
4315 rla_p_data->meas[index].acc = acc;
4316 rla_p_data->meas[index].rpt_prd = rpt_prd;
4317
4318 rla_p_data->loi = index;
4319
4320 /* if an overflow once occured it will be forever */
4321 if( rla_p_data->ovrflw EQ FALSE )
4322 {
4323 rla_p_data->ovrflw = ovrflw;
4324 }
4325 }
4326
4327 /*
4328 * Process all data relevant for average RXLEV derivation
4329 */
4330
4331 if( cnt NEQ 0 )
4332 {
4333 if( rxlev_data->nbr > RXLEV_MAX_NBR - cnt )
4334 {
4335 del_nbr = cnt - ( RXLEV_MAX_NBR - rxlev_data->nbr );
4336 rxlev_data->acc -= del_nbr * ( rxlev_data->acc / rxlev_data->nbr );
4337 rxlev_data->nbr -= del_nbr;
4338 }
4339
4340 rxlev_data->acc += ( acc * RXLEV_ACRCY );
4341 rxlev_data->nbr += cnt;
4342 }
4343 }
4344 } /* cs_fill_meas_rslt() */
4345
4346 /*
4347 +------------------------------------------------------------------------------
4348 | Function : cs_get_rla_p
4349 +------------------------------------------------------------------------------
4350 | Description : The function cs_get_rla_p() ....
4351 |
4352 | Parameters : rla_p_data - pointer to RLA_P raw data
4353 |
4354 +------------------------------------------------------------------------------
4355 */
4356 GLOBAL BOOL cs_get_rla_p( T_RLA_P_DATA *rla_p_data, UBYTE *rla_p )
4357 {
4358 BOOL s_avg; /* status of average RXLEV value */
4359 LONG avg; /* average RXLEV value used for cell re-selection */
4360 LONG cnt = 0; /* number of accumulated measurement samples */
4361 LONG acc = 0; /* accumulated receive level values */
4362 ULONG run_avg_prd = 0; /* running average period */
4363 UBYTE c_meas = 0; /* number of measurements */
4364 UBYTE index = rla_p_data->loi;
4365 /* index to actual used measurement result */
4366 BOOL v_meas_left = rla_p_data->loi NEQ CS_IDX_NOT_USED;
4367 /* indicates whether more measurement results */
4368 /* are not yet considered */
4369
4370 TRACE_FUNCTION( "cs_get_rla_p" );
4371
4372 while(
4373 (
4374 c_meas < CS_MIN_RLA_P_SAMPLES OR
4375 run_avg_prd < CS_MIN_RUN_AVG_PRD
4376 )
4377 AND
4378 (
4379 v_meas_left EQ TRUE
4380 )
4381 )
4382 {
4383 /*
4384 * check whether valid measurement results are available
4385 */
4386 if( rla_p_data->meas[index].cnt NEQ 0 AND
4387 c_meas < CS_MAX_MEAS_RSLT )
4388 {
4389 c_meas++;
4390
4391 /*
4392 * accumulate individual measurement results
4393 */
4394 run_avg_prd += rla_p_data->meas[index].rpt_prd;
4395 cnt += rla_p_data->meas[index].cnt;
4396 acc += rla_p_data->meas[index].acc;
4397
4398 /* determine the next index to be used for RLA_P calculation */
4399 if( index EQ 0 )
4400 {
4401 if( rla_p_data->ovrflw EQ TRUE )
4402 {
4403 index = CS_MAX_MEAS_RSLT - 1;
4404 }
4405 else
4406 {
4407 v_meas_left= FALSE;
4408 }
4409 }
4410 else
4411 {
4412 index--;
4413 }
4414
4415
4416 }
4417 else
4418 {
4419 v_meas_left = FALSE;
4420 }
4421 }
4422
4423 /*
4424 * calculate status of RLA_P
4425 */
4426 if( cnt EQ 0 )
4427 {
4428 s_avg = CS_RLA_P_NOT_AVAIL;
4429 }
4430 else if(
4431 (
4432 c_meas < CS_MIN_RLA_P_SAMPLES
4433 )
4434 OR
4435 (
4436 run_avg_prd < CS_MIN_RUN_AVG_PRD
4437 AND
4438 c_meas < CS_MAX_MEAS_RSLT
4439 )
4440 )
4441 {
4442 s_avg = CS_RLA_P_NOT_VALID;
4443 }
4444 else
4445 {
4446 s_avg = CS_RLA_P_VALID;
4447 }
4448
4449 if( cnt > 0 )
4450 {
4451 /*
4452 * calculate RLA_P
4453 */
4454 avg = acc / cnt;
4455
4456
4457 /*
4458 * clip RLA_P to values between 0 and 63
4459 */
4460 if( (signed char)( avg ) < CGRLC_RXLEV_MIN )
4461 {
4462 avg = CGRLC_RXLEV_MIN;
4463 }
4464 else if ( (signed char)( avg ) > CGRLC_RXLEV_MAX )
4465 {
4466 avg = CGRLC_RXLEV_MAX;
4467 }
4468 }
4469 else
4470 {
4471 avg = CGRLC_RXLEV_NONE;
4472 }
4473
4474
4475 *rla_p = (UBYTE)avg;
4476
4477 return( s_avg );
4478
4479 } /* cs_get_rla_p () */
4480
4481 /*
4482 +------------------------------------------------------------------------------
4483 | Function : cs_get_rxlev_avg
4484 +------------------------------------------------------------------------------
4485 | Description : The function cs_get_rxlev_avg() ....
4486 |
4487 | Parameters : rxlev_data - pointer to RXLEV raw data
4488 |
4489 +------------------------------------------------------------------------------
4490 */
4491 GLOBAL T_RXLEV_AVG cs_get_rxlev_avg( T_RXLEV_DATA *rxlev_data )
4492 {
4493 T_RXLEV_AVG rxlev_avg;
4494
4495 TRACE_FUNCTION( "cs_get_rxlev_avg" );
4496
4497
4498 if( rxlev_data->nbr EQ 0 )
4499 {
4500 rxlev_avg = RXLEV_AVG_INVALID;
4501 }
4502 else
4503 {
4504 rxlev_avg =
4505 ( T_RXLEV_AVG )( rxlev_data->acc / ( rxlev_data->nbr * RXLEV_ACRCY ) );
4506 }
4507
4508 TRACE_EVENT_P2("1_cs_get_rxlev_avg: nbr=%ld rx_avg=%ld",rxlev_data->nbr,rxlev_avg);
4509
4510 return( rxlev_avg );
4511 } /* cs_get_rxlev_avg () */
4512
4513 /*
4514 +------------------------------------------------------------------------------
4515 | Function : cs_tcr_meas_ind_to_pl
4516 +------------------------------------------------------------------------------
4517 | Description : The function cs_tcr_meas_ind_to_pl () forwards the cell
4518 | re-selection measurement results catched during packet transfer
4519 | mode to ALR.
4520 |
4521 | Parameters : prim - pointer to primitive payload
4522 |
4523 +------------------------------------------------------------------------------
4524 */
4525 GLOBAL void cs_tcr_meas_ind_to_pl ( T_MPHP_TCR_MEAS_IND * prim )
4526 {
4527 UBYTE i; /* used for counting */
4528
4529 TRACE_FUNCTION( "cs_tcr_meas_ind_to_pl" );
4530
4531 {
4532 PALLOC( tb_meas_ind, TB_MEAS_IND );
4533
4534 for( i = 0; i < TB_BA_LIST_SIZE; i++ )
4535 {
4536 if(( grr_data->cs.cr_meas_update EQ TRUE) AND
4537 (nc_data->cell[i].arfcn NEQ 0))
4538 {
4539 if(nc_data->cell[i].arfcn NEQ 0)
4540 {
4541 tb_meas_ind->tb_meas_result[i].arfcn = grr_g23_arfcn_to_l1(nc_data->cell[i].arfcn);
4542 }
4543 else
4544 {
4545 tb_meas_ind->tb_meas_result[i].arfcn = TB_INVALID_ARFCN;
4546 }
4547 }
4548 else
4549 {
4550 tb_meas_ind->tb_meas_result[i].arfcn = TB_INVALID_ARFCN;
4551 }
4552
4553 tb_meas_ind->tb_meas_result[i].rxlev = prim->acc_level[i];
4554 tb_meas_ind->tb_meas_result[i].num_meas = prim->acc_nbr[i];
4555 }
4556
4557 PSEND( hCommPL, tb_meas_ind );
4558 }
4559 } /* cs_tcr_meas_ind_to_pl() */
4560
4561 /*
4562 +------------------------------------------------------------------------------
4563 | Function : cs_create_cr_cell
4564 +------------------------------------------------------------------------------
4565 | Description :
4566 |
4567 | Parameters :
4568 |
4569 +------------------------------------------------------------------------------
4570 */
4571 GLOBAL T_NC_MVAL* cs_create_cr_cell ( USHORT arfcn, UBYTE bsic )
4572 {
4573 T_NC_MVAL *nc_mval;
4574 UBYTE nc_mval_idx;
4575
4576 TRACE_FUNCTION( "cs_create_cr_cell" );
4577
4578 /* if the new selected cell is not found in the neighbour cell list */
4579 nc_mval = grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &nc_mval_idx );
4580
4581 if( nc_mval NEQ NULL )
4582 {
4583 nc_mval->arfcn = arfcn;
4584 nc_mval->sync_info.bsic = bsic;
4585
4586 /*
4587 * The function cs_create_cr_cell is only called in case of processing a
4588 * packet cell change order. If the packet cell change order has been
4589 * received on a cell without PBCCH, GRR should forward the RRGRR_CR_REQ
4590 * with parameter CR_NEW in all cases. This is forced by setting the
4591 * synchronisation status to STAT_SYNC_OK.
4592 */
4593 if( grr_is_pbcch_present( ) )
4594 {
4595 TRACE_EVENT( "cs_create_cr_cell: cell not part of neighbour cell list" );
4596
4597 nc_mval->sync_info.sync.status = STAT_SYNC_NONE;
4598 }
4599 else
4600 {
4601 nc_mval->sync_info.sync.status = STAT_SYNC_OK;
4602 }
4603
4604 grr_data->db.cr_cell = &grr_data->db.nc_nw_slctd.strgst;
4605 grr_data->db.cr_cell->idx = nc_mval_idx;
4606 grr_data->db.cr_cell->mode = CS_MODE_IDLE;
4607 grr_data->db.cr_cell->avail_time = 0;
4608 }
4609
4610 return( nc_mval );
4611
4612 } /* cs_create_cr_cell() */
4613
4614 /*
4615 +------------------------------------------------------------------------------
4616 | Function : cs_get_nc_rpt_prd_idle
4617 +------------------------------------------------------------------------------
4618 | Description :
4619 |
4620 | Parameters :
4621 |
4622 +------------------------------------------------------------------------------
4623 */
4624 LOCAL T_TIME cs_get_nc_rpt_prd_idle ( void )
4625 {
4626 T_TIME reporting_period;
4627 ULONG small_int_multi; /* smallest integer multiple of DRX period */
4628 ULONG drx_period; /* DRX period in milliseconds */
4629
4630 TRACE_FUNCTION( "cs_get_nc_rpt_prd_idle" );
4631
4632 reporting_period = GET_NC_RPT_PRD( grr_data->db.nc_ref_lst.param->rep_per_i );
4633 drx_period = meas_im_get_drx_period_seconds( );
4634 drx_period = M_ROUND_UP( drx_period, DRX_NORM_FACTOR );
4635
4636 /*
4637 * In packet idle mode, the reporting period is NC_REPORTING_PERIOD_I
4638 * rounded off to the nearest smaller integer multiple of DRX period
4639 * if NC_REPORTING_PERIOD_I is greater than DRX period, else, the
4640 * reporting period is DRX period.
4641 */
4642 if( drx_period NEQ NO_PAGING )
4643 {
4644 if( reporting_period > drx_period )
4645 {
4646 small_int_multi = reporting_period / drx_period;
4647 reporting_period = drx_period * small_int_multi;
4648 }
4649 else
4650 {
4651 reporting_period = drx_period;
4652 }
4653 }
4654
4655 return( reporting_period );
4656
4657 } /* cs_get_nc_rpt_prd_idle() */
4658
4659
4660 /*
4661 +------------------------------------------------------------------------------
4662 | Function : cs_reset_meas_rep_params
4663 +------------------------------------------------------------------------------
4664 | Description : This function will reset measurement reporting parameters
4665 |
4666 | Parameters : db - pointer to serving cell database
4667 |
4668 +------------------------------------------------------------------------------
4669 */
4670 GLOBAL void cs_reset_meas_rep_params ( T_SC_DATABASE *db )
4671 {
4672 TRACE_FUNCTION( "cs_reset_meas_rep_params" );
4673
4674 db->nc_ms.ncmeas.param.ctrl_order = NC_RESET;
4675 db->nc_ms.ncmeas.param.rep_per_i = 0;
4676 db->nc_ms.ncmeas.param.rep_per_t = 0;
4677
4678 } /* cs_reset_meas_rep_params() */
4679
4680 /*
4681 +------------------------------------------------------------------------------
4682 | Function : cs_check_nc_sync_timer
4683 +------------------------------------------------------------------------------
4684 | Description : Handles the nc sync timer of 10 sec in case of PIM_PBCCH and
4685 | PTM_PBCCH
4686 |
4687 | Parameters : reporting_period
4688 |
4689 +------------------------------------------------------------------------------
4690 */
4691
4692
4693 GLOBAL void cs_check_nc_sync_timer(USHORT reporting_pd)
4694 {
4695 if(!grr_data->db.cnt_nc_six.candid) return;
4696 grr_data->cs.nc_sync_rep_pd += reporting_pd;
4697
4698
4699 if(grr_data->cs.nc_sync_rep_pd >= CS_NCSYNC_RPT_PRD_PIM)
4700 {
4701 PALLOC( rrgrr_check_bsic_req, RRGRR_NCELL_SYNC_REQ );
4702 rrgrr_check_bsic_req->sync_type = SYNC_RECONFIRM;
4703 PSEND( hCommRR, rrgrr_check_bsic_req );
4704 /*subtracting nc_sync_rep_pd from CS_NCSYNC_RPT_PRD_PIM wil provide take care
4705 of periodicity of non-uniform reporting_period values*/
4706 TRACE_EVENT_P1("GRR_NC_SYNC:EXPIRY: nc_sync_rep_pd=%d", grr_data->cs.nc_sync_rep_pd);
4707 grr_data->cs.nc_sync_rep_pd -= CS_NCSYNC_RPT_PRD_PIM;
4708 }
4709 return;
4710
4711 }
4712
4713 /*
4714 +------------------------------------------------------------------------------
4715 | Function : cs_process_serving_cell_data
4716 +------------------------------------------------------------------------------
4717 | Description : This function is used to fill rxlev and interference measurements
4718 | of the serving cell
4719 |
4720 | Parameters : rxlev, iscell
4721 |
4722 +------------------------------------------------------------------------------
4723 */
4724 LOCAL BOOL cs_process_serving_cell_data ( UBYTE *rxlev_scell, UBYTE *v_i_scell,
4725 UBYTE *i_scell, UBYTE *used_bits,
4726 BOOL *rsc_avail, BOOL *isc_avail )
4727
4728 {
4729 TRACE_FUNCTION( "cs_process_serving_cell_data" );
4730
4731 *used_bits += NC_RXLEV_SCELL_LEN;
4732
4733 if( grr_data->db.scell_info.rxlev_avg EQ RXLEV_AVG_INVALID )
4734 {
4735 TRACE_ERROR( "cs_build_xxx_meas_rpt no RXLEV of serving cell" );
4736 return( FALSE );
4737 }
4738 else
4739 {
4740 *rsc_avail = TRUE;
4741 *rxlev_scell = grr_data->db.scell_info.rxlev_avg;
4742 }
4743
4744 /* process interference measurement of serving cell */
4745 *used_bits += PMR_FLAG_LEN;
4746 *v_i_scell = FALSE;
4747
4748 if( grr_is_pbcch_present( ) EQ TRUE AND
4749 psc_db->paging_group.kc NEQ 0 AND
4750 grr_data->cs_meas.packet_mode EQ PACKET_MODE_PIM )
4751 {
4752 T_p_frequency_par freq_par;
4753
4754 if( grr_get_pccch_freq_par
4755 ( ( UBYTE )( grr_imsi_mod( ) % psc_db->paging_group.kc ),
4756 &freq_par.p_chan_sel, &freq_par.p_freq_list ) )
4757 {
4758 T_MEAS_IM_CARRIER ma;
4759 UBYTE written_bits;
4760 T_ilev_abs i_level;
4761
4762 meas_im_set_carrier( &ma, &freq_par );
4763
4764 written_bits = meas_im_get_abs_i_level( &ma, &i_level );
4765
4766 if( written_bits > CGRLC_MAX_TIMESLOTS * PMR_FLAG_LEN )
4767 {
4768 *v_i_scell = TRUE;
4769 *used_bits += NC_IF_SCELL_LEN;
4770
4771 if ( i_level.v_ilevabs0 EQ TRUE )
4772 {
4773 *i_scell = i_level.ilevabs0;
4774 *isc_avail = TRUE;
4775 }
4776 else if( i_level.v_ilevabs1 EQ TRUE )
4777 {
4778 *i_scell = i_level.ilevabs1;
4779 *isc_avail = TRUE;
4780 }
4781 else if( i_level.v_ilevabs2 EQ TRUE )
4782 {
4783 *i_scell = i_level.ilevabs2;
4784 *isc_avail = TRUE;
4785 }
4786 else if( i_level.v_ilevabs3 EQ TRUE )
4787 {
4788 *i_scell = i_level.ilevabs3;
4789 *isc_avail = TRUE;
4790 }
4791 else if( i_level.v_ilevabs4 EQ TRUE )
4792 {
4793 *i_scell = i_level.ilevabs4;
4794 *isc_avail = TRUE;
4795 }
4796 else if( i_level.v_ilevabs5 EQ TRUE )
4797 {
4798 *i_scell = i_level.ilevabs5;
4799 *isc_avail = TRUE;
4800 }
4801 else if( i_level.v_ilevabs6 EQ TRUE )
4802 {
4803 *i_scell = i_level.ilevabs6;
4804 *isc_avail = TRUE;
4805 }
4806 else if( i_level.v_ilevabs7 EQ TRUE )
4807 {
4808 *i_scell = i_level.ilevabs7;
4809 *isc_avail = TRUE;
4810 }
4811 else
4812 {
4813 TRACE_ERROR( "cs_process_serving_cell_data corrupted I_LEVEL data" );
4814 return( FALSE );
4815 }
4816 }
4817 }
4818 }
4819 return(TRUE);
4820 }/* cs_process_serving_cell_data */
4821
4822 #if defined (REL99) AND defined (TI_PS_FF_EMR)
4823 /*
4824 +------------------------------------------------------------------------------
4825 | Function : cs_send_enh_meas_rpt
4826 +------------------------------------------------------------------------------
4827 | Description : This function is used to send enh meas report to the network
4828 |
4829 | Parameters : void
4830 |
4831 +------------------------------------------------------------------------------
4832 */
4833 GLOBAL BOOL cs_send_enh_meas_rpt (void)
4834 {
4835 T_U_ENHNC_MEAS_REPORT enh_meas_rpt;
4836 BOOL rpt_send;
4837
4838 TRACE_FUNCTION( "cs_send_enh_meas_rpt" );
4839
4840 if(grr_is_pbcch_present())
4841 {
4842 cs_form_enh_cell_list();
4843 }
4844 else
4845 {
4846 cs_form_ba_bcch_enh_cell_list();
4847 }
4848
4849 cs_nc_sort_and_update_emr_info();
4850
4851 memset (&enh_meas_rpt, 0, sizeof(T_U_ENHNC_MEAS_REPORT));
4852
4853 rpt_send = cs_build_enh_meas_rpt(&enh_meas_rpt);
4854
4855 if( rpt_send EQ TRUE )
4856 {
4857 sig_cs_ctrl_enh_meas_report(&enh_meas_rpt);
4858 }
4859
4860 return(rpt_send);
4861
4862 } /* cs_send_enh_meas_rpt() */
4863
4864
4865 /*
4866 +------------------------------------------------------------------------------
4867 | Function : cs_form_enh_cell_list
4868 +------------------------------------------------------------------------------
4869 | Description : This function is used to form enhanced cell list from BA list
4870 | (nc_ref_lst) and Measured values list(nc_mval_list)
4871 |
4872 |
4873 | Parameters : Nil
4874 |
4875 +------------------------------------------------------------------------------
4876 */
4877 LOCAL void cs_form_enh_cell_list(void)
4878 {
4879 UBYTE i = 0, n = 0, j;
4880 UBYTE nc_ref_index_arfcn, nc_ref_index_bsic;
4881
4882 TRACE_FUNCTION( "cs_form_enh_cell_list" );
4883
4884 memset((grr_data->db.enh_cell_list), 0xFF, sizeof(T_ENH_CELL_LIST)*MAX_NR_OF_NCELL);
4885
4886 grr_data->db.cnt_enh_cell_list = 0;
4887
4888 /* Check one entry of Measured values list against all entries of BA list */
4889 while(i < MAX_NR_OF_NC_MVAL AND n < MAX_NR_OF_NCELL)
4890 {
4891 if( (grr_data->db.nc_mval_list.nc_mval[i].status EQ NC_MVAL_STAT_ASSIGNED)
4892 AND
4893 (grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ RRGRR_INVALID_ARFCN)
4894 AND
4895 (grr_data->db.nc_mval_list.nc_mval[i].sync_info.sync.status EQ
4896 STAT_SYNC_OK)
4897 AND
4898 (grr_data->db.nc_mval_list.nc_mval[i].rla_p.stat EQ CS_RLA_P_VALID) )
4899 {
4900 nc_ref_index_arfcn = NOT_SET; /* Will be set the 1st time ARFCN matches
4901 in the BA list */
4902 nc_ref_index_bsic = NOT_SET; /* Will be set the 1st time ARFCN-BSIC pair
4903 matches in the BA list */
4904
4905 /* Comparison with BA list */
4906 for (j = 0; j < grr_data->db.nc_ref_lst.number; j++)
4907 {
4908 if(grr_data->db.nc_mval_list.nc_mval[i].arfcn EQ
4909 grr_data->db.nc_ref_lst.info[j]->arfcn)
4910 {
4911 if(nc_ref_index_arfcn EQ NOT_SET)
4912 {
4913 /* ARFCN matched for the 1st time in BA list */
4914 nc_ref_index_arfcn = j;
4915 }
4916
4917 /* In case the same cell (ARFCN+BSIC) or the same ARFCN without BSIC
4918 occur more than once in the resulting GSM Neighbour Cell list,
4919 each occurrence shall be assigned an index but only the cell with
4920 the highest index shall be used for cell re-selection and referred
4921 to in measurement reports. */
4922 if(grr_data->db.nc_ref_lst.info[j]->index >
4923 grr_data->db.nc_ref_lst.info[nc_ref_index_arfcn]->index)
4924 {
4925 nc_ref_index_arfcn = j;
4926 }
4927
4928 if(grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic EQ
4929 grr_data->db.nc_ref_lst.info[j]->bsic)
4930 {
4931 nc_ref_index_bsic = nc_ref_index_arfcn;
4932 }
4933 }
4934 }
4935
4936 /* Store ARFCN, BSIC, RLA_P and RXLEV, if ARFCN and/or BSIC matches */
4937 if(nc_ref_index_arfcn NEQ NOT_SET)
4938 {
4939 grr_data->db.enh_cell_list[n].arfcn =
4940 grr_data->db.nc_mval_list.nc_mval[i].arfcn;
4941
4942 grr_data->db.enh_cell_list[n].bsic.bsic =
4943 grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic;
4944
4945 grr_data->db.enh_cell_list[n].rla_p =
4946 grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
4947
4948 grr_data->db.enh_cell_list[n].rxlev_avg =
4949 grr_data->db.nc_mval_list.nc_mval[i].rxlev_avg;
4950 }
4951
4952 /* Store in the enhanced cell list as Valid and Invalid BSICs */
4953 if (nc_ref_index_bsic NEQ NOT_SET)
4954 {
4955 grr_data->db.enh_cell_list[n].index =
4956 grr_data->db.nc_ref_lst.info[nc_ref_index_bsic]->index;
4957
4958 grr_data->db.enh_cell_list[n].rept_prio =
4959 grr_data->db.nc_ref_lst.enh_param->gprs_rept_prio_desc.
4960 rept_prio[grr_data->db.nc_ref_lst.info[nc_ref_index_bsic]->index];
4961
4962 grr_data->db.enh_cell_list[n++].bsic.status = BSIC_VALID;
4963 }
4964 else if(nc_ref_index_arfcn NEQ NOT_SET)
4965 {
4966 grr_data->db.enh_cell_list[n].index =
4967 grr_data->db.nc_ref_lst.info[nc_ref_index_arfcn]->index;
4968 /* Set the reporting priority to high for invalid BSICs and allowed
4969 NCC part. Refer Section 8.4.8.1 of 3GPP TS 05.08 V8.15.0 (2002-06) */
4970 grr_data->db.enh_cell_list[n].rept_prio = HIGH_PRIO;
4971 grr_data->db.enh_cell_list[n++].bsic.status = BSIC_INVALID;
4972 }
4973 }
4974 i++;
4975 }
4976 grr_data->db.cnt_enh_cell_list = n;
4977 }/* cs_form_enh_cell_list */
4978
4979 /*
4980 +------------------------------------------------------------------------------
4981 | Function : cs_form_ba_bcch_enh_cell_list
4982 +------------------------------------------------------------------------------
4983 | Description : This function is used to form enhanced cell list from BA list
4984 | (nc_ref_lst) and Measured values list(nc_mval_list)
4985 |
4986 |
4987 | Parameters : Nil
4988 |
4989 +------------------------------------------------------------------------------
4990 */
4991 LOCAL void cs_form_ba_bcch_enh_cell_list(void)
4992 {
4993 UBYTE i = 0, n = 0, j;
4994 UBYTE nc_ref_index_arfcn, nc_ref_index_bsic;
4995
4996 TRACE_FUNCTION( "cs_form_ba_bcch_enh_cell_list" );
4997
4998 memset((grr_data->db.enh_cell_list), 0xFF, sizeof(T_ENH_CELL_LIST)*MAX_NR_OF_NCELL);
4999
5000 grr_data->db.cnt_enh_cell_list = 0;
5001
5002 /* Check one entry of Measured values list against all entries of BA list */
5003 while(i < MAX_NR_OF_NC_MVAL AND n < MAX_NR_OF_NCELL)
5004 {
5005 if( (grr_data->db.nc_mval_list.nc_mval[i].status EQ NC_MVAL_STAT_ASSIGNED)
5006 AND
5007 (grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ RRGRR_INVALID_ARFCN)
5008 AND
5009 (grr_data->db.nc_mval_list.nc_mval[i].sync_info.sync.status EQ
5010 STAT_SYNC_OK)
5011 AND
5012 (grr_data->db.nc_mval_list.nc_mval[i].rla_p.stat EQ CS_RLA_P_VALID) )
5013 {
5014 nc_ref_index_arfcn = NOT_SET; /* Will be set the 1st time ARFCN matches
5015 in the BA list */
5016 nc_ref_index_bsic = NOT_SET; /* Will be set the 1st time ARFCN-BSIC pair
5017 matches in the BA list */
5018
5019 /* Comparison with BA list */
5020 for (j = 0; j < grr_data->db.ba_bcch_nc_ref_lst.number; j++)
5021 {
5022 if(grr_data->db.nc_mval_list.nc_mval[i].arfcn EQ
5023 grr_data->db.ba_bcch_nc_ref_lst.info[j]->arfcn)
5024 {
5025 if(nc_ref_index_arfcn EQ NOT_SET)
5026 {
5027 /* ARFCN matched for the 1st time in BA list */
5028 nc_ref_index_arfcn = j;
5029 }
5030
5031 /* In case the same cell (ARFCN+BSIC) or the same ARFCN without BSIC
5032 occur more than once in the resulting GSM Neighbour Cell list,
5033 each occurrence shall be assigned an index but only the cell with
5034 the highest index shall be used for cell re-selection and referred
5035 to in measurement reports. */
5036 if(grr_data->db.ba_bcch_nc_ref_lst.info[j]->index >
5037 grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_arfcn]->index)
5038 {
5039 nc_ref_index_arfcn = j;
5040 }
5041
5042 if(grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic EQ
5043 grr_data->db.ba_bcch_nc_ref_lst.info[j]->bsic)
5044 {
5045 nc_ref_index_bsic = nc_ref_index_arfcn;
5046 }
5047 }
5048 }
5049
5050 /* Store ARFCN, BSIC, RLA_P AND RXLEV, if ARFCN and/or BSIC matches */
5051 if(nc_ref_index_arfcn NEQ NOT_SET)
5052 {
5053 grr_data->db.enh_cell_list[n].arfcn =
5054 grr_data->db.nc_mval_list.nc_mval[i].arfcn;
5055
5056 grr_data->db.enh_cell_list[n].bsic.bsic =
5057 grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic;
5058
5059 grr_data->db.enh_cell_list[n].rla_p =
5060 grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
5061
5062 grr_data->db.enh_cell_list[n].rxlev_avg =
5063 grr_data->db.nc_mval_list.nc_mval[i].rxlev_avg;
5064 }
5065
5066 /* Store in the enhanced cell list as Valid and Invalid BSICs */
5067 if (nc_ref_index_bsic NEQ NOT_SET)
5068 {
5069 grr_data->db.enh_cell_list[n].index =
5070 grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_bsic]->index;
5071
5072 grr_data->db.enh_cell_list[n].rept_prio =
5073 grr_data->db.nc_ref_lst.enh_param->gprs_rept_prio_desc.
5074 rept_prio[grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_bsic]->index];
5075
5076 grr_data->db.enh_cell_list[n++].bsic.status = BSIC_VALID;
5077 }
5078 else if(nc_ref_index_arfcn NEQ NOT_SET)
5079 {
5080 grr_data->db.enh_cell_list[n].index =
5081 grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_arfcn]->index;
5082 /* Set the reporting priority to high for invalid BSICs and allowed
5083 NCC part. Refer Section 8.4.8.1 of 3GPP TS 05.08 V8.15.0 (2002-06) */
5084 grr_data->db.enh_cell_list[n].rept_prio = HIGH_PRIO;
5085 grr_data->db.enh_cell_list[n++].bsic.status = BSIC_INVALID;
5086 }
5087 }
5088 i++;
5089 }
5090 grr_data->db.cnt_enh_cell_list = n;
5091 }/* cs_form_ba_bcch_enh_cell_list */
5092
5093 /*
5094 +------------------------------------------------------------------------------
5095 | Function : cs_nc_sort_and_update_emr_info
5096 +------------------------------------------------------------------------------
5097 | Description : The purpose of this function is to handle all the specific
5098 | requirements for EMR - sorting according to priority as given
5099 | in 5.08 V8.16.0, sec.8.4.8.1, and scaling of rxlev values.
5100 |
5101 |
5102 | Parameters : Nil
5103 |
5104 +------------------------------------------------------------------------------
5105 */
5106
5107 LOCAL void cs_nc_sort_and_update_emr_info(void)
5108 {
5109 T_ENH_BIN sc_bin;
5110 T_ENH_BIN mband_bin[5]; /* 0 - 900, 1 - 1800, 2 - 400, 3 - 1900, 4 - 850*/
5111 T_ENH_BIN rest_bin;
5112 UBYTE i;
5113 UBYTE temp;
5114 T_GRR_ENH_PARA *p_enh = grr_data->db.nc_ref_lst.enh_param;
5115 T_ENH_CELL_LIST *enh_cell_list = &(grr_data->db.enh_cell_list[0]);
5116 BOOL include_cell = FALSE;
5117 grr_data->db.sorted_enh_cell_list.num_valid = 0;
5118
5119 TRACE_FUNCTION( "cs_nc_sort_and_update_emr_info" );
5120
5121 /* Flush off the old sorted ENH cell list before forming a new one */
5122 memset(&grr_data->db.sorted_enh_cell_list,0,sizeof(T_ENH_BIN));
5123
5124 /* Step 1: Sort cells into different bins - serving cell band bin,
5125 non-serving cell band bin, and the rest which can contain invalid BSIC
5126 cells */
5127 cs_nc_sort_cells_into_bins(&sc_bin, mband_bin, &rest_bin);
5128
5129 /* Step 2: Fill the cells from each bin, after sorting in descending order
5130 of RXLEV, in the order of : sc_bin, mband_bin and rest_bin.
5131 Further number of cells from sc_bin and mband_bin is restricted by SERVING_BAND
5132 and MULTIBAND reporting parameters */
5133 if ( (sc_bin.num_valid > 0) AND (p_enh->servingband_rep > 0) )
5134 {
5135 cs_nc_sort_and_store_meas_results(&sc_bin, p_enh->servingband_rep);
5136 if (sc_bin.num_valid > p_enh->servingband_rep)
5137 {
5138 cs_nc_update_rest_bin(&rest_bin, &sc_bin, p_enh->servingband_rep);
5139 }
5140 }
5141
5142 /* Fill cells from multi band after sorting*/
5143 for ( i = 0; i < MAX_NUM_BANDS AND
5144 grr_data->db.sorted_enh_cell_list.num_valid
5145 < grr_data->db.cnt_enh_cell_list; i++)
5146 {
5147 if ( (mband_bin[i].num_valid > 0) AND (p_enh->multiband_rep > 0) )
5148 {
5149 cs_nc_sort_and_store_meas_results(&mband_bin[i], p_enh->multiband_rep);
5150 if (mband_bin[i].num_valid > p_enh->multiband_rep)
5151 {
5152 cs_nc_update_rest_bin(&rest_bin, &mband_bin[i], p_enh->multiband_rep );
5153 }
5154 }
5155 }
5156
5157 /* Now sort cells in the rest bin which may contain both valid and
5158 invalid BSIC cells. Here we use the reporting offset along with measured RXLEV,
5159 for sorting. According to 5.08, sec.8.4.8.1 we need to find those cells whose sum of
5160 RXLEV and xxx_reporting_offset is maximum. This can be acheived by sorting the cells
5161 in the order of their rxlevm, where rxlevm = rxlev + offset */
5162 if ( (rest_bin.num_valid > 0) AND (grr_data->db.sorted_enh_cell_list.num_valid
5163 < grr_data->db.cnt_enh_cell_list) )
5164 {
5165 UBYTE j;
5166 UBYTE max_rxlevm;
5167 UBYTE band;
5168 UBYTE rxlevm;
5169 UBYTE k;
5170 T_ncell_info *ncell;
5171
5172 for (i = 0; i < rest_bin.num_valid; i++)
5173 {
5174 band = cs_get_band_index_for_emr (enh_cell_list[rest_bin.enh_index[i]].arfcn);
5175 max_rxlevm = enh_cell_list[rest_bin.enh_index[i]].rla_p +
5176 (p_enh->enh_rep_data[band].rep_offset * 6);
5177 k = i;
5178 for ( j = i+1; j < rest_bin.num_valid ; j++ )
5179 {
5180 band = cs_get_band_index_for_emr (enh_cell_list[rest_bin.enh_index[j]].arfcn);
5181 rxlevm = enh_cell_list[rest_bin.enh_index[j]].rla_p +
5182 (p_enh->enh_rep_data[band].rep_offset * 6) ;
5183 if ( rxlevm > max_rxlevm )
5184 {
5185 k = j;
5186 max_rxlevm = rxlevm;
5187 }
5188 }
5189 include_cell = TRUE;
5190 /* When reduced reporting is enabled we have to report low priority cell
5191 once in 4 reporting periods. The RXLEV then should be average of previous
5192 two periods */
5193 if ( (enh_cell_list[rest_bin.enh_index[k]].rept_prio EQ NORMAL_PRIO) AND
5194 (p_enh->rep_rate EQ REPORTING_RATE_REDUCED) )
5195 {
5196 /* ncell cannot be NULL since the loop will be entered only for a
5197 valid BSIC */
5198 ncell = grr_get_ncell_info(enh_cell_list[rest_bin.enh_index[k]].arfcn,
5199 enh_cell_list[rest_bin.enh_index[k]].bsic.bsic);
5200
5201 /* For every 4th time, we include this cell in the report */
5202 if ( (ncell->rep_count & (0x03)) EQ 0 )
5203 {
5204 /* For those cells that are not reported in every measurement report,
5205 the MS shall average the measurements of the current and the previous
5206 reporting period (i.e. over two reporting periods). */
5207 enh_cell_list[rest_bin.enh_index[k]].rxlev_avg =
5208 (enh_cell_list[rest_bin.enh_index[k]].rxlev_avg + ncell->last_rxlev) >> 1;
5209 /* division by 2 */
5210 }
5211 else
5212 {
5213 ncell->last_rxlev = enh_cell_list[rest_bin.enh_index[k]].rxlev_avg;
5214 include_cell = FALSE;
5215 }
5216 /* modulo 4 addition */
5217 ncell->rep_count = (ncell->rep_count + 1) & 0x03;
5218 }
5219
5220 if (include_cell EQ TRUE)
5221 {
5222 grr_data->db.sorted_enh_cell_list.
5223 enh_index[grr_data->db.sorted_enh_cell_list.num_valid] =
5224 rest_bin.enh_index[k];
5225 grr_data->db.sorted_enh_cell_list.num_valid++;
5226 }
5227
5228 if(k NEQ i)
5229 {
5230 temp = rest_bin.enh_index[k];
5231 rest_bin.enh_index[k] = rest_bin.enh_index[i];
5232 rest_bin.enh_index[i] = temp;
5233 }
5234 }
5235 }
5236 /* This leaves us with final step in neighbour cell measurement reporting - scaling.*/
5237 grr_data->db.pemr_params.scale_used = cs_nc_scale_rxlev ();
5238 }/* cs_nc_sort_and_update_emr_info */
5239
5240 /*
5241 +------------------------------------------------------------------------------
5242 | Function : cs_nc_sort_cells_into_bins
5243 +------------------------------------------------------------------------------
5244 | Description : The purpose of this function is to sort the cells into various
5245 | bins. This is the first step in handling reporting priority
5246 | as given in 5.08 sec.8.4.8.1
5247 |
5248 |
5249 | Parameters : Pointers to the three bins
5250 |
5251 +------------------------------------------------------------------------------
5252 */
5253 LOCAL void cs_nc_sort_cells_into_bins(T_ENH_BIN *p_sbin,T_ENH_BIN *p_mbin,
5254 T_ENH_BIN *p_rbin)
5255 {
5256 UBYTE i, j;
5257 UBYTE band;
5258 UBYTE sc_band;
5259 UBYTE rth;
5260 T_ENH_CELL_LIST *enh_cell_list = &(grr_data->db.enh_cell_list[0]);
5261 T_GRR_ENH_PARA *p_enh = grr_data->db.nc_ref_lst.enh_param;
5262
5263 TRACE_FUNCTION( "cs_nc_sort_cells_into_bins" );
5264
5265 memset(p_sbin, 0xFF, sizeof(T_ENH_BIN));
5266 p_sbin->num_valid = 0;
5267
5268 memset(p_rbin, 0xFF, sizeof(T_ENH_BIN));
5269 p_rbin->num_valid = 0;
5270
5271 for( i = 0; i < MAX_NUM_BANDS; i++)
5272 {
5273 memset(&p_mbin[i], 0xFF, sizeof(T_ENH_BIN));
5274 p_mbin[i].num_valid = 0;
5275 }
5276
5277 sc_band = cs_get_band_index_for_emr (psc_db->pbcch.bcch.arfcn);
5278
5279 for ( j = 0; j < grr_data->db.cnt_enh_cell_list; j++ )
5280 {
5281 if(enh_cell_list[j].bsic.status EQ BSIC_VALID) /* Valid BSIC */
5282 {
5283 /*Find the band of this arfcn*/
5284 band = cs_get_band_index_for_emr(enh_cell_list[j].arfcn);
5285 rth = p_enh->enh_rep_data[band].rep_threshold;
5286 if (band EQ sc_band )
5287 {
5288 /* Apply the threshold criteria for this band*/
5289 if ( rth NEQ REP_THRESHOLD_INF )
5290 {
5291 if((rth EQ REP_THRESHOLD_DEF) OR
5292 (enh_cell_list[j].rla_p >= (rth * 6)))
5293 {
5294 p_sbin->enh_index[p_sbin->num_valid++] = j;
5295 }
5296 else
5297 {
5298 p_rbin->enh_index[p_rbin->num_valid++] = j;
5299 }
5300 } /*otherwise report-never*/
5301 } /* otherwise cell in non-serving band*/
5302 else
5303 {
5304 /* Apply the threshold criteria for this band*/
5305 if ( rth NEQ REP_THRESHOLD_INF )
5306 {
5307 if((rth EQ REP_THRESHOLD_DEF) OR
5308 (enh_cell_list[j].rla_p >= (rth * 6)))
5309 {
5310 p_mbin[band].enh_index[p_mbin[band].num_valid++] = j;
5311 }
5312 else
5313 {
5314 p_rbin->enh_index[p_rbin->num_valid++] = j;
5315 }
5316 } /*otherwise report never*/
5317 }
5318 }
5319 else /* If there's no cell with the given BSIC, then it falls under Invalid
5320 BSIC category */
5321 {
5322 /* check whether Invalid BSIC reporting is enabled or not and NCC part is
5323 permitted or not */
5324 if ( (p_enh->inv_bsic_enabled EQ TRUE) AND
5325 ((BOOL)((UBYTE)(p_enh->ncc_permitted &
5326 ncc_bit_mask[(enh_cell_list[j].bsic.bsic & BSIC_NCC_MASK) >> 3])) NEQ 0) )
5327 {
5328 /* put it in rest bin */
5329 p_rbin->enh_index[p_rbin->num_valid++] = j;
5330 }
5331 } /* if enh_cell_list.index */
5332 } /* end of for */
5333 }/* cs_nc_sort_cells_into_bins */
5334
5335 /*
5336 +------------------------------------------------------------------------------
5337 | Function : cs_get_band_index_for_emr
5338 +------------------------------------------------------------------------------
5339 | Description : This is implementation specific function. This is used to
5340 | get index into emr reporting data (reporting threshold and
5341 | offset) array, which is band specific.
5342 |
5343 |
5344 | Parameters : ARFCN
5345 |
5346 +------------------------------------------------------------------------------
5347 */
5348
5349 LOCAL UBYTE cs_get_band_index_for_emr (USHORT arfcn)
5350 {
5351
5352 TRACE_FUNCTION( "cs_get_band_index_for_emr" );
5353
5354 if ( INRANGE(LOW_CHANNEL_900, arfcn, HIGH_CHANNEL_900) )
5355 {
5356 return 0;
5357 }
5358 else if ( INRANGE(LOW_CHANNEL_1800, arfcn, HIGH_CHANNEL_1800))
5359 {
5360 return 1;
5361 }
5362 else if (INRANGE(LOW_CHANNEL_1900, arfcn, HIGH_CHANNEL_1900))
5363 {
5364 return 3;
5365 }
5366 else if ( INRANGE(LOW_CHANNEL_850, arfcn, HIGH_CHANNEL_850))
5367 {
5368 return 4;
5369 }
5370 else
5371 {
5372 return 2;
5373 }
5374 }/* cs_get_band_index_for_emr */
5375
5376 /*
5377 +------------------------------------------------------------------------------
5378 | Function : cs_nc_sort_and_store_meas_results
5379 +------------------------------------------------------------------------------
5380 | Description : This function sorts the cells collected in each bin, in
5381 | descending order of RXLEV
5382 |
5383 |
5384 | Parameters : Pointer to bin, Number of cells to be reported
5385 |
5386 +------------------------------------------------------------------------------
5387 */
5388
5389 LOCAL void cs_nc_sort_and_store_meas_results(T_ENH_BIN *p_bin, UBYTE nbr_rpt)
5390 {
5391 UBYTE i;
5392 UBYTE j;
5393 UBYTE max_rxlev;
5394 UBYTE k;
5395 UBYTE temp;
5396 T_ENH_CELL_LIST *enh_cell_list = &(grr_data->db.enh_cell_list[0]);
5397
5398 TRACE_FUNCTION( "cs_nc_sort_and_store_meas_results" );
5399
5400 for (i = 0; (i < p_bin->num_valid AND nbr_rpt > 0); i++,nbr_rpt--)
5401 {
5402 max_rxlev = enh_cell_list[p_bin->enh_index[i]].rla_p;
5403
5404 k = i;
5405
5406 for ( j = i+1; j < p_bin->num_valid ; j++ )
5407 {
5408 if ( enh_cell_list[p_bin->enh_index[j]].rla_p > max_rxlev )
5409 {
5410
5411 k = j;
5412
5413 max_rxlev = enh_cell_list[p_bin->enh_index[j]].rla_p;
5414 }
5415 }
5416
5417 grr_data->db.sorted_enh_cell_list.
5418 enh_index[grr_data->db.sorted_enh_cell_list.num_valid] =
5419 p_bin->enh_index[k];
5420 grr_data->db.sorted_enh_cell_list.num_valid++;
5421
5422 if(k NEQ i)
5423 {
5424 temp = p_bin->enh_index[k];
5425 p_bin->enh_index[k] = p_bin->enh_index[i];
5426 p_bin->enh_index[i] = temp;
5427 }
5428
5429 }
5430 }/* cs_nc_sort_and_store_meas_results */
5431
5432 /*
5433 +------------------------------------------------------------------------------
5434 | Function : cs_nc_update_rest_bin
5435 +------------------------------------------------------------------------------
5436 | Description : This function updates the rest bin by appending the left out
5437 | cells in the other bins. These may also have to be reported
5438 | along with the cells in rest bin.
5439 |
5440 |
5441 | Parameters : Pointers to the rest and a bin, Number of cells to be reported
5442 |
5443 +------------------------------------------------------------------------------
5444 */
5445 LOCAL void cs_nc_update_rest_bin(T_ENH_BIN *p_rbin, T_ENH_BIN *p_bin,
5446 UBYTE nbr_rpt)
5447 {
5448 UBYTE i, count;
5449
5450 TRACE_FUNCTION( "cs_nc_update_rest_bin" );
5451
5452 count = p_bin->num_valid - nbr_rpt;
5453
5454 for ( i = 0; i < count; i++)
5455 {
5456 p_rbin->enh_index[p_rbin->num_valid++] = p_bin->enh_index[nbr_rpt++];
5457 p_bin->num_valid--;
5458 }
5459
5460 }/* cs_nc_update_rest_bin */
5461
5462 /*
5463 +------------------------------------------------------------------------------
5464 | Function : cs_nc_scale_rxlev
5465 +------------------------------------------------------------------------------
5466 | Description : This function performs the scaling of RXLEV.
5467 |
5468 |
5469 | Parameters : Nil
5470 |
5471 +------------------------------------------------------------------------------
5472 */
5473 LOCAL UBYTE cs_nc_scale_rxlev (void)
5474 {
5475 UBYTE i;
5476 UBYTE no_of_cells = grr_data->db.cnt_enh_cell_list;
5477 UBYTE scale;
5478 T_ENH_CELL_LIST *enh_cell_list = &(grr_data->db.enh_cell_list[0]);
5479 UBYTE scale_order = grr_data->db.nc_ref_lst.enh_param->scale_order;
5480
5481 TRACE_FUNCTION( "cs_nc_scale_rxlev" );
5482
5483 /*If scaling is automatic, then we find the scaling as below:
5484 If the maximum RXLEV is greater than 63 (MAX_RXLEV), then we add 10dB
5485 and check whether it falls into the range after scaling*/
5486 /* Note: The assumption is L1 reports values in the following way -
5487 if actual value of rxlev (x) is between y and y+1 dBm, then the reported value
5488 is 110+x rounded off to next integer. */
5489 if ( scale_order EQ SCALE_AUTO )
5490 {
5491 UBYTE max = 0;
5492
5493 if( grr_data->db.scell_info.rxlev_avg NEQ RXLEV_AVG_INVALID )
5494 {
5495 max = grr_data->db.scell_info.rxlev_avg;
5496 }
5497
5498 for ( i = 0; i < no_of_cells ; i++ )
5499 {
5500 if (enh_cell_list[i].rxlev_avg > max )
5501 {
5502 max = enh_cell_list[i].rxlev_avg;
5503 }
5504 }
5505
5506 if ( max > 63 )
5507 {
5508 /* If the max value is greater than 63, we scale by 10 so that
5509 rxlev values of maximum cells will come into range(0 - 63) */
5510 scale = 10;
5511 }
5512 else
5513 {
5514 scale = 0;
5515 }
5516 }
5517 else
5518 {
5519 scale = scale_order * 10;
5520 }
5521
5522 /* Apply the scale to the values to be reported for SCELL and NCELLs */
5523
5524 if( grr_data->db.scell_info.rxlev_avg NEQ RXLEV_AVG_INVALID )
5525 {
5526 grr_data->db.scell_info.rxlev_avg -= scale;
5527 }
5528
5529 for ( i = 0; i < no_of_cells ; i++ )
5530 {
5531 if (enh_cell_list[i].rxlev_avg > scale)
5532 {
5533 enh_cell_list[i].rxlev_avg -= scale;
5534 }
5535 else
5536 {
5537 enh_cell_list[i].rxlev_avg = 0;
5538 }
5539
5540 if (enh_cell_list[i].rxlev_avg > 63)
5541 {
5542 enh_cell_list[i].rxlev_avg = 63;
5543 }
5544 }
5545 return (scale/10);
5546 }/* cs_nc_scale_rxlev */
5547
5548 /*
5549 +------------------------------------------------------------------------------
5550 | Function : cs_build_enh_meas_rpt
5551 +------------------------------------------------------------------------------
5552 | Description : This function is used to build PEMR
5553 |
5554 | Parameters : u_enh_meas_report - Pointer to ENH measurement report
5555 |
5556 +------------------------------------------------------------------------------
5557 */
5558 LOCAL BOOL cs_build_enh_meas_rpt ( T_U_ENHNC_MEAS_REPORT *u_enh_meas_report )
5559 {
5560 T_NC_ORDER nc_ord = cs_get_network_ctrl_order( TRUE );
5561 /*UBYTE size_avail = MSG_SIZE_PEMR - MAND_SIZE_PEMR;*/
5562 BOOL pbcch_present = grr_is_pbcch_present( );
5563 UBYTE psi3_cm = grr_get_psi3_cm();
5564 T_nc_meas_rep_enh *nc_meas_rep_enh = &(u_enh_meas_report->nc_meas_rep_enh);
5565 UBYTE used_bits = 0; /* for formality sake only, not used here */
5566 UBYTE rxlev_scell;
5567 UBYTE v_i_scell;
5568 UBYTE i_scell;
5569 BOOL rsc_avail = FALSE;
5570 BOOL isc_avail = FALSE;
5571
5572 TRACE_FUNCTION( "cs_build_enh_meas_rpt" );
5573
5574 /* process message type */
5575 u_enh_meas_report->msg_type = U_ENHNC_MEAS_REPORT_c;
5576
5577 /* process TLLI */
5578 grr_set_buf_tlli( &u_enh_meas_report->tlli_value, grr_get_tlli( ) );
5579
5580 /* Process NC Measurements */
5581
5582 /* process NC mode */
5583 switch( nc_ord )
5584 {
5585 case NC_NC1: nc_meas_rep_enh->nc_mode = NCMODE_NC1; break;
5586 case NC_NC2: nc_meas_rep_enh->nc_mode = NCMODE_NC2; break;
5587
5588 default:
5589 TRACE_ERROR( "cs_build_enh_meas_rpt no valid NC mode" );
5590 return( FALSE );
5591 }
5592
5593 /* process BA used, PSI3 change mark and PMO used */
5594 if( pbcch_present EQ FALSE )
5595 {
5596 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.flag = FALSE;
5597 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.v_ba_ind_used = TRUE;
5598 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.v_ba_ind_used_3g = TRUE;
5599 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.ba_ind_used =
5600 psc_db->ba_ind;
5601 }
5602 else
5603 {
5604 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.flag = TRUE;
5605 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.v_psi3_cm = TRUE;
5606 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.psi3_cm = psi3_cm;
5607 }
5608
5609 u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.pmo_ind_used =
5610 psc_db->nc_ms.pmo_ind;
5611
5612 /* process serving cell data - rxlev and ilev */
5613 cs_process_serving_cell_data(&rxlev_scell, &v_i_scell, &i_scell, &used_bits,
5614 &rsc_avail, &isc_avail);
5615
5616 if((rsc_avail EQ TRUE) AND (isc_avail EQ FALSE))
5617 {
5618 /* Only RXLEV of SCELL avalable. ILEV of SCELL not available */
5619 nc_meas_rep_enh->v_serv_cell_data = TRUE;
5620 nc_meas_rep_enh->serv_cell_data.v_i_scell = FALSE;
5621 nc_meas_rep_enh->serv_cell_data.rxlev_scell = rxlev_scell;
5622 }
5623 else if(rsc_avail EQ FALSE)
5624 {
5625 /* RXLEV of SCELL not avalable. Hence SCELL info is not reported */
5626 nc_meas_rep_enh->v_serv_cell_data = FALSE;
5627 }
5628 else if((rsc_avail EQ TRUE) AND (isc_avail EQ TRUE))
5629 {
5630 /* Both RXLEV and ILEV of SCELL available and reported */
5631 nc_meas_rep_enh->v_serv_cell_data = TRUE;
5632 nc_meas_rep_enh->serv_cell_data.v_i_scell = TRUE;
5633 nc_meas_rep_enh->serv_cell_data.rxlev_scell = rxlev_scell;
5634 nc_meas_rep_enh->serv_cell_data.i_scell = i_scell;
5635 }
5636
5637 /* process NC measurement results */
5638 if(cs_fill_nc_enh_meas_results(nc_meas_rep_enh) EQ FALSE)
5639 {
5640 nc_meas_rep_enh->v_nc_rep_quan = FALSE;
5641 }
5642
5643 /* process BSIC_SEEN and SCALE */
5644 if(nc_meas_rep_enh->c_rep_invalid_bsic_info NEQ 0)
5645 {
5646 nc_meas_rep_enh->bsic_seen = TRUE;
5647 }
5648 else
5649 {
5650 nc_meas_rep_enh->bsic_seen = FALSE;
5651 }
5652
5653 nc_meas_rep_enh->scale = grr_data->db.pemr_params.scale_used;
5654
5655 return(TRUE);
5656
5657 } /* cs_build_enh_meas_rpt() */
5658
5659
5660 /*
5661 +------------------------------------------------------------------------------
5662 | Function : cs_fill_nc_meas_results
5663 +------------------------------------------------------------------------------
5664 | Description : This function is used to fill ENH measurements of neighbour
5665 | cells in the PEMR message
5666 |
5667 |
5668 | Parameters : Pointer to ENH meas parameters struct
5669 |
5670 +------------------------------------------------------------------------------
5671 */
5672
5673 LOCAL BOOL cs_fill_nc_enh_meas_results(T_nc_meas_rep_enh *nc_meas_rep_enh)
5674 {
5675 UBYTE size_avail = MSG_SIZE_PEMR - MAND_SIZE_PEMR;
5676 UBYTE i;
5677 UBYTE highest_index = 0;
5678 T_ENH_CELL_LIST *enh_cell_list = &(grr_data->db.enh_cell_list[0]);
5679 T_ENH_BIN *sorted_list = &grr_data->db.sorted_enh_cell_list;
5680 UBYTE index_0 = 1;
5681
5682 nc_meas_rep_enh->nc_rep_quan.c_reporting_quantity_bmp = 0;
5683 nc_meas_rep_enh->c_rep_invalid_bsic_info = 0;
5684
5685
5686 TRACE_FUNCTION( "cs_fill_nc_meas_results" );
5687
5688 /*lint -e{437} Passing struct '' to ellipsis */
5689 TRACE_EVENT_P1("dump=%x",grr_data->db.enh_cell_list[0]);
5690
5691 if(grr_data->db.sorted_enh_cell_list.num_valid EQ 0)
5692 {
5693 return(FALSE);
5694 }
5695
5696 nc_meas_rep_enh->v_nc_rep_quan = TRUE;
5697
5698 for(i = 0; i < sorted_list->num_valid; i++)
5699 {
5700 if(enh_cell_list[sorted_list->enh_index[i]].bsic.status EQ BSIC_VALID)
5701 {
5702 /*Fill it in valid BSIC bit map reporting, enh_cell_list[i]->index
5703 corresponds to the bit in the report. Find whether size permits */
5704 TRACE_EVENT_P2("I%x = %x",i,enh_cell_list[sorted_list->enh_index[i]].index);
5705 nc_meas_rep_enh->nc_rep_quan.
5706 reporting_quantity_bmp[enh_cell_list[sorted_list->enh_index[i]].index].
5707 v_reporting_quantity = TRUE;
5708 nc_meas_rep_enh->nc_rep_quan.
5709 reporting_quantity_bmp[enh_cell_list[sorted_list->enh_index[i]].index].
5710 reporting_quantity = enh_cell_list[sorted_list->enh_index[i]].rxlev_avg;
5711
5712 size_avail = size_avail - index_0;
5713 index_0 = 0;
5714
5715 if ( enh_cell_list[sorted_list->enh_index[i]].index > highest_index )
5716 {
5717 /* When the place where the RXLEV has to be filled requires
5718 additional bits in bit map, then we have to account for
5719 these single bits and additional 6 bits for RXLEV */
5720 if ( size_avail >= (enh_cell_list[sorted_list->enh_index[i]].index
5721 - highest_index) + NC_RXLEV_N_LEN )
5722 {
5723 /* This means we require atleast enh_cell_list[i]->index -
5724 highest_index+6 bits in bit map to include this rxlev */
5725 /* 6 bits for RXLEV itself */
5726 size_avail = size_avail -
5727 (enh_cell_list[sorted_list->enh_index[i]].index - highest_index
5728 + NC_RXLEV_N_LEN);
5729 highest_index = enh_cell_list[sorted_list->enh_index[i]].index;
5730 nc_meas_rep_enh->nc_rep_quan.
5731 c_reporting_quantity_bmp =
5732 enh_cell_list[sorted_list->enh_index[i]].index + 1; /* counter is index+1 */
5733 continue;
5734 }
5735 else if (size_avail >= NC_RXLEV_N_LEN)
5736 {
5737 continue;
5738 }
5739 else
5740 break; /* No more filling possible */
5741 }
5742 else if (size_avail >= NC_RXLEV_N_LEN)
5743 {
5744 size_avail -= NC_RXLEV_N_LEN; /* size for bit map is already accounted for*/
5745 nc_meas_rep_enh->nc_rep_quan.
5746 c_reporting_quantity_bmp = highest_index +1;
5747 continue;
5748 }
5749 else
5750 {
5751 break; /*no more inclusion of results is possible*/
5752 }
5753 }
5754 else
5755 {
5756 /* fill in invalid BSIC list since cell is not present in the neighbour cell
5757 list. Here the index that needs to be filled is index of the ARFCN in BA(list)*/
5758 if ( size_avail > NC_INVBSIC_PEMR )
5759 {
5760 nc_meas_rep_enh->v_rep_invalid_bsic_info = TRUE;
5761 nc_meas_rep_enh->rep_invalid_bsic_info
5762 [nc_meas_rep_enh->c_rep_invalid_bsic_info].bcch_freq_ncell
5763 = enh_cell_list[sorted_list->enh_index[i]].index;
5764 nc_meas_rep_enh->rep_invalid_bsic_info
5765 [nc_meas_rep_enh->c_rep_invalid_bsic_info].bsic
5766 = enh_cell_list[sorted_list->enh_index[i]].bsic.bsic;
5767 nc_meas_rep_enh->rep_invalid_bsic_info
5768 [nc_meas_rep_enh->c_rep_invalid_bsic_info].rxlev_ncell
5769 = enh_cell_list[sorted_list->enh_index[i]].rxlev_avg;
5770 nc_meas_rep_enh->c_rep_invalid_bsic_info++;
5771 size_avail -= NC_INVBSIC_PEMR;
5772 }
5773 }
5774 }
5775
5776 return(TRUE);
5777
5778 }/* cs_fill_nc_enh_meas_results */
5779
5780 /*
5781 +------------------------------------------------------------------------------
5782 | Function : cs_build_enh_sorted_strng_arfcn_list
5783 +------------------------------------------------------------------------------
5784 | Description : The purpose of this function is to sort the cells into various
5785 | bins and in desc order of RXLEV in each of the bin. The ARFCNs
5786 | in the sorted bin are finally sent to RR for decoding purpose
5787 |
5788 |
5789 | Parameters : Pointers to the final sorted bin for storage
5790 |
5791 +------------------------------------------------------------------------------
5792 */
5793 LOCAL void cs_build_enh_sorted_strng_arfcn_list(T_ENH_STRNG_ARFCN_LIST *f_bin)
5794 {
5795 T_ENH_STRNG_ARFCN_LIST s_bin, r_bin;
5796
5797 UBYTE total_arfcns;
5798
5799 f_bin->num = 0;
5800
5801 TRACE_FUNCTION( "cs_build_enh_sorted_strng_arfcn_list" );
5802
5803 /* Sort ARFCNs into Serving, Non-serving or the Rest*/
5804 total_arfcns = cs_sort_arfcns_into_bins(&s_bin, &r_bin);
5805
5806 /* Sort the ARFCNs in desc order of RXLEV and store them in the final bin */
5807 if(total_arfcns NEQ 0)
5808 {
5809 cs_sort_store_in_desc_order_rxlev(&s_bin, f_bin);
5810 cs_sort_store_in_desc_order_rxlev(&r_bin, f_bin);
5811 }
5812 }
5813
5814 /*
5815 +------------------------------------------------------------------------------
5816 | Function : cs_sort_arfcns_into_bins
5817 +------------------------------------------------------------------------------
5818 | Description : The purpose of this function is to sort the ARFCNs into various
5819 | bins.
5820 |
5821 |
5822 | Parameters : Pointers to the the bins
5823 |
5824 +------------------------------------------------------------------------------
5825 */
5826 LOCAL UBYTE cs_sort_arfcns_into_bins(T_ENH_STRNG_ARFCN_LIST *p_s_bin,
5827 T_ENH_STRNG_ARFCN_LIST *p_r_bin)
5828 {
5829 UBYTE i;
5830 UBYTE band, sc_band;
5831 UBYTE total_cells = 0;
5832
5833 p_s_bin->num = 0;
5834 p_r_bin->num = 0;
5835
5836 TRACE_FUNCTION( "cs_sort_arfcns_into_bins" );
5837
5838 sc_band = cs_get_band_index_for_emr (psc_db->pbcch.bcch.arfcn);
5839
5840 /* Check the ARFCNs in the NC_MVAL and store them in Serving or
5841 Rest bins according to their bands */
5842 i = 0;
5843 while( (i < MAX_NR_OF_NC_MVAL) AND (total_cells <= MAX_NR_OF_NCELL) )
5844 {
5845 if( (grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ RRGRR_INVALID_ARFCN)
5846 AND (grr_data->db.nc_mval_list.nc_mval[i].status EQ NC_MVAL_STAT_ASSIGNED) )
5847 {
5848 band = cs_get_band_index_for_emr(grr_data->db.nc_mval_list.nc_mval[i].arfcn);
5849 if (band EQ sc_band)
5850 {
5851 p_s_bin->meas[p_s_bin->num].arfcn =
5852 grr_data->db.nc_mval_list.nc_mval[i].arfcn;
5853 p_s_bin->meas[p_s_bin->num].rxlev =
5854 grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
5855 p_s_bin->num++;
5856
5857 }
5858 else /* Process the non-serving bands */
5859 {
5860 p_r_bin->meas[p_r_bin->num].arfcn =
5861 grr_data->db.nc_mval_list.nc_mval[i].arfcn;
5862 p_r_bin->meas[p_r_bin->num].rxlev =
5863 grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
5864 p_r_bin->num++;
5865 }
5866 total_cells = p_s_bin->num + p_r_bin->num;
5867 }
5868 i++;
5869 } /* end of while */
5870 return(total_cells);
5871 }/* cs_sort_arfcns_into_bins */
5872
5873 /*
5874 +------------------------------------------------------------------------------
5875 | Function : cs_sort_in_desc_order_rxlev
5876 +------------------------------------------------------------------------------
5877 | Description : This function sorts the cells collected in each bin, in
5878 | descending order of RXLEV. It will be stored in the final bin
5879 | as and when sorted.
5880 |
5881 |
5882 | Parameters : Pointer to serving or multiband bin, Pointer to final bin
5883 |
5884 +------------------------------------------------------------------------------
5885 */
5886
5887 LOCAL void cs_sort_store_in_desc_order_rxlev(T_ENH_STRNG_ARFCN_LIST *p_bin,
5888 T_ENH_STRNG_ARFCN_LIST *p_f_bin)
5889 {
5890 UBYTE i;
5891 UBYTE j;
5892 UBYTE max_rxlev;
5893 UBYTE k;
5894 T_MEAS temp;
5895
5896 TRACE_FUNCTION( "cs_sort_store_in_desc_order_rxlev" );
5897
5898 for (i = 0; i < p_bin->num; i++)
5899 {
5900 max_rxlev = p_bin->meas[i].rxlev;
5901 k = i;
5902 for ( j = i + 1; j < p_bin->num; j++ )
5903 {
5904 if ( p_bin->meas[j].rxlev > max_rxlev )
5905 {
5906 k = j;
5907 max_rxlev = p_bin->meas[j].rxlev;
5908 }
5909 }
5910
5911 /* Store the ARFCN-RXLEV pair in the final bin in desc order of RXLEV */
5912 p_f_bin->meas[p_f_bin->num++] = p_bin->meas[k];
5913
5914 if(k NEQ i)
5915 {
5916 temp = p_bin->meas[k];
5917 p_bin->meas[k] = p_bin->meas[i];
5918 p_bin->meas[i] = temp;
5919 }
5920 }
5921 }/* cs_sort_store_in_desc_order_rxlev */
5922
5923 /*
5924 +------------------------------------------------------------------------------
5925 | Function : cs_init_ba_bcch_nc_ref_list
5926 +------------------------------------------------------------------------------
5927 | Description :
5928 |
5929 | Parameters : list - pointer to NC measurement pointer list
5930 |
5931 +------------------------------------------------------------------------------
5932 */
5933 GLOBAL void cs_init_ba_bcch_nc_ref_list ()
5934 {
5935 TRACE_FUNCTION( "cs_init_ba_bcch_nc_ref_list" );
5936
5937 grr_data->db.ba_bcch_nc_ref_lst.number = 0;
5938
5939 }/* cs_init_ba_bcch_nc_ref_list */
5940
5941 /*
5942 +------------------------------------------------------------------------------
5943 | Function : cs_build_ba_bcch_nc_freq_list
5944 +------------------------------------------------------------------------------
5945 | Description :
5946 |
5947 | Parameters : db - pointer to serving cell database
5948 |
5949 +------------------------------------------------------------------------------
5950 */
5951 LOCAL void cs_build_ba_bcch_nc_freq_list ()
5952 {
5953 UBYTE i;
5954
5955 TRACE_FUNCTION( "cs_build_ba_bcch_nc_freq_list" );
5956
5957 /*
5958 * add neighbour cell information of SI2 and PMO to reference list
5959 */
5960 for( i = 0; i < psc_db->nc_ba_bcch_cw.number; i++ )
5961 {
5962 grr_data->db.ba_bcch_nc_ref_lst.info[i] = &psc_db->nc_ba_bcch_cw.info[i];
5963 grr_data->db.ba_bcch_nc_ref_lst.number++;
5964 }
5965
5966 if(use_ba_gprs EQ FALSE)
5967 {
5968 UBYTE number = psc_db->nc_ba_bcch_cw.number;
5969 for(i = 0; i < psc_db->nc_ms.ncmeas.list.number; i++)
5970 {
5971 grr_data->db.ba_bcch_nc_ref_lst.info[number] =
5972 &psc_db->nc_ms.ncmeas.list.info[i];
5973 grr_data->db.ba_bcch_nc_ref_lst.info[number]->index = number;
5974 grr_data->db.ba_bcch_nc_ref_lst.number++;
5975 number++;
5976 }
5977 }
5978 }
5979
5980 #endif
5981 /*
5982 +------------------------------------------------------------------------------
5983 | Function : cs_copy_rxlev_from_avg
5984 +------------------------------------------------------------------------------
5985 | Description : The function cs_copy_rxlev_from_avg() helps to retain the old
5986 | rxlev data obtained for the neighbour cells before the cell
5987 | change.
5988 | Parameters : Index of the nc_data->cell,nc_mval->rxlev_avg
5989 |
5990 +------------------------------------------------------------------------------
5991 */
5992 LOCAL void cs_copy_rxlev_from_avg(UBYTE rxlev_avg,T_CELL *cell)
5993 {
5994 #define INITIAL_ACC_MEAS 4
5995 UBYTE i; /* used for counting */
5996 T_RLA_P_DATA *rla_p_data = &cell->rla_p_data;
5997 T_RXLEV_DATA *rxlev_data = &cell->rxlev_data;
5998
5999 TRACE_FUNCTION( "cs_copy_rxlev_from_avg" );
6000 TRACE_EVENT_P3( "cs_copy_rxlev_from_avg arfcn=%ld LOI=%ld rxlev_avg=%ld", cell->arfcn,rla_p_data->loi,rxlev_avg);
6001
6002 rla_p_data->loi = INITIAL_ACC_MEAS - 1 ;
6003 rla_p_data->ovrflw = FALSE;
6004
6005 for( i = 0; i < INITIAL_ACC_MEAS; i++ )
6006 {
6007 rla_p_data->meas[i].cnt = 1;
6008 rla_p_data->meas[i].acc = (USHORT)rxlev_avg;
6009 rla_p_data->meas[i].rpt_prd = 208;
6010 }
6011
6012 rxlev_data->acc = rxlev_avg*INITIAL_ACC_MEAS*RXLEV_ACRCY;
6013 rxlev_data->nbr = INITIAL_ACC_MEAS;
6014 }
6015 /*
6016 +------------------------------------------------------------------------------
6017 | Function : cs_reuse_old_cell_rxlev
6018 +------------------------------------------------------------------------------
6019 | Description : The function cs_reuse_old_cell_rxlev() helps to reuse rxlev data
6020 | obtained for the neighbour cells in the old cell before the cell
6021 | change.
6022 | Parameters : void
6023 |
6024 +------------------------------------------------------------------------------
6025 */
6026 LOCAL void cs_reuse_old_cell_rxlev()
6027 {
6028 T_NC_MVAL *nc_mval;
6029 UBYTE i,found,mval_idx ;
6030 UBYTE mval_index=0;
6031
6032 TRACE_FUNCTION( "cs_reuse_old_cell_rxlev" );
6033 TRACE_EVENT( "cs_reuse_old_cell_rxlev" );
6034
6035 for( i = 0; i < MPHP_NUMC_BA_GPRS_SC; i++ )
6036 {
6037 #if 0
6038 mval_index = 0;
6039 nc_mval = grr_get_nc_mval( nc_data->cell[i].arfcn, RRGRR_INVALID_BSIC, &mval_index );
6040 if(nc_mval NEQ 0)
6041 {
6042 if(nc_mval->rla_p.stat EQ CS_RLA_P_VALID)
6043 {
6044 cs_copy_rxlev_from_avg( (UBYTE)nc_mval->rxlev_avg,&nc_data->cell[i] );
6045 }
6046 else
6047 {
6048 cs_reset_meas_result( &nc_data->cell[i] );
6049 }
6050 }
6051 else
6052 {
6053 cs_reset_meas_result( &nc_data->cell[i] );
6054 }
6055 #else
6056 found=0;
6057 for( mval_idx = 0; mval_idx < MAX_NR_OF_NC_MVAL; mval_idx++ )
6058 {
6059 nc_mval = &grr_data->db.nc_mval_list.nc_mval[mval_idx];
6060 if((UBYTE)nc_mval->rxlev_avg EQ 0xFF AND
6061 nc_mval->rla_p.stat EQ CS_RLA_P_VALID)
6062 {
6063 TRACE_EVENT_P4("PATCH: arfcn=%ld avg_lev=%ld rla_p_lev=%ld stat=%ld "
6064 ,nc_mval->arfcn,nc_mval->rxlev_avg,nc_mval->rla_p.lev,nc_mval->rla_p.stat);
6065 }
6066 if(
6067 (nc_mval->arfcn EQ nc_data->cell[i].arfcn)
6068 AND
6069 (nc_mval->rla_p.stat EQ CS_RLA_P_VALID)
6070 AND
6071 ((UBYTE)nc_mval->rxlev_avg NEQ 0xFF)
6072 )
6073 {
6074 cs_copy_rxlev_from_avg( (UBYTE)nc_mval->rxlev_avg,&nc_data->cell[i] );
6075 found=1;
6076 }
6077 }
6078 if(!found)
6079 cs_reset_meas_result( &nc_data->cell[i] );
6080 #endif
6081 }
6082 }
6083
6084
6085
6086
6087
6088
6089