comparison src/g23m-gprs/grr/grr_measf.c @ 183:219afcfc6250

src/g23m-gprs: initial import from TCS3.2/LoCosto
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 13 Oct 2016 04:24:13 +0000
parents
children
comparison
equal deleted inserted replaced
182:f02d0a0e1849 183:219afcfc6250
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 MEAS of
18 | entity GRR.
19 +-----------------------------------------------------------------------------
20 */
21
22 #ifndef GRR_MEASF_C
23 #define GRR_MEASF_C
24 #endif
25
26 #define ENTITY_GRR
27
28 /*==== INCLUDES =============================================================*/
29
30 #include <string.h>
31
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_measf.h" /* to get the own definitions */
45 #include "grr_meass.h" /* to get the own definitions */
46 #include "grr_ctrls.h"
47
48 /*==== CONST ================================================================*/
49
50 #define IDX_UBYTE_INVALID 0xFF /* invalid index */
51 #define IDX_USHORT_INVALID 0xFFFF /* invalid index */
52 #define TIME_INVALID 0x7FFFFFFF /* invalid time, should be the */
53 /* largest possible value for an */
54 /* variable of type LONG */
55
56 #define USE_ALL_TIMESLOTS 0xFF /* timeslot mask */
57
58 #define EM_EXT_RPT_TYPE_LEN 2 /* length of EXT reporting type bit field */
59 #define EM_ABS_I_LEVEL_LEN 6 /* length of absolute I_LEVEL bit field */
60 #define EM_NUM_OF_MEAS_LEN 5 /* length of number of measurement bit field */
61 #define EM_FREQ_N_LEN 6 /* length of FREQ_N bit field */
62 #define EM_BSIC_N_LEN 6 /* length of BSIC_N bit field */
63 #define EM_RXLEV_N_LEN 6 /* length of RXLEV_N bit field */
64
65 #ifdef _SIMULATION_
66 #define GET_EM_RPT_PRD(x) ((0x01<<(x))*10000) /* multiple of 10 sec., to get */
67 /* a reduced test duration */
68 #else /* #ifdef _SIMULATION_ */
69 #define GET_EM_RPT_PRD(x) ((0x01<<(x))*60000) /* multiple of 60 sec. */
70 #endif /* #ifdef _SIMULATION_ */
71
72 #define I_LEVEL_MIN I_LEVEL_0
73 #define I_LEVEL_0 0 /* i.lev. is greater than C */
74 #define I_LEVEL_15 15 /* i.lev. is less than or equal to C - 28 dB */
75 #define I_LEVEL_MAX I_LEVEL_15
76 #define I_LEVEL_GAMMA_0_SKIPPED 0xF0 /* used for tracing */
77 #define I_LEVEL_GAMMA_1_SKIPPED 0xF1 /* used for tracing */
78 #define I_LEVEL_GAMMA_2_SKIPPED 0xF2 /* used for tracing */
79 #define I_LEVEL_GAMMA_3_SKIPPED 0xF3 /* used for tracing */
80 #define I_LEVEL_STATE_MISMATCH 0xFD /* used for tracing */
81 #define I_LEVEL_IDX_TO_SMALL 0xFE /* used for tracing */
82 #define I_LEVEL_NOT_AVAIL 0xFF /* used for tracing */
83
84 #define NORM_NAVGI_FAC (ULONG)10 /* normalised Navg_i factor */
85
86 #ifdef _TARGET_
87
88 #define MIN_GAMMA_FOR_I_LEVEL_RPTING 4 /* minimum I-LEVEL value of neighbour */
89 /* cells that will be reported to the */
90 #else /* network, otherwise I-LEVEL values */
91 /* will be reported as not available */
92 #define MIN_GAMMA_FOR_I_LEVEL_RPTING 0
93
94 #endif /* #ifdef _TARGET_ */
95
96 #define MEAS_C_INC_INDEX(index) { \
97 if( index < (T_C_INDEX)(~0) ) index++; \
98 }
99
100 /*==== LOCAL VARS ===========================================================*/
101
102 LOCAL T_MEAS_IM_DATA* imeas = NULL;
103 /* pointer to interference measurement parameter */
104 LOCAL T_MEAS_EM_DATA* emeas = NULL;
105 /* pointer to extended measurement parameter */
106
107 #if defined (REL99) AND defined (TI_PS_FF_EMR)
108 LOCAL BOOL nc_freq_list_valid = FALSE;
109 LOCAL BOOL nc_freq_list_pres = FALSE;
110 GLOBAL BOOL use_ba_gprs = TRUE;
111 #endif
112
113 /*
114 * normalised math.power value
115 *
116 * NORM_POW_MIN * ( 2 ** ( k / 2 ) )
117 */
118
119 GLOBAL const ULONG norm_pow[] = { NORM_POW_MIN,
120 1414, 2000, 2828, 4000, 5657,
121 8000, 11314, 16000, 22627, 32000,
122 45255, 64000, 90510, 128000, 181019,
123 256000, 362039, 512000, 724077, 1024000,
124 1448155, 2048000, 2896309, 4096000, 5792619 };
125
126 /*==== LOCAL TYPES===========================================================*/
127
128 LOCAL void meas_im_restart_all_filters ( void );
129
130 LOCAL void meas_im_restart_filter ( T_MEAS_IM_FILTER *filter );
131
132 LOCAL void meas_im_restart_gamma ( T_MEAS_IM_FILTER *filter,
133 UBYTE index );
134
135 LOCAL T_MEAS_IM_FILTER*
136 meas_im_get_unused_filter ( void );
137
138 LOCAL void meas_im_update_filter ( T_MEAS_IM_FILTER *filter,
139 UBYTE *rxlev,
140 UBYTE state );
141
142 LOCAL BOOL meas_im_freq_cmp_a ( USHORT arfcn1,
143 USHORT arfcn2 );
144
145 LOCAL BOOL meas_im_freq_cmp_m ( T_MEAS_IM_CARRIER *ma1,
146 T_MEAS_IM_CARRIER *ma2 );
147
148 LOCAL ULONG meas_im_get_val_trns ( void );
149
150 LOCAL ULONG meas_im_get_val_idle ( void );
151
152 LOCAL UBYTE meas_im_get_number_of_measured_channels
153 ( void );
154
155 LOCAL T_MEAS_IM_FILTER*
156 meas_im_get_oldest_filter ( void );
157
158 LOCAL BOOL meas_im_get_int_meas_freq ( UBYTE index,
159 T_MEAS_IM_CARRIER *carrier,
160 UBYTE *ts_mask );
161
162 LOCAL BOOL meas_im_get_trns_freq ( T_MEAS_IM_CARRIER *ma );
163
164 LOCAL BOOL meas_im_get_idle_freq ( ULONG id,
165 T_MEAS_IM_CARRIER *carrier,
166 UBYTE *ts_mask );
167
168 LOCAL void meas_im_timer_reorg ( T_TIME time_to_elapse,
169 LONG time_diff );
170
171 LOCAL void meas_im_delete_em_rslt ( void );
172
173 LOCAL USHORT meas_im_get_unmsk_int_freq ( UBYTE index );
174
175 LOCAL void meas_im_start_t_im_sync ( T_TIME vld_prd );
176
177 LOCAL ULONG meas_im_get_paging_period ( void );
178
179 LOCAL void meas_im_set_freq_par ( T_p_frequency_par *freq_par,
180 T_MEAS_IM_CARRIER *carrier );
181
182 LOCAL void meas_em_init_pmo_seq ( void );
183
184 LOCAL UBYTE meas_em_build_meas_rpt ( T_U_MEAS_REPORT *u_meas_report );
185
186 LOCAL UBYTE meas_em_extrct_strgst ( void );
187
188 LOCAL UBYTE meas_em_extrct_strgst_with_bsic
189 ( void );
190 LOCAL void meas_em_req ( void );
191
192 LOCAL BOOL meas_em_is_meas_reporting ( void );
193
194 LOCAL void meas_em_start_t3178 ( T_TIME time );
195
196 LOCAL void meas_em_stop_t3178 ( void );
197
198 /*==== PRIVATE FUNCTIONS ====================================================*/
199 /*
200 +------------------------------------------------------------------------------
201 | Function : meas_im_init
202 +------------------------------------------------------------------------------
203 | Description : ...
204 |
205 | Parameters : void
206 |
207 +------------------------------------------------------------------------------
208 */
209 GLOBAL void meas_im_init ( T_MEAS_IM_MODE im_mode )
210 {
211 TRACE_FUNCTION( "meas_im_init" );
212
213 INIT_STATE( MEAS_IM, MEAS_IM_NULL );
214
215 imeas = &grr_data->meas_im;
216
217 #if !defined (NTRACE)
218
219 imeas->n_im_trace = 0;
220
221 #endif /* #if !defined (NTRACE) */
222
223 imeas->mode = im_mode;
224 imeas->carrier_id = IDX_USHORT_INVALID;
225 imeas->trig_signal = IM_TRIG_SIGNAL_NULL;
226 imeas->v_cs_meas_active = FALSE;
227
228 meas_im_restart_all_filters( );
229 } /* meas_im_init() */
230
231 /*
232 +------------------------------------------------------------------------------
233 | Function : meas_im_restart_all_filters
234 +------------------------------------------------------------------------------
235 | Description : This function restarts all filters used in context of
236 | interference measurements.
237 |
238 | Parameters : void
239 |
240 +------------------------------------------------------------------------------
241 */
242 LOCAL void meas_im_restart_all_filters ( void )
243 {
244 UBYTE i; /* used for counting */
245
246 TRACE_FUNCTION( "meas_im_restart_all_filters" );
247
248 for( i = 0; i < MAX_IM_CHANNELS; i++ )
249 {
250 meas_im_restart_filter( &imeas->filter[i] );
251 }
252 } /* meas_im_restart_all_filters() */
253
254 /*
255 +------------------------------------------------------------------------------
256 | Function : meas_im_restart_filter
257 +------------------------------------------------------------------------------
258 | Description : This function restarts all filters for one carrier
259 | used in context of interference measurements.
260 |
261 | Parameters : *filter - Ptr to filter
262 |
263 +------------------------------------------------------------------------------
264 */
265 LOCAL void meas_im_restart_filter ( T_MEAS_IM_FILTER* filter )
266 {
267 UBYTE i; /* used for counting */
268
269 TRACE_FUNCTION( "meas_im_restart_filter" );
270
271 for( i = 0; i < CGRLC_MAX_TIMESLOTS; i++ )
272 {
273 meas_im_restart_gamma( filter, i );
274 }
275 } /* meas_im_restart_filter() */
276
277 /*
278 +------------------------------------------------------------------------------
279 | Function : meas_im_restart_gamma
280 +------------------------------------------------------------------------------
281 | Description : This function restarts an individual filter for
282 | one channel used in context of interference measurements.
283 |
284 | Parameters : *filter - Ptr to filter
285 | index - index of the interference level values
286 |
287 +------------------------------------------------------------------------------
288 */
289 LOCAL void meas_im_restart_gamma ( T_MEAS_IM_FILTER* filter,
290 UBYTE index )
291 {
292 T_MEAS_IM_GAMMA* gamma = &filter->i_level[index];
293
294 SET_FLAG( filter->used, IM_U_MASK << index, IM_U_UNUSED << index, UBYTE );
295
296 gamma->index = 0;
297 gamma->m_gamma = IM_I_NONE;
298 gamma->gamma = 0;
299 gamma->remain_time = TIME_INVALID;
300 } /* meas_im_restart_gamma() */
301
302 /*
303 +------------------------------------------------------------------------------
304 | Function : meas_im_get_filter
305 +------------------------------------------------------------------------------
306 | Description : This function is used to look for the filter that should be
307 | updated. It searches for the filter with the same channel
308 | description.
309 |
310 | Parameters : *ma - Ptr to frequency information in MA format
311 |
312 +------------------------------------------------------------------------------
313 */
314 GLOBAL T_MEAS_IM_FILTER* meas_im_get_filter ( T_MEAS_IM_CARRIER *ma )
315 {
316 UBYTE i; /* used for counting */
317 T_MEAS_IM_FILTER *filter = NULL; /* found filter */
318 BOOL filter_found = FALSE; /* indicator */
319
320 TRACE_FUNCTION( "meas_im_get_filter" );
321
322 i = 0;
323
324 while( i < MAX_IM_CHANNELS AND !filter_found )
325 {
326 filter = &imeas->filter[i];
327
328 if( ma->hopping )
329 {
330 if( ma NEQ NULL AND
331 filter->used NEQ IM_U_UNUSED AND
332 filter->carrier.hopping EQ TRUE AND
333 meas_im_freq_cmp_m( ma, &filter->carrier ))
334 {
335 filter_found = TRUE;
336 }
337 }
338 else
339 {
340 if( filter->used NEQ IM_U_UNUSED AND
341 filter->carrier.hopping EQ FALSE AND
342 meas_im_freq_cmp_a( ma->alloc.arfcn,
343 filter->carrier.alloc.arfcn ) )
344 {
345 filter_found = TRUE;
346 }
347 }
348
349 i++;
350 }
351
352 return( filter_found ? filter : NULL );
353 } /* meas_im_get_filter() */
354
355 /*
356 +------------------------------------------------------------------------------
357 | Function : meas_im_get_unused_filter
358 +------------------------------------------------------------------------------
359 | Description : This function is used to look for the first unused filter.
360 |
361 | Parameters : void
362 |
363 +------------------------------------------------------------------------------
364 */
365 LOCAL T_MEAS_IM_FILTER* meas_im_get_unused_filter ( void )
366 {
367 UBYTE i; /* used for counting */
368 T_MEAS_IM_FILTER *filter = NULL; /* found filter */
369
370 TRACE_FUNCTION( "meas_im_get_unused_filter" );
371
372 i = 0;
373
374 while( i < MAX_IM_CHANNELS AND filter EQ NULL )
375 {
376 if( imeas->filter[i].used EQ IM_U_UNUSED )
377 {
378 filter = &imeas->filter[i];
379 }
380
381 i++;
382 }
383
384 return( filter );
385 } /* meas_im_get_unused_filter() */
386
387 /*
388 +------------------------------------------------------------------------------
389 | Function : meas_im_update_filter
390 +------------------------------------------------------------------------------
391 | Description : This function is used to update an interference level filter.
392 |
393 | Parameters : *filter - Ptr to filter
394 | *rxlev - Ptr to measurement values
395 | mode - Packet idle or packet transfer mode
396 |
397 +------------------------------------------------------------------------------
398 */
399 LOCAL void meas_im_update_filter ( T_MEAS_IM_FILTER *filter,
400 UBYTE *rxlev,
401 UBYTE state )
402 {
403 UBYTE i; /* used for counting */
404 BOOL valid_meas = FALSE; /* indicates if at least one valid */
405 /* measurement sample is present */
406 T_TIME time_to_elapse =0; /* this is the remaining time until */
407 /* timer T_IM_SYNC will elpase */
408 LONG remain_time = 0; /* this is the remaining time for an */
409 /* individual filter */
410 ULONG d; /* forgetting factor */
411 ULONG g_value;
412 T_MEAS_IM_GAMMA *ilevel;
413 /* inteference level */
414 ULONG validity; /* validity period of the measurement results */
415 BOOL v_t_im_sync = FALSE; /* indicates whether the timer T_IM_SYNC is */
416 /* running or not */
417
418
419
420 TRACE_FUNCTION( "meas_im_update_filter" );
421
422 /* calculate validity period of the measurements */
423 if( state EQ MEAS_IDLE )
424 {
425 validity = meas_im_get_val_idle( );
426 }
427 else
428 {
429 validity = meas_im_get_val_trns( );
430 }
431
432 /* calculate remaining time */
433 time_to_elapse = grr_t_status( T_IM_SYNC );
434
435 if( time_to_elapse > 0 )
436 {
437 remain_time = validity - time_to_elapse;
438 v_t_im_sync = TRUE;
439 }
440
441 for( i = 0; i < CGRLC_MAX_TIMESLOTS; i++ )
442 {
443 ilevel = &filter->i_level[i];
444
445 if( rxlev[i] NEQ CGRLC_RXLEV_NONE )
446 {
447 SET_FLAG( filter->used, IM_U_MASK << i, IM_U_USED << i, UBYTE );
448 valid_meas = TRUE;
449
450 ilevel->remain_time = remain_time;
451
452 #ifdef _SIMULATION_
453 TRACE_EVENT_P1("REMAIN_TIME = %d", remain_time);
454 #endif /* #ifdef (_SIMULATION_) */
455
456 /* counting the iteration index */
457 if( NORM_POW_MIN * ilevel->index < norm_pow[psc_db->g_pwr_par.n_avg_i] )
458 {
459 ilevel->index++;
460 }
461
462 /* calculate the forgetting factor */
463 d = ( NORM_POW_MIN * NORM_POW_MIN * NORM_NAVGI_FAC ) /
464 MINIMUM( NORM_POW_MIN * ilevel->index,
465 norm_pow[psc_db->g_pwr_par.n_avg_i] );
466
467 /* update the filter */
468 g_value = ( ( NORM_POW_MIN * NORM_NAVGI_FAC ) - d ) * ilevel->gamma
469 +
470 d * MEAS_ACRCY * rxlev[i];
471
472 ilevel->gamma = (T_IM_GAMMA)(g_value / (NORM_POW_MIN * NORM_NAVGI_FAC));
473
474 #ifdef _SIMULATION_
475 TRACE_EVENT_P2("TS = %d, I-LEVEL = %d", i, ilevel->gamma);
476 #endif /* #ifdef (_SIMULATION_) */
477
478 /* store the mode in which the measurement was performed */
479 if( state EQ MEAS_IDLE )
480 {
481 SET_FLAG( ilevel->m_gamma, IM_I_MASK_IDL, IM_I_IDL, UBYTE );
482 SET_FLAG( ilevel->m_gamma, IM_I_MASK_TRNS, IM_I_NONE, UBYTE );
483 }
484 else
485 {
486 SET_FLAG( ilevel->m_gamma, IM_I_MASK_TRNS, IM_I_TRNS, UBYTE );
487 SET_FLAG( ilevel->m_gamma, IM_I_MASK_IDL, IM_I_NONE, UBYTE );
488 }
489
490 }
491 } /* i */
492
493 /*
494 * do some administrative stuff only in case there was at least
495 * one valid sample reported by Layer 1
496 */
497 if( valid_meas )
498 {
499 if( v_t_im_sync )
500 {
501 if( remain_time < 0 )
502 {
503 meas_im_timer_reorg( time_to_elapse, remain_time );
504 }
505 }
506 else
507 {
508 meas_im_start_t_im_sync( (ULONG)validity );
509 }
510 }
511 } /* meas_im_update_filter() */
512
513 /*
514 +------------------------------------------------------------------------------
515 | Function : meas_im_freq_cmp_a
516 +------------------------------------------------------------------------------
517 | Description : This function returns whether two frequencies are identical
518 | or not.
519 |
520 | Parameters : arfcn1 - First frequency used for comparison
521 | arfcn2 - Second frequency used for comparison
522 |
523 +------------------------------------------------------------------------------
524 */
525 LOCAL BOOL meas_im_freq_cmp_a ( USHORT arfcn1, USHORT arfcn2 )
526 {
527 return( arfcn1 EQ arfcn2 );
528 } /* meas_im_freq_cmp_a() */
529
530 /*
531 +------------------------------------------------------------------------------
532 | Function : meas_im_freq_cmp_m
533 +------------------------------------------------------------------------------
534 | Description : This function returns whether two frequency information given
535 | in mobile allocation format are identical or not. Channels
536 | that only differ in MAIO are considered the same.
537 |
538 | Parameters : *ma1 - First channel description used for comparison
539 | *ma2 - Second channel description used for comparison
540 |
541 +------------------------------------------------------------------------------
542 */
543 LOCAL BOOL meas_im_freq_cmp_m ( T_MEAS_IM_CARRIER *ma1, T_MEAS_IM_CARRIER *ma2 )
544 {
545 return
546 (
547 ma1->alloc.hop_param.hsn EQ ma2->alloc.hop_param.hsn
548
549 AND
550
551 memcmp( ma1->alloc.hop_param.arfcn_bit_field,
552 ma2->alloc.hop_param.arfcn_bit_field,
553 sizeof( ma1->alloc.hop_param.arfcn_bit_field ) ) EQ 0
554 );
555 } /* meas_im_freq_cmp_m() */
556
557 /*
558 +------------------------------------------------------------------------------
559 | Function : meas_im_get_val_trns
560 +------------------------------------------------------------------------------
561 | Description : This function returns the validity period of a measurement
562 | performed in packet transfer mode (unit is milliseconds).
563 |
564 | Parameters : void
565 |
566 +------------------------------------------------------------------------------
567 */
568 LOCAL ULONG meas_im_get_val_trns ( void )
569 {
570 ULONG n_avg_i_half = norm_pow[psc_db->g_pwr_par.n_avg_i] / 2;
571
572 return(ULONG)
573 ( ( n_avg_i_half * ( USEC_PER_MF / (ULONG)10 ) ) /
574 ( NORM_POW_MIN * (ULONG)MEAS_ACRCY / (ULONG)10 ) );
575 } /* meas_im_get_val_trns() */
576
577 /*
578 +------------------------------------------------------------------------------
579 | Function : meas_im_get_val_idle
580 +------------------------------------------------------------------------------
581 | Description : This function returns the validity period of a measurement
582 | performed in packet idle mode (unit is milliseconds).
583 |
584 | Parameters : void
585 |
586 +------------------------------------------------------------------------------
587 */
588 LOCAL ULONG meas_im_get_val_idle ( void )
589 {
590 ULONG val_idle = TIME_INVALID - 1;
591 ULONG paging_period = meas_im_get_paging_period( );
592
593 if( paging_period NEQ NO_PAGING )
594 {
595 ULONG acrcy_n, acrcy_p;
596 ULONG novimc_t_navgi = meas_im_get_number_of_measured_channels( ) *
597 norm_pow[psc_db->g_pwr_par.n_avg_i];
598
599 if ( paging_period <= 650000 ) acrcy_p = 10;
600 else if( paging_period <= 6500000 ) acrcy_p = 100;
601 else acrcy_p = 1000;
602
603 if ( novimc_t_navgi <= 130000 ) acrcy_n = 1;
604 else if( novimc_t_navgi <= 1300000 ) acrcy_n = 10;
605 else acrcy_n = 100;
606
607 val_idle =
608 (ULONG)
609 (
610 ( MAXIMUM(
611 ( novimc_t_navgi / ( (ULONG)4 * acrcy_n ) ) *
612 ( USEC_PER_MF / acrcy_p ),
613 ( novimc_t_navgi / ( (ULONG)2 * acrcy_n ) ) *
614 ( paging_period / acrcy_p )
615 )
616 ) / ( NORM_POW_MIN * (ULONG)MEAS_ACRCY / ( acrcy_n * acrcy_p ) )
617 );
618 }
619
620 return val_idle;
621 } /* meas_im_get_val_idle() */
622
623 /*
624 +------------------------------------------------------------------------------
625 | Function : meas_im_get_number_of_measured_channels
626 +------------------------------------------------------------------------------
627 | Description :
628 |
629 | Parameters :
630 |
631 +------------------------------------------------------------------------------
632 */
633 LOCAL UBYTE meas_im_get_number_of_measured_channels ( void )
634 {
635 UBYTE number = psc_db->number_of_valid_int_meas_channels;
636
637 if( imeas->idle_chan.ident[CHN_ID_EM_BASE] NEQ CHN_ID_INVALID )
638 {
639 number++;
640 }
641
642 if( imeas->idle_chan.ident[CHN_ID_PCCCH_BASE] NEQ CHN_ID_INVALID )
643 {
644 number++;
645 }
646
647 return( number );
648 } /* meas_im_get_number_of_measured_channels() */
649
650 /*
651 +------------------------------------------------------------------------------
652 | Function : meas_im_get_oldest_filter
653 +------------------------------------------------------------------------------
654 | Description : This functions returns a filter that can be used for storing
655 | measurement results
656 |
657 | Parameters : void
658 |
659 +------------------------------------------------------------------------------
660 */
661 LOCAL T_MEAS_IM_FILTER* meas_im_get_oldest_filter ( void )
662 {
663 UBYTE i, j; /* used for counting */
664 LONG remain1 = TIME_INVALID; /* holds remaining time */
665 LONG remain2; /* holds remaining time */
666 BOOL all_invalid; /* indicates if all remaining times */
667 /* are invalid */
668 UBYTE filter_idx = IDX_UBYTE_INVALID; /* index of oldest filter */
669 T_MEAS_IM_GAMMA *ilevel; /* interference level */
670
671 TRACE_FUNCTION( "meas_im_get_oldest_filter" );
672
673 for( i = 0; i < MAX_IM_CHANNELS; i++ )
674 {
675 remain2 = TIME_INVALID;
676 all_invalid = TRUE;
677
678 for( j = 0; j < CGRLC_MAX_TIMESLOTS; j++ )
679 {
680 ilevel = &imeas->filter[i].i_level[j];
681
682 if( ilevel->remain_time NEQ TIME_INVALID )
683 {
684 all_invalid = FALSE;
685
686 if( remain2 EQ TIME_INVALID )
687 {
688 remain2 = ilevel->remain_time;
689 }
690 else
691 {
692 remain2 = MINIMUM( ilevel->remain_time, remain2 );
693 }
694 }
695 }
696
697 if( all_invalid )
698 {
699 filter_idx = i;
700 }
701 else if( remain1 EQ TIME_INVALID OR remain1 < remain2 )
702 {
703 remain1 = remain2;
704 filter_idx = i;
705 }
706 }
707
708 return( filter_idx EQ IDX_UBYTE_INVALID ? NULL : &imeas->filter[i] );
709 } /* meas_im_get_oldest_filter() */
710
711 /*
712 +------------------------------------------------------------------------------
713 | Function : meas_im_get_int_meas_freq
714 +------------------------------------------------------------------------------
715 | Description : ...
716 |
717 | Parameters : ...
718 |
719 +------------------------------------------------------------------------------
720 */
721 LOCAL BOOL meas_im_get_int_meas_freq ( UBYTE index,
722 T_MEAS_IM_CARRIER *carrier,
723 UBYTE *ts_mask )
724 {
725 T_p_frequency_par freq_par;
726 T_int_meas_chan_lst *lst = &psc_db->int_meas_chan_list[index];
727 BOOL valid = TRUE;
728
729 TRACE_FUNCTION( "meas_im_get_int_meas_freq" );
730
731 if( lst->v_arfcn EQ TRUE )
732 {
733 carrier->hopping = FALSE;
734 carrier->alloc.arfcn = lst->arfcn;
735 }
736 else if( lst->v_ma_num_maio EQ TRUE )
737 {
738 if( ( valid = grr_create_freq_list( lst->ma_num,
739 lst->maio,
740 &freq_par.p_chan_sel,
741 &freq_par.p_freq_list ) ) EQ TRUE )
742 {
743 meas_im_set_carrier( carrier, &freq_par );
744 }
745 }
746 else
747 {
748 valid = FALSE;
749 }
750
751 *ts_mask = lst->ts_alloc;
752
753 return( valid );
754 } /* meas_im_get_int_meas_freq() */
755
756 /*
757 +------------------------------------------------------------------------------
758 | Function : meas_im_get_trns_freq
759 +------------------------------------------------------------------------------
760 | Description : ...
761 |
762 | Parameters : ...
763 |
764 +------------------------------------------------------------------------------
765 */
766 LOCAL BOOL meas_im_get_trns_freq ( T_MEAS_IM_CARRIER *ma )
767 {
768 TRACE_FUNCTION( "meas_im_get_trns_freq" );
769
770 if( grr_data->tc.v_freq_set EQ TRUE )
771 {
772 T_p_frequency_par freq_par;
773
774 grr_set_freq_par( &freq_par );
775 meas_im_set_carrier( ma, &freq_par );
776 }
777
778 return( grr_data->tc.v_freq_set );
779 } /* meas_im_get_trns_freq() */
780
781 /*
782 +------------------------------------------------------------------------------
783 | Function : meas_im_get_idle_freq
784 +------------------------------------------------------------------------------
785 | Description : ...
786 |
787 | Parameters : ...
788 |
789 +------------------------------------------------------------------------------
790 */
791 LOCAL BOOL meas_im_get_idle_freq ( ULONG id,
792 T_MEAS_IM_CARRIER *carrier,
793 UBYTE *ts_mask )
794 {
795 BOOL valid_id = TRUE;
796 T_MEAS_IM_IDLE_CHN* chn = &imeas->idle_chan;
797
798 TRACE_FUNCTION( "meas_im_get_idle_freq" );
799
800 if( id >= MAX_IM_IDLE_CHANNELS OR
801 chn->ident[id] EQ CHN_ID_INVALID )
802 {
803 TRACE_ERROR( "ID invalid in meas_im_get_idle_freq" );
804 valid_id = FALSE;
805 }
806 else if( id EQ CHN_ID_EM_BASE )
807 {
808 *ts_mask = USE_ALL_TIMESLOTS; /* SZML-MEAS/005 */
809 carrier->hopping = FALSE;
810 carrier->alloc.arfcn = meas_im_get_unmsk_int_freq( chn->ident[id] );
811 }
812 else if( id EQ CHN_ID_PCCCH_BASE )
813 {
814 T_p_frequency_par freq_par;
815
816 *ts_mask = ( 0x80 >> psc_db->paging_group.pccch[chn->ident[id]].tn );
817
818 grr_get_pccch_freq_par( chn->ident[id],
819 &freq_par.p_chan_sel,
820 &freq_par.p_freq_list );
821
822 meas_im_set_carrier( carrier, &freq_par );
823 }
824 else
825 {
826 valid_id = meas_im_get_int_meas_freq( chn->ident[id], carrier, ts_mask );
827 }
828
829 return( valid_id );
830 } /* meas_im_get_idle_freq() */
831
832 /*
833 +------------------------------------------------------------------------------
834 | Function : meas_im_timer_reorg
835 +------------------------------------------------------------------------------
836 | Description : ...
837 |
838 | Parameters : ...
839 |
840 +------------------------------------------------------------------------------
841 */
842 LOCAL void meas_im_timer_reorg ( T_TIME time_to_elapse, LONG time_diff )
843 {
844 UBYTE i, j; /* used for counting */
845
846 TRACE_FUNCTION( "meas_im_timer_reorg" );
847
848 vsi_t_stop( GRR_handle, T_IM_SYNC );
849
850 for( i = 0; i < MAX_IM_CHANNELS; i++ )
851 {
852 for( j = 0; j < CGRLC_MAX_TIMESLOTS; j++ )
853 {
854 if( imeas->filter[i].i_level[j].remain_time NEQ TIME_INVALID )
855 {
856 imeas->filter[i].i_level[j].remain_time -= time_diff;
857 }
858 }
859 }
860
861 meas_im_start_t_im_sync( ( LONG )time_to_elapse + time_diff );
862
863 } /* meas_im_timer_reorg() */
864
865 /*
866 +------------------------------------------------------------------------------
867 | Function : meas_im_fill_rel_iLevel
868 +------------------------------------------------------------------------------
869 | Description : ...
870 |
871 | Parameters : ...
872 |
873 +------------------------------------------------------------------------------
874 */
875 GLOBAL void meas_im_fill_rel_iLevel ( UBYTE *v_ilev,
876 UBYTE *ilev,
877 T_MEAS_IM_FILTER *filter,
878 UBYTE idx )
879 {
880 UBYTE val; /* holds interference level data */
881
882 *v_ilev = FALSE;
883
884 if( filter NEQ NULL )
885 {
886
887 #ifdef _TARGET_
888
889 UBYTE state = GET_STATE( MEAS );
890
891 if(
892 (
893 state EQ MEAS_IDLE
894 AND
895 IS_FLAGGED( filter->i_level[idx].m_gamma, IM_I_MASK_IDL, IM_I_IDL )
896 )
897 OR
898 (
899 state EQ MEAS_TRANSFER
900 AND
901 IS_FLAGGED( filter->i_level[idx].m_gamma, IM_I_MASK_TRNS, IM_I_TRNS )
902 )
903 )
904
905 #endif /* #ifdef _TARGET_ */
906
907 {
908 if( NORM_POW_MIN * filter->i_level[idx].index >=
909 norm_pow[psc_db->g_pwr_par.n_avg_i] )
910 {
911 if( filter->i_level[idx].gamma >=
912 ( MIN_GAMMA_FOR_I_LEVEL_RPTING * MEAS_ACRCY ) ) /*lint !e685*/
913 {
914 T_C_FILTER *c_filter = &grr_data->meas.c_filter;
915 USHORT c_value;
916
917 if( c_filter->index > 0 )
918 {
919 c_value = c_filter->value;
920 }
921 else
922 {
923 c_value = C_VALUE_DEFAULT;
924 }
925
926 /* calculation of interference level */
927 if( c_value < filter->i_level[idx].gamma )
928 {
929 *ilev = I_LEVEL_MIN;
930 }
931 else
932 {
933 val = ( c_value - filter->i_level[idx].gamma ) / ( 2 * MEAS_ACRCY ) + 1;
934
935 if( val > I_LEVEL_MAX ) *ilev = I_LEVEL_MAX;
936 else *ilev = val;
937 }
938
939 *v_ilev = TRUE;
940 }
941
942 #if !defined (NTRACE)
943
944 else
945 {
946 /* prepare proper tracing information */
947 switch( filter->i_level[idx].gamma / MEAS_ACRCY )
948 {
949 case 0: *ilev = I_LEVEL_GAMMA_0_SKIPPED; break;
950 case 1: *ilev = I_LEVEL_GAMMA_1_SKIPPED; break;
951 case 2: *ilev = I_LEVEL_GAMMA_2_SKIPPED; break;
952 case 3: *ilev = I_LEVEL_GAMMA_3_SKIPPED; break;
953
954 default:
955 TRACE_ERROR( "meas_im_fill_rel_iLevel: impossible case" );
956 break;
957 }
958 }
959
960 #endif /* #if !defined (NTRACE) */
961
962 }
963
964 #if !defined (NTRACE)
965
966 else
967 {
968 /* prepare proper tracing information */
969 *ilev = I_LEVEL_IDX_TO_SMALL;
970 }
971
972 #endif /* #if !defined (NTRACE) */
973
974 }
975
976 #ifdef _TARGET_
977
978 #if !defined (NTRACE)
979
980 else
981 {
982 /* prepare proper tracing information */
983 *ilev = I_LEVEL_STATE_MISMATCH;
984 }
985
986 #endif /* #if !defined (NTRACE) */
987
988 #endif /* #ifdef _TARGET_ */
989
990 }
991
992 #if !defined (NTRACE)
993
994 else
995 {
996 /* prepare proper tracing information */
997 *ilev = I_LEVEL_NOT_AVAIL;
998 }
999
1000 #endif /* #if !defined (NTRACE) */
1001
1002 } /* meas_im_fill_rel_iLevel() */
1003
1004 /*
1005 +------------------------------------------------------------------------------
1006 | Function : meas_im_fill_abs_iLevel
1007 +------------------------------------------------------------------------------
1008 | Description : ...
1009 |
1010 | Parameters : ...
1011 |
1012 +------------------------------------------------------------------------------
1013 */
1014 GLOBAL UBYTE meas_im_fill_abs_iLevel ( UBYTE *v_ilev,
1015 UBYTE *ilev,
1016 T_MEAS_IM_FILTER *filter,
1017 UBYTE idx )
1018 {
1019 UBYTE used_bits = PMR_FLAG_LEN;
1020
1021 *v_ilev = FALSE;
1022
1023 if( filter NEQ NULL )
1024 {
1025
1026 #ifdef _TARGET_
1027
1028 UBYTE state = GET_STATE( MEAS );
1029
1030 if(
1031 (
1032 state EQ MEAS_IDLE
1033 AND
1034 IS_FLAGGED( filter->i_level[idx].m_gamma, IM_I_MASK_IDL, IM_I_IDL )
1035 )
1036 OR
1037 (
1038 state EQ MEAS_TRANSFER
1039 AND
1040 IS_FLAGGED( filter->i_level[idx].m_gamma, IM_I_MASK_TRNS, IM_I_TRNS )
1041 )
1042 )
1043
1044 #endif /* #ifdef _TARGET_ */
1045
1046 {
1047 if( NORM_POW_MIN * filter->i_level[idx].index >=
1048 norm_pow[psc_db->g_pwr_par.n_avg_i] )
1049 {
1050 if( filter->i_level[idx].gamma >=
1051 ( MIN_GAMMA_FOR_I_LEVEL_RPTING * MEAS_ACRCY ) ) /*lint !e685*/
1052 {
1053 /* calculation of interference level */
1054 used_bits += EM_ABS_I_LEVEL_LEN;
1055
1056 *ilev = (UBYTE)M_ROUND_UP( filter->i_level[idx].gamma, MEAS_ACRCY );
1057 *v_ilev = TRUE;
1058 }
1059
1060 #if !defined (NTRACE)
1061
1062 else
1063 {
1064 /* prepare proper tracing information */
1065 switch( filter->i_level[idx].gamma / MEAS_ACRCY )
1066 {
1067 case 0: *ilev = I_LEVEL_GAMMA_0_SKIPPED; break;
1068 case 1: *ilev = I_LEVEL_GAMMA_1_SKIPPED; break;
1069 case 2: *ilev = I_LEVEL_GAMMA_2_SKIPPED; break;
1070 case 3: *ilev = I_LEVEL_GAMMA_3_SKIPPED; break;
1071
1072 default:
1073 TRACE_ERROR( "meas_im_fill_rel_iLevel: impossible case" );
1074 break;
1075 }
1076 }
1077
1078 #endif /* #if !defined (NTRACE) */
1079
1080 }
1081
1082 #if !defined (NTRACE)
1083
1084 else
1085 {
1086 /* prepare proper tracing information */
1087 *ilev = I_LEVEL_IDX_TO_SMALL;
1088 }
1089
1090 #endif /* #if !defined (NTRACE) */
1091
1092 }
1093
1094 #ifdef _TARGET_
1095
1096 #if !defined (NTRACE)
1097
1098 else
1099 {
1100 /* prepare proper tracing information */
1101 *ilev = I_LEVEL_STATE_MISMATCH;
1102 }
1103
1104 #endif /* #if !defined (NTRACE) */
1105
1106 #endif /* #ifdef _TARGET_ */
1107
1108 }
1109
1110 #if !defined (NTRACE)
1111
1112 else
1113 {
1114 /* prepare proper tracing information */
1115 *ilev = I_LEVEL_NOT_AVAIL;
1116 }
1117
1118 #endif /* #if !defined (NTRACE) */
1119
1120 return( used_bits );
1121 } /* meas_im_fill_abs_iLevel() */
1122
1123 /*
1124 +------------------------------------------------------------------------------
1125 | Function : meas_im_delete_em_rslt
1126 +------------------------------------------------------------------------------
1127 | Description : ...
1128 |
1129 | Parameters : ...
1130 |
1131 +------------------------------------------------------------------------------
1132 */
1133 LOCAL void meas_im_delete_em_rslt ( void )
1134 {
1135 T_MEAS_IM_FILTER *filter;
1136
1137 TRACE_FUNCTION( "meas_im_delete_em_rslt" );
1138
1139 if( emeas->xmeas_set.param->em1.param.int_frequency NEQ NOT_SET )
1140 {
1141 T_MEAS_IM_CARRIER ma;
1142
1143 ma.hopping = FALSE;
1144 ma.alloc.arfcn =
1145 meas_im_get_unmsk_int_freq( emeas->xmeas_set.param->em1.param.int_frequency );
1146
1147 filter = meas_im_get_filter( &ma );
1148
1149 if( filter NEQ NULL )
1150 {
1151 meas_im_restart_filter ( filter );
1152 }
1153 }
1154 } /* meas_im_delete_em_rslt() */
1155
1156 /*
1157 +------------------------------------------------------------------------------
1158 | Function : meas_im_get_unmsk_int_freq
1159 +------------------------------------------------------------------------------
1160 | Description : ...
1161 |
1162 | Parameters : ...
1163 |
1164 +------------------------------------------------------------------------------
1165 */
1166 LOCAL USHORT meas_im_get_unmsk_int_freq ( UBYTE index )
1167 {
1168 USHORT arfcn;
1169
1170 TRACE_FUNCTION( "meas_im_get_unmsk_int_freq" );
1171
1172 arfcn = emeas->xmeas_set.param->em1.list.freq[index];
1173 SET_FLAG( arfcn, EM_VLDTY_ARFCN_MASK, EM_VLD_ARFCN, USHORT );
1174
1175 return( arfcn );
1176 } /* meas_im_get_unmsk_int_freq() */
1177
1178 /*
1179 +------------------------------------------------------------------------------
1180 | Function : meas_im_start_t_im_sync
1181 +------------------------------------------------------------------------------
1182 | Description : ...
1183 |
1184 | Parameters : ...
1185 |
1186 +------------------------------------------------------------------------------
1187 */
1188 LOCAL void meas_im_start_t_im_sync ( T_TIME vld_prd )
1189 {
1190 TRACE_FUNCTION( "meas_im_start_t_im_sync" );
1191
1192 if( vld_prd NEQ 0 )
1193 {
1194 vsi_t_start( GRR_handle, T_IM_SYNC, vld_prd );
1195
1196 #ifdef _SIMULATION_
1197 TRACE_EVENT_P1( "T_IM_SYNC: %d ms", vld_prd );
1198 #endif /* #ifdef _SIMULATION_ */
1199
1200 }
1201 else
1202 {
1203 TRACE_ERROR( "Try to start T_IM_SYNC with 0 ms" );
1204 }
1205 } /* meas_im_start_t_im_sync() */
1206
1207
1208 /*
1209 +------------------------------------------------------------------------------
1210 | Function : meas_im_get_paging_period
1211 +------------------------------------------------------------------------------
1212 | Description : This functon calculates the paging period in microseconds.
1213 |
1214 | Please look at GSM 05.02, chapter 6.5.6, Determination of
1215 | PCCCH_GROUP and PAGING_GROUP for MS in GPRS attached mode.
1216 |
1217 | Parameters : void
1218 |
1219 +------------------------------------------------------------------------------
1220 */
1221 LOCAL ULONG meas_im_get_paging_period ( void )
1222 {
1223 ULONG paging_period = NO_PAGING; /* paging period in MICROSECONDS */
1224 USHORT paging_distance; /* paging period as difference of two paging */
1225 /* groups */
1226 USHORT paging_group[BL_FOR_PAGE_PERIOD_CALC];
1227 /* blocks which are used to page the MS, in */
1228 /* maximum 2 blocks are needed to calculate */
1229 /* the paging period */
1230 USHORT M; /* number of paging blocks "available" on */
1231 /* one PCCCH */
1232 USHORT m; /* number of paging groups for this MS */
1233 USHORT min; /* minimum of M and SPLIT_PG_CYCLE */
1234 USHORT imsi_mod = grr_imsi_mod( );
1235 /* IMSI modulo 1000 */
1236 USHORT N = 1; /* N */
1237 USHORT res_blocks = psc_db->pccch.bs_pag_blks + psc_db->pccch.bs_pbcch_blks + 1;
1238 /* number of reserved blocks for access */
1239 /* grant and PBCCH */
1240
1241 TRACE_FUNCTION( "meas_im_get_paging_period" );
1242
1243 /* see GSM 05.02, Clause 7 Table 7 of 7: Mapping of logical channels onto */
1244 /* physical channels ( see subclause 6.3, 6.4, 6.5 ) */
1245 M = ( res_blocks > ( BLOCK_PER_MF - 1 ) ?
1246 0 : ( BLOCK_PER_MF - res_blocks ) * PAGING_CYCLE );
1247
1248 /* in case M is equal to zero no paging blocks are reserved */
1249 if( M NEQ 0 )
1250 {
1251 if( grr_data->ms.split_pg_cycle EQ GMMRR_NO_DRX )
1252 {
1253 /* in non-DRX mode the MS shall listen to all M blocks per */
1254 /* multiframe where paging may appear on a PCCCH channel */
1255 /* we assume that all paging groups have the same distance */
1256 /* to its preceding and subsequent paging groups ( equi- */
1257 /* distance) */
1258 paging_period = ( PAGING_CYCLE * USEC_PER_MF ) / M;
1259 }
1260 else
1261 {
1262 min = MINIMUM( M, grr_data->ms.split_pg_cycle );
1263
1264 if( min EQ 1 )
1265 {
1266 /* in case only one paging group is available the MS is */
1267 /* paged every PAGING_CYCLE multiframes */
1268 paging_period = PAGING_CYCLE * USEC_PER_MF;
1269 }
1270 else
1271 {
1272 /* calculate two paging groups, this is the minimum which */
1273 /* is needed to calculate a time difference ( paging */
1274 /* period ), we assume that all paging groups have the */
1275 /* same distance to its preceding and subsequent paging */
1276 /* groups ( equi-distance ) */
1277 for( m = 0; m < BL_FOR_PAGE_PERIOD_CALC; m++ )
1278 {
1279 /* the following statement calculates the paging groups */
1280 paging_group[m] =
1281 (
1282 ( ( imsi_mod / ( psc_db->paging_group.kc * N ) ) * N ) +
1283 ( imsi_mod % N ) +
1284 MAXIMUM( ( m * M ) / grr_data->ms.split_pg_cycle, m )
1285 ) % M;
1286 }
1287
1288 /* the paging is repeated cyclic every PAGING_CYCLE multiframes, */
1289 /* this should be taken into account when calculating the time */
1290 /* difference between two paging groups */
1291 if( paging_group[1] > paging_group[0] )
1292 {
1293 paging_distance = paging_group[1] - paging_group[0];
1294 }
1295 else
1296 {
1297 paging_distance = M - paging_group[0] + paging_group[1];
1298 }
1299
1300 paging_period = ( paging_distance * PAGING_CYCLE * USEC_PER_MF ) / M;
1301 }
1302 }
1303 }
1304
1305 return( paging_period );
1306 } /* meas_im_get_paging_period() */
1307
1308 /*
1309 +------------------------------------------------------------------------------
1310 | Function : meas_em_init
1311 +------------------------------------------------------------------------------
1312 | Description : ...
1313 |
1314 | Parameters : void
1315 |
1316 +------------------------------------------------------------------------------
1317 */
1318 GLOBAL void meas_em_init ( void )
1319 {
1320 TRACE_FUNCTION( "meas_em_init" );
1321
1322 INIT_STATE( MEAS_EM, MEAS_EM_NULL );
1323
1324 emeas = &grr_data->meas_em;
1325
1326 emeas->xmeas_set.ident = 0;
1327 emeas->xmeas_set.param = NULL;
1328 emeas->pmr_snd_ref = 0;
1329
1330 grr_init_xmeas_struct( &psc_db->ext_pmo );
1331 meas_em_init_pmo_seq( );
1332 } /* meas_em_init() */
1333
1334 /*
1335 +------------------------------------------------------------------------------
1336 | Function : meas_em_init_pmo_seq
1337 +------------------------------------------------------------------------------
1338 | Description : This function ...
1339 |
1340 | Parameters : void
1341 |
1342 +------------------------------------------------------------------------------
1343 */
1344 LOCAL void meas_em_init_pmo_seq ( void )
1345 {
1346 UBYTE i;
1347
1348 TRACE_FUNCTION( "meas_em_init_pmo_seq" );
1349
1350 grr_init_xmeas_struct( &emeas->pmo.extd );
1351 grr_init_ncmeas_extd_struct( &emeas->pmo.nc, FALSE );
1352
1353 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1354 grr_init_enh_param(&emeas->pmo.enh, TRUE);
1355 #endif
1356
1357 for( i = 0; i < MAX_NR_OF_INSTANCES_OF_PMO; i++ )
1358 {
1359 emeas->pmo.prm.instances[i] = FALSE;
1360 emeas->pmo.prm.idx[i].start = RRGRR_INVALID_IDX;
1361 emeas->pmo.prm.idx[i].stop = RRGRR_INVALID_IDX;
1362 }
1363
1364 emeas->pmo.prm.count = NOT_SET;
1365 } /* meas_em_init_pmo_seq() */
1366
1367 /*
1368 +------------------------------------------------------------------------------
1369 | Function : meas_em_build_meas_rpt
1370 +------------------------------------------------------------------------------
1371 | Description : This function ...
1372 |
1373 | Parameters : u_meas_report - Pointer to measurement report
1374 |
1375 +------------------------------------------------------------------------------
1376 */
1377 LOCAL UBYTE meas_em_build_meas_rpt ( T_U_MEAS_REPORT *u_meas_report )
1378 {
1379 UBYTE used_bits; /* bits currently used for the measurement report */
1380 UBYTE next_meas_bits; /* bits used for the next element of the */
1381 /* measurement result list */
1382
1383 UBYTE strg_bsic;
1384 UBYTE strg_rxlev;
1385 UBYTE rslt_rxlev;
1386 T_ext_mp_s1 *p_mrpt;
1387
1388 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1389 UBYTE psi3_cm = grr_get_psi3_cm();
1390 BOOL pbcch_present = grr_is_pbcch_present( );
1391 #endif
1392
1393
1394 T_xmeas_rep *xmeas_rep = &u_meas_report->xmeas_rep;
1395
1396 TRACE_FUNCTION( "meas_em_build_meas_rpt" );
1397
1398 /* process message type */
1399 used_bits = PMR_MSG_TYPE_LEN;
1400 u_meas_report->msg_type = U_MEAS_REPORT_c;
1401
1402 /* process TLLI */
1403 used_bits += PMR_TLLI_LEN;
1404 grr_set_buf_tlli( &u_meas_report->tlli_value, grr_get_tlli( ) );
1405
1406 /* process PSI5 change mark */
1407 used_bits += PMR_FLAG_LEN;
1408
1409 if( emeas->xmeas_set.param EQ &psc_db->ext_psi5 )
1410 {
1411 used_bits += PMR_PSI5_CHNGE_MRK_LEN;
1412
1413 u_meas_report->v_psi5_cm = TRUE;
1414 u_meas_report->psi5_cm = psc_db->psi5_params.psi5_change_mark;
1415 }
1416 else if ( emeas->xmeas_set.param EQ &psc_db->ext_pmo )
1417 {
1418 u_meas_report->v_psi5_cm = FALSE;
1419 }
1420 else
1421 {
1422 TRACE_ERROR( "no valid data set in meas_em_build_meas_rpt" );
1423 return( 0 );
1424 }
1425
1426 /* process flags */
1427 used_bits += PMR_FLAG_LEN;
1428 u_meas_report->flag = 1;
1429 u_meas_report->v_nc_meas_rep = FALSE;
1430 u_meas_report->v_xmeas_rep = TRUE;
1431
1432 #if defined (REL99) AND defined (TI_PS_FF_EMR)
1433 /*if(psc_db->network_rel NEQ BSS_NW_REL_97)*/
1434 {
1435 used_bits += PMR_FLAG_LEN;
1436 u_meas_report->v_release_99_str_pmr = TRUE;
1437
1438 used_bits += PMR_FLAG_LEN;
1439 u_meas_report->release_99_str_pmr.v_meas_rep_3g_str = FALSE;
1440
1441 used_bits += PMR_FLAG_LEN;
1442 u_meas_report->release_99_str_pmr.v_ba_psi3_str = TRUE;
1443
1444 used_bits += PMO_IND_USED_LEN;
1445 u_meas_report->release_99_str_pmr.ba_psi3_str.pmo_ind_used = psc_db->nc_ms.pmo_ind;
1446
1447 /* 1 bit for u_meas_report->ba_psi3_str.flag */
1448 used_bits += PMR_FLAG_LEN;
1449
1450 /* process BA used, PSI3 change mark and PMO used */
1451 if( pbcch_present EQ FALSE )
1452 {
1453 u_meas_report->release_99_str_pmr.ba_psi3_str.flag = FALSE;
1454
1455 u_meas_report->release_99_str_pmr.ba_psi3_str.v_ba_ind_used = TRUE;
1456 u_meas_report->release_99_str_pmr.ba_psi3_str.v_ba_ind_used_3g = TRUE;
1457
1458 used_bits += PMR_BA_IND_USED_LEN;
1459 u_meas_report->release_99_str_pmr.ba_psi3_str.ba_ind_used = psc_db->ba_ind;
1460
1461 /* Add 1 bit for ba_ind_used_3g */
1462 u_meas_report->release_99_str_pmr.ba_psi3_str.ba_ind_used_3g = 0;
1463 used_bits += PMR_BA_IND_USED_LEN;
1464 }
1465 else
1466 {
1467 u_meas_report->release_99_str_pmr.ba_psi3_str.flag = TRUE;
1468
1469 u_meas_report->release_99_str_pmr.ba_psi3_str.v_psi3_cm = TRUE;
1470
1471 used_bits += PMR_PSI3_CHNGE_MRK_LEN;
1472 u_meas_report->release_99_str_pmr.ba_psi3_str.psi3_cm = psi3_cm;
1473 }
1474 }
1475 #elif defined (REL99)
1476 used_bits += PMR_FLAG_LEN;
1477 u_meas_report->v_release_99_str_pmr = FALSE;
1478 #endif
1479
1480 /* process report type */
1481 used_bits += EM_EXT_RPT_TYPE_LEN;
1482 xmeas_rep->xrep_type = emeas->xmeas_set.param->em1.param.reporting_type;
1483
1484 /* process interference measurement results */
1485 used_bits += PMR_FLAG_LEN;
1486
1487 if( emeas->xmeas_set.param->em1.param.reporting_type EQ REP_TYPE_3 AND
1488 emeas->xmeas_set.param->em1.param.int_frequency NEQ NOT_SET )
1489 {
1490 T_MEAS_IM_CARRIER ma;
1491
1492 xmeas_rep->v_ilev_abs = TRUE;
1493
1494 ma.hopping = FALSE;
1495 ma.alloc.arfcn =
1496 meas_im_get_unmsk_int_freq( emeas->xmeas_set.param->em1.param.int_frequency );
1497
1498 used_bits += meas_im_get_abs_i_level( &ma, &xmeas_rep->ilev_abs );
1499 }
1500 else
1501 {
1502 xmeas_rep->v_ilev_abs = FALSE;
1503 }
1504
1505 /* process EXT measurement results */
1506 used_bits += EM_NUM_OF_MEAS_LEN;
1507 xmeas_rep->num_meas = 0;
1508 xmeas_rep->c_ext_mp_s1 = 0;
1509
1510 do
1511 {
1512 /* calculate length of next measurement result */
1513 next_meas_bits = EM_FREQ_N_LEN + EM_RXLEV_N_LEN + PMR_FLAG_LEN;
1514 strg_rxlev = 0;
1515 rslt_rxlev = 0;
1516 strg_bsic = EM_INVLD_BSIC;
1517
1518
1519 switch( emeas->xmeas_set.param->em1.param.reporting_type )
1520 {
1521 case( REP_TYPE_1 ):
1522 case( REP_TYPE_2 ):
1523 if( emeas->pmr_snd_ref EQ emeas->strg.number )
1524 {
1525 next_meas_bits = 0;
1526 }
1527 else
1528 {
1529 strg_bsic = emeas->rslt.elem[emeas->strg.refidx[emeas->pmr_snd_ref]].bsic;
1530 strg_rxlev = emeas->rslt.elem[emeas->strg.refidx[emeas->pmr_snd_ref]].rxlev;
1531
1532 if( strg_bsic NEQ RRGRR_INVALID_BSIC OR
1533 emeas->xmeas_set.param->em1.param.reporting_type EQ REP_TYPE_2 )
1534 {
1535 next_meas_bits += EM_BSIC_N_LEN;
1536 }
1537 }
1538 break;
1539
1540 case( REP_TYPE_3 ):
1541 if( emeas->pmr_snd_ref EQ emeas->rslt.number )
1542 {
1543 next_meas_bits = 0;
1544 }
1545 else
1546 {
1547 rslt_rxlev = emeas->rslt.elem[emeas->pmr_snd_ref].rxlev;
1548 }
1549 break;
1550 default:
1551 next_meas_bits = 0;
1552 TRACE_ERROR( "no valid reporting type in meas_em_build_meas_rpt" );
1553 break;
1554 }
1555
1556 if( next_meas_bits NEQ 0 AND
1557 ( BIT_UL_CTRL_BLOCK_CONTENTS - used_bits ) >= next_meas_bits )
1558 {
1559 /* copy next measurement result to measurement report */
1560 xmeas_rep->num_meas++;
1561 xmeas_rep->c_ext_mp_s1++;
1562 used_bits += next_meas_bits;
1563 p_mrpt = &xmeas_rep->ext_mp_s1[xmeas_rep->c_ext_mp_s1 - 1];
1564
1565 switch( emeas->xmeas_set.param->em1.param.reporting_type )
1566 {
1567 case( REP_TYPE_1 ):
1568 case( REP_TYPE_2 ):
1569 p_mrpt->freq_n = emeas->rslt.elem[emeas->strg.refidx[emeas->pmr_snd_ref]].refidx;
1570 p_mrpt->rxlev_n = strg_rxlev;
1571
1572 if( strg_bsic NEQ RRGRR_INVALID_BSIC OR
1573 emeas->xmeas_set.param->em1.param.reporting_type EQ REP_TYPE_2 )
1574 {
1575 p_mrpt->bsic = strg_bsic;
1576 p_mrpt->v_bsic = TRUE;
1577 }
1578 else
1579 {
1580 p_mrpt->v_bsic = FALSE;
1581 }
1582 break;
1583
1584 case( REP_TYPE_3 ):
1585 p_mrpt->freq_n = emeas->rslt.elem[emeas->pmr_snd_ref].refidx;
1586 p_mrpt->rxlev_n = rslt_rxlev;
1587 p_mrpt->v_bsic = FALSE;
1588 break;
1589 default:
1590 TRACE_ERROR( "no valid reporting type in meas_em_build_meas_rpt" );
1591 break;
1592 }
1593
1594 emeas->pmr_snd_ref++;
1595 }
1596 else
1597 {
1598 next_meas_bits = 0;
1599 }
1600 }
1601 while( next_meas_bits NEQ 0 );
1602
1603 return( xmeas_rep->num_meas );
1604 } /* meas_em_build_meas_rpt() */
1605
1606 /*
1607 +------------------------------------------------------------------------------
1608 | Function : meas_em_extrct_strgst
1609 +------------------------------------------------------------------------------
1610 | Description : This function ...
1611 |
1612 | Parameters : void
1613 |
1614 +------------------------------------------------------------------------------
1615 */
1616 LOCAL UBYTE meas_em_extrct_strgst ( void )
1617 {
1618 UBYTE i, j; /* used for couting */
1619 UBYTE min_rxlev;
1620 UBYTE min_index;
1621
1622 TRACE_FUNCTION( "meas_em_extrct_strgst" );
1623
1624 emeas->strg.number = 0;
1625
1626 for( i = 0; i < emeas->rslt.number; i++ )
1627 {
1628 if( emeas->rslt.elem[i].rxlev NEQ RRGRR_INVALID_RXLEV )
1629 {
1630 if( emeas->strg.number < EM_MAX_STRONG_CARRIER )
1631 {
1632 emeas->strg.refidx[emeas->strg.number] = i;
1633 emeas->strg.number++;
1634 }
1635 else
1636 {
1637 min_rxlev = 0xFF;
1638 min_index = 0xFF;
1639
1640 for( j = 0; j < emeas->strg.number; j++ )
1641 {
1642 if( emeas->rslt.elem[emeas->strg.refidx[j]].rxlev < min_rxlev )
1643 {
1644 min_rxlev = emeas->rslt.elem[emeas->strg.refidx[j]].rxlev;
1645 min_index = j;
1646 }
1647 }
1648
1649 if( emeas->rslt.elem[i].rxlev < min_rxlev )
1650 {
1651 if( min_index < EM_MAX_STRONG_CARRIER )
1652 {
1653 emeas->strg.refidx[min_index] = i;
1654 }
1655 else
1656 {
1657 TRACE_ASSERT( min_index < EM_MAX_STRONG_CARRIER );
1658 }
1659 }
1660 }
1661 }
1662 }
1663
1664 return( emeas->strg.number );
1665 } /* meas_em_extrct_strgst() */
1666
1667 /*
1668 +------------------------------------------------------------------------------
1669 | Function : meas_em_extrct_strgst_with_bsic
1670 +------------------------------------------------------------------------------
1671 | Description : This function ...
1672 |
1673 | Parameters : void
1674 |
1675 +------------------------------------------------------------------------------
1676 */
1677 LOCAL UBYTE meas_em_extrct_strgst_with_bsic ( void )
1678 {
1679 UBYTE i, j; /* used for couting */
1680
1681 TRACE_FUNCTION( "meas_em_extrct_strgst_with_bsic" );
1682
1683 meas_em_extrct_strgst( );
1684
1685 for( i = 0, j = 0; i < emeas->strg.number; i++ )
1686 {
1687
1688 if(
1689 emeas->rslt.elem[emeas->strg.refidx[i]].bsic NEQ RRGRR_INVALID_BSIC
1690
1691 AND
1692
1693 ((0x01 << ((emeas->rslt.elem[emeas->strg.refidx[i]].bsic & BSIC_NCC_MASK) >> 3)) &
1694 emeas->xmeas_set.param->em1.param.ncc_permitted ) NEQ 0
1695 )
1696 {
1697 emeas->strg.refidx[j] = emeas->strg.refidx[i];
1698 j++;
1699 }
1700 }
1701
1702 emeas->strg.number = j;
1703
1704 return( emeas->strg.number );
1705 } /* meas_em_extrct_strgst_with_bsic() */
1706
1707
1708 /*
1709 +------------------------------------------------------------------------------
1710 | Function : meas_em_store_rslt
1711 +------------------------------------------------------------------------------
1712 | Description : This function ...
1713 |
1714 | Parameters : void
1715 |
1716 +------------------------------------------------------------------------------
1717 */
1718 GLOBAL BOOL meas_em_store_rslt ( T_RRGRR_EXT_MEAS_CNF *rrgrr_em_cnf )
1719 {
1720 UBYTE i; /* used for counting */
1721 BOOL result = FALSE;
1722
1723 TRACE_FUNCTION( "meas_em_store_rslt" );
1724
1725 /* check call reference */
1726 if( rrgrr_em_cnf->call_ref EQ emeas->xmeas_set.ident - 1 )
1727 {
1728 if( rrgrr_em_cnf->xmeas_cause EQ EXT_MEAS_OK )
1729 {
1730 T_xmeas_res *em_res;
1731
1732 result = TRUE;
1733 emeas->rslt.number = 0;
1734
1735 for( i = 0; i < rrgrr_em_cnf->c_xmeas_res; i++ )
1736 {
1737 em_res = &rrgrr_em_cnf->xmeas_res[i];
1738
1739 if( em_res->arfcn_idx.idx <
1740 emeas->xmeas_set.param->em1.list.number AND
1741 em_res->arfcn_idx.arfcn EQ
1742 emeas->xmeas_set.param->em1.list.freq[em_res->arfcn_idx.idx] )
1743 {
1744 emeas->rslt.elem[emeas->rslt.number].refidx = em_res->arfcn_idx.idx;
1745 emeas->rslt.elem[emeas->rslt.number].rxlev = em_res->rxlev;
1746 emeas->rslt.elem[emeas->rslt.number].bsic = em_res->bsic;
1747
1748 emeas->rslt.number++;
1749 }
1750 else
1751 {
1752 TRACE_ERROR( "meas_em_store_rslt: mismatch of ARFCNs" );
1753 }
1754 }
1755 }
1756 else
1757 {
1758 TRACE_EVENT_P1( "meas_em_store_rslt: unexpected cause %d",
1759 rrgrr_em_cnf->xmeas_cause );
1760 }
1761 }
1762 else
1763 {
1764 TRACE_EVENT_P2( "meas_em_store_rslt: mismatch of call references %d %d",
1765 rrgrr_em_cnf->call_ref, emeas->xmeas_set.ident - 1 );
1766 }
1767
1768 return( result );
1769 } /* meas_em_store_rslt() */
1770
1771
1772
1773 /*
1774 +------------------------------------------------------------------------------
1775 | Function : meas_em_req
1776 +------------------------------------------------------------------------------
1777 | Description : This function ...
1778 |
1779 | Parameters : void
1780 |
1781 +------------------------------------------------------------------------------
1782 */
1783 LOCAL void meas_em_req ( void )
1784 {
1785 UBYTE i; /* used for counting */
1786
1787 TRACE_FUNCTION( "meas_em_req" );
1788
1789 {
1790 PALLOC( em_req, RRGRR_EXT_MEAS_REQ );
1791
1792 em_req->c_arfcn_idx = 0;
1793
1794 for( i = 0; i < emeas->xmeas_set.param->em1.list.number; i++ )
1795 {
1796 if( IS_NOT_FLAGGED( emeas->xmeas_set.param->em1.list.freq[i],
1797 EM_VLDTY_ARFCN_MASK,
1798 EM_NON_VLD_ARFCN ) )
1799 {
1800 em_req->arfcn_idx[em_req->c_arfcn_idx].idx = i;
1801 em_req->arfcn_idx[em_req->c_arfcn_idx].arfcn =
1802 emeas->xmeas_set.param->em1.list.freq[i];
1803 em_req->c_arfcn_idx++;
1804 }
1805 }
1806
1807 #ifdef _SIMULATION_
1808 for( i = em_req->c_arfcn_idx; i < RRGRR_MAX_ARFCN_EXT_MEAS; i++ )
1809 {
1810 em_req->arfcn_idx[i].arfcn = RRGRR_INVALID_ARFCN;
1811 em_req->arfcn_idx[i].idx = RRGRR_INVALID_IDX;
1812 }
1813 #endif /* #ifdef _SIMULATION_ */
1814
1815 em_req->call_ref = emeas->xmeas_set.ident;
1816 em_req->report_type = emeas->xmeas_set.param->em1.param.reporting_type;
1817 em_req->ncc_permitted = emeas->xmeas_set.param->em1.param.ncc_permitted;
1818
1819 PSEND( hCommRR, em_req );
1820 }
1821
1822 emeas->xmeas_set.ident++;
1823
1824 } /* meas_em_req() */
1825
1826
1827 /*
1828 +------------------------------------------------------------------------------
1829 | Function : meas_em_is_meas_reporting
1830 +------------------------------------------------------------------------------
1831 | Description : This function ...
1832 |
1833 | Parameters : void
1834 |
1835 +------------------------------------------------------------------------------
1836 */
1837 LOCAL BOOL meas_em_is_meas_reporting ( void )
1838 {
1839 TRACE_FUNCTION( "meas_em_is_meas_reporting" );
1840
1841 return( emeas->xmeas_set.param NEQ NULL AND
1842 emeas->xmeas_set.param->em_order_type EQ EM_EM1 AND
1843 GET_STATE( MEAS_EM ) NEQ MEAS_EM_SUSPEND );
1844 } /* meas_em_is_meas_reporting() */
1845
1846
1847 /*==== PUBLIC FUNCTIONS =====================================================*/
1848 /*
1849 +------------------------------------------------------------------------------
1850 | Function : meas_im_new_value
1851 +------------------------------------------------------------------------------
1852 | Description : This function is used to process new interference measurement
1853 | samples send by Layer 1 measured in packet transfer or packet
1854 | transfer mode.
1855 |
1856 | Parameters :
1857 |
1858 +------------------------------------------------------------------------------
1859 */
1860 GLOBAL void meas_im_new_value ( T_MPHP_INT_MEAS_IND *mphp_int_meas_ind,
1861 UBYTE state )
1862 {
1863 T_MEAS_IM_FILTER *filter; /* filter to be updated */
1864 UBYTE rx_lev[8];
1865 UBYTE dummy; /* dummy parameter, not used */
1866
1867 TRACE_FUNCTION( "meas_im_new_value" );
1868
1869 meas_handle_int_meas_values ( mphp_int_meas_ind, rx_lev );
1870
1871 if( imeas->carrier_id NEQ mphp_int_meas_ind->carrier_id )
1872 {
1873 BOOL valid;
1874
1875 if( state EQ MEAS_IDLE )
1876 {
1877 valid = meas_im_get_idle_freq( mphp_int_meas_ind->carrier_id,
1878 &imeas->carrier,
1879 &dummy );
1880 }
1881 else
1882 {
1883 valid = meas_im_get_trns_freq( &imeas->carrier );
1884 }
1885
1886 if( valid EQ TRUE )
1887 {
1888 imeas->carrier_id = ( USHORT )mphp_int_meas_ind->carrier_id;
1889 }
1890 else
1891 {
1892 TRACE_ERROR( "FATAL ERROR 1 in meas_im_new_value" );
1893 return;
1894 }
1895 }
1896
1897 filter = meas_im_get_filter( &imeas->carrier );
1898
1899 if( filter EQ NULL )
1900 {
1901 filter = meas_im_get_unused_filter( );
1902
1903 if( filter EQ NULL )
1904 {
1905 filter = meas_im_get_oldest_filter( );
1906
1907 if( filter EQ NULL )
1908 {
1909 TRACE_ERROR( "FATAL ERROR 2 in meas_im_new_value" );
1910 return;
1911 }
1912 else
1913 {
1914 meas_im_restart_filter( filter );
1915 }
1916 }
1917
1918 filter->carrier = imeas->carrier;
1919 }
1920
1921 meas_im_update_filter( filter, rx_lev, state );
1922
1923 if( state EQ MEAS_IDLE )
1924 {
1925 meas_im_start_idle( );
1926 }
1927
1928 meas_im_cgrlc_int_level_req( FALSE );
1929
1930 } /* meas_im_new_value() */
1931
1932 /*
1933 +------------------------------------------------------------------------------
1934 | Function : meas_im_cgrlc_int_level_req
1935 +------------------------------------------------------------------------------
1936 | Description :
1937 |
1938 | Parameters :
1939 |
1940 +------------------------------------------------------------------------------
1941 */
1942 GLOBAL void meas_im_cgrlc_int_level_req ( BOOL init )
1943 {
1944 PALLOC( int_level_req, CGRLC_INT_LEVEL_REQ );
1945
1946 TRACE_FUNCTION( "meas_im_cgrlc_int_level_req" );
1947
1948 /*
1949 * | | primitive content | primitive shall
1950 * init | v_ilev_abs | changed | be sent
1951 * -----+------------+-------------------+----------------
1952 * 0 | 0 | X | 1
1953 * 0 | 0 | X | 1
1954 * 0 | 1 | 0 | 0
1955 * 0 | 1 | 1 | 1
1956 * 1 | 0 | X | 1
1957 * 1 | 0 | X | 1
1958 * 1 | 1 | 0 | 0
1959 * 1 | 1 | 1 | 1
1960 */
1961
1962 memset( int_level_req->ilev, CGRLC_RXLEV_NONE, CGRLC_MAX_TIMESLOTS );
1963
1964 if( init EQ FALSE AND grr_data->tc.v_freq_set EQ TRUE )
1965 {
1966 T_p_frequency_par freq_par;
1967 T_MEAS_IM_CARRIER ma;
1968 T_ilev_abs ilev;
1969
1970 grr_set_freq_par( &freq_par );
1971 meas_im_set_carrier( &ma, &freq_par );
1972 meas_im_get_abs_i_level( &ma, &ilev );
1973
1974 if( ilev.v_ilevabs0 EQ TRUE ) int_level_req->ilev[0] = ilev.ilevabs0;
1975 if( ilev.v_ilevabs1 EQ TRUE ) int_level_req->ilev[1] = ilev.ilevabs1;
1976 if( ilev.v_ilevabs2 EQ TRUE ) int_level_req->ilev[2] = ilev.ilevabs2;
1977 if( ilev.v_ilevabs3 EQ TRUE ) int_level_req->ilev[3] = ilev.ilevabs3;
1978 if( ilev.v_ilevabs4 EQ TRUE ) int_level_req->ilev[4] = ilev.ilevabs4;
1979 if( ilev.v_ilevabs5 EQ TRUE ) int_level_req->ilev[5] = ilev.ilevabs5;
1980 if( ilev.v_ilevabs6 EQ TRUE ) int_level_req->ilev[6] = ilev.ilevabs6;
1981 if( ilev.v_ilevabs7 EQ TRUE ) int_level_req->ilev[7] = ilev.ilevabs7;
1982 }
1983
1984 PSEND( hCommGRLC, int_level_req );
1985
1986 } /* meas_im_cgrlc_int_level_req() */
1987
1988 /*
1989 +------------------------------------------------------------------------------
1990 | Function : meas_im_stop_trns
1991 +------------------------------------------------------------------------------
1992 | Description : This function stops the interference measurements in packet
1993 | transfer mode.
1994 |
1995 | Parameters : void
1996 |
1997 +------------------------------------------------------------------------------
1998 */
1999 GLOBAL void meas_im_stop_trns ( void )
2000 {
2001 TRACE_FUNCTION( "meas_im_stop_trns" );
2002
2003 imeas->carrier_id = IDX_USHORT_INVALID;
2004 } /* meas_im_stop_trns() */
2005
2006 /*
2007 +------------------------------------------------------------------------------
2008 | Function : meas_im_stop_idle
2009 +------------------------------------------------------------------------------
2010 | Description : This function stops the interference measurements in packet
2011 | idle mode.
2012 |
2013 | Parameters : void
2014 |
2015 +------------------------------------------------------------------------------
2016 */
2017 GLOBAL void meas_im_stop_idle ( void )
2018 {
2019 TRACE_FUNCTION( "meas_im_stop_idle" );
2020
2021 {
2022 PALLOC( mphp_int_meas_stop_req, MPHP_INT_MEAS_STOP_REQ );
2023 PSEND( hCommL1, mphp_int_meas_stop_req );
2024 }
2025
2026 imeas->carrier_id = IDX_USHORT_INVALID;
2027 } /* meas_im_stop_idle() */
2028
2029 /*
2030 +------------------------------------------------------------------------------
2031 | Function : meas_im_prepare_trns
2032 +------------------------------------------------------------------------------
2033 | Description : This function prepares the interference measurements in packet
2034 | transfer mode.
2035 |
2036 | Parameters : void
2037 |
2038 +------------------------------------------------------------------------------
2039 */
2040 GLOBAL void meas_im_prepare_trns ( void )
2041 {
2042 TRACE_FUNCTION( "meas_im_prepare_trns" );
2043 } /* meas_im_prepare_trns() */
2044
2045 /*
2046 +------------------------------------------------------------------------------
2047 | Function : meas_im_prepare_idle
2048 +------------------------------------------------------------------------------
2049 | Description : This function prepares the interference measurements in packet
2050 | idle mode.
2051 |
2052 | Parameters : void
2053 |
2054 +------------------------------------------------------------------------------
2055 */
2056 GLOBAL void meas_im_prepare_idle ( void )
2057 {
2058 UBYTE i; /* used for counting */
2059
2060 TRACE_FUNCTION( "meas_im_prepare_idle" );
2061
2062 /* process the carrier indicated in the parameter EXT_FREQUENCY_LIST */
2063 #if ( ! ( CHN_ID_EM_BASE < MAX_IM_IDLE_CHANNELS ) )
2064 #error CHN_ID_EM_BASE < MAX_IM_IDLE_CHANNELS required
2065 #endif
2066
2067 if( emeas->xmeas_set.param NEQ NULL AND
2068 emeas->xmeas_set.param->em1.param.reporting_type EQ REP_TYPE_3 AND
2069 emeas->xmeas_set.param->em1.param.int_frequency NEQ NOT_SET )
2070 {
2071 imeas->idle_chan.ident[CHN_ID_EM_BASE] =
2072 emeas->xmeas_set.param->em1.param.int_frequency;
2073 }
2074 else
2075 {
2076 imeas->idle_chan.ident[CHN_ID_EM_BASE] = CHN_ID_INVALID;
2077 }
2078
2079 /* process the monitored PCCCH */
2080 #if ( ! ( CHN_ID_PCCCH_BASE < MAX_IM_IDLE_CHANNELS ) )
2081 #error CHN_ID_PCCCH_BASE < MAX_IM_IDLE_CHANNELS required
2082 #endif
2083
2084 if( imeas->v_cs_meas_active EQ TRUE AND
2085 psc_db->paging_group.kc NEQ 0 )
2086 {
2087 UBYTE pccch_group;
2088
2089 pccch_group = ( UBYTE )( grr_imsi_mod( ) % psc_db->paging_group.kc );
2090
2091 if( pccch_group > psc_db->paging_group.kc - 1 )
2092 {
2093 TRACE_ERROR( "pccch_group > psc_db->paging_group.kc - 1 in meas_im_prepare_idle" );
2094 imeas->idle_chan.ident[CHN_ID_PCCCH_BASE] = CHN_ID_INVALID;
2095 }
2096 else
2097 {
2098 imeas->idle_chan.ident[CHN_ID_PCCCH_BASE] = pccch_group;
2099 }
2100 }
2101 else
2102 {
2103 imeas->idle_chan.ident[CHN_ID_PCCCH_BASE] = CHN_ID_INVALID;
2104 }
2105
2106 /* process the carriers indicated by the parameter INT_MEAS_CHANNEL_LIST */
2107 i = CHN_ID_IM_BASE;
2108
2109 while( i < MAX_IM_IDLE_CHANNELS AND
2110 ( i - CHN_ID_IM_BASE ) < psc_db->number_of_valid_int_meas_channels )
2111 {
2112 imeas->idle_chan.ident[i] = i - CHN_ID_IM_BASE;
2113 i++;
2114 }
2115
2116 while( i < MAX_IM_IDLE_CHANNELS )
2117 {
2118 imeas->idle_chan.ident[i] = CHN_ID_INVALID;
2119 i++;
2120 }
2121
2122 /* let's start measurements with the first entry in the idle channel list */
2123 imeas->idle_chan.index = 0;
2124 } /* meas_im_prepare_idle() */
2125
2126 /*
2127 +------------------------------------------------------------------------------
2128 | Function : meas_im_timer_elapsed
2129 +------------------------------------------------------------------------------
2130 | Description :
2131 |
2132 | Parameters : void
2133 |
2134 +------------------------------------------------------------------------------
2135 */
2136 GLOBAL void meas_im_timer_elapsed ( void )
2137 {
2138 UBYTE i, j; /* used for counting */
2139 LONG new_remain_time = TIME_INVALID;
2140 LONG* old_remain_time;
2141
2142 TRACE_FUNCTION( "meas_im_timer_elapsed" );
2143
2144 for( i = 0; i < MAX_IM_CHANNELS; i++ )
2145 {
2146 for( j = 0; j < CGRLC_MAX_TIMESLOTS; j++ )
2147 {
2148 old_remain_time = &imeas->filter[i].i_level[j].remain_time;
2149
2150 if( *old_remain_time < 0 )
2151 {
2152 TRACE_ERROR( "unexpected time value in meas_im_timer_elapsed" );
2153 }
2154 if( *old_remain_time EQ 0 )
2155 {
2156 *old_remain_time = TIME_INVALID;
2157 }
2158 else if ( *old_remain_time NEQ TIME_INVALID AND
2159 *old_remain_time < new_remain_time )
2160 {
2161 new_remain_time = *old_remain_time;
2162 }
2163 }
2164 }
2165
2166 if( new_remain_time NEQ TIME_INVALID )
2167 {
2168 meas_im_timer_reorg( 0, new_remain_time );
2169 }
2170 } /* meas_im_timer_elapsed() */
2171
2172 /*
2173 +------------------------------------------------------------------------------
2174 | Function : meas_im_state_changed
2175 +------------------------------------------------------------------------------
2176 | Description :
2177 |
2178 | Parameters :
2179 |
2180 +------------------------------------------------------------------------------
2181 */
2182 GLOBAL void meas_im_state_changed ( UBYTE state )
2183 {
2184 UBYTE i, j; /* used for counting */
2185
2186 TRACE_FUNCTION( "meas_im_state_changed" );
2187
2188 /*
2189 * the three if-statements below are just used to skip
2190 * the following for-loops in all impossible cases
2191 */
2192 if( grr_data->meas_im.mode EQ IM_MODE_NONE )
2193 {
2194 return;
2195 }
2196
2197 if( ( state EQ MEAS_IDLE OR
2198 state EQ MEAS_ACCESS )
2199 AND
2200 ( grr_data->meas_im.mode EQ IM_MODE_TRANSFER ) )
2201 {
2202 return;
2203 }
2204
2205 if( state EQ MEAS_TRANSFER AND
2206 grr_data->meas_im.mode EQ IM_MODE_IDLE )
2207 {
2208 return;
2209 }
2210
2211 for( i = 0; i < MAX_IM_CHANNELS; i++ )
2212 {
2213 for( j = 0; j < CGRLC_MAX_TIMESLOTS; j++ )
2214 {
2215 if( ( ( state EQ MEAS_IDLE OR state EQ MEAS_ACCESS ) AND
2216 IS_FLAGGED( imeas->filter[i].i_level[j].m_gamma,
2217 IM_I_MASK_IDL, IM_I_IDL ) )
2218 OR
2219 ( ( state EQ MEAS_TRANSFER ) AND
2220 IS_FLAGGED( imeas->filter[i].i_level[j].m_gamma,
2221 IM_I_MASK_TRNS, IM_I_TRNS ) ) )
2222 {
2223 if( imeas->filter[i].i_level[j].remain_time EQ TIME_INVALID )
2224 {
2225 meas_im_restart_gamma( &imeas->filter[i], j );
2226 }
2227 }
2228 }
2229 }
2230 } /* meas_im_state_changed() */
2231
2232 /*
2233 +------------------------------------------------------------------------------
2234 | Function : meas_im_start_idle
2235 +------------------------------------------------------------------------------
2236 | Description : This function starts the interference measurements in packet
2237 | idle mode.
2238 |
2239 | Parameters : void
2240 |
2241 +------------------------------------------------------------------------------
2242 */
2243 GLOBAL BOOL meas_im_start_idle ( void )
2244 {
2245 T_MEAS_IM_IDLE_CHN* chn = &imeas->idle_chan;
2246 UBYTE ts_mask;
2247 UBYTE max_checks = MAX_IM_IDLE_CHANNELS;
2248 BOOL is_started = FALSE;
2249
2250 TRACE_FUNCTION( "meas_im_start_idle" );
2251
2252 while( chn->ident[chn->index] EQ CHN_ID_INVALID AND
2253 max_checks > 0 )
2254 {
2255 chn->index = ((chn->index < MAX_IM_IDLE_CHANNELS - 1) ? chn->index + 1 : 0);
2256 max_checks--;
2257 }
2258
2259 if( max_checks > 0 )
2260 {
2261 PALLOC( mphp_int_meas_req, MPHP_INT_MEAS_REQ );
2262
2263 meas_im_get_idle_freq( chn->index, &imeas->carrier, &ts_mask );
2264 meas_im_set_freq_par( &mphp_int_meas_req->p_frequency_par, &imeas->carrier );
2265
2266 imeas->carrier_id = chn->index;
2267 mphp_int_meas_req->carrier_id = ( UBYTE )chn->index;
2268
2269 mphp_int_meas_req->ts_mask = ts_mask;
2270 mphp_int_meas_req->m_class = grr_get_gprs_ms_class( );
2271
2272 PSEND( hCommL1, mphp_int_meas_req );
2273
2274 is_started = TRUE;
2275
2276 if( chn->index < MAX_IM_IDLE_CHANNELS )
2277 {
2278 chn->index++;
2279 }
2280 else
2281 {
2282 chn->index = 0;
2283 }
2284 }
2285
2286 return( is_started );
2287 } /* meas_im_start_idle() */
2288
2289 /*
2290 +------------------------------------------------------------------------------
2291 | Function : meas_im_set_freq_par
2292 +------------------------------------------------------------------------------
2293 | Description :
2294 |
2295 | Frequency Band config. ETSI GSM spec. coding used in L1
2296 | GSM 900 STD_900 1-124 1-124
2297 | E-GSM STD_EGSM 1-124, 1-124,
2298 | 975-1023, 0 125-174
2299 | PCS 1900 STD_1900 512-810 512-810
2300 | DCS 1800 STD_1800 512-885 512-885
2301 | GSM 900/DCS 1800 STD_DUAL 1-124, 1-124,
2302 | 512-885 125-498
2303 | E-GSM/DCS 1800 STD_DUAL_EGSM 1-124, 1-124,
2304 | 975-1023,0 125-174,
2305 | 512-885 175-548
2306 | GSM 850 STD_850 128-251 128-251
2307 | GSM 850/PCS 1900 STD_DUAL_US 128-251, 1-124,
2308 | 512-810 125-424
2309 |
2310 | Parameters :
2311 |
2312 +------------------------------------------------------------------------------
2313 */
2314 LOCAL void meas_im_set_freq_par ( T_p_frequency_par *freq_par,
2315 T_MEAS_IM_CARRIER *carrier )
2316 {
2317 TRACE_FUNCTION( "meas_im_set_freq_par" );
2318
2319 if( carrier->hopping )
2320 {
2321 UBYTE i = 0;
2322 UBYTE bit_shift;
2323 USHORT array_idx;
2324 USHORT arfcn;
2325
2326 freq_par->p_chan_sel.hopping = MPHP_INT_MEAS_HOPPING;
2327 freq_par->p_chan_sel.p_rf_ch.arfcn =
2328 ( ( USHORT )carrier->alloc.hop_param.hsn << 8 ) |
2329 ( USHORT )carrier->alloc.hop_param.maio;
2330
2331 for ( array_idx = 0;
2332 array_idx < MAX_IM_HOP_ARFCN_BIT_FIELD_SIZE;
2333 array_idx++ )
2334 {
2335 for( bit_shift = 0; bit_shift < 8 AND i < MPHP_NUMC_MA; bit_shift++ )
2336 {
2337 if( ( carrier->alloc.hop_param.arfcn_bit_field[array_idx] &
2338 ( 0x01 << bit_shift ) ) NEQ 0 )
2339 {
2340 arfcn = ( array_idx * 8 ) + bit_shift;
2341
2342 switch( std )
2343 {
2344 case STD_1900: arfcn += LOW_CHANNEL_1900; break;
2345 case STD_1800: arfcn += LOW_CHANNEL_1800; break;
2346 default : break;
2347 }
2348
2349 freq_par->p_freq_list.p_rf_chan_no.p_radio_freq[i] = arfcn;
2350 i++;
2351 }
2352 }
2353 }
2354
2355 freq_par->p_freq_list.p_rf_chan_cnt = i;
2356 }
2357 else
2358 {
2359 freq_par->p_chan_sel.hopping = MPHP_INT_MEAS_STATIC;
2360 freq_par->p_chan_sel.p_rf_ch.arfcn =
2361 grr_g23_arfcn_to_l1( carrier->alloc.arfcn );
2362 }
2363 } /* meas_im_set_freq_par() */
2364
2365 /*
2366 +------------------------------------------------------------------------------
2367 | Function : meas_im_start_trns
2368 +------------------------------------------------------------------------------
2369 | Description : This function starts the interference measurements in packet
2370 | transfer mode.
2371 |
2372 | Parameters : void
2373 |
2374 +------------------------------------------------------------------------------
2375 */
2376 GLOBAL void meas_im_start_trns ( void )
2377 {
2378 TRACE_FUNCTION( "meas_im_start_trns" );
2379 } /* meas_im_start_trns() */
2380
2381 /*
2382 +------------------------------------------------------------------------------
2383 | Function : meas_em_prcs_meas_order
2384 +------------------------------------------------------------------------------
2385 | Description : This function ...
2386 |
2387 | Parameters : d_meas_order - Pointer to packet measurement order message
2388 |
2389 +------------------------------------------------------------------------------
2390 */
2391 GLOBAL UBYTE meas_em_prcs_meas_order ( T_D_MEAS_ORDER *d_meas_order,
2392 T_NC_ORDER *ctrl_order )
2393 {
2394 BOOL is_pmo_ok;
2395 UBYTE i;
2396 UBYTE ret_value = PMO_NONE_VLD;
2397
2398 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2399 UBYTE psi3_cm = grr_get_psi3_cm();
2400 #endif
2401
2402 TRACE_FUNCTION( "meas_em_prcs_meas_order" );
2403
2404 TRACE_EVENT_P2( "D_MEAS_ORDER received idx = %d, cnt = %d",
2405 d_meas_order->pmo_index, d_meas_order->pmo_cnt );
2406
2407
2408 /* process the PMO_COUNT and PMO_INDEX parameter */
2409 if( ( emeas->pmo.prm.count NEQ NOT_SET AND
2410 emeas->pmo.prm.count NEQ d_meas_order->pmo_cnt ) OR
2411 d_meas_order->pmo_cnt < d_meas_order->pmo_index )
2412 {
2413 TRACE_ERROR( "D_MEAS_ORDER: parameter inconsistent" );
2414
2415 meas_em_init_pmo_seq( );
2416
2417 return( ret_value );
2418 }
2419
2420 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2421 /* Set to ENH params not present by default */
2422 if( emeas->pmo.prm.count EQ NOT_SET )
2423 {
2424 emeas->pmo.v_enh_meas_param_pmo = FALSE;
2425 nc_freq_list_pres = FALSE;
2426 nc_freq_list_valid = FALSE;
2427 use_ba_gprs = TRUE;
2428 }
2429 #endif
2430
2431 emeas->pmo.prm.instances[d_meas_order->pmo_index] = TRUE;
2432 emeas->pmo.prm.count = d_meas_order->pmo_cnt;
2433
2434 /* process the EXT measurement parameter */
2435 if( d_meas_order->v_xmeas_par EQ TRUE )
2436 {
2437 grr_prcs_xmeas_struct
2438 ( &emeas->pmo.extd, &d_meas_order->xmeas_par,
2439 TRUE, d_meas_order->pmo_index,
2440 &emeas->pmo.prm.idx[d_meas_order->pmo_index].start,
2441 &emeas->pmo.prm.idx[d_meas_order->pmo_index].stop );
2442 }
2443
2444 if( d_meas_order->v_nc_meas_par_list EQ TRUE )
2445 {
2446 /*
2447 * process the NC measurement parameter
2448 *
2449 * maybe more than one instance of PMO, store data in temporary location
2450 */
2451 emeas->v_pmo_nc_ncmeas_param = TRUE;
2452
2453 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2454 /* Do not get back to BA-GPRS list since NC_FREQ_LIST is present */
2455 if(d_meas_order->nc_meas_par_list.v_nc_freq_list)
2456 {
2457 nc_freq_list_pres = TRUE;
2458 }
2459 #endif
2460
2461 grr_prcs_nc_param_struct ( &emeas->pmo.nc.ncmeas.param,
2462 &d_meas_order->nc_meas_par_list.nc_meas_par,
2463 d_meas_order->pmo_index );
2464
2465
2466 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2467 /* Check for presence of ENH parameters in PMO. If present, then PSI3_CM or
2468 BA_IND will be checked depending on the presence or absence of PBCCH for
2469 consistency with the BA list existing currently. If consistent, then only
2470 the PMO NC frequency list is considered. */
2471 if( d_meas_order->release_98_str_d_meas_order.v_release_99_str_d_meas_order AND
2472 (d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.v_enh_meas_param_pmo EQ TRUE) )
2473 {
2474 if(grr_is_pbcch_present() AND
2475 d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.enh_meas_param_pmo.ba_psi3_str.v_psi3_cm)
2476 {
2477 if(d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.enh_meas_param_pmo.ba_psi3_str.psi3_cm EQ psi3_cm)
2478 {
2479 nc_freq_list_valid = TRUE;
2480 }
2481 }
2482 else if(!grr_is_pbcch_present() AND
2483 d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.enh_meas_param_pmo.ba_psi3_str.v_ba_ind_used)
2484 {
2485 if(d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.enh_meas_param_pmo.ba_psi3_str.ba_ind_used EQ
2486 psc_db->ba_ind)
2487 {
2488 nc_freq_list_valid = TRUE;
2489 }
2490 }
2491 }
2492 else
2493 /* PMO is not checked for BA_IND or PSI3_CM consistency since ENH params
2494 are absent */
2495 {
2496 nc_freq_list_valid = TRUE;
2497 }
2498
2499 if(nc_freq_list_valid EQ TRUE)
2500 {
2501 #endif
2502
2503 /*
2504 * process NC_FREQUENCY_LIST
2505 *
2506 * maybe more than one instance of PMO, store data in temporary location
2507 */
2508
2509 emeas->v_pmo_nc_ncmeas_list_rfreq =
2510 grr_prcs_nc_freq_list ( &emeas->pmo.nc.ncmeas.list,
2511 &emeas->pmo.nc.rfreq,
2512 d_meas_order->nc_meas_par_list.v_nc_freq_list,
2513 &d_meas_order->nc_meas_par_list.nc_freq_list,
2514 INFO_TYPE_PMO,
2515 d_meas_order->pmo_index );
2516
2517 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2518 }
2519 }
2520
2521 if( d_meas_order->release_98_str_d_meas_order.v_release_99_str_d_meas_order AND
2522 (d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.v_enh_meas_param_pmo EQ TRUE) )
2523 {
2524 emeas->pmo.v_enh_meas_param_pmo = TRUE;
2525 /*
2526 * process the ENH measurement parameter
2527 *
2528 * maybe more than one instance of PMO, store data in temporary location
2529 */
2530 grr_prcs_enh_param_pmo(&emeas->pmo.enh, &d_meas_order->release_98_str_d_meas_order.release_99_str_d_meas_order.enh_meas_param_pmo,
2531 d_meas_order->pmo_index, &emeas->pmo.nc.pmo_ind);
2532 #endif
2533
2534 }
2535
2536 for( i = 0, is_pmo_ok = TRUE;
2537 i <= emeas->pmo.prm.count AND is_pmo_ok EQ TRUE;
2538 i++ )
2539 {
2540 if( emeas->pmo.prm.instances[i] EQ FALSE )
2541 {
2542 is_pmo_ok = FALSE;
2543 }
2544 }
2545
2546 if( is_pmo_ok )
2547 {
2548 /* process EXT measurement service */
2549 grr_sort_ext_lst_freq ( &emeas->pmo.extd.em1.list,
2550 MAX_NR_OF_INSTANCES_OF_PMO,
2551 &emeas->pmo.prm.idx[0] );
2552
2553 memcpy( &psc_db->ext_pmo, &emeas->pmo.extd, sizeof( psc_db->ext_pmo ) );
2554
2555 if( emeas->pmo.extd.em_order_type NEQ EM_EMPTY AND
2556 !( emeas->pmo.extd.em_order_type EQ EM_EM1 AND
2557 emeas->pmo.extd.em1.param.reporting_type EQ REP_TYPE_RES ) )
2558 {
2559 ret_value |= PMO_EXT_VLD;
2560 }
2561
2562 /* process NC measurement service */
2563
2564 /*
2565 * Before copying the NC parameter store the old value
2566 * for the network control order
2567 */
2568 *ctrl_order = psc_db->nc_ms.ncmeas.param.ctrl_order;
2569
2570 grr_prcs_nc_param_final ( &psc_db->nc_ms.ncmeas.param,
2571 &emeas->v_pmo_nc_ncmeas_param,
2572 &emeas->pmo.nc.ncmeas.param );
2573 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2574
2575 if( (nc_freq_list_pres EQ TRUE) AND
2576 (psc_db->nc_ms.ncmeas.param.ctrl_order NEQ NC_RESET) )
2577 {
2578 use_ba_gprs = FALSE;
2579 }
2580
2581 if(rr_get_support_for_emr() AND emeas->pmo.v_enh_meas_param_pmo EQ TRUE)
2582 {
2583 /* The ENH parameters that are temporarily stored are moved to final
2584 destination after consistent set of PMO is received */
2585 memcpy(&(psc_db->enh_ms), &(emeas->pmo.enh), sizeof(T_GRR_ENH_PARA));
2586 psc_db->nc_ms.pmo_ind = emeas->pmo.nc.pmo_ind;
2587 }
2588 else
2589 {
2590 memset(&(psc_db->enh_ms), 0, sizeof(T_GRR_ENH_PARA));
2591 psc_db->enh_ms.rept_type = REPORT_TYPE_REP;
2592 emeas->pmo.v_enh_meas_param_pmo = FALSE;
2593 }
2594
2595 #endif
2596
2597 /*
2598 * At cell re-selection the NC measurement parameters valid for the mobile
2599 * station in the new cell are brought from the old cell if received in a
2600 * PACKET MEASUREMENT ORDER message. Storing is done in advance even in
2601 * case no cell re-selection took place at this time.
2602 */
2603 memcpy( &pcr_db->nc_ms.ncmeas.param, &psc_db->nc_ms.ncmeas.param,
2604 sizeof( T_NC_PARAM ) );
2605
2606 pcr_db->nc_ms.ncmeas.param.chng_mrk.curr = 0;
2607 pcr_db->nc_ms.ncmeas.param.chng_mrk.prev = 0;
2608
2609 #if defined (REL99) AND defined (TI_PS_FF_EMR)
2610 if(nc_freq_list_valid EQ TRUE)
2611 {
2612 grr_prcs_nc_freq_final ( &psc_db->nc_ms.ncmeas.list,
2613 &psc_db->nc_ms.rfreq,
2614 &emeas->v_pmo_nc_ncmeas_list_rfreq,
2615 &emeas->pmo.nc.ncmeas.list,
2616 &emeas->pmo.nc.rfreq );
2617 }
2618
2619 #else
2620 grr_prcs_nc_freq_final ( &psc_db->nc_ms.ncmeas.list,
2621 &psc_db->nc_ms.rfreq,
2622 &emeas->v_pmo_nc_ncmeas_list_rfreq,
2623 &emeas->pmo.nc.ncmeas.list,
2624 &emeas->pmo.nc.rfreq );
2625 #endif
2626
2627 if( emeas->pmo.nc.ncmeas.param.ctrl_order NEQ NC_EMPTY )
2628 {
2629 ret_value |= PMO_NC_VLD;
2630 }
2631
2632 meas_em_init_pmo_seq( );
2633 }
2634
2635 return( ret_value );
2636 } /* meas_em_prcs_meas_order() */
2637
2638 /*
2639 +------------------------------------------------------------------------------
2640 | Function : meas_em_valid_pmo
2641 +------------------------------------------------------------------------------
2642 | Description : This function ...
2643 |
2644 | Parameters : void
2645 |
2646 +------------------------------------------------------------------------------
2647 */
2648 GLOBAL void meas_em_valid_pmo ( void )
2649 {
2650 TRACE_FUNCTION( "meas_em_valid_pmo" );
2651
2652 switch( psc_db->ext_pmo.em_order_type )
2653 {
2654 case( EM_RESET ):
2655 meas_em_valid_psi5( );
2656 break;
2657
2658 default:
2659 if( psc_db->ext_pmo.em_order_type EQ EM_EM1 )
2660 {
2661 emeas->xmeas_set.param = &psc_db->ext_pmo;
2662 }
2663 else
2664 {
2665 emeas->xmeas_set.param = NULL;
2666 }
2667 break;
2668 }
2669 } /* meas_em_valid_pmo() */
2670
2671 /*
2672 +------------------------------------------------------------------------------
2673 | Function : meas_em_valid_psi5
2674 +------------------------------------------------------------------------------
2675 | Description : This function ...
2676 |
2677 | Parameters : void
2678 |
2679 +------------------------------------------------------------------------------
2680 */
2681 GLOBAL void meas_em_valid_psi5 ( void )
2682 {
2683 TRACE_FUNCTION( "meas_em_valid_psi5" );
2684
2685 if( psc_db->ext_psi5.em_order_type EQ EM_EM1 )
2686 {
2687 emeas->xmeas_set.param = &psc_db->ext_psi5;
2688 }
2689 else
2690 {
2691 emeas->xmeas_set.param = NULL;
2692 }
2693 } /* meas_em_valid_psi5() */
2694
2695
2696 /*
2697 +------------------------------------------------------------------------------
2698 | Function : meas_em_is_valid_pmo_present
2699 +------------------------------------------------------------------------------
2700 | Description : This function ...
2701 |
2702 | Parameters : void
2703 |
2704 +------------------------------------------------------------------------------
2705 */
2706 GLOBAL BOOL meas_em_is_valid_pmo_present ( void )
2707 {
2708 TRACE_FUNCTION( "meas_em_is_valid_pmo_present" );
2709
2710 return( psc_db->ext_pmo.em_order_type NEQ EM_EMPTY AND
2711 psc_db->ext_pmo.em_order_type NEQ EM_RESET );
2712 } /* meas_em_is_valid_pmo_present() */
2713
2714
2715 /*
2716 +------------------------------------------------------------------------------
2717 | Function : meas_em_process_t3178
2718 +------------------------------------------------------------------------------
2719 | Description : ...
2720 |
2721 | Parameters : void
2722 |
2723 +------------------------------------------------------------------------------
2724 */
2725 GLOBAL void meas_em_process_t3178 ( void )
2726 {
2727 T_TIME reporting_period;
2728 T_TIME time_to_go;
2729 BOOL tmr_3178_rng_le_rp = FALSE;
2730
2731 TRACE_FUNCTION( "meas_em_process_t3178" );
2732
2733 if( meas_em_is_meas_reporting( ) )
2734 {
2735 reporting_period =
2736 GET_EM_RPT_PRD( emeas->xmeas_set.param->em1.param.reporting_period );
2737
2738 time_to_go = grr_t_status( T3178 );
2739
2740 if( time_to_go > 0 )
2741 {
2742 if( time_to_go > reporting_period )
2743 {
2744 meas_em_stop_t3178( );
2745 }
2746 else
2747 {
2748 tmr_3178_rng_le_rp = TRUE;
2749 }
2750 }
2751
2752 if( reporting_period NEQ 0 AND
2753 tmr_3178_rng_le_rp EQ FALSE )
2754 {
2755 meas_em_start_t3178( reporting_period );
2756 }
2757 }
2758 else
2759 {
2760 meas_em_stop_t3178( );
2761 }
2762 } /* meas_em_process_t3178() */
2763
2764 /*
2765 +------------------------------------------------------------------------------
2766 | Function : meas_em_start_t3178
2767 +------------------------------------------------------------------------------
2768 | Description :
2769 |
2770 | Parameters :
2771 |
2772 +------------------------------------------------------------------------------
2773 */
2774 LOCAL void meas_em_start_t3178 ( T_TIME time )
2775 {
2776 TRACE_FUNCTION( "meas_em_start_t3178" );
2777
2778 vsi_t_start( GRR_handle, T3178, time );
2779
2780 TRACE_EVENT_P1( "T3178: %d", time );
2781
2782 } /* meas_em_start_t3178() */
2783
2784
2785 /*
2786 +------------------------------------------------------------------------------
2787 | Function : meas_em_stop_t3178
2788 +------------------------------------------------------------------------------
2789 | Description :
2790 |
2791 | Parameters : void
2792 |
2793 +------------------------------------------------------------------------------
2794 */
2795 LOCAL void meas_em_stop_t3178 ( void )
2796 {
2797 TRACE_FUNCTION( "meas_em_stop_t3178" );
2798
2799 if( grr_t_status( T3178 ) > 0 )
2800 {
2801 vsi_t_stop( GRR_handle, T3178 );
2802
2803 TRACE_EVENT( "T3178 stopped" );
2804 }
2805 } /* meas_em_stop_t3178() */
2806
2807
2808 /*
2809 +------------------------------------------------------------------------------
2810 | Function : meas_em_stop_req
2811 +------------------------------------------------------------------------------
2812 | Description : This function ...
2813 |
2814 | Parameters : void
2815 |
2816 +------------------------------------------------------------------------------
2817 */
2818 GLOBAL void meas_em_stop_req ( void )
2819 {
2820 TRACE_FUNCTION( "meas_em_stop_req" );
2821
2822 {
2823 PALLOC( rrgrr_em_stop_req, RRGRR_EXT_MEAS_STOP_REQ );
2824 PSEND( hCommRR, rrgrr_em_stop_req );
2825 }
2826 } /* meas_em_stop_req() */
2827
2828 /*
2829 +------------------------------------------------------------------------------
2830 | Function : meas_em_start
2831 +------------------------------------------------------------------------------
2832 | Description : This function ...
2833 |
2834 | Parameters : void
2835 |
2836 +------------------------------------------------------------------------------
2837 */
2838 GLOBAL void meas_em_start ( void )
2839 {
2840
2841 TRACE_FUNCTION( "meas_em_start" );
2842
2843 meas_im_delete_em_rslt( );
2844 meas_em_req( );
2845 meas_em_process_t3178( );
2846
2847
2848 } /* meas_em_start() */
2849
2850
2851 /*
2852 +------------------------------------------------------------------------------
2853 | Function : meas_em_send_meas_rpt
2854 +------------------------------------------------------------------------------
2855 | Description : This function ...
2856 |
2857 | Parameters : void
2858 |
2859 +------------------------------------------------------------------------------
2860 */
2861 GLOBAL BOOL meas_em_send_meas_rpt ( BOOL perform_init )
2862 {
2863 BOOL rpt_snd;
2864 T_U_MEAS_REPORT meas_rpt;
2865
2866 TRACE_FUNCTION( "meas_em_send_meas_rpt" );
2867
2868 if( perform_init EQ TRUE )
2869 {
2870 emeas->pmr_snd_ref = 0;
2871
2872 if ( emeas->xmeas_set.param->em1.param.reporting_type EQ REP_TYPE_1 )
2873 {
2874 meas_em_extrct_strgst( );
2875 }
2876 else if( emeas->xmeas_set.param->em1.param.reporting_type EQ REP_TYPE_2 )
2877 {
2878 meas_em_extrct_strgst_with_bsic( );
2879 }
2880
2881 }
2882
2883 if( meas_em_build_meas_rpt( &meas_rpt ) NEQ 0 OR
2884 perform_init EQ TRUE )
2885 {
2886 sig_meas_ctrl_meas_report( &meas_rpt );
2887
2888 rpt_snd = TRUE;
2889 }
2890 else
2891 {
2892 rpt_snd = FALSE;
2893 }
2894
2895 return( rpt_snd );
2896 } /* meas_em_send_meas_rpt() */
2897
2898
2899 /*
2900 +------------------------------------------------------------------------------
2901 | Function : meas_is_spgc_ccch_supported
2902 +------------------------------------------------------------------------------
2903 | Description : This function ...
2904 |
2905 | Parameters : void
2906 |
2907 +------------------------------------------------------------------------------
2908 */
2909 GLOBAL BOOL meas_is_spgc_ccch_supported ( void )
2910 {
2911 TRACE_FUNCTION( "meas_is_spgc_ccch_supported" );
2912
2913 return
2914 ( psc_db->net_ctrl.spgc_ccch_supp.nw_supp EQ GMMRR_SPGC_CCCH_SUPP_YES AND
2915 psc_db->net_ctrl.spgc_ccch_supp.ms_supp EQ GMMRR_SPGC_CCCH_SUPP_YES );
2916 } /* meas_is_spgc_ccch_supported() */
2917
2918
2919
2920 /*
2921 +------------------------------------------------------------------------------
2922 | Function : meas_handle_int_meas_values
2923 +------------------------------------------------------------------------------
2924 | Description : This function ...
2925 |
2926 | Parameters : mphp_int_meas_ind - pointer to primitive
2927 | rx_lev - pointer on array of 8 byte,
2928 | where the results are stored
2929 |
2930 +------------------------------------------------------------------------------
2931 */
2932 GLOBAL void meas_handle_int_meas_values
2933 ( T_MPHP_INT_MEAS_IND *mphp_int_meas_ind, UBYTE *rx_lev )
2934 {
2935 UBYTE i; /* used for counting */
2936 T_int_meas_rxlev *sample;
2937
2938 TRACE_FUNCTION( "meas_handle_int_meas_values" );
2939
2940 for ( i = 0; i < CGRLC_MAX_TIMESLOTS; i++ )
2941 {
2942 sample = &mphp_int_meas_ind->int_meas_rxlev[i];
2943
2944 if( sample->rx_lev[0] EQ CGRLC_RXLEV_NONE )
2945 {
2946 if( sample->rx_lev[1] EQ CGRLC_RXLEV_NONE )
2947 {
2948 rx_lev[i] = CGRLC_RXLEV_NONE;
2949 }
2950 else
2951 {
2952 rx_lev[i] = sample->rx_lev[1];
2953 }
2954 }
2955 else
2956 {
2957 if( sample->rx_lev[1] EQ CGRLC_RXLEV_NONE )
2958 {
2959 rx_lev[i] = sample->rx_lev[0];
2960 }
2961 else
2962 {
2963 rx_lev[i] = MINIMUM( (signed char)( sample->rx_lev[0] ),
2964 (signed char)( sample->rx_lev[1] ) );
2965 }
2966 }
2967 }
2968
2969 grr_clip_rxlev ( rx_lev, rx_lev, CGRLC_MAX_TIMESLOTS );
2970
2971 #if !defined (NTRACE)
2972
2973 if( grr_data->meas_im.n_im_trace & M_IM_TRACE_INPUT_VALUE )
2974 {
2975 USHORT rx_lev[8];
2976
2977 rx_lev[0] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[0].rx_lev[0] << 0;
2978 rx_lev[0] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[0].rx_lev[1] << 8;
2979 rx_lev[1] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[1].rx_lev[0] << 0;
2980 rx_lev[1] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[1].rx_lev[1] << 8;
2981 rx_lev[2] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[2].rx_lev[0] << 0;
2982 rx_lev[2] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[2].rx_lev[1] << 8;
2983 rx_lev[3] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[3].rx_lev[0] << 0;
2984 rx_lev[3] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[3].rx_lev[1] << 8;
2985 rx_lev[4] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[4].rx_lev[0] << 0;
2986 rx_lev[4] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[4].rx_lev[1] << 8;
2987 rx_lev[5] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[5].rx_lev[0] << 0;
2988 rx_lev[5] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[5].rx_lev[1] << 8;
2989 rx_lev[6] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[6].rx_lev[0] << 0;
2990 rx_lev[6] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[6].rx_lev[1] << 8;
2991 rx_lev[7] = ( USHORT )mphp_int_meas_ind->int_meas_rxlev[7].rx_lev[0] << 0;
2992 rx_lev[7] |= ( USHORT )mphp_int_meas_ind->int_meas_rxlev[7].rx_lev[1] << 8;
2993
2994 TRACE_EVENT_P8( "meas_handle_int_meas_values: %04X %04X %04X %04X %04X %04X %04X %04X",
2995 rx_lev[0], rx_lev[1], rx_lev[2], rx_lev[3],
2996 rx_lev[4], rx_lev[5], rx_lev[6], rx_lev[7] );
2997 }
2998
2999 #endif /* #if !defined (NTRACE) */
3000
3001 } /* meas_handle_int_meas_values() */
3002
3003 /*
3004 +------------------------------------------------------------------------------
3005 | Function : meas_c_init
3006 +------------------------------------------------------------------------------
3007 | Description : This function initializes the parameters for deriving the
3008 | C value.
3009 |
3010 | Parameters : void
3011 |
3012 +------------------------------------------------------------------------------
3013 */
3014 GLOBAL void meas_c_init ( void )
3015 {
3016 TRACE_FUNCTION( "meas_c_init" );
3017
3018 grr_data->meas.c_filter.value = 0;
3019 grr_data->meas.c_filter.index = 0;
3020 } /* meas_c_init() */
3021
3022 /*
3023 +------------------------------------------------------------------------------
3024 | Function : meas_c_val_update_pim
3025 +------------------------------------------------------------------------------
3026 | Description : ...
3027 |
3028 | Parameters : -
3029 |
3030 +------------------------------------------------------------------------------
3031 */
3032 GLOBAL void meas_c_val_update_pim ( UBYTE rx_lev )
3033 {
3034 ULONG ff; /* forgetting factor */
3035 ULONG avgw_drx;
3036 ULONG c_value;
3037 UBYTE c_block;
3038
3039 T_C_FILTER *c_filter = &grr_data->meas.c_filter;
3040
3041 TRACE_FUNCTION( "meas_c_val_update_pim" );
3042
3043 grr_clip_rxlev ( &c_block, &rx_lev, 1 );
3044
3045 if( c_block NEQ CGRLC_RXLEV_NONE )
3046 {
3047 MEAS_C_INC_INDEX( c_filter->index );
3048
3049 /* calculate the forgetting factor */
3050 avgw_drx =
3051 ( (NORM_TAVGW_FAC * NORM_TAVGW_FAC *
3052 norm_pow[psc_db->g_pwr_par.t_avg_w]) / 6 ) / meas_im_get_drx_period_seconds( );
3053
3054 ff = DRX_NORM_FACTOR / MINIMUM( NORM_TAVGW_FAC * c_filter->index,
3055 MAXIMUM( 5 * NORM_TAVGW_FAC, avgw_drx ) );
3056
3057 /* update the filter */
3058 c_value = ( NORM_POW_MIN - ff ) * c_filter->value +
3059 MEAS_ACRCY * ff * c_block;
3060
3061 c_filter->value = (T_C_VALUE)( M_ROUND_UP( c_value, NORM_POW_MIN ) );
3062
3063 #ifdef _SIMULATION_
3064 TRACE_EVENT_P2( "C-Value = %d, C-Index = %d",
3065 c_filter->value, c_filter->index );
3066 #endif /* #ifdef _SIMULATION_ */
3067
3068 grr_data->pwr_ctrl_valid_flags.v_c_value = TRUE;
3069 }
3070 else
3071 {
3072 #ifdef _SIMULATION_
3073 TRACE_EVENT( "no valid RXLEV information in meas_c_val_update_pim" );
3074 #endif /* #ifdef _SIMULATION_ */
3075 }
3076 } /* meas_c_val_update_pim() */
3077
3078 /*
3079 +------------------------------------------------------------------------------
3080 | Function : meas_handle_pwr_par
3081 +------------------------------------------------------------------------------
3082 | Description : The function meas_handle_pwr_par() ....
3083 |
3084 | Parameters : void
3085 |
3086 +------------------------------------------------------------------------------
3087 */
3088 GLOBAL void meas_handle_pwr_par ( void )
3089 {
3090 MCAST( d_ctrl_pwr_ta, D_CTRL_PWR_TA ); /* T_D_CTRL_PWR_TA */
3091
3092 TRACE_FUNCTION( "meas_handle_pwr_par" );
3093
3094 /* process global power control parameter */
3095 if( d_ctrl_pwr_ta->v_g_pwr_par )
3096 {
3097 grr_store_g_pwr_par( &d_ctrl_pwr_ta->g_pwr_par );
3098 }
3099
3100 /* process power control parameter */
3101 if( d_ctrl_pwr_ta->v_pwr_par )
3102 {
3103 grr_store_type_pwr_par( &d_ctrl_pwr_ta->pwr_par, FALSE );
3104 }
3105 } /* meas_handle_pwr_par() */