diff src/g23m-gprs/grr/grr_csf.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
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/g23m-gprs/grr/grr_csf.c	Thu Oct 13 04:24:13 2016 +0000
@@ -0,0 +1,6089 @@
+/* 
++----------------------------------------------------------------------------- 
+|  Project :  GPRS (8441)
+|  Modul   :  GRR
++----------------------------------------------------------------------------- 
+|  Copyright 2002 Texas Instruments Berlin, AG 
+|                 All rights reserved. 
+| 
+|                 This file is confidential and a trade secret of Texas 
+|                 Instruments Berlin, AG 
+|                 The receipt of or possession of this file does not convey 
+|                 any rights to reproduce or disclose its contents or to 
+|                 manufacture, use, or sell anything it may describe, in 
+|                 whole, or in part, without the specific written consent of 
+|                 Texas Instruments Berlin, AG. 
++----------------------------------------------------------------------------- 
+|  Purpose :  This module implements local functions for service CS of
+|             entity GRR.
++----------------------------------------------------------------------------- 
+*/ 
+       
+#ifndef GRR_CSF_C
+#define GRR_CSF_C
+#endif
+
+#define ENTITY_GRR
+
+/*==== INCLUDES =============================================================*/
+
+#include <stdio.h>
+#include <string.h>
+#include "typedefs.h"    /* to get Condat data types */
+#include "vsi.h"        /* to get a lot of macros */
+#include "macdef.h"
+#include "gprs.h"
+#include "gsm.h"        /* to get a lot of macros */
+#include "ccdapi.h"     /* to get CCD API */
+#include "cnf_grr.h"    /* to get cnf-definitions */
+#include "mon_grr.h"    /* to get mon-definitions */
+#include "prim.h"       /* to get the definitions of used SAP and directions */
+#include "message.h"
+#include "grr.h"        /* to get the global entity definitions */
+#include "grr_f.h"
+#include "grr_ctrls.h"
+#include "grr_meass.h"
+#include "grr_csf.h"
+#include "grr_em.h"     /*for Engineering mode*/
+
+
+/*==== CONST ================================================================*/
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+/*
+ * Bitmasks
+ */
+#define BIT_0                     0x01
+#define BIT_1                     0x02
+#define BIT_2                     0x04
+#define BIT_3                     0x08
+#define BIT_4                     0x10
+#define BIT_5                     0x20
+#define BIT_6                     0x40
+#define BIT_7                     0x80
+#endif
+
+T_NC_DATA* nc_data = NULL; /* pointer to neighbour cell data */
+
+const SHORT p_res_off[32]       = { -52,  /*  0 -> -52 dB */
+                                    -48,  /*  1 -> -48 dB */
+                                    -44,  /*  2 -> -44 dB */
+                                    -40,  /*  3 -> -40 dB */
+                                    -36,  /*  4 -> -36 dB */
+                                    -32,  /*  5 -> -32 dB */
+                                    -28,  /*  6 -> -28 dB */
+                                    -24,  /*  7 -> -24 dB */
+                                    -20,  /*  8 -> -20 dB */
+                                    -16,  /*  9 -> -16 dB */
+                                    -12,  /* 10 -> -12 dB */
+                                    -10,  /* 11 -> -10 dB */
+                                    - 8,  /* 12 -> - 8 dB */
+                                    - 6,  /* 13 -> - 6 dB */
+                                    - 4,  /* 14 -> - 4 dB */
+                                    - 2,  /* 15 -> - 2 dB */
+                                      0,  /* 16 ->   0 dB */
+                                      2,  /* 17 ->   2 dB */
+                                      4,  /* 18 ->   4 dB */
+                                      6,  /* 19 ->   6 dB */
+                                      8,  /* 20 ->   8 dB */
+                                     10,  /* 21 ->  10 dB */
+                                     12,  /* 22 ->  12 dB */
+                                     16,  /* 23 ->  16 dB */
+                                     20,  /* 24 ->  20 dB */
+                                     24,  /* 25 ->  24 dB */
+                                     28,  /* 26 ->  28 dB */
+                                     32,  /* 27 ->  32 dB */
+                                     36,  /* 28 ->  36 dB */
+                                     40,  /* 29 ->  40 dB */
+                                     44,  /* 30 ->  44 dB */
+                                     48   /* 31 ->  48 dB */
+};
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+/*
+PURPOSE : checks whether the network colour code (ncc) is member
+          of the ncc permitted field.
+*/
+LOCAL const UBYTE ncc_bit_mask[8] =
+{
+  BIT_0, BIT_1, BIT_2, BIT_3,
+  BIT_4, BIT_5, BIT_6, BIT_7
+};
+#endif
+
+#define NC_MODE_LEN        1
+#define NC_RXLEV_SCELL_LEN 6
+#define NC_IF_SCELL_LEN    6
+#define NC_NUM_OF_MEAS_LEN 3
+#define NC_FREQ_N_LEN      6
+#define NC_BSIC_N_LEN      6
+#define NC_RXLEV_N_LEN     6
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+#define BA_USED_LEN        1
+#define BA_USED_3G_LEN     1
+#define PSI3_CM_LEN        2
+#define PMO_USED_LEN       1
+#endif
+
+#define GET_NC_RPT_PRD(x)  ((0x01<<(x))*480) /* multiple of 480 ms */
+
+#define CS_PERIOD_1_SEC    217               /* 1 second defined by           */
+                                             /* multiplies of TDMA frames     */
+#define MAX_SYNC_FAILED_CNT 3
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+#define INRANGE(min, x, max)  ((unsigned)(x-min) <= (max-min))
+#endif
+
+#ifdef _TARGET_
+
+#define MIN_RXLEV_FOR_SIX_STRGST 4 /* minimum RXLEV value of neighbour cells  */
+                                   /* which shall be considered for cell      */
+                                   /* re-selection decision                   */
+#endif /* #ifdef _TARGET_ */
+
+#define RXLEV_ACRCY        1000
+#define RXLEV_MAX_NBR      ((T_RXLEV_DATA_NBR)(~((T_RXLEV_DATA_NBR)0)))
+#define RXLEV_AVG_INVALID  0xFF
+
+#ifdef TI_PS_FF_QUAD_BAND_SUPPORT
+#define CHECK_DUAL_BANDS (std EQ STD_DUAL        OR std EQ STD_DUAL_EGSM    OR \
+                          std EQ STD_DUAL_US     OR std EQ STD_850_1800     OR \
+                          std EQ STD_900_1900    OR std EQ STD_850_900_1800 OR \
+                          std EQ STD_850_900_1900)
+#endif
+
+/*==== GLOBAL VARS ===========================================================*/
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+EXTERN BOOL use_ba_gprs;
+#endif 
+
+/*==== LOCAL VARS ===========================================================*/
+
+/*==== PRIVATE FUNCTIONS ====================================================*/
+
+LOCAL void   cs_trace_nc_mval_lst ( void                           );
+LOCAL void   cs_init_nc_mval      ( T_NC_MVAL       *mval          );
+LOCAL void   cs_reorg_nc_mval_lst ( void                           );
+
+
+LOCAL BOOL   cs_build_meas_rpt    ( T_U_MEAS_REPORT *u_meas_report );
+
+LOCAL BOOL cs_process_serving_cell_data 
+                                 ( UBYTE *rxlev_scell, UBYTE *v_i_scell, 
+                                   UBYTE *i_scell, UBYTE *used_bits,
+                                   BOOL *rsc_avail, BOOL *isc_avail );
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+LOCAL void cs_build_enh_sorted_strng_arfcn_list
+                                 (T_ENH_STRNG_ARFCN_LIST *f_bin   );
+/*
+LOCAL UBYTE cs_sort_arfcns_into_bins
+                                 ( T_ENH_STRNG_ARFCN_LIST *p_s_bin,
+                                   T_ENH_STRNG_ARFCN_LIST *p_m_bin,
+                                   T_ENH_STRNG_ARFCN_LIST *p_r_bin);*/
+LOCAL UBYTE cs_sort_arfcns_into_bins
+                                 ( T_ENH_STRNG_ARFCN_LIST *p_s_bin,
+                                   T_ENH_STRNG_ARFCN_LIST *p_r_bin);
+LOCAL void cs_sort_store_in_desc_order_rxlev
+                                 ( T_ENH_STRNG_ARFCN_LIST *p_bin, 
+                                   T_ENH_STRNG_ARFCN_LIST *p_f_bin);
+LOCAL BOOL cs_build_enh_meas_rpt( T_U_ENHNC_MEAS_REPORT *u_enh_meas_report );
+
+LOCAL BOOL cs_fill_nc_enh_meas_results
+                                 (T_nc_meas_rep_enh *nc_meas_rep_enh);
+LOCAL void cs_form_enh_cell_list (void                            );
+LOCAL void cs_form_ba_bcch_enh_cell_list
+                                 (void                            );
+LOCAL void cs_nc_sort_and_update_emr_info
+                                 (void                            );
+LOCAL void cs_nc_sort_cells_into_bins
+                                 (T_ENH_BIN *p_sbin,T_ENH_BIN *p_mbin,
+                                  T_ENH_BIN *p_rbin               );
+LOCAL void cs_nc_sort_and_store_meas_results
+                                 (T_ENH_BIN *p_bin, UBYTE nbr_rpt );
+LOCAL void cs_nc_update_rest_bin
+                                 (T_ENH_BIN *p_rbin, 
+                                  T_ENH_BIN *p_bin, UBYTE nbr_rpt );
+LOCAL UBYTE cs_get_band_index_for_emr 
+                                 (USHORT arfcn);
+LOCAL UBYTE cs_nc_scale_rxlev    (void);
+#endif
+
+LOCAL void   cs_build_nc_freq_list
+                                  ( T_SC_DATABASE   *db            );
+LOCAL void   cs_find_strongest_with_status
+                                  ( UBYTE           *count, 
+                                    UBYTE           *index,
+                                    UBYTE            select_status,
+                                    UBYTE            maximum,
+                                    UBYTE            limitation    );
+LOCAL void   cs_consider_multiband
+                                  ( UBYTE           *count, 
+                                    UBYTE           *index,
+                                    UBYTE            select_status,
+                                    UBYTE            maximum       );
+LOCAL BOOL   cs_update_strongest  ( UBYTE            cnt_strgst,
+                                    UBYTE            cnt_candid,
+                                    UBYTE           *index,
+                                    ULONG            fn_offset     );
+LOCAL void   cs_start_t3158       ( T_TIME           time          );
+LOCAL void   cs_set_cnt_nc_six    ( UBYTE            strgst,
+                                    UBYTE            candid        );
+LOCAL T_TIME cs_get_nc_rpt_prd_idle
+                                  ( void                           );
+
+LOCAL void cs_copy_rxlev_from_avg( UBYTE            rxlev_avg,
+                                   T_CELL          *cell           );
+LOCAL void cs_reuse_old_cell_rxlev  (void);
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+LOCAL void cs_build_ba_bcch_nc_freq_list ();
+#endif
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_set_cnt_nc_six
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters  :
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_set_cnt_nc_six ( UBYTE strgst, UBYTE candid )
+{
+  TRACE_FUNCTION( "cs_set_cnt_nc_six" );
+
+#if defined FF_EOTD
+  grr_data->db.cnt_nc_six.strgst = MINIMUM( CS_MAX_STRONG_CARRIER_CR, strgst );
+#else  /* #if defined FF_EOTD */
+  grr_data->db.cnt_nc_six.strgst = strgst;
+#endif /* #if defined FF_EOTD */
+
+  grr_data->db.cnt_nc_six.candid = candid;
+
+} /* cs_set_cnt_nc_six() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_meas_rpt
++------------------------------------------------------------------------------
+| Description : This function ...
+|
+| Parameters  : u_meas_report - Pointer to measurement report
+|
++------------------------------------------------------------------------------
+*/
+LOCAL BOOL cs_build_meas_rpt ( T_U_MEAS_REPORT *u_meas_report )
+{
+  T_NC_ORDER      nc_ord        = cs_get_network_ctrl_order( TRUE );
+  BOOL            pbcch_present = grr_is_pbcch_present( );
+  UBYTE           used_bits;     
+                           /* bits currently used for the measurement report */
+  UBYTE           next_meas_bits = 0;
+                           /* bits used for the next element of the          */
+                           /* measurement result list                        */
+  BOOL            is_first_instance;
+
+  T_CS_MEAS_DATA *nmeas      = &grr_data->cs_meas;
+  T_nc_meas_rep  *ncmeas_rep = &u_meas_report->nc_meas_rep;
+  T_nc_meas_s1   *p_mrpt;
+  T_ncell_info   *ncell;
+  T_NC_MVAL      *mval;
+  UBYTE return_value;
+  BOOL rsc_avail = FALSE;
+  BOOL isc_avail = FALSE;
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  UBYTE psi3_cm = grr_get_psi3_cm();
+#endif
+  TRACE_FUNCTION( "cs_build_meas_rpt" );
+
+  /* process message type */
+  used_bits               = PMR_MSG_TYPE_LEN;
+  u_meas_report->msg_type = U_MEAS_REPORT_c;
+
+  /* process TLLI */
+  used_bits += PMR_TLLI_LEN;
+  grr_set_buf_tlli( &u_meas_report->tlli_value, grr_get_tlli( ) );
+
+  /* process PSI5 change mark */
+  used_bits += PMR_FLAG_LEN;
+
+  if( pbcch_present                 EQ FALSE                       OR 
+      grr_data->db.nc_ref_lst.param EQ &psc_db->nc_ms.ncmeas.param    )
+  { 
+    u_meas_report->v_psi5_cm = FALSE;
+  }
+  else if( grr_data->db.nc_ref_lst.param EQ &psc_db->nc_cw.param )
+  {
+    used_bits += PMR_PSI5_CHNGE_MRK_LEN;
+
+    u_meas_report->v_psi5_cm = TRUE;
+    u_meas_report->psi5_cm   = psc_db->psi5_params.psi5_change_mark;
+  }
+  else
+  {
+    TRACE_ERROR( "cs_build_meas_rpt no valid data set" );
+    return( FALSE );
+  }
+  
+  /* process flags */
+  used_bits                    += PMR_FLAG_LEN;
+  u_meas_report->flag           = 0;
+  u_meas_report->v_nc_meas_rep  = TRUE;
+  u_meas_report->v_xmeas_rep    = FALSE;
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  /*if(psc_db->network_rel NEQ BSS_NW_REL_97)*/
+  {
+    used_bits                += PMR_FLAG_LEN;
+    u_meas_report->v_release_99_str_pmr = TRUE;
+    
+    used_bits                += PMR_FLAG_LEN;
+    u_meas_report->release_99_str_pmr.v_meas_rep_3g_str = FALSE;
+    
+    used_bits                += PMR_FLAG_LEN;      
+    u_meas_report->release_99_str_pmr.v_ba_psi3_str = TRUE;
+    
+    used_bits                += PMO_IND_USED_LEN;
+    u_meas_report->release_99_str_pmr.ba_psi3_str.pmo_ind_used = psc_db->nc_ms.pmo_ind;
+    
+    /* 1 bit for u_meas_report->ba_psi3_str.flag */
+    used_bits                += PMR_FLAG_LEN;      
+    
+    /* process BA used, PSI3 change mark and PMO used */
+    if( pbcch_present EQ FALSE )
+    {
+      TRACE_EVENT_P1("pbcch_present %d", pbcch_present);
+      u_meas_report->release_99_str_pmr.ba_psi3_str.flag = FALSE;
+      
+      u_meas_report->release_99_str_pmr.ba_psi3_str.v_ba_ind_used = TRUE;
+      u_meas_report->release_99_str_pmr.ba_psi3_str.v_ba_ind_used_3g = TRUE;
+      
+      used_bits                += PMR_BA_IND_USED_LEN;
+      u_meas_report->release_99_str_pmr.ba_psi3_str.ba_ind_used = psc_db->ba_ind;
+      
+      /* Add 1 bit for ba_ind_used_3g */ 
+      u_meas_report->release_99_str_pmr.ba_psi3_str.ba_ind_used_3g = 0;
+      used_bits                += PMR_BA_IND_USED_LEN;
+    }
+    else
+    {
+      u_meas_report->release_99_str_pmr.ba_psi3_str.flag = TRUE;
+      
+      u_meas_report->release_99_str_pmr.ba_psi3_str.v_psi3_cm = TRUE;
+      
+      used_bits                += PMR_PSI3_CHNGE_MRK_LEN;
+      u_meas_report->release_99_str_pmr.ba_psi3_str.psi3_cm = psi3_cm;
+    }
+  }
+#endif
+
+  /* process NC mode */
+  used_bits += NC_MODE_LEN;
+
+  switch( nc_ord )
+  {
+    case NC_NC1: ncmeas_rep->nc_mode = NCMODE_NC1; break;
+    case NC_NC2: ncmeas_rep->nc_mode = NCMODE_NC2; break;
+
+    default: TRACE_ERROR( "cs_build_meas_rpt no valid NC mode" ); return( FALSE );
+  }
+
+  /* process serving cell data - rxlev and ilev */
+  
+  return_value = 
+  cs_process_serving_cell_data(&ncmeas_rep->rxlev_scell, 
+                              &ncmeas_rep->v_i_scell,
+                              &ncmeas_rep->i_scell, &used_bits,
+                              &rsc_avail, &isc_avail);
+  if((return_value EQ FALSE) AND (rsc_avail EQ FALSE))
+    return(FALSE);
+
+  
+  /* process NC measurement results */
+  used_bits               += NC_NUM_OF_MEAS_LEN;
+  ncmeas_rep->num_nc_meas  = 0;
+  ncmeas_rep->c_nc_meas_s1 = 0;
+  is_first_instance        = nmeas->pmr_snd_ref EQ 0 ? TRUE : FALSE;
+
+  do
+  {
+    /* calculate estimated length of next measurement result */
+    if( nmeas->pmr_snd_ref >= grr_data->db.cnt_nc_six.candid )
+    {
+      mval  = NULL;
+      ncell = NULL;    
+    }
+    else
+    {
+      mval = &grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[nmeas->pmr_snd_ref].idx];
+
+      next_meas_bits = NC_FREQ_N_LEN + NC_RXLEV_N_LEN + PMR_FLAG_LEN;
+
+      if( mval->sync_info.sync.status EQ STAT_SYNC_OK )
+      {
+        UBYTE ncell_idx = 0;
+
+        ncell = grr_get_ncell_info( mval->arfcn, mval->sync_info.bsic );
+
+        while( ncell_idx  <  grr_data->db.nc_ref_lst.number AND
+               ncell      EQ NULL                               )
+        {
+          ncell = grr_data->db.nc_ref_lst.info[ncell_idx];
+
+          if( ncell->arfcn                   NEQ mval->arfcn       OR 
+              NC_GET_TYPE( ncell->info_src ) NEQ INFO_TYPE_BA_BCCH    )
+          {
+            ncell = NULL;
+          }
+
+          ncell_idx++;
+        }
+
+        if( ncell NEQ NULL )
+        {
+          next_meas_bits = NC_FREQ_N_LEN + NC_RXLEV_N_LEN + PMR_FLAG_LEN;
+
+          if( NC_GET_TYPE( ncell->info_src ) EQ INFO_TYPE_BA_BCCH )
+          {
+            next_meas_bits += NC_BSIC_N_LEN;
+          }
+        }
+      }
+      else
+      {
+        ncell = NULL;
+      }
+    }
+
+    if( ncell NEQ NULL AND mval NEQ NULL)
+    {
+      if( BIT_UL_CTRL_BLOCK_CONTENTS - used_bits  >=  next_meas_bits     )
+      {
+        /* copy next measurement result to measurement report */
+
+        ncmeas_rep->num_nc_meas++;
+        ncmeas_rep->c_nc_meas_s1++;
+        used_bits += next_meas_bits;
+        p_mrpt     = &ncmeas_rep->nc_meas_s1[ncmeas_rep->c_nc_meas_s1 - 1];
+
+        p_mrpt->freq_n   = ncell->index;
+        p_mrpt->rxlev_n  = mval->rxlev_avg;
+
+        if( NC_GET_TYPE( ncell->info_src ) EQ INFO_TYPE_BA_BCCH )
+        {
+          p_mrpt->bsic   = mval->sync_info.bsic;
+          p_mrpt->v_bsic = TRUE;
+        }
+        else
+        {
+          p_mrpt->v_bsic = FALSE;
+        }
+
+        nmeas->pmr_snd_ref++;
+      }
+      else
+      {
+        mval = NULL;
+      }
+    }
+    else
+    {
+      nmeas->pmr_snd_ref++;
+    }
+
+  }
+  while( mval NEQ NULL );
+
+  return( is_first_instance OR ncmeas_rep->num_nc_meas );
+
+
+} /* cs_build_meas_rpt() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_is_meas_reporting
++------------------------------------------------------------------------------
+| Description : This function ...
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL UBYTE cs_is_meas_reporting ( void )
+{
+  T_NC_ORDER ctrl_order = cs_get_network_ctrl_order( TRUE );
+
+  TRACE_FUNCTION( "cs_is_meas_reporting" );
+
+  return( ctrl_order EQ NC_NC1 OR ctrl_order EQ NC_NC2 );
+
+} /* cs_is_meas_reporting() */
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+/*
++------------------------------------------------------------------------------
+| Function    : cs_is_enh_meas_reporting
++------------------------------------------------------------------------------
+| Description : This function is used to check whether enhanced measurement 
+|               reporting is to be done.
+|
+| Parameters  : returns TRUE if ENH reporting is to be done
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_is_enh_meas_reporting ( void )
+{
+  BOOL return_value = FALSE;
+    
+  TRACE_FUNCTION( "cs_is_enh_meas_reporting" );
+
+  if ( cs_is_meas_reporting() AND 
+    (grr_data->db.nc_ref_lst.enh_param->rept_type EQ REPORT_TYPE_ENH_REP) )
+  {
+    return_value = TRUE;
+  }
+
+  return( return_value );
+} /* cs_is_enh_meas_reporting() */
+#endif
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_nc_freq_list
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : db - pointer to serving cell database
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_build_nc_freq_list ( T_SC_DATABASE *db )
+{ 
+  UBYTE i, j, k;        /* used for counting                              */
+  UBYTE act_idx;        /* index of actual processed reference list entry */
+  BOOL  is_removed;
+  BOOL  is_overwritten;
+  
+  T_ncell_info *info_ref_lst;
+  T_ncell_info *info_prev  = ( db->nc_cw.list.number EQ 0 ?
+                               NULL :
+                               &db->nc_cw.list.info[db->nc_cw.list.number-1] );
+  T_ncell_info *info_curr;
+  T_INFO_SRC    info_src   = 0;
+
+  TRACE_FUNCTION( "cs_build_nc_freq_list" );
+
+  /*
+   * add neighbour cell information of BA(GPRS) to reference list
+   * in case they are not removed 
+   */
+  for( i = 0; i < db->nc_cw.list.number; i++ )
+  {
+    /*
+     * looking for entry with correct index, 
+     * they are no longer sorted with increasing number
+     */
+    k = 0;
+    
+    while( k < db->nc_cw.list.number AND i NEQ db->nc_cw.list.info[k].index )
+    {
+      k++;
+    }
+
+    if( db->nc_cw.list.info[k].arfcn EQ psc_db->pbcch.bcch.arfcn )
+    {
+      /* remove the serving cell from the neighbour cell reference list */
+      is_removed = TRUE;
+    }
+    else
+    {
+      for( j = 0, is_removed = FALSE;
+           j < db->nc_ms.rfreq.number AND is_removed EQ FALSE; 
+           j++ )
+      {
+        if( db->nc_cw.list.info[k].index EQ db->nc_ms.rfreq.idx[j] )
+        {
+          is_removed = TRUE;
+        }
+      }
+    }
+  
+    if( is_removed EQ FALSE )
+    {
+      if( !( db->nc_cw.list.info[k].v_cr_par                EQ  FALSE             AND
+             NC_GET_TYPE( db->nc_cw.list.info[k].info_src ) NEQ INFO_TYPE_BA_BCCH AND
+             cs_get_network_ctrl_order( TRUE )              NEQ NC_NC2                ) 
+           AND
+          !( db->nc_cw.list.info[k].cr_par.cell_ba                                    ) )
+      {
+        grr_data->db.nc_ref_lst.info[grr_data->db.nc_ref_lst.number] =
+                                                       &db->nc_cw.list.info[k];
+        grr_data->db.nc_ref_lst.number++;
+      }
+      else
+      {
+
+#if !defined (NTRACE)
+
+        if( grr_data->cs.v_crp_trace EQ TRUE )
+        {
+          TRACE_EVENT_P2( "cs_build_nc_freq_list 1: not added to NC_REF_LST %d %d",
+                          db->nc_cw.list.info[k].arfcn, db->nc_cw.list.info[k].bsic );
+        }
+
+#endif /* #if !defined (NTRACE) */
+
+      }
+    }
+    else
+    {
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT_P2( "cs_build_nc_freq_list 2: not added to NC_REF_LST %d %d",
+                        db->nc_cw.list.info[k].arfcn, db->nc_cw.list.info[k].bsic );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+
+    }
+  }
+
+  /*
+   * add/overwrite neighbour cell information to/of reference list
+   */
+  i = 0;
+  
+  while( ( info_curr = grr_get_next_bigger_ncell_param
+                              ( &db->nc_ms.ncmeas.list, info_src ) ) NEQ NULL )
+  {
+    j              = 0;
+    is_overwritten = FALSE;
+
+    while( j < grr_data->db.nc_ref_lst.number AND is_overwritten EQ FALSE )
+    {
+      info_ref_lst = grr_data->db.nc_ref_lst.info[j];
+  
+      if( NC_GET_TYPE( info_ref_lst->info_src ) NEQ INFO_TYPE_BA_BCCH AND
+          info_ref_lst->v_cr_par                EQ  TRUE              AND
+          info_curr->v_cr_par                   EQ  TRUE              AND
+          info_ref_lst->bsic                    EQ  info_curr->bsic   AND
+          info_ref_lst->arfcn                   EQ  info_curr->arfcn      )
+      {
+        is_overwritten = TRUE;
+      }
+      else
+      {
+        j++;
+      }
+    }
+
+    /*
+     * calculate the index of the reference list entry 
+     * which shall be used for further processing 
+     */
+    if( is_overwritten EQ FALSE )
+    {
+      if( grr_data->db.nc_ref_lst.number < MAX_NR_OF_NCELL )
+      {
+        act_idx = grr_data->db.nc_ref_lst.number;
+      }
+      else
+      {
+        TRACE_ERROR( "cs_build_nc_freq_list: reference list full" );
+        return;
+      }
+    }
+    else
+    {
+      act_idx = j;
+    }
+
+
+    if(
+        !( info_curr->v_cr_par                EQ  FALSE                    AND
+           NC_GET_TYPE( info_curr->info_src ) NEQ INFO_TYPE_BA_BCCH        AND
+           cs_get_network_ctrl_order( TRUE )  NEQ NC_NC2                       ) 
+         AND
+        !( info_curr->cr_par.cell_ba                                           ) 
+         AND
+         ( info_curr->arfcn                   NEQ psc_db->pbcch.bcch.arfcn     )
+      )
+    {
+     /*
+      * add/overwrite reference list entry
+      */
+      grr_data->db.nc_ref_lst.info[act_idx] = info_curr;
+      grr_data->db.nc_ref_lst.number++;
+
+      /* process cell selection parameter */
+      grr_restore_cs_param
+                  ( info_curr, info_prev, (UBYTE)( db->nc_cw.list.number + i ) );
+
+
+      if( info_curr->v_cr_par EQ TRUE )
+      {
+        info_prev = info_curr;
+      }
+    }
+    else
+    {
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT_P2( "cs_build_nc_freq_list 3: not added to NC_REF_LST %d %d",
+                        info_curr->arfcn, info_curr->bsic );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+      info_curr->index = db->nc_cw.list.number + i;
+    }
+
+    info_src = info_curr->info_src;
+  
+    i++;  
+  }  
+
+#if !defined (NTRACE)
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    UBYTE         read;
+    USHORT        crp_s;
+    ULONG         crp[4];
+    T_ncell_info *info;
+
+    crp[0]  = ( ( ULONG )psc_db->pbcch.bcch.arfcn  << 16 );
+    crp[0] |= ( ( ULONG )psc_db->pbcch.bcch.bsic   <<  8 );
+    crp[0] |=   ( ULONG )psc_db->scell_par.cell_ba;
+
+    crp[1]  = ( ( ULONG )psc_db->scell_par.exc_acc                                   << 24 );
+    crp[1] |= ( ( ULONG )psc_db->scell_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min << 16 );
+    crp[1] |= ( ( ULONG )psc_db->scell_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch <<  8 );
+
+    if( psc_db->scell_par.cr_par_1.v_hcs_par )
+    {
+      crp[1] |=   ( ULONG  )psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class;
+      crp_s   = ( ( USHORT )psc_db->scell_par.cr_par_1.hcs_par.gprs_hcs_thr    << 8 );
+    }
+    else
+    {
+      crp[1] |=   ( ULONG  )0xFF;
+      crp_s   = ( ( USHORT )0xFF << 8 );
+    }
+
+    crp_s |= ( ULONG )psc_db->scell_par.multi_band_rep;
+
+    TRACE_EVENT_P3( "SCELL %08X%08X%04X", crp[0], crp[1], crp_s );
+
+    for( read = 0; read < grr_data->db.nc_ref_lst.number; read++ )
+    {
+      info = grr_data->db.nc_ref_lst.info[read];
+      
+      crp[0]  = ( ( ULONG )info->arfcn << 16 );
+      crp[0] |= ( ( ULONG )info->bsic  <<  8 );
+      
+      if( info->v_cr_par )
+      {
+        crp[0] |=   ( ULONG )info->cr_par.cell_ba;
+      
+        crp[1]  = ( ( ULONG )info->cr_par.exc_acc                                   << 24 );
+        crp[1] |= ( ( ULONG )info->cr_par.same_ra_scell                             << 16 );
+        crp[1] |= ( ( ULONG )info->cr_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min <<  8 );
+        crp[1] |=   ( ULONG )info->cr_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch;
+
+        crp[2]  = ( ( ULONG )info->cr_par.cr_offset.gprs_temp_offset  << 24 );
+        crp[2] |= ( ( ULONG )info->cr_par.cr_offset.gprs_penalty_time << 16 );
+        crp[2] |= ( ( ULONG )info->cr_par.gprs_resel_off              <<  8 );
+
+        if( grr_data->db.nc_ref_lst.info[read]->cr_par.cr_par_1.v_hcs_par )
+        {
+          crp[2] |=   ( ULONG )info->cr_par.cr_par_1.hcs_par.gprs_prio_class;
+          crp[3]  = ( ( ULONG )info->cr_par.cr_par_1.hcs_par.gprs_hcs_thr    << 24 );
+        }
+        else
+        {
+          crp[2] |=   ( ULONG )0xFF;
+          crp[3]  = ( ( ULONG )0xFF << 24 );
+        }
+
+        if( info->cr_par.v_si13_pbcch )
+        {
+          if( info->cr_par.si13_pbcch.v_si13_location )
+          {
+            crp[3] |= ( ( ULONG )info->cr_par.si13_pbcch.si13_location << 16 );
+            crp[3] |= ( ( ULONG )0xFF                                  << 8  );
+            crp[3] |=   ( ULONG )0xFF;
+          }
+          else
+          {
+            crp[3] |= ( ( ULONG )0xFF                                       << 16 );
+            crp[3] |= ( ( ULONG )info->cr_par.si13_pbcch.pbcch_location     << 8  );
+            crp[3] |=   ( ULONG )info->cr_par.si13_pbcch.psi1_repeat_period;
+          }
+        }
+        else
+        {
+          crp[3] |= ( ULONG )0xFFFFFF;
+        }
+      }
+      else
+      {
+        crp[1] |= ( ULONG )0xFF;
+        crp[2]  = ( ULONG )0xFFFFFFFF;
+        crp[3]  = ( ULONG )0xFFFFFFFF;
+      }
+
+      TRACE_EVENT_P5( "NC_REF_LST[%d] %08X%08X%08X%08X", 
+                      read, crp[0], crp[1], crp[2], crp[3] );
+    }
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+}/* cs_build_nc_freq_list */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reorg_nc_mval_lst
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_reorg_nc_mval_lst ( void )
+{ 
+  BOOL          scell_restored = FALSE;
+  UBYTE         mval_idx;
+  UBYTE         nc_idx;
+  T_NC_MVAL    *nc_mval;
+  T_ncell_info *ncell_info;
+
+  TRACE_FUNCTION( "cs_reorg_nc_mval_lst" );
+
+  for( mval_idx = 0; mval_idx < MAX_NR_OF_NC_MVAL; mval_idx++ )
+  {
+    /* 
+     * check whether measured values can be reused
+     */
+    
+    nc_mval = &grr_data->db.nc_mval_list.nc_mval[mval_idx];
+    
+    if( nc_mval->status NEQ NC_MVAL_STAT_NONE )
+    {
+      /*
+       * only used entries shall be considered 
+       */
+    
+      if( psc_db->pbcch.bcch.arfcn EQ  nc_mval->arfcn      AND 
+          psc_db->pbcch.bcch.arfcn NEQ RRGRR_INVALID_ARFCN     )
+      {
+        /*
+         * remove the measured values from the serving cell,
+         * this cell will not be used for cell re-selection
+         */ 
+        cs_init_nc_mval( nc_mval );
+      }
+      else
+      {
+        ncell_info = grr_get_ncell_info( nc_mval->arfcn, RRGRR_INVALID_BSIC );
+
+        if( ncell_info EQ NULL )
+        {
+          /*
+           * cell is not on the neighbor cell list,
+           * keep the measured values until RR informs GRR,
+           * but do not use them
+           */
+          nc_mval->status     = NC_MVAL_STAT_PENDING;
+          nc_mval->rla_p.stat = CS_RLA_P_NOT_AVAIL;
+        }
+        else
+        {
+          /*
+           * cell is on the neighbor cell list,
+           * re-activate the measured values
+           */
+          nc_mval->status = NC_MVAL_STAT_ASSIGNED;
+        }
+
+        if( grr_data->db.old_scell.arfcn EQ  nc_mval->arfcn      AND 
+            grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN     )
+        {
+          /*
+           * in case the old serving cell is on the measured values list,
+           * keep the results for further use
+           */
+          scell_restored = TRUE;
+
+          nc_mval->sync_info.bsic                 = grr_data->db.old_scell.bsic;
+          nc_mval->sync_info.sync.status          = STAT_SYNC_OK;
+          nc_mval->sync_info.sync.sync_failed_cnt = 0;
+        }
+      }
+    }
+  }
+
+  for( nc_idx = 0; nc_idx < grr_data->db.nc_ref_lst.number; nc_idx++ )
+  {
+    nc_mval = grr_get_nc_mval( grr_data->db.nc_ref_lst.info[nc_idx]->arfcn,
+                               RRGRR_INVALID_BSIC, &mval_idx );
+
+    if( nc_mval EQ NULL )
+    {
+      nc_mval =
+        grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &mval_idx );
+
+      if( nc_mval NEQ NULL )
+      {
+        nc_mval->status = NC_MVAL_STAT_ASSIGNED;
+        nc_mval->arfcn  = grr_data->db.nc_ref_lst.info[nc_idx]->arfcn;
+
+        if( grr_data->db.old_scell.arfcn EQ  nc_mval->arfcn      AND
+            grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN     )
+        {
+          scell_restored = TRUE;
+
+          nc_mval->sync_info.bsic                 = grr_data->db.old_scell.bsic;
+          nc_mval->sync_info.sync.status          = STAT_SYNC_OK;
+          nc_mval->sync_info.sync.sync_failed_cnt = 0;
+
+          TRACE_EVENT_P2( "cs_reorg_nc_mval_lst: old SCELL on new NCELL list (1) %d %d",
+                          grr_data->db.nc_ref_lst.info[nc_idx]->arfcn,
+                          grr_data->db.nc_ref_lst.info[nc_idx]->bsic );
+        }
+      }
+      else
+      {
+        TRACE_EVENT_P1( "cs_reorg_nc_mval_lst: nc_mval EQ NULL (1) %d",
+                        RRGRR_INVALID_ARFCN );
+      }
+    }
+    else
+    {
+      if( grr_data->db.old_scell.arfcn EQ  nc_mval->arfcn      AND 
+          grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN     )
+      {
+        scell_restored = TRUE;
+
+        nc_mval->status                         = NC_MVAL_STAT_ASSIGNED;
+        nc_mval->sync_info.bsic                 = grr_data->db.old_scell.bsic;
+        nc_mval->sync_info.sync.status          = STAT_SYNC_OK;
+        nc_mval->sync_info.sync.sync_failed_cnt = 0;
+
+        TRACE_EVENT_P2( "cs_reorg_nc_mval_lst: old SCELL on new NCELL list (2) %d %d",
+                        grr_data->db.nc_ref_lst.info[nc_idx]->arfcn,
+                        grr_data->db.nc_ref_lst.info[nc_idx]->bsic );
+      }
+    }
+  }
+
+  if( scell_restored               EQ  FALSE               AND 
+      grr_data->db.old_scell.arfcn NEQ RRGRR_INVALID_ARFCN     )
+  {
+    nc_mval =
+      grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &mval_idx );
+
+    if( nc_mval NEQ NULL )
+    {
+      nc_mval->status                         = NC_MVAL_STAT_PENDING;
+      nc_mval->arfcn                          = grr_data->db.old_scell.arfcn;
+      nc_mval->sync_info.bsic                 = grr_data->db.old_scell.bsic;
+      nc_mval->sync_info.sync.status          = STAT_SYNC_OK;
+      nc_mval->sync_info.sync.sync_failed_cnt = 0;
+    }
+    else
+    {
+      TRACE_EVENT_P1( "cs_reorg_nc_mval_lst: nc_mval EQ NULL (2) %d",
+                      RRGRR_INVALID_ARFCN );
+    }
+  }
+
+  grr_data->cs.is_mval_initialized = FALSE;
+
+  cs_trace_nc_mval_lst( );
+
+}/* cs_reorg_nc_mval_lst */
+
+/*==== PUBLIC FUNCTIONS =====================================================*/
+/*
++------------------------------------------------------------------------------
+| Function    : cs_grr_init
++------------------------------------------------------------------------------
+| Description : The function cs_grr_init() .... name change becauce there is a
+|               function in cs_init in TIL.
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_grr_init ( void )
+{
+  TRACE_FUNCTION( "cs_grr_init" );
+
+  grr_data->cs.gmm_state           = STANDBY_STATE;
+  grr_data->cs.last_cr             = 0;
+  grr_data->cs.reselect_cause      = CS_RESELECT_CAUSE_CS_NORMAL;
+  grr_data->cs.is_mval_initialized = FALSE;
+  grr_data->cs.nc_sync_rep_pd      = 0;
+
+#if !defined (NTRACE)
+
+  grr_data->cs.v_crp_trace = FALSE;
+      
+#endif /* #if !defined (NTRACE) */
+
+  grr_init_ncmeas_extd_struct( &psc_db->nc_ms, FALSE );
+  cs_init_nc_ref_list( &grr_data->db.nc_ref_lst );
+  cs_init_nc_mval_lst( );
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  /* Initialize Enhanced Measurement parameters and list */
+  grr_init_enh_param(&psc_db->enh_ms, TRUE);
+  grr_init_enh_cell_list();
+#endif
+
+  grr_data->cs_meas.pmr_snd_ref = 0;
+  grr_data->cs_meas.packet_mode = PACKET_MODE_NULL;
+
+  nc_data = &grr_data->nc_data;
+
+  cs_reset_all_cell_results( );
+
+  grr_data->cs.list_id             = 0;
+  grr_data->cs.stop_req            = FALSE;
+
+  nc_data->c_cell                  = 0;
+
+  grr_data->cs.cr_meas_mode        = CS_CRMM_BA_GPRS;
+  grr_data->cs.cr_meas_update      = FALSE;
+  grr_data->cs.last_assignment_id  = 0;
+
+
+  INIT_STATE( CS_MEAS, CS_MEAS_NULL  );
+  INIT_STATE( CS, CS_NULL );
+} /* cs_grr_init() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_process_cc_order
++------------------------------------------------------------------------------
+| Description : The function cs_process_cc_order() ....
+|
+| Parameters  : d_cell_chan_order - Pointer to packet cell change order message
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_process_cc_order ( T_nc_meas_par  *nc_meas_par,
+                                  UBYTE           v_nc_freq_list,
+                                  T_nc_freq_list *nc_freq_list
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+                                , UBYTE       v_enh_meas_param_pcco,  
+                                  T_enh_meas_param_pcco   *enh_meas_param_pcco
+#endif
+                                )
+{
+  TRACE_FUNCTION( "cs_process_cc_order" );
+
+  grr_init_ncmeas_extd_struct( &pcr_db->nc_ms, FALSE );
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  /* Initialize Enhanced Measurement parameters */
+  grr_init_enh_param(&pcr_db->enh_ms, TRUE);
+#endif
+
+  /*
+   * process the NC measurement parameter
+   *
+   * only one instance of PCCO, store data in final location
+   */
+  grr_prcs_nc_param_struct ( &pcr_db->nc_ms.ncmeas.param, 
+                             nc_meas_par,
+                             0 );
+
+  /* For PCCO the paramater obtained in PCCO should be applied immediately
+  Sec 5.6.1 Spec 4.60 */
+  grr_data->db.nc_ref_lst.param = &pcr_db->nc_ms.ncmeas.param;
+
+  /* 
+   * process NC_FREQUENCY_LIST
+   *
+   * only one instance of PCCO, store data in final location
+   */
+  grr_prcs_nc_freq_list ( &pcr_db->nc_ms.ncmeas.list,
+                          &pcr_db->nc_ms.rfreq,
+                          v_nc_freq_list,
+                          nc_freq_list,
+                          INFO_TYPE_PCCO,
+                          0 );
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  /*
+   * process the ENH measurement parameter
+   *
+   * only one instance of PCCO, store data in final location
+   */
+  if(v_enh_meas_param_pcco)
+  {
+  grr_prcs_enh_param_pcco ( pcr_db, enh_meas_param_pcco );
+  }
+#endif
+
+} /* cs_process_cc_order() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_calc_cr_criterion
++------------------------------------------------------------------------------
+| Description : The function cs_calc_cr_criterion() ....
+|
+| Parameters  : dummy - description of parameter dummy
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_calc_cr_criterion ( T_CR_CRITERIONS *cr_crit,
+                                   USHORT           arfcn, 
+                                   T_rla_p         *rla_p,
+                                   T_CR_PAR_1      *cr_par_1 )
+{
+  T_MS_PWR_CAP mspc;
+  SHORT        A, B;
+
+  TRACE_FUNCTION( "cs_calc_cr_criterion" );
+
+  /* C1     = A - MAX(B,0)                                                 */
+  /* A      = RLA_P - GPRS_RXLEV_ACCESS_MIN                                */
+  /* B      = GPRS_MS_TXPWR_MAX_CCH - P                                    */
+  /* P      = max MS RF output power                                       */
+
+  /* C31    = RLA_P(s) - HCS_THR(s) (serving cell)                         */
+  /* C31    = RLA_P(n) - HCS_THR(n) - TO(n)*L(n) (neighbour cell)          */
+  /* TO(n)  = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) )  */
+  /* L(n)   = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+  /*          1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+
+  /* C32(s) = C1(s)                                                        */
+  /* C32(n) = C1(n) + GPRS_RESELECT OFFSET(n) - TO(n)*(1-L(n))             */
+  /* TO(n)  = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) )  */
+  /* L(n)   = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+  /*          1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+  /* H(n)   = 0 for x <  0                                                 */
+  /*          1 for x >= 0                                                 */
+  /* T(n)   = ?????                                                        */
+
+  grr_get_ms_pwr_cap( arfcn, grr_data->meas.pwr_offset, &mspc );
+
+  /*
+   * calculate cell re-selection criteria acc. GSM05.08, 
+   * chapter 10.1.2 for the serving/neighbour cell
+   */
+
+  /* intermediate results for serving/neighbour cell */
+  A = (SHORT)rla_p->lev - (SHORT)cr_par_1->cr_pow_par.gprs_rxlev_access_min;
+  B = mspc.p_control[cr_par_1->cr_pow_par.gprs_ms_txpwr_max_cch] - mspc.p[mspc.ms_power];
+
+  /* path loss criterion for serving/neighbour cell */
+  cr_crit->c1 = A - MAXIMUM( B, 0 );
+
+  /* signal threshold criterion for serving/neighbour cell */
+  cr_crit->c31 = ( SHORT )rla_p->lev;
+
+  if( cr_par_1->v_hcs_par )
+  {
+    cr_crit->c31 -= ( 2 * cr_par_1->hcs_par.gprs_hcs_thr );
+  }
+
+  /* cell ranking criterion for serving/neighbour cell */
+  cr_crit->c32 = cr_crit->c1;
+
+} /* cs_calc_cr_criterion() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_calc_params
++------------------------------------------------------------------------------
+| Description : The function cs_calc_params() ....
+|
+| Parameters  : dummy - description of parameter dummy
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_calc_params ( void )
+{
+  BOOL          prio_cr = FALSE;
+  UBYTE         h;
+  UBYTE         i, prios, prion, strgst = 0xFF;
+  T_ncell_info *ncell_info;
+  T_NC_MVAL    *nc_mval;
+
+  TRACE_FUNCTION( "cs_calc_params" );
+
+  /* C1     = A - MAX(B,0)                                                 */
+  /* A      = RLA_P - GPRS_RXLEV_ACCESS_MIN                                */
+  /* B      = GPRS_MS_TXPWR_MAX_CCH - P                                    */
+  /* P      = max MS RF output power                                       */
+
+  /* C31    = RLA_P(s) - HCS_THR(s) (serving cell)                         */
+  /* C31    = RLA_P(n) - HCS_THR(n) - TO(n)*L(n) (neighbour cell)          */
+  /* TO(n)  = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) )  */
+  /* L(n)   = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+  /*          1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+
+  /* C32(s) = C1(s)                                                        */
+  /* C32(n) = C1(n) + GPRS_RESELECT OFFSET(n) - TO(n)*(1-L(n))             */
+  /* TO(n)  = GPRS_TEMPORARY_OFFSET(n) * H( GPRS_PENALTY_TIME(N) - T(n) )  */
+  /* L(n)   = 0 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+  /*          1 if PRIORITY_CLASS(n) = PRIORITY_CLASS(s)                   */
+  /* H(n)   = 0 for x <  0                                                 */
+  /*          1 for x >= 0                                                 */
+  /* T(n)   = ?????                                                        */
+
+  cs_calc_cr_criterion( &grr_data->db.scell_info.cr_crit,
+                         psc_db->pbcch.bcch.arfcn, 
+                        &grr_data->db.scell_info.rla_p,
+                        &psc_db->scell_par.cr_par_1 );
+
+  /* priority class for serving cell */
+  prios = ( psc_db->scell_par.cr_par_1.v_hcs_par ) ?
+                        psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class : 0;
+    
+  /*
+   * calculate cell re-selection criteria acc. GSM05.08, 
+   * chapter 10.1.2 for the neighbour cells
+   */
+  for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
+  {
+    h          = FALSE;
+    nc_mval = &grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx];
+
+    if( nc_mval->sync_info.sync.status EQ STAT_SYNC_OK )
+    {
+      ncell_info = 
+        grr_get_ncell_info( nc_mval->arfcn, nc_mval->sync_info.bsic );
+
+      if( ncell_info NEQ NULL )
+      {
+        cs_calc_cr_criterion( &grr_data->db.nc_six_strgst[i].cr_crit,
+                               ncell_info->arfcn, 
+                              &nc_mval->rla_p,
+                              &ncell_info->cr_par.cr_par_1 );
+
+        /* cell ranking criterion for neighbour cell, add GPRS_RESELECT_OFFSET */
+
+        /*
+         * if the parameter C32_QUAL is set, positive GPRS_RESELECT_OFFSET values
+         * shall only be applied to the neighbour cell with the highest RLA_P value
+         * of those cells for which C32 is compared.
+         *
+         * calculation part 1
+         */
+        if( psc_db->gen_cell_par.c32_qual                EQ FALSE OR
+            p_res_off[ncell_info->cr_par.gprs_resel_off] <  0        )
+        {
+          grr_data->db.nc_six_strgst[i].cr_crit.c32 +=
+                                      p_res_off[ncell_info->cr_par.gprs_resel_off];
+        }
+
+        /* priority class of neighbour cell */
+        prion = ( ncell_info->cr_par.cr_par_1.v_hcs_par ) ? 
+                           ncell_info->cr_par.cr_par_1.hcs_par.gprs_prio_class : 0;
+
+        /* check whether GPRS_TEMPORARY_OFFSET shall be considered */
+        if( (ULONG)( ( ncell_info->cr_par.cr_offset.gprs_penalty_time + 1 ) * 
+            10 * CS_PERIOD_1_SEC ) > grr_data->db.nc_six_strgst[i].avail_time )
+        {
+          h = TRUE;
+        }
+
+        /*
+         * cell ranking and signal threshold criterion for neighbour cell,
+         * subtract GPRS_TEMPORARY_OFFSET 
+         */
+        if( h )
+        {
+          SHORT *criterion;
+
+          if( prios NEQ prion )
+          {
+            criterion = &grr_data->db.nc_six_strgst[i].cr_crit.c31;
+          }
+          else
+          {
+            criterion = &grr_data->db.nc_six_strgst[i].cr_crit.c32;
+          }
+
+          if( ncell_info->cr_par.cr_offset.gprs_temp_offset EQ
+              GPRS_TEMPORARY_OFFSET_INFINITY                   )
+          {
+            *criterion = CS_SMALLEST_SHORT_VALUE;
+          }
+          else
+          {
+            *criterion -= 10 * ncell_info->cr_par.cr_offset.gprs_temp_offset;
+          }
+        }
+
+        /*
+         * cell ranking and signal threshold criterion for neighbour cell,
+         * subtract RA_RESELECT_HYSTERESIS and/or GPRS_CELL_RESELECT_HYSTERESIS
+         */
+        if( !ncell_info->cr_par.same_ra_scell )
+        {
+          grr_data->db.nc_six_strgst[i].cr_crit.c32 -= 
+                                               2 * psc_db->gen_cell_par.ra_re_hyst;
+        }
+        else if( grr_data->cs.gmm_state NEQ STANDBY_STATE )
+        {
+          grr_data->db.nc_six_strgst[i].cr_crit.c32 -= 
+                                              2 * psc_db->gen_cell_par.gprs_c_hyst;
+      
+          if( psc_db->gen_cell_par.c31_hyst )
+          {
+            grr_data->db.nc_six_strgst[i].cr_crit.c31 -= 
+                                              2 * psc_db->gen_cell_par.gprs_c_hyst;
+          }
+        }
+    
+        /*
+         * in case a cell re-selection occured within the
+         * previous 15 seconds, subtract 5 dB
+         */
+        if(grr_t_status( T15_SEC_CC ) > 0)
+        {
+          grr_data->db.nc_six_strgst[i].cr_crit.c32 -= 5;
+        }
+      }
+      else
+      {
+        grr_data->db.nc_six_strgst[i].cr_crit.c1  = -2;
+        grr_data->db.nc_six_strgst[i].cr_crit.c31 = -2;
+        grr_data->db.nc_six_strgst[i].cr_crit.c32 = -2;
+      }
+    }
+    else
+    {
+      grr_data->db.nc_six_strgst[i].cr_crit.c1  = -1;
+      grr_data->db.nc_six_strgst[i].cr_crit.c31 = -1;
+      grr_data->db.nc_six_strgst[i].cr_crit.c32 = -1;
+    }
+  }
+
+  /*
+   * calculate the correct neighbour cell for adding positive
+   * GPRS_RESELECT_OFFSET values to C32 in case C32_QUAL is set
+   */
+  if( psc_db->gen_cell_par.c32_qual EQ TRUE )
+  {
+    /*
+     * check whether priorized cell re-selection should be performed
+     */
+    for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
+    {
+      if( grr_data->db.nc_six_strgst[i].cr_crit.c31 >= 0 )
+      {
+        prio_cr = TRUE;
+      }
+    }
+
+    if( grr_data->db.scell_info.cr_crit.c31 >= 0 )
+    {
+      prio_cr = TRUE;
+    }
+
+    /* find out the strongest neighbour cell */
+    for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
+    {
+      if( ( prio_cr AND grr_data->db.nc_six_strgst[i].cr_crit.c31 >= 0 ) OR 
+          ( !prio_cr )                                                      )
+      {
+        if( strgst EQ 0xFF                                                                        OR
+            grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].rla_p.lev      >
+            grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[strgst].idx].rla_p.lev      )
+        {
+          strgst = i;
+        }
+      }
+    }
+
+    if( strgst NEQ 0xFF )
+    {
+      nc_mval = &grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[strgst].idx];
+
+      if( nc_mval->sync_info.sync.status EQ STAT_SYNC_OK )
+      {
+        ncell_info = 
+          grr_get_ncell_info( nc_mval->arfcn, nc_mval->sync_info.bsic );
+
+        if( ncell_info NEQ NULL )
+        {
+          /*
+           * if the parameter C32_QUAL is set, positive GPRS_RESELECT_OFFSET values
+           * shall only be applied to the neighbour cell with the highest RLA_P value
+           * of those cells for which C32 is compared.
+           *
+           * calculation part 2
+           */
+      
+          if( p_res_off[ncell_info->cr_par.gprs_resel_off] > 0 )
+          {
+            grr_data->db.nc_six_strgst[strgst].cr_crit.c32 +=
+                                      p_res_off[ncell_info->cr_par.gprs_resel_off];
+          }
+        }
+      }
+    }
+  }
+
+  /*
+   * perform some tracing
+   */
+
+#if !defined (NTRACE)
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    /* trace the C1 criterion */
+    for( i = grr_data->db.cnt_nc_six.strgst; i < CS_MAX_STRONG_CARRIER; i++ )
+    {
+      grr_data->db.nc_six_strgst[i].cr_crit.c1 = 0;
+    }
+
+     TRACE_EVENT_P7
+    (
+      "C1   : %6d %6d %6d %6d %6d %6d %6d",
+      grr_data->db.scell_info.cr_crit.c1,
+      grr_data->db.nc_six_strgst[0].cr_crit.c1,
+      grr_data->db.nc_six_strgst[1].cr_crit.c1,
+      grr_data->db.nc_six_strgst[2].cr_crit.c1,
+      grr_data->db.nc_six_strgst[3].cr_crit.c1,
+      grr_data->db.nc_six_strgst[4].cr_crit.c1,
+      grr_data->db.nc_six_strgst[5].cr_crit.c1
+    );
+
+    /* trace the C31 criterion */
+    for( i = grr_data->db.cnt_nc_six.strgst; i < CS_MAX_STRONG_CARRIER; i++ )
+    {
+      grr_data->db.nc_six_strgst[i].cr_crit.c31 = 0;
+    }
+
+    TRACE_EVENT_P7
+    (
+      "C31  : %6d %6d %6d %6d %6d %6d %6d",
+
+        grr_data->db.scell_info.cr_crit.c31,
+        grr_data->db.nc_six_strgst[0].cr_crit.c31, 
+        grr_data->db.nc_six_strgst[1].cr_crit.c31,
+        grr_data->db.nc_six_strgst[2].cr_crit.c31, 
+        grr_data->db.nc_six_strgst[3].cr_crit.c31,
+        grr_data->db.nc_six_strgst[4].cr_crit.c31, 
+        grr_data->db.nc_six_strgst[5].cr_crit.c31
+      );
+
+    /* trace the C32 criterion */
+    for( i = grr_data->db.cnt_nc_six.strgst; i < CS_MAX_STRONG_CARRIER; i++ )
+    {
+      grr_data->db.nc_six_strgst[i].cr_crit.c32 = 0;
+    }
+
+    TRACE_EVENT_P7
+      ( 
+        "C32  : %6d %6d %6d %6d %6d %6d %6d",
+        grr_data->db.scell_info.cr_crit.c32,
+        grr_data->db.nc_six_strgst[0].cr_crit.c32, 
+        grr_data->db.nc_six_strgst[1].cr_crit.c32,
+        grr_data->db.nc_six_strgst[2].cr_crit.c32, 
+        grr_data->db.nc_six_strgst[3].cr_crit.c32,
+        grr_data->db.nc_six_strgst[4].cr_crit.c32, 
+        grr_data->db.nc_six_strgst[5].cr_crit.c32
+      );
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+} /* cs_calc_params() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_store_meas_values
++------------------------------------------------------------------------------
+| Description : The function cs_store_meas_values() saves the received
+|               rla_p values in the grr database
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_store_meas_values ( void )
+{
+  UBYTE   i, j; /* used for counting */
+
+  USHORT  arfcn;
+
+  T_rla_p rla_p;
+
+  TRACE_FUNCTION( "cs_store_meas_values" );
+
+  /*
+   * store the first value as serving cell
+   */
+  grr_data->db.scell_info.rla_p.stat =
+                            cs_get_rla_p( &nc_data->cell[0].rla_p_data, 
+                                          &grr_data->db.scell_info.rla_p.lev );
+
+  if( grr_data->db.scell_info.rla_p.stat NEQ CS_RLA_P_NOT_AVAIL )
+  {
+#ifdef FF_PS_RSSI
+    RX_SetValue( grr_data->db.scell_info.rla_p.lev,
+                 RX_QUAL_UNAVAILABLE,
+                 psc_db->scell_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min);
+#else
+    RX_SetValue( grr_data->db.scell_info.rla_p.lev );
+#endif
+  }
+
+  /*
+   * store the next values as neighbour cells
+   */
+  for( j = 1; j < nc_data->c_cell; j++ )
+  { 
+    i          = 0;
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+    arfcn      = nc_data->cell[j].arfcn;
+#else
+    arfcn      = grr_l1_arfcn_to_g23( nc_data->cell[j].arfcn );
+#endif
+    rla_p.stat = cs_get_rla_p( &nc_data->cell[j].rla_p_data, &rla_p.lev );
+
+    while( i                                          <   MAX_NR_OF_NC_MVAL AND
+           grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ arfcn                 )
+
+    {
+      i++;
+    }
+    
+    if( i < MAX_NR_OF_NC_MVAL )
+    {
+      grr_data->db.nc_mval_list.nc_mval[i].rla_p = rla_p;
+    }
+  }
+} /* cs_store_meas_values() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_store_rxlev_values
++------------------------------------------------------------------------------
+| Description : The function cs_store_rxlev_values()
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_store_rxlev_values ( void )
+{
+  UBYTE  i, j; /* used for counting */
+
+  USHORT  arfcn;
+
+  TRACE_FUNCTION( "cs_store_rxlev_values" );
+
+  /*
+   * store the first value as serving cell
+   */
+  grr_data->db.scell_info.rxlev_avg = 
+                              cs_get_rxlev_avg( &nc_data->cell[0].rxlev_data );
+
+  /*
+   * store the next values as neighbour cells
+   */
+  for( j = 1; j < nc_data->c_cell; j++ )
+  { 
+    i     = 0;
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+    arfcn      = nc_data->cell[j].arfcn;
+#else
+    arfcn      = grr_l1_arfcn_to_g23( nc_data->cell[j].arfcn );
+#endif
+
+    while( i                                          <   MAX_NR_OF_NC_MVAL AND
+           grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ arfcn                 )
+
+    {
+      i++;
+    }
+    
+    if( i < MAX_NR_OF_NC_MVAL )
+    {
+      grr_data->db.nc_mval_list.nc_mval[i].rxlev_avg = 
+                              cs_get_rxlev_avg( &nc_data->cell[j].rxlev_data );
+    }
+  }
+} /* cs_store_rxlev_values() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_find_strongest
++------------------------------------------------------------------------------
+| Description : The function cs_find_strongest() finds out the six strongest
+|               neighbour cells and stores their indices in an array.
+|
+| Parameters  : cnt_strgst - number of strongest carriers
+|               cnt_candid - number of strongest plus candidate carriers
+|               index      - index of carriers
+|               status     - status of carriers
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_find_strongest ( ULONG fn_offset )
+{
+  UBYTE cnt_strgst;
+  UBYTE cnt_candid;
+  UBYTE index[CS_MAX_STRONG_CARRIER];
+
+  UBYTE max_nc_excl_sc_band = 0; /* maximum number of reported neighbour */
+                                 /* cells that should be not in the band */
+                                 /* of the serving cell                  */
+
+  TRACE_FUNCTION( "cs_find_strongest" );
+  
+#ifdef TI_PS_FF_QUAD_BAND_SUPPORT
+  if( CHECK_DUAL_BANDS EQ TRUE)
+#else
+  if( std EQ STD_DUAL OR std EQ STD_DUAL_EGSM OR std EQ STD_DUAL_US )
+#endif
+  {
+    switch( psc_db->scell_par.multi_band_rep )
+    {
+      case GRR_MULTIBAND_REPORTING_1: max_nc_excl_sc_band = 1; break;
+      case GRR_MULTIBAND_REPORTING_2: max_nc_excl_sc_band = 2; break;
+      case GRR_MULTIBAND_REPORTING_3: max_nc_excl_sc_band = 3; break;
+      default                       : max_nc_excl_sc_band = 0; break;
+    }
+  }
+
+  /*
+   * look for strongest neighbour cells with a valid RLA_P value,
+   * these are used for cell re-selection only
+   */
+  cnt_strgst = 0;
+
+  cs_consider_multiband
+    ( &cnt_strgst, index, CS_RLA_P_VALID, max_nc_excl_sc_band );
+
+  /*
+   * look for strongest neighbour cells with a RLA_P which is not valid
+   * but available and add them to the remaining storage areas in the list
+   * of strongest neighbour cells, these are used for checking the BSIC
+   * in advance, these cells may become a valid RLA_P value soon
+   */
+  cnt_candid = cnt_strgst;
+
+  if( cnt_candid < CS_MAX_STRONG_CARRIER )
+  {
+    cs_consider_multiband
+      ( &cnt_candid, index, CS_RLA_P_NOT_VALID, max_nc_excl_sc_band );
+  }
+
+  return(cs_update_strongest( cnt_strgst, cnt_candid, index, fn_offset ));
+} /* cs_find_strongest() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_consider_multiband
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_consider_multiband ( UBYTE *count, 
+                                   UBYTE *index,
+                                   UBYTE  select_status,
+                                   UBYTE  maximum )
+{
+  TRACE_FUNCTION( "cs_consider_multiband" );
+
+  if( maximum NEQ 0 )
+  {
+    /*
+     * A maximum of zero means that normal reporting of the six strongest
+     * cell irrespective of the band used should be performed.
+     *
+     * A maximum greater zero means that multi band reporting should be
+     * performed, so the MS shall report the strongest cells in each of the
+     * frequency bands in the BA list, excluding the frequency band of the 
+     * serving cell. The remaining positions shall be used for reporting of 
+     * the cells in the band of the serving cell.
+     */
+    cs_find_strongest_with_status
+      ( count, index, select_status, maximum, CS_EXCLUDE_SC_BAND );
+
+    cs_find_strongest_with_status
+      ( count, index, select_status, 
+        (UBYTE)( CS_MAX_STRONG_CARRIER - maximum ), CS_ONLY_SC_BAND );
+  }
+
+  if( *count < CS_MAX_STRONG_CARRIER )
+  {
+    cs_find_strongest_with_status
+      ( count, index, select_status,
+        (UBYTE)( CS_MAX_STRONG_CARRIER - *count ), CS_NO_BAND_LIMITATION );
+  }
+} /* cs_consider_multiband() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_find_strongest_with_status
++------------------------------------------------------------------------------
+| Description : The function cs_find_strongest_with_status() finds out the 
+|               six strongest neighbour cells with a specific status and 
+|               stores their indices in an array.
+|
+| Parameters  : count         - number of strongest carriers
+|               index         - index of carriers
+|               status        - status of carriers
+|               select_status - status which should be used for selection
+|
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_find_strongest_with_status ( UBYTE *count, 
+                                           UBYTE *index,
+                                           UBYTE  select_status,
+                                           UBYTE  maximum,
+                                           UBYTE  limitation )
+{
+  UBYTE          strgst_idx;         /* used for counting                       */
+  UBYTE          mval_idx;           /* used for counting                       */
+  UBYTE          k;                  /* used for counting                       */  
+  BOOL           cells_left = TRUE;  /* indicates whether there are more cells  */
+                                     /* which may belong to the strongest       */
+  SHORT          max_rla_p;          /* next maximum RLA_P value                */
+  UBYTE          idx_next_max;       /* index of the cell with the next max.    */
+                                     /* RLA_P value                             */
+  BOOL           one_of_six_flag;    /* indicates whether a cell already        */
+                                     /* belongs to the strongest                */
+  BOOL           limit;              /* indicator for limitation precedence     */
+  BOOL           scell_is_high_band; /* serving cell is in DCS or PCS band      */
+  BOOL           ncell_is_high_band; /* neighbour cell is in DCS or PCS band    */
+  UBYTE          max_found_cell = MINIMUM( *count + maximum, CS_MAX_STRONG_CARRIER );
+                                     /* maximum number of strongest neighbour   */
+                                     /* cells that should be found after        */
+                                     /* leaving this function                   */
+  USHORT         low_channel;
+  USHORT         high_channel;
+  
+  T_NC_MVAL  *nc_mval;
+
+  TRACE_FUNCTION( "cs_find_strongest_with_status" );
+
+#ifdef TI_PS_FF_QUAD_BAND_SUPPORT
+  if( std EQ STD_DUAL_US OR std EQ STD_900_1900 OR 
+      std EQ STD_850_900_1900 )
+#else
+  if( std EQ STD_DUAL_US )
+#endif
+  {
+    low_channel  = LOW_CHANNEL_1900;
+    high_channel = HIGH_CHANNEL_1900;
+  }
+  else
+  {
+    low_channel  = LOW_CHANNEL_1800;
+    high_channel = HIGH_CHANNEL_1800;
+  }
+
+  for( strgst_idx = *count;
+       strgst_idx < max_found_cell AND cells_left;
+       strgst_idx++ )
+  {
+    max_rla_p    = -1;
+    idx_next_max = 0xFF;
+
+    for( mval_idx = 0; mval_idx < MAX_NR_OF_NC_MVAL; mval_idx++  )
+    {
+      nc_mval = &grr_data->db.nc_mval_list.nc_mval[mval_idx];
+      
+      if( nc_mval->status EQ NC_MVAL_STAT_ASSIGNED  )
+      {
+        one_of_six_flag = FALSE;
+
+        for( k = 0; k < *count AND one_of_six_flag EQ FALSE; k++ )
+        {
+          if( mval_idx EQ index[k] )
+          {
+            one_of_six_flag = TRUE;
+          }
+        }
+
+        if( one_of_six_flag     EQ FALSE                    AND
+            nc_mval->rla_p.stat EQ select_status            AND
+
+#ifdef _TARGET_
+            nc_mval->rla_p.lev  >= MIN_RXLEV_FOR_SIX_STRGST AND
+#endif /* #ifdef _TARGET_ */
+
+            nc_mval->rla_p.lev  >  max_rla_p                    )        
+        {
+          switch( limitation )
+          {   
+            default:
+              TRACE_ASSERT( limitation EQ CS_NO_BAND_LIMITATION OR 
+                            limitation EQ CS_EXCLUDE_SC_BAND    OR
+                            limitation EQ CS_ONLY_SC_BAND          );
+            
+              /*lint -fallthrough*/
+              
+              /*
+               * fallthrough statement inserted to pass lint process,
+               * error 644: (Warning -- limit may not have been initialized) 
+               */
+            
+            case( CS_NO_BAND_LIMITATION ):
+              limit = FALSE;
+              break;
+        
+            case( CS_EXCLUDE_SC_BAND ):
+              scell_is_high_band =
+                ( psc_db->pbcch.bcch.arfcn >= low_channel  AND
+                  psc_db->pbcch.bcch.arfcn <= high_channel     );
+
+              ncell_is_high_band =
+                ( nc_mval->arfcn >= low_channel  AND
+                  nc_mval->arfcn <= high_channel     );
+
+               limit = ( scell_is_high_band EQ ncell_is_high_band  );
+              break;
+
+            case( CS_ONLY_SC_BAND ):
+              scell_is_high_band =
+                ( psc_db->pbcch.bcch.arfcn >= low_channel  AND
+                  psc_db->pbcch.bcch.arfcn <= high_channel     );
+
+              ncell_is_high_band = 
+                ( nc_mval->arfcn >= low_channel  AND
+                  nc_mval->arfcn <= high_channel     );
+
+              limit = ( scell_is_high_band NEQ ncell_is_high_band );
+              break;
+          }
+
+          /*
+           * limitation may take precedence,
+           * do not consider neighbour cell in case 
+           */
+          if( limit EQ FALSE )
+          {
+            max_rla_p    = nc_mval->rla_p.lev;
+            idx_next_max = mval_idx;
+          }
+        }
+      }
+    }
+    
+    if( idx_next_max EQ 0xFF )
+    {
+      cells_left = FALSE;
+    }
+    else
+    {
+      index[strgst_idx] = idx_next_max;
+
+      (*count)++;
+    }
+  }
+} /* cs_find_strongest_with_status() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_update_strongest
++------------------------------------------------------------------------------
+| Description : The function cs_update_strongest() updates the list of the 
+|               strongest neighbour cells stored in the database.
+|
+| Parameters  : cnt_strgst - number of strongest carriers
+|               cnt_candid - number of strongest plus candidate carriers
+|               index      - index of carriers
+|               status     - status of carriers
+|               fn_offset  - frame number offset
+|
++------------------------------------------------------------------------------
+*/
+LOCAL BOOL cs_update_strongest ( UBYTE  cnt_strgst,
+                                 UBYTE  cnt_candid,
+                                 UBYTE *index,
+                                 ULONG  fn_offset )
+{
+  UBYTE i, j;          /* used for counting                                  */
+  ULONG avail_time[CS_MAX_STRONG_CARRIER];
+                       /* used to store the times when a cell becomes first  */
+                       /* a cell of the strongest carriers for a possible    */
+                       /* rearrangment of the list of the strongest carriers */
+
+  T_NC_SIX_STRGST *six_strgst;
+  T_NC_SIX_STRGST *six_candid;
+
+  BOOL has_changed = ( grr_data->db.cnt_nc_six.candid NEQ cnt_candid );
+
+
+  TRACE_FUNCTION( "cs_update_strongest" );
+
+  memset( avail_time, 0, sizeof( avail_time ) );
+
+  for( i = 0; i < cnt_candid; i++ )
+  {
+    /*
+     * check whether cell is already inserted in list of strongest carrier 
+     */
+    six_strgst = NULL;
+    six_candid = NULL;
+    j          = 0;    
+    
+    while( j          <  grr_data->db.cnt_nc_six.candid AND 
+           six_strgst EQ NULL                           AND
+           six_candid EQ NULL                               )
+    {
+      six_candid = &grr_data->db.nc_six_strgst[j];
+
+      if( index[i] EQ six_candid->idx )
+      {
+        if( j < grr_data->db.cnt_nc_six.strgst )
+        {
+          six_strgst = six_candid;
+        }
+      }
+      else
+      {
+        six_candid = NULL;
+
+        j++;
+      }
+    }
+
+
+    if( six_strgst NEQ NULL )
+    {      
+      if( six_strgst->avail_time                               <=
+            ( GPRS_PENALTY_TIME_MAX + 1 ) * 10 * CS_PERIOD_1_SEC    )
+      {
+        /*
+         * the time how long the cell is already inserted
+         * is stored up to a limited period
+         */
+        avail_time[i] = six_strgst->avail_time + fn_offset;
+      }
+      else
+      {
+        avail_time[i] = six_strgst->avail_time;
+      }    
+    }
+    else
+    {
+      if( six_candid EQ NULL )
+      {
+        has_changed = TRUE;
+      }
+
+      if( grr_data->db.old_scell.arfcn EQ
+                      grr_data->db.nc_mval_list.nc_mval[index[i]].arfcn           AND
+          grr_data->db.old_scell.bsic  EQ
+                      grr_data->db.nc_mval_list.nc_mval[index[i]].sync_info.bsic           )
+      {
+        /* for the old serving cell timer T shall always set to status expired */
+        avail_time[i] = 
+                  ( ( GPRS_PENALTY_TIME_MAX + 1 ) * 10 * CS_PERIOD_1_SEC ) + 1;
+      }
+
+    }
+  }
+
+  for( i = 0; i < cnt_candid; i++ )
+  {
+    grr_data->db.nc_six_strgst[i].idx        = index[i];
+    grr_data->db.nc_six_strgst[i].avail_time = avail_time[i];
+
+    /*
+     * every time a new list of strongest carriers is build-up 
+     * the parameter mode should be set to CS_MODE_IDLE.
+     */
+    grr_data->db.nc_six_strgst[i].mode = CS_MODE_IDLE;
+  } 
+
+  cs_set_cnt_nc_six( cnt_strgst, cnt_candid );
+
+  /*
+   * perform some tracing
+   */
+
+#if !defined (NTRACE)
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    /* trace the ARFCN */
+    {
+      USHORT arfcn[CS_MAX_STRONG_CARRIER];
+
+      memset( arfcn, RRGRR_INVALID_ARFCN, sizeof( arfcn ) );
+      
+      for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
+      {
+        arfcn[i] =
+          grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].arfcn;
+      }
+
+      TRACE_EVENT_P7
+      (
+        "ARFCN: %6d %6d %6d %6d %6d %6d %6d",
+        psc_db->pbcch.bcch.arfcn,
+        arfcn[0], arfcn[1], arfcn[2], arfcn[3], arfcn[4], arfcn[5]
+      );
+    }
+
+    /* trace the BSIC */
+    {
+      USHORT bsic[CS_MAX_STRONG_CARRIER];
+
+      memset( bsic, RRGRR_INVALID_BSIC, sizeof( bsic ) );
+      
+      for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
+      {
+        bsic[i] =
+          grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].sync_info.bsic;
+      }
+
+      TRACE_EVENT_P7
+      (
+        "BSIC : %6d %6d %6d %6d %6d %6d %6d",
+        psc_db->pbcch.bcch.bsic,
+        bsic[0], bsic[1], bsic[2], bsic[3], bsic[4], bsic[5]
+      );
+    }
+
+    /* trace the RLA_P */
+    {
+      UBYTE rla_p[CS_MAX_STRONG_CARRIER];
+      UBYTE rxlev_avg[CS_MAX_STRONG_CARRIER];
+
+      memset( rla_p, 0, sizeof( rla_p ) );
+      memset( rxlev_avg, 0, sizeof( rxlev_avg ) );
+
+      for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
+      {
+        rla_p[i] = 
+          grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].rla_p.lev;
+
+
+        rxlev_avg[i] = 
+          grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].rxlev_avg;
+
+      }
+
+      TRACE_EVENT_P7
+      ( 
+        "RLA_P: %6d %6d %6d %6d %6d %6d %6d",
+        grr_data->db.scell_info.rla_p.lev,
+        rla_p[0], rla_p[1], rla_p[2], rla_p[3], rla_p[4], rla_p[5]
+      );
+
+      TRACE_EVENT_P7
+      ( 
+        "RXLEV_AVG: %6d %6d %6d %6d %6d %6d %6d",
+        grr_data->db.scell_info.rxlev_avg,
+        rxlev_avg[0], rxlev_avg[1], rxlev_avg[2], rxlev_avg[3], rxlev_avg[4], rxlev_avg[5]
+      );
+
+    }
+
+    /* trace the synchronisation status */
+    {
+      UBYTE sync_stat[CS_MAX_STRONG_CARRIER];
+
+      memset( sync_stat, 0xFF, sizeof( sync_stat ) );
+     
+      for( i = 0; i < grr_data->db.cnt_nc_six.candid; i++ )
+      {
+        sync_stat[i] =
+          grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].sync_info.sync.status;
+      }
+
+      TRACE_EVENT_P6
+      (
+        "SYNC :        %6d %6d %6d %6d %6d %6d",
+        sync_stat[0], sync_stat[1], sync_stat[2],
+        sync_stat[3], sync_stat[4], sync_stat[5]
+      );
+    }
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+  return( has_changed );
+
+} /* cs_update_strongest() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_compare_bsic
++------------------------------------------------------------------------------
+| Description : The function cs_compare_bsic() compares the indicated BSIC
+|               with the stored BSICs
+|
+| Parameters  : rrgrr_check_bsic_ind - pointer to primitive
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_compare_bsic ( T_RRGRR_NCELL_SYNC_IND *rrgrr_check_bsic_ind )
+{
+  UBYTE      i = 0;
+  UBYTE      j;
+  UBYTE      nc_mval_idx;
+  T_NC_MVAL *nc_mval;
+
+    
+  TRACE_FUNCTION( "cs_compare_bsic" );
+
+
+
+  while( i                                          <   RRGRR_MAX_RSLT_NCELL_SYNC_IND AND 
+         rrgrr_check_bsic_ind->sync_result[i].arfcn NEQ RRGRR_INVALID_ARFCN               )
+  {
+    if( ( nc_mval = grr_get_nc_mval(  rrgrr_check_bsic_ind->sync_result[i].arfcn,
+                                      RRGRR_INVALID_BSIC, &nc_mval_idx ) ) NEQ NULL )
+    {
+      switch( rrgrr_check_bsic_ind->sync_result[i].sb_flag )
+      {
+        case( SB_FOUND ):
+          nc_mval->sync_info.bsic                 = rrgrr_check_bsic_ind->sync_result[i].bsic;
+          nc_mval->sync_info.sync.status          = STAT_SYNC_OK;
+          nc_mval->sync_info.sync.sync_failed_cnt = 0;
+          break;
+  
+        case( NO_SB_FOUND ):
+          nc_mval->sync_info.bsic = RRGRR_INVALID_BSIC;
+
+          if( nc_mval->sync_info.sync.sync_failed_cnt EQ MAX_SYNC_FAILED_CNT )
+          {
+            nc_mval->sync_info.sync.status          = STAT_SYNC_NONE;
+            nc_mval->sync_info.sync.sync_failed_cnt = 0;
+
+            j=0;     
+            while( j < grr_data->nc_data.c_cell                   AND 
+                   grr_data->nc_data.cell[j].arfcn    NEQ
+                   nc_mval->arfcn         )
+            {
+              j++;
+            }
+
+            if( j < grr_data->nc_data.c_cell )
+            {
+              cs_reset_meas_result( &grr_data->nc_data.cell[j] );
+            }
+
+          }
+          else
+          {
+            nc_mval->sync_info.sync.status          =  STAT_SYNC_FAILED;
+            nc_mval->sync_info.sync.sync_failed_cnt += 1;
+          }
+          break;
+
+        case( SB_UNKNOWN ):
+          if( nc_mval->status EQ NC_MVAL_STAT_PENDING )
+          {
+            cs_init_nc_mval( nc_mval );
+          }
+          else
+          {
+            nc_mval->sync_info.bsic                 = RRGRR_INVALID_BSIC;
+            nc_mval->sync_info.sync.status          = STAT_SYNC_NONE;
+            nc_mval->sync_info.sync.sync_failed_cnt = 0;
+          }
+          break;
+      }
+    }
+
+    if( nc_mval EQ NULL )
+    {
+      if( ( nc_mval = grr_get_nc_mval( RRGRR_INVALID_ARFCN,
+                                       RRGRR_INVALID_BSIC,
+                                       &nc_mval_idx ) ) NEQ NULL )
+      {
+        switch( rrgrr_check_bsic_ind->sync_result[i].sb_flag )
+        {
+          case( SB_FOUND ):
+            nc_mval->status                         = NC_MVAL_STAT_PENDING;
+            nc_mval->arfcn                          = rrgrr_check_bsic_ind->sync_result[i].arfcn;
+            nc_mval->sync_info.bsic                 = rrgrr_check_bsic_ind->sync_result[i].bsic;
+            nc_mval->sync_info.sync.status          = STAT_SYNC_OK;
+            nc_mval->sync_info.sync.sync_failed_cnt = 0;
+          
+            grr_data->cs.is_mval_initialized        = FALSE;
+            break;
+
+          case( NO_SB_FOUND ):
+            nc_mval->status                         = NC_MVAL_STAT_PENDING;
+            nc_mval->arfcn                          = rrgrr_check_bsic_ind->sync_result[i].arfcn;
+            nc_mval->sync_info.bsic                 = RRGRR_INVALID_BSIC;
+            nc_mval->sync_info.sync.status          = STAT_SYNC_FAILED;
+            nc_mval->sync_info.sync.sync_failed_cnt = 0;
+          
+            grr_data->cs.is_mval_initialized        = FALSE;
+            break;
+
+          case( SB_UNKNOWN ):
+            TRACE_EVENT_P1( "cs_compare_bsic: SB_UNKNOWN for %d which is not on measured values list, e.g. after GRR suspension",
+                            rrgrr_check_bsic_ind->sync_result[i].arfcn );
+            break;
+        }
+      }
+      else
+      {
+        TRACE_EVENT_P1( "cs_compare_bsic: no free entry for measured values found %d",
+                        rrgrr_check_bsic_ind->sync_result[i].arfcn );
+      }
+    }
+
+#ifdef _SIMULATION_
+
+    TRACE_EVENT_P3( "BSIC: %d %d %d",
+                    rrgrr_check_bsic_ind->sync_result[i].arfcn,
+                    rrgrr_check_bsic_ind->sync_result[i].sb_flag,
+                    rrgrr_check_bsic_ind->sync_result[i].bsic );
+
+#endif /* #ifdef _SIMULATION_ */
+
+    i++;
+  }
+
+  cs_trace_nc_mval_lst( );
+
+} /* cs_compare_bsic() */
+
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_best_cell
++------------------------------------------------------------------------------
+| Description : The function cs_get_best_cell() checks the start of
+|               cell reselection.
+|               Is a criterion fulfilled for cell reselction, then reading of
+|               best neighbourcell is started.
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_get_best_cell ( T_NC_SIX_STRGST **nc, T_scell_info **sc )
+{
+  UBYTE            strgst_idx;
+  UBYTE            i;
+  T_NC_SIX_STRGST *next_cell;
+  BOOL             c31_bc;     /* best neighbour cell priorized           */
+  BOOL             c31_nc;     /* next neighbour cell priorized           */
+  BOOL             c31_sc;     /* serving cell priorized                  */
+  T_ncell_info    *ncell_best; /* best neighbour cell                     */
+  T_ncell_info    *ncell_next; /* next neighbour cell                     */
+  T_NC_MVAL       *mval_best;  /* measured values for best neighbour cell */
+  T_NC_MVAL       *mval_next;  /* measured values for next neighbour cell */
+
+  TRACE_FUNCTION( "cs_get_best_cell" );
+
+  /*
+   * start cell reselection if:
+   *
+   * 1. C1 for the serving cell falls below zero: C1 < 0
+   *
+   * 2. A non-serving cell is evaluated to be better than the serving cell.
+   *
+   *    a) The best cell is the cell with the highest value of C32 among those
+   *       cells that have the highest PRIOROTY_CLASS among those that fulfill
+   *       the criterion C31 >= 0.
+   *       
+   *       Interpretation: If C31 is fulfilled, take cells with highest
+   *                       priority and then select the cell with highest
+   *                       C32 value.
+   *
+   *    b) The best cell is the cell with the highest value of C32 among all
+   *       cells if no cell fulfill the criterion C31 >= 0.
+   *
+   *       Interpretation: If C31 is not fulfilled, take the cell with the
+   *                       highest C32 value.
+   *
+   * NOTE: When selecting a neighbour cell to be the new serving cell,
+   *       C1 criterion of that cell shall be taken into account.
+   */
+
+  /*
+   * set default results
+   */
+  *sc        = NULL;
+  *nc        = NULL;
+  mval_best  = NULL;
+  strgst_idx = 0xFF;
+
+  if( grr_data->cs.is_upd_ncell_stat_needed )
+  {
+    TRACE_EVENT( "cs_get_best_cell: is_upd_ncell_stat_needed EQ TRUE" );
+
+    return;
+  }
+
+  if(
+      (
+        grr_data->db.scell_info.rla_p.stat  NEQ CS_RLA_P_VALID
+      )
+      OR
+      (
+        grr_data->db.scell_info.rla_p.stat  EQ  CS_RLA_P_VALID AND
+        grr_data->db.scell_info.cr_crit.c1  >=  0              AND
+        grr_data->db.scell_info.cell_barred EQ  FALSE
+      )
+    )
+  {
+    *sc = &grr_data->db.scell_info;
+  }
+
+  /*
+   * search the best neighbour cell,
+   * this cell should not be used for a cell re-selection attempt before
+   */
+  for( i = 0; 
+       i < grr_data->db.cnt_nc_six.strgst AND *nc EQ NULL;
+       i++ )
+  {
+    *nc        = &grr_data->db.nc_six_strgst[i];
+    mval_best  = &grr_data->db.nc_mval_list.nc_mval[(*nc)->idx];
+    strgst_idx = i;
+
+    if( (*nc)->mode                      NEQ CS_MODE_IDLE OR
+        mval_best->sync_info.sync.status NEQ STAT_SYNC_OK OR
+        (*nc)->cr_crit.c1                <   0               )
+    {
+      *nc        = NULL;
+      mval_best  = NULL;
+      strgst_idx = 0xFF;
+    }
+  }
+
+  /*
+   * if no best neighbour cell was found inform the caller
+   */
+  if( *nc EQ NULL OR mval_best EQ NULL )
+  {
+    return;
+  }
+
+  ncell_best = 
+    grr_get_ncell_info( mval_best->arfcn, mval_best->sync_info.bsic );
+
+  if( ncell_best EQ NULL )
+  {
+    TRACE_EVENT( "cs_get_best_cell: ncell_best EQ NULL" );
+    *nc        = NULL;
+    strgst_idx = 0xFF;
+
+    return;
+  }
+
+  /* 
+   * check whether best neighbour cell is priorized
+   */
+  c31_bc = ( (*nc)->cr_crit.c31                    >= 0    AND
+             ncell_best->cr_par.cr_par_1.v_hcs_par EQ TRUE     );
+
+#if !defined (NTRACE)
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    TRACE_EVENT_P4( "cs_get_best_cell: ncell_best %d %d %d %d",
+                    mval_best->arfcn,
+                    mval_best->sync_info.bsic,
+                    c31_bc,
+                    ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class );
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+  /* 
+   * look for a better neighbour cell 
+   */
+  for( i = 0; i < grr_data->db.cnt_nc_six.strgst; i++ )
+  {
+    next_cell = &grr_data->db.nc_six_strgst[i];
+    mval_next = &grr_data->db.nc_mval_list.nc_mval[next_cell->idx];
+    
+    if( next_cell->mode                  EQ   CS_MODE_IDLE AND
+        next_cell                        NEQ *nc           AND
+        mval_next->sync_info.sync.status EQ   STAT_SYNC_OK AND
+        next_cell->cr_crit.c1            >=   0                )
+    {
+      ncell_next = 
+        grr_get_ncell_info( mval_next->arfcn, mval_next->sync_info.bsic );
+
+      if( ncell_next EQ NULL )
+      {
+        TRACE_EVENT( "cs_get_best_cell: ncell_next EQ NULL" );
+
+        *nc        = NULL;
+        strgst_idx = 0xFF;
+
+        return;
+      }
+
+      /* 
+       * check whether next neighbour cell is priorized
+       */
+      c31_nc = ( next_cell->cr_crit.c31                >= 0    AND
+                 ncell_next->cr_par.cr_par_1.v_hcs_par EQ TRUE     );
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT_P4( "cs_get_best_cell: ncell_next %d %d %d %d",
+                        mval_next->arfcn,
+                        mval_next->sync_info.bsic,
+                        c31_nc,
+                        ncell_next->cr_par.cr_par_1.hcs_par.gprs_prio_class );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+      if( c31_bc AND
+          c31_nc AND
+          (
+            ( ncell_next->cr_par.cr_par_1.hcs_par.gprs_prio_class EQ
+                ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class  AND
+              next_cell->cr_crit.c32 > (*nc)->cr_crit.c32                )
+            OR
+            ( ncell_next->cr_par.cr_par_1.hcs_par.gprs_prio_class >
+                ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class      )
+          )
+        )
+      {
+        /*
+         * priorized cell reselection must be done
+         */
+         *nc        = next_cell;
+         ncell_best = ncell_next;
+         strgst_idx = i;
+      }
+      else if ( !c31_bc )
+      {
+        /*
+         * check whether next neighbour cell is priorized 
+         */
+        if( c31_nc )
+        {
+          /*
+           * first priorized cell found
+           */
+          c31_bc     = TRUE;
+          *nc        = next_cell;
+          ncell_best = ncell_next;
+          strgst_idx = i;
+        }
+        else if ( next_cell->cr_crit.c32 > (*nc)->cr_crit.c32 )
+        {
+          /*
+           * until now, no priorized cell found
+           */
+          *nc        = next_cell;
+          ncell_best = ncell_next;
+          strgst_idx = i;
+        }
+      }
+    }
+  }
+
+  /*
+   * check whether serving cell is priorized 
+   */
+  c31_sc = ( grr_data->db.scell_info.cr_crit.c31  >= 0    AND
+             psc_db->scell_par.cr_par_1.v_hcs_par EQ TRUE     );
+
+#if !defined (NTRACE)
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    TRACE_EVENT_P3( "cs_get_best_cell: scell %d %d %d",
+                    *sc, c31_sc,
+                    psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class );
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+  /*
+   * check whether cell reselection must be done
+   */
+  if( 
+      (
+        *sc EQ NULL
+      )
+      OR
+      (
+        c31_bc AND
+        c31_sc AND
+        (
+          ( ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class EQ
+              psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class     AND
+            (*nc)->cr_crit.c32 > grr_data->db.scell_info.cr_crit.c32     )
+          OR
+          ( ncell_best->cr_par.cr_par_1.hcs_par.gprs_prio_class >
+              psc_db->scell_par.cr_par_1.hcs_par.gprs_prio_class         )
+        )
+      )
+      OR
+      (
+        !c31_bc                                                  AND
+        !c31_sc                                                  AND
+        (*nc)->cr_crit.c32 > grr_data->db.scell_info.cr_crit.c32
+      )
+      OR
+      (
+         c31_bc AND 
+        !c31_sc
+      )
+    )
+  {
+    *sc = NULL;
+  }
+  else
+  {
+    *nc        = NULL;
+    strgst_idx = 0xFF;
+  }
+
+#if !defined (NTRACE)
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    TRACE_EVENT_P3( "cs_get_best_cell: strong/candid %d %d %d",
+                    grr_data->db.cnt_nc_six.strgst,
+                    grr_data->db.cnt_nc_six.candid,
+                    strgst_idx );
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+} /* cs_get_best_cell() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_network_ctrl_order
++------------------------------------------------------------------------------
+| Description : The NETWORK_CONTROL_ORDER values NC1 and NC2 shall only apply
+|               in Ready state. In Standby state, the MS shall always use 
+|               normal MS control independent of the ordered NC mode.
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL T_NC_ORDER cs_get_network_ctrl_order ( BOOL consider_gmm_state )
+{
+  T_NC_ORDER ctrl_order = NC_NC0;
+
+  TRACE_FUNCTION( "cs_get_network_ctrl_order" );
+
+  if( grr_data->nc2_on )
+  { 
+    if(
+        (
+          (
+            consider_gmm_state     EQ TRUE        AND
+            grr_data->cs.gmm_state EQ READY_STATE 
+          ) 
+          OR
+          (
+            consider_gmm_state     EQ FALSE
+          )
+        )
+        AND
+        (
+          grr_data->db.nc_ref_lst.param NEQ NULL 
+        )
+      )
+    {
+      ctrl_order = grr_data->db.nc_ref_lst.param->ctrl_order;
+    }
+  }
+
+#ifdef _SIMULATION_
+
+  TRACE_EVENT_P2( "NETWORK_CONTROL_ORDER: %d, GMM_STATE: %d",
+                  grr_data->db.nc_ref_lst.param EQ NULL ?
+                    ctrl_order : grr_data->db.nc_ref_lst.param->ctrl_order,
+                  grr_data->cs.gmm_state );
+
+#endif /* #ifdef _SIMULATION_ */
+
+  return( ctrl_order );
+
+} /* cs_get_network_ctrl_order() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reset_nc_change_mark
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_reset_nc_change_mark ( T_SC_DATABASE *db )
+{
+  TRACE_FUNCTION( "cs_reset_nc_change_mark" );
+
+  db->nc_cw.list.chng_mrk.curr         = 0;
+  db->nc_cw.list.chng_mrk.prev         = 0;
+  db->nc_cw.param.chng_mrk.curr        = 0;
+  db->nc_cw.param.chng_mrk.prev        = 0;
+  db->nc_ms.ncmeas.list.chng_mrk.curr  = 0;
+  db->nc_ms.ncmeas.list.chng_mrk.prev  = 0;
+  db->nc_ms.ncmeas.param.chng_mrk.curr = 0;
+  db->nc_ms.ncmeas.param.chng_mrk.prev = 0;
+
+} /* cs_reset_nc_change_mark() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_cr_meas_mode
++------------------------------------------------------------------------------
+| Description : The function cs_get_cr_meas_mode() returns the cell
+|               re-selection measurement mode used in context of TBF 
+|               establishment.
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL UBYTE cs_get_cr_meas_mode ( void )
+{
+  TRACE_FUNCTION( "cs_get_cr_meas_mode" );
+
+  return( grr_is_pbcch_present() ? CS_CRMM_BA_GPRS : CS_CRMM_BA_BCCH );
+} /* cs_get_cr_meas_mode() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_send_cr_meas_req
++------------------------------------------------------------------------------
+| Description : The function cs_send_cr_meas_req() sends the cell reselection
+|               measurement request to L1 (MPHP_CR_MEAS_REQ)
+|
+| Parameters  : dummy - description of parameter dummy
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_send_cr_meas_req ( UBYTE del_meas_rslt )
+{
+  BOOL           is_pbcch_present = grr_is_pbcch_present( );
+  UBYTE          i, j,number_of_frequencies;
+  BOOL           is_existing;
+  BOOL           v_cs_par[MAX_NR_OF_NCELL];
+  T_NC_ORDER     nc_ord  = cs_get_network_ctrl_order( TRUE );
+  T_NC_REF_LIST *nc_list = &grr_data->db.nc_ref_lst;
+
+  TRACE_FUNCTION( "cs_send_cr_meas_req" );
+
+  {   
+    /*
+     * first value represents the arfcn of the serving cell
+     */
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+    grr_data->nc_data.cell[0].arfcn =  psc_db->pbcch.bcch.arfcn;
+#else
+    grr_data->nc_data.cell[0].arfcn =  grr_g23_arfcn_to_l1( psc_db->pbcch.bcch.arfcn );
+#endif
+    number_of_frequencies           = 1;
+    
+    memset( v_cs_par, ( is_pbcch_present ? FALSE : TRUE ), sizeof( v_cs_par ) );
+
+    for( i = 0; i < nc_list->number; i++ )
+    {
+      if( is_pbcch_present )
+      {
+        v_cs_par[i] |= nc_list->info[i]->v_cr_par;
+      }
+      
+      for( j = i + 1, is_existing = FALSE;
+           j < nc_list->number AND is_existing EQ FALSE; 
+           j++ )
+      {
+        if( nc_list->info[j]->arfcn EQ nc_list->info[i]->arfcn )
+        {
+          is_existing  = TRUE;
+
+          if( is_pbcch_present )
+          {
+            v_cs_par[j] |= nc_list->info[i]->v_cr_par;
+          }
+        }
+      }
+
+      if( !is_existing                                                  AND
+          ( nc_ord EQ NC_NC2 OR ( nc_ord NEQ NC_NC2 AND v_cs_par[i] ) )     )
+      {
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+        grr_data->nc_data.cell[number_of_frequencies].arfcn = nc_list->info[i]->arfcn;
+#else
+        grr_data->nc_data.cell[number_of_frequencies].arfcn = 
+            grr_g23_arfcn_to_l1( nc_list->info[i]->arfcn );
+#endif
+        number_of_frequencies++;
+      }
+    } 
+         
+    if( del_meas_rslt EQ CS_DELETE_MEAS_RSLT )
+    {
+      cs_reuse_old_cell_rxlev( );
+    }
+    grr_data->nc_data.c_cell = number_of_frequencies;
+    cs_req_cr_meas( );
+  }
+} /* cs_send_cr_meas_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_send_cr_meas_stop_req
++------------------------------------------------------------------------------
+| Description : The function cs_send_cr_meas_stop_req() sends the cell
+|               reselection measurement stop request to L1
+|               (MPHP_CR_MEAS_STOP_REQ)
+|
+| Parameters  : dummy - description of parameter dummy
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_send_cr_meas_stop_req ( void )
+{
+  TRACE_FUNCTION( "cs_send_cr_meas_stop_req" );
+
+
+  grr_data->nc_data.c_cell   = 0;
+  grr_data->cs.cr_meas_mode  = cs_get_cr_meas_mode( );
+  cs_stop_cr_meas( );
+
+} /* cs_send_cr_meas_stop_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_send_update_ba_req
++------------------------------------------------------------------------------
+| Description : The function cs_send_update_ba_req() updates the BA(BCCH) list
+|               by passing the lists of added and removed frequencies.
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_send_update_ba_req ( T_SC_DATABASE *db )
+{
+  UBYTE            i, j;     /* used for counting */
+  BOOL             is_found;
+  T_add_freq_list *afreq;
+  T_ncell_info    *ncinfo;
+  T_NC_ORDER       ctrl_order = cs_get_network_ctrl_order( FALSE );
+
+  TRACE_FUNCTION( "cs_send_update_ba_req" );
+
+  {
+    PALLOC( rrgrr_upd_ba_req, RRGRR_UPDATE_BA_REQ );
+
+    /* process cell type */
+    rrgrr_upd_ba_req->cell_type = SYNC_SCELL;
+
+    /* process NC mode */
+    switch( ctrl_order )
+    {
+      case NC_NC2:   rrgrr_upd_ba_req->nc_mode = NC2_USED;     break;
+      case NC_RESET: rrgrr_upd_ba_req->nc_mode = NC_RESET;     break;
+      default    :   rrgrr_upd_ba_req->nc_mode = NC2_NOT_USED; break;
+    }
+
+    /* process list of removed frequencies */
+    if( db->nc_ms.rfreq.number > RRGRR_BA_LIST_SIZE )
+    {
+      TRACE_ERROR ( "Number of removed frequencies > RRGRR_BA_LIST_SIZE" );
+    }
+
+    i = 0;
+    while( i < db->nc_ms.rfreq.number AND i < RRGRR_BA_LIST_SIZE )
+    {
+      j        = 0;
+      is_found = FALSE;
+      while( j < db->nc_cw.list.number AND is_found EQ FALSE )
+      {
+        if( db->nc_cw.list.info[j].index EQ db->nc_ms.rfreq.idx[i] )
+        {
+          is_found = TRUE;
+        }
+        else
+        {
+          j++;
+        }
+      }
+
+      if( is_found EQ TRUE )
+      {
+        rrgrr_upd_ba_req->rm_freq_list[i].arfcn = db->nc_cw.list.info[j].arfcn;
+        rrgrr_upd_ba_req->rm_freq_list[i].bsic  = db->nc_cw.list.info[j].bsic;
+      }
+      else
+      {
+        TRACE_ERROR( "Removed frequency cannot be found in nc_cw structure" );
+      }
+
+      i++;
+    }
+
+    if( i < RRGRR_BA_LIST_SIZE )
+    {
+      rrgrr_upd_ba_req->rm_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
+      rrgrr_upd_ba_req->rm_freq_list[i].bsic  = RRGRR_INVALID_BSIC;
+    }
+
+#ifdef _SIMULATION_ 
+
+    i++;
+    while( i < RRGRR_BA_LIST_SIZE )
+    {
+      rrgrr_upd_ba_req->rm_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
+      rrgrr_upd_ba_req->rm_freq_list[i].bsic  = RRGRR_INVALID_BSIC;
+      i++;
+    }
+
+#endif /* #ifdef _SIMULATION_  */
+
+    /* process list of added frequencies */
+    if( db->nc_ms.ncmeas.list.number > RRGRR_BA_LIST_SIZE )
+    {
+      TRACE_ERROR ( "Number of added frequencies > RRGRR_BA_LIST_SIZE" );
+    }
+
+    i = 0;
+    while( i < db->nc_ms.ncmeas.list.number AND i < RRGRR_BA_LIST_SIZE )
+    {
+      afreq        = &rrgrr_upd_ba_req->add_freq_list[i];
+      ncinfo       = &db->nc_ms.ncmeas.list.info[i];
+
+      afreq->arfcn = ncinfo->arfcn;
+      afreq->bsic  = ncinfo->bsic;
+
+      if( ncinfo->v_cr_par EQ TRUE )
+      {
+        afreq->v_cr_par = TRUE;
+
+        afreq->cr_par.cell_bar_access_2       = ncinfo->cr_par.cell_ba;
+        afreq->cr_par.exc_acc                 = ncinfo->cr_par.exc_acc;
+        afreq->cr_par.same_ra_as_serving_cell = ncinfo->cr_par.same_ra_scell;
+        afreq->cr_par.gprs_rxlev_access_min   = ncinfo->cr_par.cr_par_1.cr_pow_par.gprs_rxlev_access_min;
+        afreq->cr_par.gprs_ms_txpwr_max_cch   = ncinfo->cr_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch;
+        afreq->cr_par.gprs_temporary_offset   = ncinfo->cr_par.cr_offset.gprs_temp_offset;
+        afreq->cr_par.gprs_penalty_time       = ncinfo->cr_par.cr_offset.gprs_penalty_time;
+        afreq->cr_par.gprs_reselect_offset    = ncinfo->cr_par.gprs_resel_off;
+        afreq->cr_par.priority_class          = ncinfo->cr_par.cr_par_1.hcs_par.gprs_prio_class;
+        afreq->cr_par.hcs_thr                 = ncinfo->cr_par.cr_par_1.hcs_par.gprs_hcs_thr;
+        afreq->cr_par.si13_location           = SI13_LOC_INVALID;
+        afreq->cr_par.pbcch_location          = PBCCH_LOC_INVALID;
+        afreq->cr_par.psi1_repeat_period      = PSI1_RPT_PRD_INVALID;
+
+        if( ncinfo->cr_par.v_si13_pbcch )
+        {
+          if( ncinfo->cr_par.si13_pbcch.v_si13_location )
+          {
+            afreq->cr_par.si13_location       = ncinfo->cr_par.si13_pbcch.si13_location;
+          }
+          else
+          {
+            afreq->cr_par.pbcch_location      = ncinfo->cr_par.si13_pbcch.pbcch_location;
+            afreq->cr_par.psi1_repeat_period  = ncinfo->cr_par.si13_pbcch.psi1_repeat_period - 1;
+          }
+        }
+      }
+      else
+      {
+        afreq->v_cr_par = FALSE;
+      }
+
+      i++;
+    }
+
+    if( i < RRGRR_BA_LIST_SIZE )
+    {
+      rrgrr_upd_ba_req->add_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
+      rrgrr_upd_ba_req->add_freq_list[i].bsic  = RRGRR_INVALID_BSIC;
+    }
+
+#ifdef _SIMULATION_ 
+
+    i++;
+    while( i < RRGRR_BA_LIST_SIZE )
+    {
+      rrgrr_upd_ba_req->add_freq_list[i].arfcn = RRGRR_INVALID_ARFCN;
+      rrgrr_upd_ba_req->add_freq_list[i].bsic  = RRGRR_INVALID_BSIC;
+      i++;
+    }
+
+#endif /* #ifdef _SIMULATION_  */
+
+    PSEND( hCommRR, rrgrr_upd_ba_req );
+  }
+} /* cs_send_update_ba_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_send_meas_rep_req
++------------------------------------------------------------------------------
+| Description : The function cs_send_meas_rep_req() updates RR with cause 
+|               NC_START_MEAS or NC_REPORT_MEAS or NC_STOP_MEAS.
+|
+| Parameters  : NC_START_MEAS  - start the measurement
+|               NC_REPORT_MEAS - report the measurement
+|               NC_STOP_MEAS   - stop the measurement
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_send_meas_rep_req ( UBYTE cause )
+{
+  TRACE_FUNCTION( "cs_send_meas_rep_req" );
+
+  {
+    PALLOC( rrgrr_meas_rep_req, RRGRR_MEAS_REP_REQ );
+
+    rrgrr_meas_rep_req->meas_cause = grr_data->cs_meas.nc_meas_cause = cause;
+
+    PSEND( hCommRR, rrgrr_meas_rep_req );
+  }
+} /* cs_send_meas_rep_req() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_store_meas_rep_cnf
++------------------------------------------------------------------------------
+| Description : ...
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_store_meas_rep_cnf ( T_RRGRR_MEAS_REP_CNF *rrgrr_meas_rep_cnf )
+{ 
+  UBYTE      i;        /* used for counting */
+  UBYTE      mval_idx;
+  T_NC_MVAL *mval;
+
+  TRACE_FUNCTION( "cs_store_meas_rep_cnf" );
+
+  /*
+   * store the first value as serving cell
+   */
+  grr_data->db.scell_info.rxlev_avg = rrgrr_meas_rep_cnf->meas_res[0].rxlev;
+  
+  /*
+   * store the next values as neighbour cells
+   */
+  cs_init_nc_mval_lst( );
+
+  for( i = 1;
+       i                                     <   RRGRR_MEAS_REP_LIST_SIZE AND 
+       rrgrr_meas_rep_cnf->meas_res[i].arfcn NEQ RRGRR_INVALID_ARFCN;
+       i++ )
+  {
+    mval = grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &mval_idx );
+  
+    if( mval NEQ NULL )
+    {
+      mval->status                = NC_MVAL_STAT_ASSIGNED;
+      mval->arfcn                 = rrgrr_meas_rep_cnf->meas_res[i].arfcn;
+      mval->rla_p.stat            = CS_RLA_P_VALID;
+      mval->rla_p.lev             = 
+      mval->rxlev_avg             = rrgrr_meas_rep_cnf->meas_res[i].rxlev;
+      mval->sync_info.bsic        = rrgrr_meas_rep_cnf->meas_res[i].bsic;
+      mval->sync_info.sync.status = STAT_SYNC_OK;
+
+      grr_data->cs.is_mval_initialized = FALSE;
+    }
+    else
+    {
+      TRACE_EVENT_P2( "No free entry for measured value found: %d %d",
+                      rrgrr_meas_rep_cnf->meas_res[i].arfcn,
+                      rrgrr_meas_rep_cnf->meas_res[i].bsic );
+    }     
+  }
+} /* cs_store_meas_rep_cnf() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_strongest
++------------------------------------------------------------------------------
+| Description : ...
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_build_strongest ( void )
+{
+  UBYTE i;
+  UBYTE count = 0;
+  UBYTE index[CS_MAX_STRONG_CARRIER];
+
+  TRACE_FUNCTION( "cs_build_strongest" );
+
+  cs_find_strongest_with_status
+    ( &count, index, CS_RLA_P_VALID,
+      (UBYTE)( CS_MAX_STRONG_CARRIER - count ), CS_NO_BAND_LIMITATION );
+
+  for( i = 0; i < count; i++ )
+  {
+    grr_data->db.nc_six_strgst[i].idx = index[i];
+  } 
+
+  cs_set_cnt_nc_six( count, count );
+
+} /* cs_build_strongest() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_send_meas_rpt
++------------------------------------------------------------------------------
+| Description : This function ...
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_send_meas_rpt ( BOOL perform_init )
+{
+  BOOL            rpt_snd;
+  T_U_MEAS_REPORT meas_rpt;
+
+  TRACE_FUNCTION( "cs_send_meas_rpt" );
+
+  if( perform_init EQ TRUE )
+  {
+    grr_data->cs_meas.pmr_snd_ref = 0;
+  }
+
+  memset(&meas_rpt, 0, sizeof(T_U_MEAS_REPORT));
+
+  rpt_snd = cs_build_meas_rpt( &meas_rpt );
+
+  if( rpt_snd EQ TRUE )
+  {
+    sig_cs_ctrl_meas_report( &meas_rpt );
+  }
+
+  return( rpt_snd );
+} /* cs_send_meas_rpt() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_start_t_reselect
++------------------------------------------------------------------------------
+| Description : ...
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_start_t_reselect ( void )
+{
+  TRACE_FUNCTION( "cs_start_t_reselect" );
+
+  if( grr_t_status( T_RESELECT ) EQ 0 )
+  {
+    vsi_t_start( GRR_handle, T_RESELECT, T_RESELECT_VALUE );
+
+    TRACE_EVENT( "Timer T_RESELECT started" );
+  }
+} /* cs_start_t_reselect() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_stop_t_reselect
++------------------------------------------------------------------------------
+| Description : ...
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_stop_t_reselect ( void )
+{
+  TRACE_FUNCTION( "cs_stop_t_reselect" );
+
+  if( grr_t_status( T_RESELECT ) NEQ 0 )
+  {
+    vsi_t_stop( GRR_handle, T_RESELECT );
+
+    TRACE_EVENT( "Timer T_RESELECT stopped" );
+  }
+} /* cs_stop_t_reselect() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_process_t3158
++------------------------------------------------------------------------------
+| Description : ...
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_process_t3158 ( void )
+{
+  T_TIME reporting_period;
+  T_TIME time_to_go;
+  BOOL   tmr_3158_rng_le_rp = FALSE;
+
+  TRACE_FUNCTION( "cs_process_t3158" );
+
+  if( cs_is_meas_reporting( ) )
+    /* Implies NC measurement conditions are satisfied. May mean Enhanced 
+       measurement conditions are also satisfied */
+  {
+    switch( grr_data->cs_meas.packet_mode )
+    {
+      case( PACKET_MODE_PIM ):
+      case( PACKET_MODE_PAM ):
+        reporting_period = cs_get_nc_rpt_prd_idle( );
+        break;
+
+      case( PACKET_MODE_PTM ):
+        /*
+         * In packet transfer mode, the reporting period is indicated in 
+         * NC_REPORTING_PERIOD_T.
+         */
+        reporting_period = 
+                    GET_NC_RPT_PRD( grr_data->db.nc_ref_lst.param->rep_per_t );
+        break;
+
+      default:
+        if( GET_STATE( CS ) EQ CS_CR_NETWORK )
+        {
+          /*
+           * In case timer T3158 expires during processing of Packet Cell Change
+           * Order, the timer should be re-started and not stopped at all.
+           */
+          reporting_period = cs_get_nc_rpt_prd_idle( );
+        }
+        else
+        {  
+          reporting_period = 0;
+        }
+        break;
+    }
+
+    time_to_go = grr_t_status( T3158 );
+    
+    if( time_to_go > 0 )
+    {
+      if( time_to_go > reporting_period )
+      {
+        cs_stop_t3158( );
+      
+        if(  grr_is_pbcch_present( ) EQ FALSE      AND
+             grr_data->cs_meas.nc_meas_cause NEQ NC_STOP_MEAS   )
+        {
+           cs_send_meas_rep_req ( NC_STOP_MEAS ); 
+        }
+      }
+      else
+      {
+        tmr_3158_rng_le_rp = TRUE;
+      }
+    }
+
+    if( reporting_period NEQ 0 )     
+    {
+      if( tmr_3158_rng_le_rp EQ FALSE )
+      {
+        cs_reset_all_rxlev_results( );   
+        cs_start_t3158( reporting_period );
+        /* 
+         * Start rx_lev averaging when NC=1 or NC=2 in ALR 
+         */
+        if(  grr_is_pbcch_present( ) EQ FALSE     AND
+             grr_data->cs_meas.nc_meas_cause EQ NC_STOP_MEAS   ) 
+        {
+          cs_send_meas_rep_req ( NC_START_MEAS ) ;
+        }
+      }
+    }
+    else
+    {
+      cs_reset_all_rxlev_results( );
+    }
+  }
+  else
+  {
+    cs_reset_all_rxlev_results( );
+    cs_stop_t3158( );
+    /* 
+     * Stop rx_lev averaging when NC=1 or NC=2 in ALR 
+     */
+    if(  grr_is_pbcch_present( ) EQ FALSE      AND
+         grr_data->cs_meas.nc_meas_cause NEQ NC_STOP_MEAS   )
+    {
+      cs_send_meas_rep_req ( NC_STOP_MEAS ); 
+    }
+  }
+} /* cs_process_t3158() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_start_t3158
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_start_t3158 ( T_TIME time )
+{
+  TRACE_FUNCTION( "cs_start_t3158" );
+
+  vsi_t_start( GRR_handle, T3158, time );
+
+  TRACE_EVENT_P1( "T3158: %d", time );
+
+} /* cs_start_t3158() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_stop_t3158
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_stop_t3158 ( void )
+{
+  TRACE_FUNCTION( "cs_stop_t3158" );
+
+  if( grr_t_status( T3158 ) > 0 )
+  {
+    vsi_t_stop( GRR_handle, T3158 );
+
+    TRACE_EVENT( "T3158 stopped" );
+  }
+} /* cs_stop_t3158() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_cancel_meas_report
++------------------------------------------------------------------------------
+| Description : ...
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_cancel_meas_report ( void )
+{
+  TRACE_FUNCTION( "cs_cancel_meas_report" );
+
+  switch( GET_STATE( CS_MEAS ) )
+  {
+    case CS_MEAS_REP_REQ:
+      SET_STATE( CS_MEAS, CS_NULL );
+      break;
+    case CS_MEAS_PMR_SENDING:
+      sig_cs_ctrl_cancel_meas_report( );
+      break;
+    default:
+      /* do nothing */
+      break;
+  }
+} /* cs_cancel_meas_report() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_nc_ref_list
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : db - pointer to serving cell database
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_build_nc_ref_list ( T_SC_DATABASE *db, BOOL is_dsf )
+{ 
+  TRACE_FUNCTION( "cs_build_nc_ref_list" );
+  
+  cs_init_nc_ref_list( &grr_data->db.nc_ref_lst );
+
+  if( 
+      grr_data->cs.gmm_state EQ READY_STATE AND 
+      is_dsf                 EQ FALSE       AND 
+      (
+        db->nc_ms.ncmeas.param.ctrl_order EQ NC_NC0 OR
+        db->nc_ms.ncmeas.param.ctrl_order EQ NC_NC1 OR
+        db->nc_ms.ncmeas.param.ctrl_order EQ NC_NC2         
+      ) 
+    )
+  {
+    grr_data->db.nc_ref_lst.param = &db->nc_ms.ncmeas.param;
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+    grr_data->db.nc_ref_lst.enh_param = &db->enh_ms;
+#endif
+  }
+  else if( db->nc_cw.param.ctrl_order EQ NC_NC0 OR
+           db->nc_cw.param.ctrl_order EQ NC_NC1 OR
+           db->nc_cw.param.ctrl_order EQ NC_NC2    )
+  {
+    grr_data->db.nc_ref_lst.param = &db->nc_cw.param;
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+    grr_data->db.nc_ref_lst.enh_param = &db->enh_cw;
+#endif
+  }
+
+  cs_build_nc_freq_list( db );
+  cs_reorg_nc_mval_lst( );
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+   if( !grr_is_pbcch_present() AND 
+    grr_data->db.nc_ref_lst.enh_param->rept_type EQ REPORT_TYPE_ENH_REP)
+  {
+    cs_init_ba_bcch_nc_ref_list();
+    cs_build_ba_bcch_nc_freq_list();
+  }
+#endif
+
+}/* cs_build_nc_ref_list */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_init_nc_ref_list
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : list  - pointer to NC measurement pointer list
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_init_nc_ref_list ( T_NC_REF_LIST *list )
+{ 
+  TRACE_FUNCTION( "cs_init_nc_ref_list" );
+  
+  list->number = 0;
+  list->param  = NULL;
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  list->enh_param = NULL;
+#endif
+
+}/* cs_init_nc_ref_list */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_init_nc_mval_lst
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_init_nc_mval_lst ( void )
+{ 
+  UBYTE i;
+
+  TRACE_FUNCTION( "cs_init_nc_mval_lst" );
+  
+  if( grr_data->cs.is_mval_initialized EQ FALSE )
+  {
+    for( i = 0; i < MAX_NR_OF_NC_MVAL; i++ )
+    {
+      cs_init_nc_mval( &grr_data->db.nc_mval_list.nc_mval[i] );
+    }
+
+    grr_data->cs.is_mval_initialized = TRUE;
+  
+#if !defined (NTRACE)
+
+    if( grr_data->cs.v_crp_trace EQ TRUE )
+    {
+      TRACE_EVENT( "cs_init_nc_mval_lst: now initialized" );
+    }
+
+#endif /* #if !defined (NTRACE) */
+
+  }
+  else
+  {
+
+#if !defined (NTRACE)
+
+    if( grr_data->cs.v_crp_trace EQ TRUE )
+    {
+      TRACE_EVENT( "cs_init_nc_mval_lst: already initialized" );
+    }
+
+#endif /* #if !defined (NTRACE) */
+
+  }
+}/* cs_init_nc_mval_lst */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_init_nc_mval
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : mval - pointer to NC measured value
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_init_nc_mval ( T_NC_MVAL *mval )
+{ 
+  TRACE_FUNCTION( "cs_init_nc_mval" );
+  
+  mval->arfcn                          = RRGRR_INVALID_ARFCN;
+  mval->sync_info.bsic                 = RRGRR_INVALID_BSIC;
+  mval->sync_info.sync.status          = STAT_SYNC_NONE;
+  mval->sync_info.sync.sync_failed_cnt = 0;
+  mval->rla_p.stat                     = CS_RLA_P_NOT_AVAIL;
+  mval->rxlev_avg                      = RXLEV_AVG_INVALID;
+  mval->status                         = NC_MVAL_STAT_NONE;
+}/* cs_init_nc_mval */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_update_bsic
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_update_bsic ( void )
+{ 
+  UBYTE i 
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+        ,j, k
+#endif
+        ;
+        /* used for counting */
+#if defined (TI_PS_FF_RTD) AND defined (REL99)
+  UBYTE i_max,rtd_index,rtd_count;
+#else 
+  UBYTE i_max;
+#endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+
+
+  TRACE_FUNCTION( "cs_update_bsic" );
+
+  i     = 0;
+  i_max = MINIMUM( grr_data->db.cnt_nc_six.candid, CS_MAX_STRONG_CARRIER );
+  i_max = MINIMUM( i_max, RRGRR_MAX_ARFCN_NCELL_SYNC_REQ );
+
+  if( i_max NEQ 0 )
+  {
+    PALLOC( rrgrr_check_bsic_req, RRGRR_NCELL_SYNC_REQ );
+
+    while( i < i_max )
+    {
+#if defined (TI_PS_FF_RTD) AND defined (REL99)
+      rrgrr_check_bsic_req->ncell_sync_list[i].arfcn = grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].arfcn;   
+#else 
+      rrgrr_check_bsic_req->arfcn[i] = grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[i].idx].arfcn;
+#endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+
+
+      i++;
+    }
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+  /* Extend the ARFCN list only if ENH reporting is requested */
+  if(cs_is_enh_meas_reporting())
+  {
+    T_ENH_STRNG_ARFCN_LIST f_bin;/* Stores the ARFCN-RXLEV pair in descending
+                                    order of RXLEV */
+    BOOL found; /* Will be set, if ARFCN in f_bin is found in NC_MVAL */
+
+    memset(&f_bin, 0, sizeof(T_ENH_STRNG_ARFCN_LIST));
+
+    /* Form a ARFCN-RXLEV pair list in descending order of RXLEV */
+    cs_build_enh_sorted_strng_arfcn_list(&f_bin);
+    
+    /* Fill the NCELL_SYNC_REQ with ARFCNs from the above list. This list
+       will be filled without disturbing the six strongest cells for
+       cell reselection or PMR. The request for SYNC is now done for a
+       max of 12 cells with 1st few cells upto a max of six for cell
+       reselection and the remaining will be filled with ARFCNs from
+       the ENH list in the order of serving band, multiband and the rest
+       contains the excess from the above bands, each group containing
+       cells in descending order of RXLEV */
+    j = 0;
+    while(i_max < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ AND j < f_bin.num)
+    {
+      found = FALSE;
+      for(k = 0; k < grr_data->db.cnt_nc_six.candid; k++)
+      {
+        if(f_bin.meas[j].arfcn EQ 
+          grr_data->db.nc_mval_list.nc_mval[grr_data->db.nc_six_strgst[k].idx].arfcn)
+        {
+          found = TRUE;
+          break;
+        }
+      }
+      
+      if(!found)
+      {
+#if defined (TI_PS_FF_RTD) AND defined (REL99)
+          rrgrr_check_bsic_req->ncell_sync_list[i_max].arfcn = f_bin.meas[j].arfcn;
+#else 
+          rrgrr_check_bsic_req->arfcn[i_max] = f_bin.meas[j].arfcn;
+#endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+
+        i_max++;
+      }
+      j++;
+    }
+  }
+  
+  if( i_max < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
+  {
+#if defined (TI_PS_FF_RTD) AND defined (REL99)
+      rrgrr_check_bsic_req->ncell_sync_list[i_max].arfcn = RRGRR_INVALID_ARFCN;
+#else 
+      rrgrr_check_bsic_req->arfcn[i_max] = RRGRR_INVALID_ARFCN;
+#endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+    } /*if*/
+#if defined (TI_PS_FF_RTD) AND defined (REL99)
+    i=0;
+    while (i < i_max)
+    {
+      j = 0;
+      rtd_count = 0;
+      /*More than 3 RTD values is not acceptable */
+      while( j < grr_data->db.nc_ref_lst.number AND rtd_count < MAX_NUM_OF_RTD_VALUES )
+      {
+        /* Check the NC ARFCN in the BA-list to get the index of that ARFCN in BA-list*/
+        if(rrgrr_check_bsic_req->ncell_sync_list[i].arfcn EQ (grr_data->db.nc_ref_lst.info[j])->arfcn)
+        {
+          /* Pickup the right RTD value for that ARFCN */
+          rtd_index = (grr_data->db.nc_ref_lst.info[j])->index;
+          /*Maximum number of ncell is 32 if it exceeds then store RTD_NOT_AVAILABLE for that ARFCN*/
+          if(rtd_index < MAX_NR_OF_NCELL AND psc_db->rtd[rtd_index] NEQ RTD_NOT_AVAILABLE )
+          {
+            rrgrr_check_bsic_req->ncell_sync_list[i].v_rtd          = 1;
+            rrgrr_check_bsic_req->ncell_sync_list[i].rtd[rtd_count] = psc_db->rtd[rtd_index];
+            rtd_count++;
+          }/*if*/
+        } /*if*/
+        j++;
+      } /*while*/
+      rrgrr_check_bsic_req->ncell_sync_list[i].c_rtd = rtd_count;
+      i++;
+    } /*while*/
+#endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+
+
+#ifdef _SIMULATION_
+
+  i_max = i_max + 1;
+  while( i_max < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
+  {
+#if defined (TI_PS_FF_RTD) AND defined (REL99)
+      rrgrr_check_bsic_req->ncell_sync_list[i_max].arfcn = RRGRR_INVALID_ARFCN;
+#else 
+      rrgrr_check_bsic_req->arfcn[i_max] = RRGRR_INVALID_ARFCN;
+#endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+
+    i_max++;
+  }
+#endif
+#else
+
+    if( i < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
+    {
+      rrgrr_check_bsic_req->arfcn[i] = RRGRR_INVALID_ARFCN;
+    }
+
+#ifdef _SIMULATION_
+
+    i = i + 1;
+    while( i < RRGRR_MAX_ARFCN_NCELL_SYNC_REQ )
+    {
+      rrgrr_check_bsic_req->arfcn[i] = RRGRR_INVALID_ARFCN;
+      i++;
+    }
+
+#endif /* #ifdef _SIMULATION_ */
+
+#endif /* REL99 AND TI_PS_FF_EMR */
+
+    rrgrr_check_bsic_req->sync_type = SYNC_INITIAL;
+    PSEND( hCommRR, rrgrr_check_bsic_req );
+  }
+}/* cs_update_bsic */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_find_candidate
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_find_candidate ( void )
+{ 
+  BOOL          is_new_candidate = FALSE;
+  T_scell_info *sc;
+
+  TRACE_FUNCTION( "cs_find_candidate" );
+
+  if( grr_data->cs.reselect_cause   EQ CS_RESELECT_CAUSE_CTRL_ABNORMAL AND
+      psc_db->gen_cell_par.rab_acc_re EQ GRR_RA_RETRY_DISABLED               )
+  {
+    grr_data->db.cr_cell = NULL;
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT( "no candidate found, RA retry bit for abnormal cell re-selection not set" );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+  }
+  else if( grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_SCELL )
+  {
+    if( cs_create_cr_cell( psc_db->pbcch.bcch.arfcn, 
+                           psc_db->pbcch.bcch.bsic ) NEQ NULL )
+    {
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT( "serving cell found as candidate" );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+      /*
+       * the cell re-selection process will be started
+       */
+      is_new_candidate = TRUE;
+    }
+  }
+  else
+  {
+    cs_get_best_cell( &grr_data->db.cr_cell, &sc );
+
+    if( grr_data->db.cr_cell NEQ NULL )
+    {
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT( "candidate found" );
+      }
+
+#endif /* #if !defined (NTRACE) */
+  
+      /*
+       * the cell re-selection process will be started
+       */
+      is_new_candidate = TRUE;
+    }
+    else if( sc NEQ NULL )
+    {
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT( "no candidate found, serving cell good" );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+      /*
+       * the serving cell becomes good again or is still good
+       */
+      cs_stop_t_reselect( );
+    }
+    else
+    {
+
+#if !defined (NTRACE)
+
+      if( grr_data->cs.v_crp_trace EQ TRUE )
+      {
+        TRACE_EVENT( "no candidate found, serving cell bad" );
+      }
+
+#endif /* #if !defined (NTRACE) */
+
+      /*
+       * the serving cell becomes bad but 
+       * no suitable neighbour cell is available
+       */
+      cs_start_t_reselect( );
+    }
+  }
+
+  return( is_new_candidate );
+}/* cs_find_candidate */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_cr_decision
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : 
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_cr_decision ( T_CRDM mode )
+{ 
+  T_NC_ORDER ctrl_order; 
+  BOOL       cr_initiated = FALSE;
+
+  TRACE_FUNCTION( "cs_cr_decision" );
+
+  switch( mode )
+  {
+    case( CRDM_T_RESELECT ):
+      sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
+    
+      cr_initiated = TRUE;
+      break;
+
+    case( CRDM_CR_CTRL ):
+      ctrl_order = cs_get_network_ctrl_order( TRUE );
+
+      if( ctrl_order                  EQ NC_NC0                       OR
+          ctrl_order                  EQ NC_NC1                       OR
+          grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_SCELL            OR 
+          ( grr_data->cs.reselect_cause EQ CS_RESELECT_CAUSE_CTRL_DL_SIG_FAIL    AND 
+            ctrl_order                  EQ NC_NC2 ) )
+      {
+        /*
+         * Only in case the NETWORK_CONTROL_ORDER is either equal to
+         * NC0 or NC1 the MS shall perform automomous cell re-selection
+         */
+
+        if( cs_find_candidate( ) )
+        {
+          sig_cs_ctrl_new_candidate( grr_data->cs.reselect_cause );
+        }
+        else
+        {
+          sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
+        }
+      }
+      else
+      {
+        sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
+      }
+      
+      cr_initiated = TRUE;
+      break;
+
+    case( CRDM_CR_INITIAL ):
+      ctrl_order = cs_get_network_ctrl_order( TRUE );
+
+      if( ctrl_order EQ NC_NC0 OR ctrl_order EQ NC_NC1 )
+      {
+        /*
+         * Only in case the NETWORK_CONTROL_ORDER is either equal to
+         * NC0 or NC1 the MS shall perform automomous cell re-selection
+         */
+    
+        grr_data->db.cr_cell = NULL;
+
+        cs_calc_params( );
+
+        if( cs_find_candidate( ) )
+        {
+          sig_cs_ctrl_new_candidate( grr_data->cs.reselect_cause );
+
+          cr_initiated = TRUE;
+        }
+      }
+      break;
+
+    case( CRDM_CR_CONT ):
+      if( cs_find_candidate( ) )
+      {
+        sig_cs_ctrl_new_candidate( grr_data->cs.reselect_cause );
+      }
+      else
+      {
+        sig_cs_ctrl_no_more_candidate( grr_data->cs.reselect_cause );
+      }
+      
+      cr_initiated = TRUE;
+      break;
+
+    default:
+      TRACE_ASSERT( mode EQ CRDM_T_RESELECT OR 
+                    mode EQ CRDM_CR_CTRL    OR
+                    mode EQ CRDM_CR_INITIAL OR
+                    mode EQ CRDM_CR_CONT       );
+      break;  
+  }
+
+  if( cr_initiated EQ TRUE )
+  {
+    TRACE_EVENT_P2( "cs_cr_decision: mode %d, reselect_cause %d",
+                    mode, grr_data->cs.reselect_cause );
+  }
+
+  return( cr_initiated );
+
+}/* cs_cr_decision */
+
+
+
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_trace_nc_mval_lst
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_trace_nc_mval_lst ( void )
+{
+
+#if !defined (NTRACE)
+
+  UBYTE            read, write;
+  USHORT           arfcn[8];
+  UBYTE            bsic[8];
+  T_NC_MVAL_STATUS status[8];
+  T_RXLEV_AVG      rxlev_avg[8];
+  UBYTE            rla_p_lev[8];
+  UBYTE            rla_p_stat[8];
+
+
+  TRACE_FUNCTION( "cs_trace_nc_mval_lst" );
+
+  if( grr_data->cs.v_crp_trace EQ TRUE )
+  {
+    memset( arfcn,  0xFF, sizeof( arfcn  ) );
+    memset( bsic,   0xFF, sizeof( bsic   ) );
+    memset( status, 0xFF, sizeof( status ) );
+    memset( rxlev_avg, 0xFF, sizeof( rxlev_avg ) );
+    memset( rla_p_lev, 0xFF, sizeof( rla_p_lev ) );
+    memset( rla_p_stat, 0xFF, sizeof( rla_p_stat ) );
+
+    write = 0;
+
+    for( read = 0; read < MAX_NR_OF_NC_MVAL; read++ )
+    {
+      if( grr_data->db.nc_mval_list.nc_mval[read].status NEQ NC_MVAL_STAT_NONE )
+      {
+        arfcn[write]  = grr_data->db.nc_mval_list.nc_mval[read].arfcn;
+        bsic[write]   = grr_data->db.nc_mval_list.nc_mval[read].sync_info.bsic;
+        status[write] = grr_data->db.nc_mval_list.nc_mval[read].status;
+        rla_p_lev [write] = grr_data->db.nc_mval_list.nc_mval[read].rla_p.lev;
+        rla_p_stat [write] = grr_data->db.nc_mval_list.nc_mval[read].rla_p.stat;
+        rxlev_avg [write] = grr_data->db.nc_mval_list.nc_mval[read].rxlev_avg;
+
+        write++;
+      }
+
+      if( write EQ 8 )
+      {
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST ARFCN:  %5d %5d %5d %5d %5d %5d %5d %5d",
+            arfcn[0], arfcn[1], arfcn[2], arfcn[3], 
+            arfcn[4], arfcn[5], arfcn[6], arfcn[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST BSIC:   %5d %5d %5d %5d %5d %5d %5d %5d",
+            bsic[0], bsic[1], bsic[2], bsic[3], 
+            bsic[4], bsic[5], bsic[6], bsic[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST STATUS: %5d %5d %5d %5d %5d %5d %5d %5d",
+            status[0], status[1], status[2], status[3], 
+            status[4], status[5], status[6], status[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST T_RXLEV_AVG: %5d %5d %5d %5d %5d %5d %5d %5d",
+            rxlev_avg[0], rxlev_avg[1], rxlev_avg[2], rxlev_avg[3], 
+            rxlev_avg[4], rxlev_avg[5], rxlev_avg[6], rxlev_avg[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST rla_p.stat: %5d %5d %5d %5d %5d %5d %5d %5d",
+            rla_p_stat[0], rla_p_stat[1], rla_p_stat[2], rla_p_stat[3], 
+            rla_p_stat[4], rla_p_stat[5], rla_p_stat[6], rla_p_stat[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST rla_p.lev: %5d %5d %5d %5d %5d %5d %5d %5d",
+            rla_p_lev[0], rla_p_lev[1], rla_p_lev[2], rla_p_lev[3], 
+            rla_p_lev[4], rla_p_lev[5], rla_p_lev[6], rla_p_lev[7] );
+
+        memset( arfcn,  0xFF, sizeof( arfcn  ) );
+        memset( bsic,   0xFF, sizeof( bsic   ) );
+        memset( status, 0xFF, sizeof( status ) );
+        memset( rxlev_avg, 0xFF, sizeof( rxlev_avg ) );
+        memset( rla_p_lev, 0xFF, sizeof( rla_p_lev ) );
+        memset( rla_p_stat, 0xFF, sizeof( rla_p_stat ) );
+
+        write = 0;
+      }
+    }
+
+    if( write NEQ 0 )
+    {
+      TRACE_EVENT_P8
+        ( "NC_MVAL_LIST ARFCN:  %5d %5d %5d %5d %5d %5d %5d %5d",
+          arfcn[0], arfcn[1], arfcn[2], arfcn[3], 
+          arfcn[4], arfcn[5], arfcn[6], arfcn[7] );
+
+      TRACE_EVENT_P8
+        ( "NC_MVAL_LIST BSIC:   %5d %5d %5d %5d %5d %5d %5d %5d",
+          bsic[0], bsic[1], bsic[2], bsic[3], 
+          bsic[4], bsic[5], bsic[6], bsic[7] );
+
+      TRACE_EVENT_P8
+        ( "NC_MVAL_LIST STATUS: %5d %5d %5d %5d %5d %5d %5d %5d",
+          status[0], status[1], status[2], status[3], 
+          status[4], status[5], status[6], status[7] );
+
+      TRACE_EVENT_P8
+          ( "NC_MVAL_LIST T_RXLEV_AVG: %5d %5d %5d %5d %5d %5d %5d %5d",
+            rxlev_avg[0], rxlev_avg[1], rxlev_avg[2], rxlev_avg[3], 
+            rxlev_avg[4], rxlev_avg[5], rxlev_avg[6], rxlev_avg[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST rla_p.stat: %5d %5d %5d %5d %5d %5d %5d %5d",
+            rla_p_stat[0], rla_p_stat[1], rla_p_stat[2], rla_p_stat[3], 
+            rla_p_stat[4], rla_p_stat[5], rla_p_stat[6], rla_p_stat[7] );
+
+        TRACE_EVENT_P8
+          ( "NC_MVAL_LIST rla_p.lev: %5d %5d %5d %5d %5d %5d %5d %5d",
+            rla_p_lev[0], rla_p_lev[1], rla_p_lev[2], rla_p_lev[3], 
+            rla_p_lev[4], rla_p_lev[5], rla_p_lev[6], rla_p_lev[7] );
+    }
+  }
+
+#endif /* #if !defined (NTRACE) */
+
+} /* cs_trace_nc_mval_lst( ) */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_stop_cr_meas 
++------------------------------------------------------------------------------
+| Description : The function cs_stop_cr_meas () .... 
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_stop_cr_meas( void )
+{ 
+  TRACE_FUNCTION( "cs_stop_cr_meas" );
+
+  switch( grr_data->cs.cr_meas_mode )
+  {
+    case( CS_CRMM_BA_GPRS ):
+      if( grr_data->cs.stop_req EQ FALSE )
+      {
+        PALLOC( mphp_cr_meas_stop_req, MPHP_CR_MEAS_STOP_REQ );
+
+#if 0
+
+        /*
+         * the timing for the MPHP_CR_MEAS_STOP_CON is not correct on
+         * layer 1 side, so we are no longer consider the confirmation
+         */
+
+        grr_data->cs.stop_req = TRUE;
+
+#endif /* #if 0 */
+
+        PSEND( hCommL1, mphp_cr_meas_stop_req );
+      }
+      break;
+    case( CS_CRMM_BA_BCCH ):
+      grr_data->cs.cr_meas_update = FALSE;
+      break;
+  }
+} /* cs_stop_cr_meas() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_req_cr_meas 
++------------------------------------------------------------------------------
+| Description : The function cs_req_cr_meas () .... 
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_req_cr_meas ( void )
+{ 
+  TRACE_FUNCTION( "cs_req_cr_meas" );
+
+  if( nc_data->c_cell NEQ 0 )
+  {
+    if( grr_data->cs_meas.packet_mode NEQ PACKET_MODE_PTM )
+    {
+      PALLOC( mphp_cr_meas_req, MPHP_CR_MEAS_REQ );
+    
+      cs_fill_cr_meas_req( mphp_cr_meas_req, grr_data->cs.list_id );
+
+      grr_data->cs.list_id++;
+
+      PSEND( hCommL1, mphp_cr_meas_req );
+    }
+    else
+    {
+      PALLOC( mphp_tcr_meas_req, MPHP_TCR_MEAS_REQ );
+
+      grr_data->cs.last_assignment_id++;
+      grr_data->cs.cr_meas_update = TRUE;
+
+      cs_fill_cr_meas_req( (T_MPHP_CR_MEAS_REQ*)mphp_tcr_meas_req,
+                             grr_data->cs.last_assignment_id );
+
+      PSEND( hCommL1, mphp_tcr_meas_req );
+    }
+
+    grr_data->cs.stop_req = FALSE;
+  }
+} /* cs_req_cr_meas() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_fill_cr_meas_req
++------------------------------------------------------------------------------
+| Description : ... 
+|
+| Parameters  : prim - Pointer to primitive buffer
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_fill_cr_meas_req ( T_MPHP_CR_MEAS_REQ *prim, UBYTE id )
+{
+  UBYTE i; /* used for counting */
+
+  TRACE_FUNCTION( "cs_fill_cr_meas_req" );
+
+  prim->nb_carrier = nc_data->c_cell;
+  prim->list_id    = id;
+    
+  for( i = 0; i < nc_data->c_cell; i++ )
+  {
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+    prim->carrier_list[i] = grr_g23_arfcn_to_l1(nc_data->cell[i].arfcn);
+#else
+    prim->carrier_list[i] = nc_data->cell[i].arfcn;
+#endif
+  }
+
+#ifdef _SIMULATION_
+
+  for( i = nc_data->c_cell; i < MPHP_NUMC_BA_GPRS_SC; i++ )
+  {
+    prim->carrier_list[i] = 0xFFFF;
+  }
+
+#endif /* #ifdef _SIMULATION_ */
+
+} /* cs_fill_cr_meas_req() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reset_all_cell_results
++------------------------------------------------------------------------------
+| Description : The function cs_reset_all_cell_results() .... 
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_reset_all_cell_results ( void )
+{
+  UBYTE i; /* used for counting */
+    
+  TRACE_FUNCTION( "cs_reset_all_cell_results" );
+
+  for( i = 0; i < MPHP_NUMC_BA_GPRS_SC; i++ )
+  {
+    cs_reset_meas_result( &nc_data->cell[i] );
+  }
+} /* cs_reset_all_cell_results () */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reset_all_rxlev_results
++------------------------------------------------------------------------------
+| Description : The function cs_reset_all_rxlev_results() .... 
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_reset_all_rxlev_results ( void )
+{
+  UBYTE i; /* used for counting */
+    
+  TRACE_FUNCTION( "cs_reset_all_rxlev_results" );
+
+  for( i = 0; i < MPHP_NUMC_BA_GPRS_SC; i++ )
+  {
+    nc_data->cell[i].rxlev_data.acc = 0;
+    nc_data->cell[i].rxlev_data.nbr = 0;
+  }
+} /* cs_reset_all_rxlev_results () */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reset_meas_result
++------------------------------------------------------------------------------
+| Description : The function cs_reset_meas_result() .... 
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_reset_meas_result ( T_CELL *cell )
+{
+  T_RLA_P_DATA *rla_p_data = &cell->rla_p_data;
+  T_RXLEV_DATA *rxlev_data = &cell->rxlev_data;
+
+  UBYTE i; /* used for counting */
+    
+  TRACE_FUNCTION( "cs_reset_meas_result" );
+  TRACE_EVENT_P2( "cs_reset_meas_result arfcn =%ld LOI=%ld",cell->arfcn,rla_p_data->loi );
+
+  rla_p_data->loi    = CS_IDX_NOT_USED;
+  rla_p_data->ovrflw = FALSE;
+
+  for( i = 0; i < CS_MAX_MEAS_RSLT; i++ )
+  {
+    rla_p_data->meas[i].cnt     = 0;
+    rla_p_data->meas[i].acc     = 0;
+    rla_p_data->meas[i].rpt_prd = 0;
+  }
+
+  rxlev_data->acc = 0;
+  rxlev_data->nbr = 0;
+} /* cs_reset_meas_result () */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_fill_meas_rslt
++------------------------------------------------------------------------------
+| Description : ... 
+|
+| Parameters  : ...
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_fill_meas_rslt ( T_MPHP_CR_MEAS_IND  *mphp_cr_meas_ind,
+                                T_MPHP_TCR_MEAS_IND *mphp_tcr_meas_ind  )
+{
+  T_RLA_P_DATA *rla_p_data;
+  T_RXLEV_DATA *rxlev_data;
+
+  T_RXLEV_DATA_NBR del_nbr;
+
+  UBYTE  i;
+  UBYTE  index  = 0;
+  BOOL   ovrflw = FALSE;
+
+  UBYTE  cnt;
+  SHORT  acc;
+  USHORT rpt_prd;
+
+  TRACE_FUNCTION( "cs_fill_meas_rslt" );
+
+  if( mphp_cr_meas_ind NEQ NULL )
+  {
+    rpt_prd = mphp_cr_meas_ind->reporting_period;
+  }
+  else
+  {
+    rpt_prd = CS_RPT_PRD_PTM;
+  }
+  
+  /*
+   * Process all data relevant for RLA_P derivation
+   */
+
+  for( i = 0; i < nc_data->c_cell; i++ )
+  {
+    rla_p_data = &nc_data->cell[i].rla_p_data;
+    rxlev_data = &nc_data->cell[i].rxlev_data;
+
+    if( mphp_cr_meas_ind NEQ NULL )
+    {
+      cnt = 1;
+	  if((signed char)mphp_cr_meas_ind->p_ncell_meas[i].rxlev <0)
+      {
+        acc = 0;
+      }
+      else     
+      {
+        acc = (signed char)mphp_cr_meas_ind->p_ncell_meas[i].rxlev;
+	  }
+    }
+    else
+    {
+      cnt = mphp_tcr_meas_ind->acc_nbr[i];
+	   if((SHORT)mphp_tcr_meas_ind->acc_level[i] <0)
+      {
+        acc = 0;
+      }
+      else   
+      {
+        acc = mphp_tcr_meas_ind->acc_level[i];
+      }
+    }
+
+    if( rla_p_data->loi NEQ CS_IDX_NOT_USED )
+    {
+      if( rla_p_data->loi EQ CS_MAX_MEAS_RSLT - 1 )
+      {
+        ovrflw = TRUE;
+      }
+      else
+      {
+        index = rla_p_data->loi + 1;
+      }
+    }
+    
+    if( cnt EQ 0 )
+    {
+      if( rla_p_data->meas[index].cnt EQ 0 )
+      {
+        rla_p_data->meas[index].rpt_prd += rpt_prd;
+      }
+      else
+      {
+        rla_p_data->meas[index].cnt      = 0;
+        rla_p_data->meas[index].acc      = 0;
+        rla_p_data->meas[index].rpt_prd = rpt_prd;
+      }
+    }
+    else
+    {
+      rla_p_data->meas[index].cnt     = cnt;
+      rla_p_data->meas[index].acc     = acc;
+      rla_p_data->meas[index].rpt_prd = rpt_prd;
+
+      rla_p_data->loi = index;
+
+      /* if an overflow once occured it will be forever */
+      if( rla_p_data->ovrflw EQ FALSE )
+      {
+        rla_p_data->ovrflw = ovrflw;
+      }
+    }
+
+    /*
+     * Process all data relevant for average RXLEV derivation
+     */
+
+    if( cnt NEQ 0 )
+    {
+      if( rxlev_data->nbr > RXLEV_MAX_NBR - cnt )
+      {
+        del_nbr          = cnt - ( RXLEV_MAX_NBR - rxlev_data->nbr );
+        rxlev_data->acc -= del_nbr * ( rxlev_data->acc / rxlev_data->nbr );
+        rxlev_data->nbr -= del_nbr;
+      }
+
+      rxlev_data->acc += ( acc * RXLEV_ACRCY );
+      rxlev_data->nbr += cnt;
+    }
+  }
+} /* cs_fill_meas_rslt() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_rla_p
++------------------------------------------------------------------------------
+| Description : The function cs_get_rla_p() .... 
+|
+| Parameters  : rla_p_data - pointer to RLA_P raw data
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_get_rla_p( T_RLA_P_DATA *rla_p_data, UBYTE *rla_p )
+{
+  BOOL  s_avg;             /* status of average RXLEV value                  */
+  LONG  avg;               /* average RXLEV value used for cell re-selection */
+  LONG  cnt         = 0;   /* number of accumulated measurement samples      */
+  LONG  acc         = 0;   /* accumulated receive level values               */
+  ULONG run_avg_prd = 0;   /* running average period                         */
+  UBYTE c_meas      = 0;   /* number of measurements                         */
+  UBYTE index       = rla_p_data->loi;
+                           /* index to actual used measurement result  */
+  BOOL  v_meas_left = rla_p_data->loi NEQ CS_IDX_NOT_USED;
+                           /* indicates whether more measurement results     */
+                           /* are not yet considered                         */
+
+  TRACE_FUNCTION( "cs_get_rla_p" );
+
+  while(
+         (
+           c_meas      <  CS_MIN_RLA_P_SAMPLES OR
+           run_avg_prd <  CS_MIN_RUN_AVG_PRD     
+         )
+         AND
+         (
+           v_meas_left EQ TRUE
+         )
+       )
+  {
+    /*
+     * check whether valid measurement results are available 
+     */
+    if( rla_p_data->meas[index].cnt NEQ 0                AND     
+        c_meas                      <   CS_MAX_MEAS_RSLT     )
+    {
+      c_meas++;
+      
+      /* 
+       * accumulate individual measurement results 
+       */
+      run_avg_prd += rla_p_data->meas[index].rpt_prd;
+      cnt         += rla_p_data->meas[index].cnt;
+      acc         += rla_p_data->meas[index].acc;
+
+      /* determine the next index to be used for RLA_P calculation */
+      if( index EQ 0 )
+      {
+        if( rla_p_data->ovrflw EQ TRUE )
+        {
+          index = CS_MAX_MEAS_RSLT - 1;
+        }
+        else
+        {
+          v_meas_left= FALSE;
+        }
+      }
+      else
+      {
+        index--;
+      }
+
+
+    }
+    else
+    {
+      v_meas_left = FALSE;
+    }
+  }
+           
+  /* 
+   * calculate status of RLA_P
+   */
+  if( cnt EQ 0 )
+  {
+    s_avg = CS_RLA_P_NOT_AVAIL;
+  }
+  else if(
+           (
+             c_meas      < CS_MIN_RLA_P_SAMPLES
+           )
+           OR 
+           ( 
+             run_avg_prd < CS_MIN_RUN_AVG_PRD 
+             AND
+             c_meas      < CS_MAX_MEAS_RSLT
+           )
+         )
+  {
+    s_avg = CS_RLA_P_NOT_VALID;
+  }
+  else
+  {
+    s_avg = CS_RLA_P_VALID;
+  }
+
+  if( cnt > 0 )
+  { 
+    /*
+     * calculate RLA_P
+     */
+    avg = acc / cnt;
+
+
+    /*
+     * clip RLA_P to values between 0 and 63
+     */
+    if( (signed char)( avg ) < CGRLC_RXLEV_MIN )
+    {
+      avg = CGRLC_RXLEV_MIN;
+    }
+    else if ( (signed char)( avg ) > CGRLC_RXLEV_MAX )
+    {
+      avg = CGRLC_RXLEV_MAX;
+    }
+  }
+  else
+  {
+    avg = CGRLC_RXLEV_NONE;
+  }
+
+
+  *rla_p = (UBYTE)avg;
+
+  return( s_avg );
+
+} /* cs_get_rla_p () */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_rxlev_avg
++------------------------------------------------------------------------------
+| Description : The function cs_get_rxlev_avg() .... 
+|
+| Parameters  : rxlev_data - pointer to RXLEV raw data
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL T_RXLEV_AVG cs_get_rxlev_avg( T_RXLEV_DATA *rxlev_data )
+{
+  T_RXLEV_AVG rxlev_avg;
+  
+  TRACE_FUNCTION( "cs_get_rxlev_avg" );
+
+
+  if( rxlev_data->nbr EQ 0 )
+  {
+    rxlev_avg = RXLEV_AVG_INVALID;
+  }
+  else
+  {
+    rxlev_avg = 
+        ( T_RXLEV_AVG )( rxlev_data->acc / ( rxlev_data->nbr * RXLEV_ACRCY ) );
+  }
+
+  TRACE_EVENT_P2("1_cs_get_rxlev_avg: nbr=%ld rx_avg=%ld",rxlev_data->nbr,rxlev_avg);
+
+  return( rxlev_avg );
+} /* cs_get_rxlev_avg () */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_tcr_meas_ind_to_pl 
++------------------------------------------------------------------------------
+| Description : The function cs_tcr_meas_ind_to_pl () forwards the cell
+|               re-selection measurement results catched during packet transfer
+|               mode to ALR.
+|
+| Parameters  : prim - pointer to primitive payload
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_tcr_meas_ind_to_pl ( T_MPHP_TCR_MEAS_IND * prim )
+{ 
+  UBYTE i; /* used for counting */
+
+  TRACE_FUNCTION( "cs_tcr_meas_ind_to_pl" );
+
+  {
+    PALLOC( tb_meas_ind, TB_MEAS_IND );
+
+    for( i = 0; i < TB_BA_LIST_SIZE; i++ )
+    {
+      if(( grr_data->cs.cr_meas_update EQ TRUE) AND 
+         (nc_data->cell[i].arfcn NEQ 0))
+      {
+        if(nc_data->cell[i].arfcn NEQ 0)
+      {
+        tb_meas_ind->tb_meas_result[i].arfcn  = grr_g23_arfcn_to_l1(nc_data->cell[i].arfcn);
+      }
+      else
+      {
+        tb_meas_ind->tb_meas_result[i].arfcn  = TB_INVALID_ARFCN;
+      }
+      }
+      else
+      {
+        tb_meas_ind->tb_meas_result[i].arfcn  = TB_INVALID_ARFCN;
+      }
+
+      tb_meas_ind->tb_meas_result[i].rxlev    = prim->acc_level[i];
+      tb_meas_ind->tb_meas_result[i].num_meas = prim->acc_nbr[i];
+    }
+
+    PSEND( hCommPL, tb_meas_ind );
+  }
+} /* cs_tcr_meas_ind_to_pl() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_create_cr_cell 
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters  :
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL T_NC_MVAL* cs_create_cr_cell ( USHORT arfcn, UBYTE  bsic )
+{ 
+  T_NC_MVAL *nc_mval;
+  UBYTE      nc_mval_idx;
+
+  TRACE_FUNCTION( "cs_create_cr_cell" );
+
+  /* if the new selected cell is not found in the neighbour cell list */
+  nc_mval = grr_get_nc_mval( RRGRR_INVALID_ARFCN, RRGRR_INVALID_BSIC, &nc_mval_idx );
+  
+  if( nc_mval NEQ NULL )
+  {
+    nc_mval->arfcn          = arfcn;
+    nc_mval->sync_info.bsic = bsic;
+
+    /* 
+     * The function cs_create_cr_cell is only called in case of processing a 
+     * packet cell change order. If the packet cell change order has been 
+     * received on a cell without PBCCH, GRR should forward the RRGRR_CR_REQ
+     * with parameter CR_NEW in all cases. This is forced by setting the
+     * synchronisation status to STAT_SYNC_OK.
+     */
+    if( grr_is_pbcch_present( ) )
+    {
+      TRACE_EVENT( "cs_create_cr_cell: cell not part of neighbour cell list" );
+
+      nc_mval->sync_info.sync.status = STAT_SYNC_NONE;
+    }
+    else
+    {
+      nc_mval->sync_info.sync.status = STAT_SYNC_OK;
+    }
+
+    grr_data->db.cr_cell             = &grr_data->db.nc_nw_slctd.strgst;
+    grr_data->db.cr_cell->idx        = nc_mval_idx;
+    grr_data->db.cr_cell->mode       = CS_MODE_IDLE;
+    grr_data->db.cr_cell->avail_time = 0;
+  }
+
+  return( nc_mval );
+
+} /* cs_create_cr_cell() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_nc_rpt_prd_idle 
++------------------------------------------------------------------------------
+| Description :
+|
+| Parameters  :
+|
++------------------------------------------------------------------------------
+*/
+LOCAL T_TIME cs_get_nc_rpt_prd_idle ( void )
+{ 
+  T_TIME reporting_period;
+  ULONG  small_int_multi; /* smallest integer multiple of DRX period */
+  ULONG  drx_period;      /* DRX period in milliseconds              */
+        
+  TRACE_FUNCTION( "cs_get_nc_rpt_prd_idle" );
+
+  reporting_period = GET_NC_RPT_PRD( grr_data->db.nc_ref_lst.param->rep_per_i );
+  drx_period       = meas_im_get_drx_period_seconds( );
+  drx_period       = M_ROUND_UP( drx_period, DRX_NORM_FACTOR );
+
+  /*
+   * In packet idle mode, the reporting period is NC_REPORTING_PERIOD_I
+   * rounded off to the nearest smaller integer multiple of DRX period
+   * if NC_REPORTING_PERIOD_I is greater than DRX period, else, the
+   * reporting period is DRX period.
+   */
+  if( drx_period NEQ NO_PAGING )
+  {
+    if( reporting_period > drx_period )
+    {
+      small_int_multi  = reporting_period / drx_period;
+      reporting_period = drx_period * small_int_multi;
+    }
+    else
+    {
+      reporting_period = drx_period;
+    }
+  }
+  
+  return( reporting_period );
+
+} /* cs_get_nc_rpt_prd_idle() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reset_meas_rep_params
++------------------------------------------------------------------------------
+| Description : This function will reset measurement reporting parameters
+|
+| Parameters  : db - pointer to serving cell database
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_reset_meas_rep_params ( T_SC_DATABASE *db )
+{
+  TRACE_FUNCTION( "cs_reset_meas_rep_params" );
+
+  db->nc_ms.ncmeas.param.ctrl_order = NC_RESET;
+  db->nc_ms.ncmeas.param.rep_per_i = 0;
+  db->nc_ms.ncmeas.param.rep_per_t = 0;
+
+} /* cs_reset_meas_rep_params() */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_check_nc_sync_timer
++------------------------------------------------------------------------------
+| Description : Handles the nc sync timer of 10 sec in case of PIM_PBCCH and
+| PTM_PBCCH
+|
+| Parameters  : reporting_period
+|
++------------------------------------------------------------------------------
+*/
+
+
+GLOBAL void cs_check_nc_sync_timer(USHORT reporting_pd)
+{
+   if(!grr_data->db.cnt_nc_six.candid) return;
+   grr_data->cs.nc_sync_rep_pd += reporting_pd;
+
+
+   if(grr_data->cs.nc_sync_rep_pd >= CS_NCSYNC_RPT_PRD_PIM)
+   {
+      PALLOC( rrgrr_check_bsic_req, RRGRR_NCELL_SYNC_REQ );
+      rrgrr_check_bsic_req->sync_type = SYNC_RECONFIRM;
+      PSEND( hCommRR, rrgrr_check_bsic_req );
+      /*subtracting nc_sync_rep_pd from CS_NCSYNC_RPT_PRD_PIM wil provide take care 
+      of periodicity of non-uniform reporting_period values*/
+      TRACE_EVENT_P1("GRR_NC_SYNC:EXPIRY: nc_sync_rep_pd=%d", grr_data->cs.nc_sync_rep_pd);
+      grr_data->cs.nc_sync_rep_pd -= CS_NCSYNC_RPT_PRD_PIM; 
+   }
+   return;
+
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_process_serving_cell_data
++------------------------------------------------------------------------------
+| Description : This function is used to fill rxlev and interference measurements
+|               of the serving cell
+|
+| Parameters  : rxlev, iscell
+|
++------------------------------------------------------------------------------
+*/
+LOCAL BOOL cs_process_serving_cell_data ( UBYTE *rxlev_scell, UBYTE *v_i_scell, 
+                                       UBYTE *i_scell, UBYTE *used_bits, 
+                                       BOOL *rsc_avail, BOOL *isc_avail )
+
+{
+  TRACE_FUNCTION( "cs_process_serving_cell_data" );
+
+  *used_bits += NC_RXLEV_SCELL_LEN;
+
+  if( grr_data->db.scell_info.rxlev_avg EQ RXLEV_AVG_INVALID )
+  {
+    TRACE_ERROR( "cs_build_xxx_meas_rpt no RXLEV of serving cell" );
+    return( FALSE );
+  }
+  else
+  {
+    *rsc_avail   = TRUE;
+    *rxlev_scell = grr_data->db.scell_info.rxlev_avg;
+  }
+  
+  /* process interference measurement of serving cell */
+  *used_bits             += PMR_FLAG_LEN;
+  *v_i_scell  = FALSE;
+
+  if( grr_is_pbcch_present( )       EQ  TRUE            AND 
+      psc_db->paging_group.kc       NEQ 0               AND
+      grr_data->cs_meas.packet_mode EQ  PACKET_MODE_PIM     )
+  {
+    T_p_frequency_par freq_par;
+
+    if( grr_get_pccch_freq_par
+          ( ( UBYTE )( grr_imsi_mod( ) % psc_db->paging_group.kc ), 
+            &freq_par.p_chan_sel, &freq_par.p_freq_list ) )
+    {
+      T_MEAS_IM_CARRIER ma;
+      UBYTE             written_bits;
+      T_ilev_abs        i_level;
+
+      meas_im_set_carrier( &ma, &freq_par );
+
+      written_bits = meas_im_get_abs_i_level( &ma, &i_level );
+
+      if( written_bits > CGRLC_MAX_TIMESLOTS * PMR_FLAG_LEN )
+      {
+        *v_i_scell = TRUE;
+        *used_bits += NC_IF_SCELL_LEN;
+
+        if     ( i_level.v_ilevabs0 EQ TRUE )
+        {
+          *i_scell = i_level.ilevabs0;
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs1 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs1; 
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs2 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs2; 
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs3 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs3; 
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs4 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs4; 
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs5 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs5; 
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs6 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs6; 
+          *isc_avail = TRUE;
+        }
+        else if( i_level.v_ilevabs7 EQ TRUE ) 
+        {
+          *i_scell = i_level.ilevabs7; 
+          *isc_avail = TRUE;
+        }
+        else 
+        {
+          TRACE_ERROR( "cs_process_serving_cell_data corrupted I_LEVEL data" );
+          return( FALSE );
+        }
+      }
+    }
+  }
+  return(TRUE);
+}/* cs_process_serving_cell_data */
+
+#if defined (REL99) AND defined (TI_PS_FF_EMR)
+/*
++------------------------------------------------------------------------------
+| Function    : cs_send_enh_meas_rpt
++------------------------------------------------------------------------------
+| Description : This function is used to send enh meas report to the network
+|
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL BOOL cs_send_enh_meas_rpt (void)
+{
+  T_U_ENHNC_MEAS_REPORT enh_meas_rpt;
+  BOOL  rpt_send;
+
+  TRACE_FUNCTION( "cs_send_enh_meas_rpt" );
+
+  if(grr_is_pbcch_present())
+  {
+    cs_form_enh_cell_list();
+  }
+  else
+  {
+    cs_form_ba_bcch_enh_cell_list();
+  }
+
+  cs_nc_sort_and_update_emr_info();
+
+  memset (&enh_meas_rpt, 0, sizeof(T_U_ENHNC_MEAS_REPORT));
+
+  rpt_send = cs_build_enh_meas_rpt(&enh_meas_rpt);
+
+  if( rpt_send EQ TRUE )
+  {
+    sig_cs_ctrl_enh_meas_report(&enh_meas_rpt);
+  }
+
+  return(rpt_send);
+    
+} /* cs_send_enh_meas_rpt() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_form_enh_cell_list
++------------------------------------------------------------------------------
+| Description : This function is used to form enhanced cell list from BA list
+|               (nc_ref_lst) and Measured values list(nc_mval_list)
+|               
+|
+| Parameters  : Nil
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_form_enh_cell_list(void)
+{
+  UBYTE i = 0, n = 0, j;
+  UBYTE nc_ref_index_arfcn, nc_ref_index_bsic;
+  
+  TRACE_FUNCTION( "cs_form_enh_cell_list" );
+
+  memset((grr_data->db.enh_cell_list), 0xFF, sizeof(T_ENH_CELL_LIST)*MAX_NR_OF_NCELL);
+  
+  grr_data->db.cnt_enh_cell_list = 0; 
+
+    /* Check one entry of Measured values list against all entries of BA list */
+  while(i < MAX_NR_OF_NC_MVAL AND n < MAX_NR_OF_NCELL)
+  {
+    if( (grr_data->db.nc_mval_list.nc_mval[i].status EQ NC_MVAL_STAT_ASSIGNED)
+         AND 
+         (grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ RRGRR_INVALID_ARFCN)
+         AND
+        (grr_data->db.nc_mval_list.nc_mval[i].sync_info.sync.status EQ 
+         STAT_SYNC_OK)
+         AND
+         (grr_data->db.nc_mval_list.nc_mval[i].rla_p.stat EQ CS_RLA_P_VALID) )
+    {
+      nc_ref_index_arfcn = NOT_SET; /* Will be set the 1st time ARFCN matches 
+                                      in the BA list */
+      nc_ref_index_bsic = NOT_SET;  /* Will be set the 1st time ARFCN-BSIC pair
+                                      matches in the BA list */
+
+      /* Comparison with BA list */
+      for (j = 0; j < grr_data->db.nc_ref_lst.number; j++)
+      {
+        if(grr_data->db.nc_mval_list.nc_mval[i].arfcn EQ
+           grr_data->db.nc_ref_lst.info[j]->arfcn)
+        {          
+          if(nc_ref_index_arfcn EQ NOT_SET)
+          {
+            /* ARFCN matched for the 1st time in BA list */
+            nc_ref_index_arfcn  = j;
+          }
+
+          /* In case the same cell (ARFCN+BSIC) or the same ARFCN without BSIC
+             occur more than once in the resulting GSM Neighbour Cell list, 
+             each occurrence shall be assigned an index but only the cell with
+             the highest index shall be used for cell re-selection and referred
+             to in measurement reports. */
+          if(grr_data->db.nc_ref_lst.info[j]->index >
+             grr_data->db.nc_ref_lst.info[nc_ref_index_arfcn]->index)
+          {
+            nc_ref_index_arfcn = j;
+          }
+          
+          if(grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic EQ
+             grr_data->db.nc_ref_lst.info[j]->bsic)
+          {
+            nc_ref_index_bsic = nc_ref_index_arfcn;
+          }
+        }
+      }
+      
+      /* Store ARFCN, BSIC, RLA_P and RXLEV, if ARFCN and/or BSIC matches */
+      if(nc_ref_index_arfcn NEQ NOT_SET)
+      {
+        grr_data->db.enh_cell_list[n].arfcn =
+          grr_data->db.nc_mval_list.nc_mval[i].arfcn;
+
+        grr_data->db.enh_cell_list[n].bsic.bsic =
+          grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic;
+
+        grr_data->db.enh_cell_list[n].rla_p =
+          grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
+        
+        grr_data->db.enh_cell_list[n].rxlev_avg =
+          grr_data->db.nc_mval_list.nc_mval[i].rxlev_avg;
+      }
+      
+      /* Store in the enhanced cell list as Valid and Invalid BSICs */
+      if (nc_ref_index_bsic NEQ NOT_SET)
+      {
+        grr_data->db.enh_cell_list[n].index =
+          grr_data->db.nc_ref_lst.info[nc_ref_index_bsic]->index;
+
+        grr_data->db.enh_cell_list[n].rept_prio = 
+          grr_data->db.nc_ref_lst.enh_param->gprs_rept_prio_desc.
+          rept_prio[grr_data->db.nc_ref_lst.info[nc_ref_index_bsic]->index];
+
+        grr_data->db.enh_cell_list[n++].bsic.status = BSIC_VALID;
+      }
+      else if(nc_ref_index_arfcn NEQ NOT_SET)
+      {
+        grr_data->db.enh_cell_list[n].index =
+          grr_data->db.nc_ref_lst.info[nc_ref_index_arfcn]->index;
+        /* Set the reporting priority to high for invalid BSICs and allowed 
+        NCC part. Refer Section 8.4.8.1 of 3GPP TS 05.08 V8.15.0 (2002-06) */
+        grr_data->db.enh_cell_list[n].rept_prio = HIGH_PRIO;
+        grr_data->db.enh_cell_list[n++].bsic.status = BSIC_INVALID;
+      }
+    }
+    i++;
+  }
+  grr_data->db.cnt_enh_cell_list = n;
+}/* cs_form_enh_cell_list */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_form_ba_bcch_enh_cell_list
++------------------------------------------------------------------------------
+| Description : This function is used to form enhanced cell list from BA list
+|               (nc_ref_lst) and Measured values list(nc_mval_list)
+|               
+|
+| Parameters  : Nil
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_form_ba_bcch_enh_cell_list(void)
+{
+  UBYTE i = 0, n = 0, j;
+  UBYTE nc_ref_index_arfcn, nc_ref_index_bsic;
+
+  TRACE_FUNCTION( "cs_form_ba_bcch_enh_cell_list" );
+
+  memset((grr_data->db.enh_cell_list), 0xFF, sizeof(T_ENH_CELL_LIST)*MAX_NR_OF_NCELL);
+  
+  grr_data->db.cnt_enh_cell_list = 0; 
+
+  /* Check one entry of Measured values list against all entries of BA list */
+  while(i < MAX_NR_OF_NC_MVAL AND n < MAX_NR_OF_NCELL)
+   {
+    if( (grr_data->db.nc_mval_list.nc_mval[i].status EQ NC_MVAL_STAT_ASSIGNED)
+         AND 
+         (grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ RRGRR_INVALID_ARFCN)
+         AND
+        (grr_data->db.nc_mval_list.nc_mval[i].sync_info.sync.status EQ 
+         STAT_SYNC_OK)
+         AND
+         (grr_data->db.nc_mval_list.nc_mval[i].rla_p.stat EQ CS_RLA_P_VALID) )
+    {
+      nc_ref_index_arfcn = NOT_SET; /* Will be set the 1st time ARFCN matches 
+                                      in the BA list */
+      nc_ref_index_bsic = NOT_SET; /* Will be set the 1st time ARFCN-BSIC pair
+                                      matches in the BA list */
+
+      /* Comparison with BA list */
+      for (j = 0; j < grr_data->db.ba_bcch_nc_ref_lst.number; j++)
+      {
+        if(grr_data->db.nc_mval_list.nc_mval[i].arfcn EQ
+           grr_data->db.ba_bcch_nc_ref_lst.info[j]->arfcn)
+        {
+          if(nc_ref_index_arfcn EQ NOT_SET)
+          {
+            /* ARFCN matched for the 1st time in BA list */
+            nc_ref_index_arfcn  = j;
+          }
+
+          /* In case the same cell (ARFCN+BSIC) or the same ARFCN without BSIC
+             occur more than once in the resulting GSM Neighbour Cell list, 
+             each occurrence shall be assigned an index but only the cell with
+             the highest index shall be used for cell re-selection and referred
+             to in measurement reports. */
+          if(grr_data->db.ba_bcch_nc_ref_lst.info[j]->index >
+             grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_arfcn]->index)
+          {
+            nc_ref_index_arfcn = j;
+          }
+          
+          if(grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic EQ
+             grr_data->db.ba_bcch_nc_ref_lst.info[j]->bsic)
+          {
+            nc_ref_index_bsic = nc_ref_index_arfcn;
+          }
+        }
+      }
+      
+      /* Store ARFCN, BSIC, RLA_P AND RXLEV, if ARFCN and/or BSIC matches */
+      if(nc_ref_index_arfcn NEQ NOT_SET)
+      {
+        grr_data->db.enh_cell_list[n].arfcn =
+          grr_data->db.nc_mval_list.nc_mval[i].arfcn;
+
+        grr_data->db.enh_cell_list[n].bsic.bsic =
+          grr_data->db.nc_mval_list.nc_mval[i].sync_info.bsic;
+
+        grr_data->db.enh_cell_list[n].rla_p =
+          grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
+
+        grr_data->db.enh_cell_list[n].rxlev_avg =
+          grr_data->db.nc_mval_list.nc_mval[i].rxlev_avg;
+      }
+      
+      /* Store in the enhanced cell list as Valid and Invalid BSICs */
+      if (nc_ref_index_bsic NEQ NOT_SET)
+      {
+        grr_data->db.enh_cell_list[n].index =
+          grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_bsic]->index;
+
+        grr_data->db.enh_cell_list[n].rept_prio = 
+          grr_data->db.nc_ref_lst.enh_param->gprs_rept_prio_desc.
+          rept_prio[grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_bsic]->index];
+
+        grr_data->db.enh_cell_list[n++].bsic.status = BSIC_VALID;
+      }
+      else if(nc_ref_index_arfcn NEQ NOT_SET)
+      {
+        grr_data->db.enh_cell_list[n].index =
+          grr_data->db.ba_bcch_nc_ref_lst.info[nc_ref_index_arfcn]->index;
+        /* Set the reporting priority to high for invalid BSICs and allowed 
+        NCC part. Refer Section 8.4.8.1 of 3GPP TS 05.08 V8.15.0 (2002-06) */
+        grr_data->db.enh_cell_list[n].rept_prio = HIGH_PRIO;
+        grr_data->db.enh_cell_list[n++].bsic.status = BSIC_INVALID;
+      }
+    }
+    i++;
+  }
+  grr_data->db.cnt_enh_cell_list = n;
+}/* cs_form_ba_bcch_enh_cell_list */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_nc_sort_and_update_emr_info
++------------------------------------------------------------------------------
+| Description : The purpose of this function is to handle all the specific 
+|               requirements for EMR - sorting according to priority as given 
+|               in 5.08 V8.16.0, sec.8.4.8.1, and scaling of rxlev values.
+|               
+|
+| Parameters  : Nil
+|
++------------------------------------------------------------------------------
+*/
+
+LOCAL void cs_nc_sort_and_update_emr_info(void)
+{
+  T_ENH_BIN     sc_bin;
+  T_ENH_BIN     mband_bin[5]; /* 0 - 900, 1 - 1800, 2 - 400, 3 - 1900, 4 - 850*/
+  T_ENH_BIN     rest_bin;
+  UBYTE         i;
+  UBYTE         temp;
+  T_GRR_ENH_PARA  *p_enh          = grr_data->db.nc_ref_lst.enh_param;
+  T_ENH_CELL_LIST *enh_cell_list  = &(grr_data->db.enh_cell_list[0]);
+  BOOL            include_cell    = FALSE;
+  grr_data->db.sorted_enh_cell_list.num_valid = 0;
+
+  TRACE_FUNCTION( "cs_nc_sort_and_update_emr_info" );
+
+  /* Flush off the old sorted ENH cell list before forming a new one */
+  memset(&grr_data->db.sorted_enh_cell_list,0,sizeof(T_ENH_BIN));
+
+  /* Step 1: Sort cells into different bins - serving cell band bin,
+    non-serving cell band bin, and the rest which can contain invalid BSIC
+    cells */
+  cs_nc_sort_cells_into_bins(&sc_bin, mband_bin, &rest_bin);
+
+  /* Step 2: Fill the cells from each bin, after sorting in descending order
+     of RXLEV, in the order of : sc_bin, mband_bin and rest_bin.
+     Further number of cells from sc_bin and mband_bin is restricted by SERVING_BAND
+     and MULTIBAND reporting parameters */
+  if ( (sc_bin.num_valid > 0) AND (p_enh->servingband_rep > 0) )
+  {
+    cs_nc_sort_and_store_meas_results(&sc_bin, p_enh->servingband_rep);
+    if (sc_bin.num_valid > p_enh->servingband_rep)
+    {
+      cs_nc_update_rest_bin(&rest_bin, &sc_bin, p_enh->servingband_rep);
+    }
+  }
+    
+  /* Fill cells from multi band after sorting*/
+  for ( i = 0; i < MAX_NUM_BANDS AND 
+      grr_data->db.sorted_enh_cell_list.num_valid 
+      < grr_data->db.cnt_enh_cell_list; i++)    
+  {
+    if ( (mband_bin[i].num_valid > 0) AND (p_enh->multiband_rep > 0) )
+    {
+      cs_nc_sort_and_store_meas_results(&mband_bin[i], p_enh->multiband_rep);
+      if (mband_bin[i].num_valid > p_enh->multiband_rep)
+      {
+        cs_nc_update_rest_bin(&rest_bin, &mband_bin[i], p_enh->multiband_rep );
+      }
+    }
+  }
+  
+  /* Now sort cells in the rest bin which may contain both valid and 
+    invalid BSIC cells. Here we use the reporting offset along with measured RXLEV,
+    for sorting. According to 5.08, sec.8.4.8.1 we need to find those cells whose sum of 
+    RXLEV and xxx_reporting_offset is maximum. This can be acheived by sorting the cells
+    in the order of their rxlevm, where rxlevm = rxlev + offset */
+  if ( (rest_bin.num_valid > 0) AND (grr_data->db.sorted_enh_cell_list.num_valid 
+      < grr_data->db.cnt_enh_cell_list) )
+  {
+    UBYTE     j;
+    UBYTE     max_rxlevm;
+    UBYTE     band;
+    UBYTE     rxlevm;
+    UBYTE     k;
+    T_ncell_info *ncell;
+    
+    for (i = 0; i < rest_bin.num_valid; i++)
+    {
+      band = cs_get_band_index_for_emr (enh_cell_list[rest_bin.enh_index[i]].arfcn);
+      max_rxlevm = enh_cell_list[rest_bin.enh_index[i]].rla_p + 
+        (p_enh->enh_rep_data[band].rep_offset * 6);
+      k = i;
+      for ( j = i+1; j < rest_bin.num_valid ; j++ )
+      {
+        band = cs_get_band_index_for_emr (enh_cell_list[rest_bin.enh_index[j]].arfcn);
+        rxlevm = enh_cell_list[rest_bin.enh_index[j]].rla_p +
+          (p_enh->enh_rep_data[band].rep_offset * 6) ;
+        if ( rxlevm > max_rxlevm )
+        {
+          k = j;
+          max_rxlevm = rxlevm;            
+        }
+      }
+      include_cell = TRUE;
+      /* When reduced reporting is enabled we have to report low priority cell 
+      once in 4 reporting periods. The RXLEV then should be average of previous
+      two periods */
+      if ( (enh_cell_list[rest_bin.enh_index[k]].rept_prio EQ NORMAL_PRIO) AND 
+           (p_enh->rep_rate EQ REPORTING_RATE_REDUCED) )
+      {
+        /* ncell cannot be NULL since the loop will be entered only for a 
+           valid BSIC */
+        ncell = grr_get_ncell_info(enh_cell_list[rest_bin.enh_index[k]].arfcn, 
+          enh_cell_list[rest_bin.enh_index[k]].bsic.bsic);
+
+        /* For every 4th time, we include this cell in the report */
+        if ( (ncell->rep_count & (0x03)) EQ 0 )
+        {
+          /* For those cells that are not reported in every measurement report,
+          the MS shall average the measurements of the current and the previous
+          reporting period (i.e. over two reporting periods). */
+          enh_cell_list[rest_bin.enh_index[k]].rxlev_avg = 
+            (enh_cell_list[rest_bin.enh_index[k]].rxlev_avg + ncell->last_rxlev) >> 1;
+                                                          /* division by 2 */
+        }
+        else
+        {
+          ncell->last_rxlev = enh_cell_list[rest_bin.enh_index[k]].rxlev_avg;
+          include_cell = FALSE;
+        }
+        /* modulo 4 addition */
+        ncell->rep_count = (ncell->rep_count + 1) & 0x03;
+      }
+
+      if (include_cell EQ TRUE)
+      {
+        grr_data->db.sorted_enh_cell_list.
+          enh_index[grr_data->db.sorted_enh_cell_list.num_valid] = 
+          rest_bin.enh_index[k];
+        grr_data->db.sorted_enh_cell_list.num_valid++;
+      }
+
+      if(k NEQ i)
+      {
+        temp = rest_bin.enh_index[k];
+        rest_bin.enh_index[k] = rest_bin.enh_index[i];
+        rest_bin.enh_index[i] = temp;
+      }
+    }
+  }
+  /* This leaves us with final step in neighbour cell measurement reporting - scaling.*/
+  grr_data->db.pemr_params.scale_used = cs_nc_scale_rxlev ();  
+}/* cs_nc_sort_and_update_emr_info */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_nc_sort_cells_into_bins
++------------------------------------------------------------------------------
+| Description : The purpose of this function is to sort the cells into various
+|               bins. This is the first step in handling reporting priority 
+|               as given in 5.08 sec.8.4.8.1
+|               
+|
+| Parameters  : Pointers to the three bins
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_nc_sort_cells_into_bins(T_ENH_BIN *p_sbin,T_ENH_BIN *p_mbin,
+                                      T_ENH_BIN *p_rbin)
+{
+  UBYTE     i, j;
+  UBYTE     band;
+  UBYTE     sc_band;
+  UBYTE     rth;  
+  T_ENH_CELL_LIST *enh_cell_list  = &(grr_data->db.enh_cell_list[0]);
+  T_GRR_ENH_PARA  *p_enh          = grr_data->db.nc_ref_lst.enh_param;
+
+  TRACE_FUNCTION( "cs_nc_sort_cells_into_bins" );
+  
+  memset(p_sbin, 0xFF, sizeof(T_ENH_BIN));
+  p_sbin->num_valid = 0;
+
+  memset(p_rbin, 0xFF, sizeof(T_ENH_BIN));
+  p_rbin->num_valid = 0;
+  
+  for( i = 0; i < MAX_NUM_BANDS; i++)
+  {
+    memset(&p_mbin[i], 0xFF, sizeof(T_ENH_BIN));
+    p_mbin[i].num_valid = 0;
+  }
+
+  sc_band = cs_get_band_index_for_emr (psc_db->pbcch.bcch.arfcn);
+  
+  for ( j = 0; j < grr_data->db.cnt_enh_cell_list; j++ )
+  {
+    if(enh_cell_list[j].bsic.status EQ BSIC_VALID) /* Valid BSIC */
+    {
+      /*Find the band of this arfcn*/
+      band = cs_get_band_index_for_emr(enh_cell_list[j].arfcn);
+      rth = p_enh->enh_rep_data[band].rep_threshold;
+      if (band EQ sc_band )
+      {
+        /* Apply the threshold criteria for this band*/
+        if ( rth NEQ REP_THRESHOLD_INF )
+        {
+          if((rth EQ REP_THRESHOLD_DEF) OR
+            (enh_cell_list[j].rla_p >= (rth * 6)))
+          {
+            p_sbin->enh_index[p_sbin->num_valid++] = j;
+          }
+          else
+          {
+            p_rbin->enh_index[p_rbin->num_valid++] = j;
+          }
+        } /*otherwise report-never*/            
+      } /* otherwise cell in non-serving band*/
+      else
+      {
+        /* Apply the threshold criteria for this band*/
+        if ( rth NEQ REP_THRESHOLD_INF )                  
+        {
+          if((rth EQ REP_THRESHOLD_DEF) OR
+            (enh_cell_list[j].rla_p >= (rth * 6))) 
+          {
+            p_mbin[band].enh_index[p_mbin[band].num_valid++] = j;
+          }
+          else
+          {
+            p_rbin->enh_index[p_rbin->num_valid++] = j;
+          }
+        } /*otherwise report never*/
+      }
+    }
+    else /* If there's no cell with the given BSIC, then it falls under Invalid 
+            BSIC category */
+    {
+      /* check whether Invalid BSIC reporting is enabled or not and NCC part is 
+        permitted or not */
+      if ( (p_enh->inv_bsic_enabled EQ TRUE) AND
+           ((BOOL)((UBYTE)(p_enh->ncc_permitted & 
+           ncc_bit_mask[(enh_cell_list[j].bsic.bsic & BSIC_NCC_MASK) >> 3])) NEQ 0) )
+      {
+        /* put it in rest bin */
+        p_rbin->enh_index[p_rbin->num_valid++] = j;
+      }     
+    } /* if enh_cell_list.index */
+  } /* end of for */
+}/* cs_nc_sort_cells_into_bins */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_get_band_index_for_emr
++------------------------------------------------------------------------------
+| Description : This is implementation specific function. This is used to
+|               get index into emr reporting data (reporting threshold and
+|               offset) array, which is band specific.
+|               
+|
+| Parameters  : ARFCN
+|
++------------------------------------------------------------------------------
+*/
+
+LOCAL UBYTE cs_get_band_index_for_emr (USHORT arfcn)
+{
+ 
+  TRACE_FUNCTION( "cs_get_band_index_for_emr" );
+
+  if ( INRANGE(LOW_CHANNEL_900, arfcn, HIGH_CHANNEL_900) )
+  {
+    return 0;
+  }
+  else if ( INRANGE(LOW_CHANNEL_1800, arfcn, HIGH_CHANNEL_1800))
+  {
+    return 1;
+  }
+  else if (INRANGE(LOW_CHANNEL_1900, arfcn, HIGH_CHANNEL_1900))
+  {
+    return 3;
+  }
+  else if ( INRANGE(LOW_CHANNEL_850, arfcn, HIGH_CHANNEL_850))
+  {
+    return 4;
+  }
+  else
+  {
+    return 2;
+  }
+}/* cs_get_band_index_for_emr */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_nc_sort_and_store_meas_results
++------------------------------------------------------------------------------
+| Description : This function sorts the cells collected in each bin, in
+|               descending order of RXLEV
+|               
+|
+| Parameters  : Pointer to bin, Number of cells to be reported
+|
++------------------------------------------------------------------------------
+*/
+
+LOCAL void cs_nc_sort_and_store_meas_results(T_ENH_BIN *p_bin, UBYTE nbr_rpt)
+{
+  UBYTE     i;
+  UBYTE     j;
+  UBYTE     max_rxlev;
+  UBYTE     k;
+  UBYTE     temp;
+  T_ENH_CELL_LIST *enh_cell_list  = &(grr_data->db.enh_cell_list[0]);
+  
+  TRACE_FUNCTION( "cs_nc_sort_and_store_meas_results" );
+
+  for (i = 0; (i < p_bin->num_valid AND nbr_rpt > 0); i++,nbr_rpt--)
+  {
+    max_rxlev = enh_cell_list[p_bin->enh_index[i]].rla_p;
+
+    k = i;
+
+    for ( j = i+1; j < p_bin->num_valid ; j++ )
+    {
+      if ( enh_cell_list[p_bin->enh_index[j]].rla_p > max_rxlev )
+      {
+
+        k = j;
+        
+        max_rxlev = enh_cell_list[p_bin->enh_index[j]].rla_p;
+      }
+    }
+    
+    grr_data->db.sorted_enh_cell_list.
+      enh_index[grr_data->db.sorted_enh_cell_list.num_valid] = 
+      p_bin->enh_index[k];
+    grr_data->db.sorted_enh_cell_list.num_valid++;
+    
+    if(k NEQ i)
+    {
+      temp = p_bin->enh_index[k];
+      p_bin->enh_index[k] = p_bin->enh_index[i];
+      p_bin->enh_index[i] = temp;
+    }
+
+  }
+}/* cs_nc_sort_and_store_meas_results */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_nc_update_rest_bin
++------------------------------------------------------------------------------
+| Description : This function updates the rest bin by appending the left out
+|               cells in the other bins. These may also have to be reported
+|               along with the cells in rest bin.
+|               
+|
+| Parameters  : Pointers to the rest and a bin, Number of cells to be reported
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_nc_update_rest_bin(T_ENH_BIN *p_rbin, T_ENH_BIN *p_bin, 
+                                 UBYTE nbr_rpt)
+{
+  UBYTE i, count;
+
+  TRACE_FUNCTION( "cs_nc_update_rest_bin" );
+
+  count = p_bin->num_valid - nbr_rpt;
+
+  for ( i = 0; i < count; i++)
+  {
+    p_rbin->enh_index[p_rbin->num_valid++] = p_bin->enh_index[nbr_rpt++];
+    p_bin->num_valid--;
+  }
+
+}/* cs_nc_update_rest_bin */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_nc_scale_rxlev
++------------------------------------------------------------------------------
+| Description : This function performs the scaling of RXLEV.
+|               
+|
+| Parameters  : Nil
+|
++------------------------------------------------------------------------------
+*/
+LOCAL UBYTE cs_nc_scale_rxlev (void)
+{
+  UBYTE     i;
+  UBYTE     no_of_cells = grr_data->db.cnt_enh_cell_list;
+  UBYTE     scale;
+  T_ENH_CELL_LIST   *enh_cell_list   = &(grr_data->db.enh_cell_list[0]);
+  UBYTE     scale_order = grr_data->db.nc_ref_lst.enh_param->scale_order;
+
+  TRACE_FUNCTION( "cs_nc_scale_rxlev" );
+
+    /*If scaling is automatic, then we find the scaling as below:
+     If the maximum RXLEV is greater than 63 (MAX_RXLEV), then we add 10dB
+     and check whether it falls into the range after scaling*/
+  /* Note: The assumption is L1 reports values in the following way -
+     if actual value of rxlev (x) is between y and y+1 dBm, then the reported value
+     is 110+x rounded off to next integer. */
+  if ( scale_order EQ SCALE_AUTO )
+  {
+    UBYTE     max = 0;
+    
+    if( grr_data->db.scell_info.rxlev_avg NEQ RXLEV_AVG_INVALID )
+    {
+      max = grr_data->db.scell_info.rxlev_avg;
+    }
+
+    for ( i = 0; i < no_of_cells ; i++ )
+    {
+      if (enh_cell_list[i].rxlev_avg > max )
+      {
+        max = enh_cell_list[i].rxlev_avg;
+      }
+    }
+    
+    if ( max > 63 )
+    {
+      /* If the max value is greater than 63, we scale by 10 so that
+         rxlev values of maximum cells will come into range(0 - 63) */
+      scale = 10;
+    }
+    else
+    {
+      scale = 0;
+    }
+  }
+  else
+  {
+    scale = scale_order * 10;
+  }
+
+  /* Apply the scale to the values to be reported for SCELL and NCELLs */
+
+  if( grr_data->db.scell_info.rxlev_avg NEQ RXLEV_AVG_INVALID )
+  {
+    grr_data->db.scell_info.rxlev_avg -= scale;
+  }
+
+  for ( i = 0; i < no_of_cells ; i++ )
+  {
+    if (enh_cell_list[i].rxlev_avg > scale)
+    {
+      enh_cell_list[i].rxlev_avg -= scale;
+    }
+    else
+    {
+      enh_cell_list[i].rxlev_avg = 0;
+    }
+
+    if (enh_cell_list[i].rxlev_avg > 63)
+    {
+      enh_cell_list[i].rxlev_avg = 63;
+    }
+  }
+  return (scale/10);
+}/* cs_nc_scale_rxlev */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_enh_meas_rpt
++------------------------------------------------------------------------------
+| Description : This function is used to build PEMR
+|
+| Parameters  : u_enh_meas_report - Pointer to ENH measurement report
+|
++------------------------------------------------------------------------------
+*/
+LOCAL BOOL cs_build_enh_meas_rpt ( T_U_ENHNC_MEAS_REPORT *u_enh_meas_report )
+{
+  T_NC_ORDER nc_ord        = cs_get_network_ctrl_order( TRUE );
+  /*UBYTE     size_avail     = MSG_SIZE_PEMR - MAND_SIZE_PEMR;*/
+  BOOL   pbcch_present     = grr_is_pbcch_present( );
+  UBYTE  psi3_cm = grr_get_psi3_cm();
+  T_nc_meas_rep_enh *nc_meas_rep_enh = &(u_enh_meas_report->nc_meas_rep_enh);
+  UBYTE used_bits = 0; /* for formality sake only, not used here */
+  UBYTE rxlev_scell;
+  UBYTE v_i_scell;
+  UBYTE i_scell;
+  BOOL rsc_avail = FALSE;
+  BOOL isc_avail = FALSE;
+
+  TRACE_FUNCTION( "cs_build_enh_meas_rpt" );
+
+  /* process message type */
+  u_enh_meas_report->msg_type = U_ENHNC_MEAS_REPORT_c;
+
+  /* process TLLI */
+  grr_set_buf_tlli( &u_enh_meas_report->tlli_value, grr_get_tlli( ) );
+
+  /* Process NC Measurements */
+
+  /* process NC mode */
+  switch( nc_ord )
+  {
+    case NC_NC1: nc_meas_rep_enh->nc_mode = NCMODE_NC1; break;
+    case NC_NC2: nc_meas_rep_enh->nc_mode = NCMODE_NC2; break;
+
+    default:
+    TRACE_ERROR( "cs_build_enh_meas_rpt no valid NC mode" ); 
+    return( FALSE );
+  }
+  
+  /* process BA used, PSI3 change mark and PMO used */
+  if( pbcch_present EQ FALSE )
+  {
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.flag = FALSE;
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.v_ba_ind_used = TRUE;
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.v_ba_ind_used_3g = TRUE;
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.ba_ind_used =
+      psc_db->ba_ind;
+  }
+  else
+  {
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.flag = TRUE;
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.v_psi3_cm = TRUE;
+    u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.psi3_cm = psi3_cm;
+  }
+  
+  u_enh_meas_report->nc_meas_rep_enh.ba_psi3_str.pmo_ind_used =
+    psc_db->nc_ms.pmo_ind;
+
+  /* process serving cell data - rxlev and ilev */
+  cs_process_serving_cell_data(&rxlev_scell, &v_i_scell, &i_scell, &used_bits,
+                                 &rsc_avail, &isc_avail);
+  
+  if((rsc_avail EQ TRUE) AND (isc_avail EQ FALSE))
+  {
+    /* Only RXLEV of SCELL avalable. ILEV of SCELL not available */
+    nc_meas_rep_enh->v_serv_cell_data = TRUE;
+    nc_meas_rep_enh->serv_cell_data.v_i_scell = FALSE;
+    nc_meas_rep_enh->serv_cell_data.rxlev_scell = rxlev_scell;
+  }
+  else if(rsc_avail EQ FALSE)
+  {
+    /* RXLEV of SCELL not avalable. Hence SCELL info is not reported */
+    nc_meas_rep_enh->v_serv_cell_data = FALSE;
+  }
+  else if((rsc_avail EQ TRUE) AND (isc_avail EQ TRUE))
+  {
+    /* Both RXLEV and ILEV of SCELL available and reported */
+    nc_meas_rep_enh->v_serv_cell_data = TRUE;
+    nc_meas_rep_enh->serv_cell_data.v_i_scell = TRUE;
+    nc_meas_rep_enh->serv_cell_data.rxlev_scell = rxlev_scell;
+    nc_meas_rep_enh->serv_cell_data.i_scell = i_scell;
+  }
+
+  /* process NC measurement results */
+  if(cs_fill_nc_enh_meas_results(nc_meas_rep_enh) EQ FALSE)
+  {
+    nc_meas_rep_enh->v_nc_rep_quan = FALSE;
+  }
+
+  /* process BSIC_SEEN and SCALE */
+  if(nc_meas_rep_enh->c_rep_invalid_bsic_info NEQ 0)
+  {
+    nc_meas_rep_enh->bsic_seen = TRUE;
+  }
+  else
+  {
+    nc_meas_rep_enh->bsic_seen = FALSE;
+  }
+
+  nc_meas_rep_enh->scale = grr_data->db.pemr_params.scale_used;
+
+  return(TRUE);
+    
+} /* cs_build_enh_meas_rpt() */
+
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_fill_nc_meas_results
++------------------------------------------------------------------------------
+| Description : This function is used to fill ENH measurements of neighbour 
+|               cells in the PEMR message
+|               
+|
+| Parameters  : Pointer to ENH meas parameters struct
+|
++------------------------------------------------------------------------------
+*/
+
+LOCAL BOOL cs_fill_nc_enh_meas_results(T_nc_meas_rep_enh *nc_meas_rep_enh)
+{
+  UBYTE     size_avail = MSG_SIZE_PEMR - MAND_SIZE_PEMR;
+  UBYTE     i;
+  UBYTE     highest_index = 0;
+  T_ENH_CELL_LIST *enh_cell_list = &(grr_data->db.enh_cell_list[0]);
+  T_ENH_BIN *sorted_list = &grr_data->db.sorted_enh_cell_list;
+  UBYTE     index_0 = 1;
+
+  nc_meas_rep_enh->nc_rep_quan.c_reporting_quantity_bmp = 0;
+  nc_meas_rep_enh->c_rep_invalid_bsic_info = 0;
+  
+  
+  TRACE_FUNCTION( "cs_fill_nc_meas_results" );
+
+  /*lint -e{437} Passing struct '' to ellipsis */
+  TRACE_EVENT_P1("dump=%x",grr_data->db.enh_cell_list[0]);
+
+  if(grr_data->db.sorted_enh_cell_list.num_valid EQ 0)
+  {
+    return(FALSE);
+  }
+
+  nc_meas_rep_enh->v_nc_rep_quan = TRUE;
+  
+  for(i = 0; i < sorted_list->num_valid; i++)
+  {
+    if(enh_cell_list[sorted_list->enh_index[i]].bsic.status EQ BSIC_VALID)
+    {
+      /*Fill it in valid BSIC bit map reporting, enh_cell_list[i]->index 
+        corresponds to the bit in the report. Find whether size permits */
+        TRACE_EVENT_P2("I%x = %x",i,enh_cell_list[sorted_list->enh_index[i]].index);
+      nc_meas_rep_enh->nc_rep_quan.
+        reporting_quantity_bmp[enh_cell_list[sorted_list->enh_index[i]].index].
+        v_reporting_quantity = TRUE;
+      nc_meas_rep_enh->nc_rep_quan.
+        reporting_quantity_bmp[enh_cell_list[sorted_list->enh_index[i]].index].
+        reporting_quantity = enh_cell_list[sorted_list->enh_index[i]].rxlev_avg;
+      
+      size_avail = size_avail - index_0;
+      index_0 = 0;
+        
+      if ( enh_cell_list[sorted_list->enh_index[i]].index > highest_index ) 
+      {
+        /* When the place where the RXLEV has to be filled requires
+           additional bits in bit map, then we have to account for
+           these single bits and additional 6 bits for RXLEV */
+        if ( size_avail >= (enh_cell_list[sorted_list->enh_index[i]].index 
+                            - highest_index) + NC_RXLEV_N_LEN )
+        {
+          /* This means we require atleast enh_cell_list[i]->index - 
+             highest_index+6 bits in bit map to include this rxlev */
+          /* 6 bits for RXLEV itself */
+          size_avail = size_avail - 
+            (enh_cell_list[sorted_list->enh_index[i]].index - highest_index
+             + NC_RXLEV_N_LEN);
+          highest_index = enh_cell_list[sorted_list->enh_index[i]].index;
+          nc_meas_rep_enh->nc_rep_quan.
+            c_reporting_quantity_bmp = 
+            enh_cell_list[sorted_list->enh_index[i]].index + 1; /* counter is index+1 */
+          continue;
+        }
+        else if (size_avail >= NC_RXLEV_N_LEN)
+        {
+          continue;
+        }
+        else
+          break; /* No more filling possible */       
+      }
+      else if (size_avail >= NC_RXLEV_N_LEN)
+      {
+        size_avail -= NC_RXLEV_N_LEN; /* size for bit map is already accounted for*/
+        nc_meas_rep_enh->nc_rep_quan.
+              c_reporting_quantity_bmp = highest_index +1;
+        continue;
+      }
+      else
+      {
+        break; /*no more inclusion of results is possible*/
+      }              
+    }
+    else
+    {
+      /* fill in invalid BSIC list since cell is not present in the neighbour cell
+         list. Here the index that needs to be filled is index of the ARFCN in BA(list)*/
+      if ( size_avail > NC_INVBSIC_PEMR )
+      {
+        nc_meas_rep_enh->v_rep_invalid_bsic_info = TRUE;
+        nc_meas_rep_enh->rep_invalid_bsic_info
+        [nc_meas_rep_enh->c_rep_invalid_bsic_info].bcch_freq_ncell
+        = enh_cell_list[sorted_list->enh_index[i]].index;
+        nc_meas_rep_enh->rep_invalid_bsic_info
+          [nc_meas_rep_enh->c_rep_invalid_bsic_info].bsic
+          = enh_cell_list[sorted_list->enh_index[i]].bsic.bsic;
+        nc_meas_rep_enh->rep_invalid_bsic_info
+          [nc_meas_rep_enh->c_rep_invalid_bsic_info].rxlev_ncell
+          = enh_cell_list[sorted_list->enh_index[i]].rxlev_avg;
+        nc_meas_rep_enh->c_rep_invalid_bsic_info++;
+        size_avail -= NC_INVBSIC_PEMR;
+      }          
+    }
+  }
+
+  return(TRUE);
+
+}/* cs_fill_nc_enh_meas_results */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_enh_sorted_strng_arfcn_list
++------------------------------------------------------------------------------
+| Description : The purpose of this function is to sort the cells into various
+|               bins and in desc order of RXLEV in each of the bin. The ARFCNs
+|               in the sorted bin are finally sent to RR for decoding purpose
+|               
+|
+| Parameters  : Pointers to the final sorted bin for storage
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_build_enh_sorted_strng_arfcn_list(T_ENH_STRNG_ARFCN_LIST *f_bin)
+{
+  T_ENH_STRNG_ARFCN_LIST s_bin, r_bin;
+
+  UBYTE total_arfcns;
+
+  f_bin->num = 0;
+  
+  TRACE_FUNCTION( "cs_build_enh_sorted_strng_arfcn_list" );
+
+  /* Sort ARFCNs into Serving, Non-serving or the Rest*/
+  total_arfcns = cs_sort_arfcns_into_bins(&s_bin, &r_bin);
+
+  /* Sort the ARFCNs in desc order of RXLEV and store them in the final bin */
+  if(total_arfcns NEQ 0)
+  {
+    cs_sort_store_in_desc_order_rxlev(&s_bin, f_bin);
+    cs_sort_store_in_desc_order_rxlev(&r_bin, f_bin);
+  }
+}
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_sort_arfcns_into_bins
++------------------------------------------------------------------------------
+| Description : The purpose of this function is to sort the ARFCNs into various
+|               bins. 
+|               
+|
+| Parameters  : Pointers to the the bins
+|
++------------------------------------------------------------------------------
+*/
+LOCAL UBYTE cs_sort_arfcns_into_bins(T_ENH_STRNG_ARFCN_LIST *p_s_bin,
+                                     T_ENH_STRNG_ARFCN_LIST *p_r_bin)
+{
+  UBYTE     i;
+  UBYTE     band, sc_band;
+  UBYTE     total_cells = 0;
+  
+  p_s_bin->num = 0;
+  p_r_bin->num = 0;
+
+  TRACE_FUNCTION( "cs_sort_arfcns_into_bins" );
+
+  sc_band = cs_get_band_index_for_emr (psc_db->pbcch.bcch.arfcn);
+  
+  /* Check the ARFCNs in the NC_MVAL and store them in Serving or
+     Rest bins according to their bands */
+  i = 0;
+  while( (i < MAX_NR_OF_NC_MVAL) AND (total_cells <= MAX_NR_OF_NCELL) )
+  {
+    if( (grr_data->db.nc_mval_list.nc_mval[i].arfcn NEQ RRGRR_INVALID_ARFCN) 
+      AND (grr_data->db.nc_mval_list.nc_mval[i].status EQ NC_MVAL_STAT_ASSIGNED) )
+    {
+      band = cs_get_band_index_for_emr(grr_data->db.nc_mval_list.nc_mval[i].arfcn);
+      if (band EQ sc_band)
+      {
+        p_s_bin->meas[p_s_bin->num].arfcn =
+          grr_data->db.nc_mval_list.nc_mval[i].arfcn;
+        p_s_bin->meas[p_s_bin->num].rxlev = 
+          grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
+        p_s_bin->num++;
+        
+      }
+      else /* Process the non-serving bands */
+      {
+        p_r_bin->meas[p_r_bin->num].arfcn = 
+          grr_data->db.nc_mval_list.nc_mval[i].arfcn;
+        p_r_bin->meas[p_r_bin->num].rxlev = 
+          grr_data->db.nc_mval_list.nc_mval[i].rla_p.lev;
+        p_r_bin->num++;
+      }
+      total_cells = p_s_bin->num + p_r_bin->num;
+    }
+    i++;
+  } /* end of while */
+  return(total_cells);
+}/* cs_sort_arfcns_into_bins */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_sort_in_desc_order_rxlev
++------------------------------------------------------------------------------
+| Description : This function sorts the cells collected in each bin, in
+|               descending order of RXLEV. It will be stored in the final bin
+|               as and when sorted.
+|               
+|
+| Parameters  : Pointer to serving or multiband bin, Pointer to final bin
+|
++------------------------------------------------------------------------------
+*/
+
+LOCAL void cs_sort_store_in_desc_order_rxlev(T_ENH_STRNG_ARFCN_LIST *p_bin, 
+                                             T_ENH_STRNG_ARFCN_LIST *p_f_bin)
+{
+  UBYTE     i;
+  UBYTE     j;
+  UBYTE     max_rxlev;
+  UBYTE     k;
+  T_MEAS    temp;
+  
+  TRACE_FUNCTION( "cs_sort_store_in_desc_order_rxlev" );
+
+  for (i = 0; i < p_bin->num; i++)
+  {
+    max_rxlev = p_bin->meas[i].rxlev;
+    k = i;
+    for ( j = i + 1; j < p_bin->num; j++ )
+    {
+      if ( p_bin->meas[j].rxlev > max_rxlev )
+      {
+        k = j;
+        max_rxlev = p_bin->meas[j].rxlev;
+      }
+    }
+    
+    /* Store the ARFCN-RXLEV pair in the final bin in desc order of RXLEV */
+    p_f_bin->meas[p_f_bin->num++] = p_bin->meas[k];
+
+    if(k NEQ i)
+    {
+      temp = p_bin->meas[k];
+      p_bin->meas[k] = p_bin->meas[i];
+      p_bin->meas[i] = temp;
+    }
+  }
+}/* cs_sort_store_in_desc_order_rxlev */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_init_ba_bcch_nc_ref_list
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : list  - pointer to NC measurement pointer list
+|
++------------------------------------------------------------------------------
+*/
+GLOBAL void cs_init_ba_bcch_nc_ref_list ()
+{ 
+  TRACE_FUNCTION( "cs_init_ba_bcch_nc_ref_list" );
+  
+  grr_data->db.ba_bcch_nc_ref_lst.number = 0;
+
+}/* cs_init_ba_bcch_nc_ref_list */
+
+/*
++------------------------------------------------------------------------------
+| Function    : cs_build_ba_bcch_nc_freq_list
++------------------------------------------------------------------------------
+| Description : 
+|
+| Parameters  : db - pointer to serving cell database
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_build_ba_bcch_nc_freq_list ()
+{
+  UBYTE i;
+  
+  TRACE_FUNCTION( "cs_build_ba_bcch_nc_freq_list" );
+
+  /*
+   * add neighbour cell information of SI2 and PMO to reference list
+   */
+  for( i = 0; i < psc_db->nc_ba_bcch_cw.number; i++ )
+  {
+    grr_data->db.ba_bcch_nc_ref_lst.info[i] = &psc_db->nc_ba_bcch_cw.info[i];
+    grr_data->db.ba_bcch_nc_ref_lst.number++;
+  }
+
+  if(use_ba_gprs EQ FALSE)  
+  {
+    UBYTE number = psc_db->nc_ba_bcch_cw.number;
+    for(i = 0; i < psc_db->nc_ms.ncmeas.list.number; i++)
+    {
+      grr_data->db.ba_bcch_nc_ref_lst.info[number] =
+        &psc_db->nc_ms.ncmeas.list.info[i];
+      grr_data->db.ba_bcch_nc_ref_lst.info[number]->index = number;
+      grr_data->db.ba_bcch_nc_ref_lst.number++;
+      number++;
+    }
+  } 
+}
+
+#endif
+/*
++------------------------------------------------------------------------------
+| Function    : cs_copy_rxlev_from_avg
++------------------------------------------------------------------------------
+| Description : The function cs_copy_rxlev_from_avg() helps to retain the old
+|               rxlev data obtained for the neighbour cells before the cell 
+|               change. 
+| Parameters  : Index of the nc_data->cell,nc_mval->rxlev_avg 
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_copy_rxlev_from_avg(UBYTE rxlev_avg,T_CELL *cell)
+{
+#define INITIAL_ACC_MEAS 4
+  UBYTE i; /* used for counting */ 
+  T_RLA_P_DATA *rla_p_data = &cell->rla_p_data;
+  T_RXLEV_DATA *rxlev_data = &cell->rxlev_data;
+  
+  TRACE_FUNCTION( "cs_copy_rxlev_from_avg" );
+  TRACE_EVENT_P3( "cs_copy_rxlev_from_avg arfcn=%ld LOI=%ld rxlev_avg=%ld", cell->arfcn,rla_p_data->loi,rxlev_avg);
+  
+  rla_p_data->loi    = INITIAL_ACC_MEAS - 1 ;
+  rla_p_data->ovrflw = FALSE;
+  
+  for( i = 0; i < INITIAL_ACC_MEAS; i++ )
+  {
+    rla_p_data->meas[i].cnt     = 1;
+    rla_p_data->meas[i].acc     = (USHORT)rxlev_avg;
+    rla_p_data->meas[i].rpt_prd = 208;
+  }
+  
+  rxlev_data->acc = rxlev_avg*INITIAL_ACC_MEAS*RXLEV_ACRCY; 
+  rxlev_data->nbr = INITIAL_ACC_MEAS;
+}
+/*
++------------------------------------------------------------------------------
+| Function    : cs_reuse_old_cell_rxlev
++------------------------------------------------------------------------------
+| Description : The function cs_reuse_old_cell_rxlev() helps to reuse rxlev data
+|               obtained for the neighbour cells in the old cell before the cell 
+|               change. 
+| Parameters  : void
+|
++------------------------------------------------------------------------------
+*/
+LOCAL void cs_reuse_old_cell_rxlev()
+{
+  T_NC_MVAL  *nc_mval;
+  UBYTE       i,found,mval_idx ;
+  UBYTE       mval_index=0;
+  
+  TRACE_FUNCTION( "cs_reuse_old_cell_rxlev" );
+  TRACE_EVENT( "cs_reuse_old_cell_rxlev" );
+  
+  for( i = 0; i < MPHP_NUMC_BA_GPRS_SC; i++ )
+  {
+#if 0	  
+    mval_index = 0;
+    nc_mval = grr_get_nc_mval( nc_data->cell[i].arfcn, RRGRR_INVALID_BSIC, &mval_index );
+    if(nc_mval NEQ 0)
+    {
+      if(nc_mval->rla_p.stat EQ CS_RLA_P_VALID)
+      {
+        cs_copy_rxlev_from_avg( (UBYTE)nc_mval->rxlev_avg,&nc_data->cell[i] );
+      }
+      else
+      {
+        cs_reset_meas_result( &nc_data->cell[i] );		
+      }
+    }
+    else
+    {
+      cs_reset_meas_result( &nc_data->cell[i] );
+    }
+#else
+    found=0;
+    for( mval_idx = 0; mval_idx < MAX_NR_OF_NC_MVAL; mval_idx++ )
+    {
+      nc_mval = &grr_data->db.nc_mval_list.nc_mval[mval_idx];
+      if((UBYTE)nc_mval->rxlev_avg EQ 0xFF AND 
+          nc_mval->rla_p.stat EQ CS_RLA_P_VALID)
+      {
+        TRACE_EVENT_P4("PATCH: arfcn=%ld avg_lev=%ld rla_p_lev=%ld stat=%ld "
+                    ,nc_mval->arfcn,nc_mval->rxlev_avg,nc_mval->rla_p.lev,nc_mval->rla_p.stat);
+      }
+      if(
+          (nc_mval->arfcn EQ nc_data->cell[i].arfcn) 
+          AND 
+          (nc_mval->rla_p.stat EQ CS_RLA_P_VALID)
+          AND
+          ((UBYTE)nc_mval->rxlev_avg NEQ 0xFF)
+        )
+      {
+        cs_copy_rxlev_from_avg( (UBYTE)nc_mval->rxlev_avg,&nc_data->cell[i] );
+        found=1;
+      }
+    }
+    if(!found)
+      cs_reset_meas_result( &nc_data->cell[i] );
+#endif
+  }
+}
+
+
+
+
+
+
+