FreeCalypso > hg > freecalypso-sw
diff gsm-fw/g23m-gsm/rr/rr_srv.c @ 673:2f7df7a314f8
gsm-fw/g23m-gsm subtree: initial import from LoCosto source
author | Michael Spacefalcon <msokolov@ivan.Harhan.ORG> |
---|---|
date | Sun, 28 Sep 2014 23:20:04 +0000 |
parents | |
children | 74cfa6727aa3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gsm-fw/g23m-gsm/rr/rr_srv.c Sun Sep 28 23:20:04 2014 +0000 @@ -0,0 +1,1034 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : ++----------------------------------------------------------------------------- +| 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 defines the functions for the common +| services of the component RR of the mobile station. ++----------------------------------------------------------------------------- +*/ + +#ifndef RR_SRV_C +#define RR_SRV_C + +#define ENTITY_RR + +/*==== INCLUDES ===================================================*/ + +#include <string.h> +#include <stdlib.h> +#include <stddef.h> /* offsetof */ +#include "typedefs.h" +#include "pcm.h" +#include "pconst.cdg" +#include "mconst.cdg" +#include "message.h" +#include "ccdapi.h" +#include "vsi.h" +#include "custom.h" +#include "gsm.h" +#include "prim.h" +#include "cnf_rr.h" +#include "tok.h" +#include "rr.h" + + +/*==== EXPORT =====================================================*/ + +/*==== PRIVAT =====================================================*/ +LOCAL UBYTE srv_is_not_in_list (USHORT * channels, + USHORT new_channel, + USHORT size); +/*==== VARIABLES ==================================================*/ + +/*==== FUNCTIONS ==================================================*/ +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_store_prim | ++--------------------------------------------------------------------+ + + PURPOSE : stores a primitive into a ring buffer. The buffer contains + up to MAX_RR_STORED_PRIM primitives. The ring buffer is + controlled by the variables stored_prim_in, which is the + index of the next free place in the buffer. The variable + stored_prim_read defines the number of stored primitives, + which are already indicated as to be read again (by function + srv_use_stored_prim. The variable stored_prim_write indicates + the number of stored primitives, which are not indicated as + to be read again (by function srv_use_stored_prim). + The return value of the function indicates whether the storing + was successful or not. + +*/ + +BOOL srv_store_prim (T_PRIM * prim) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("srv_store_prim()"); + + /* + * check the limits. If buffer is full, return false. + */ + if (rr_data->stored_prim_read + rr_data->stored_prim_write >= + MAX_RR_STORED_PRIM) + { + TRACE_EVENT ("Buffer overrun"); + return FALSE; + } + + + /* + * Else store the primitive + */ + TRACE_EVENT ("save prim"); + + /* + * store primitive address and increment stored_prim_in + * to next free location. + */ + rr_data->stored_prim [rr_data->stored_prim_in++] = prim; + + /* + * set stored_prim_in to 0 if at the boarder of the ring buffer + */ + if (rr_data->stored_prim_in EQ MAX_RR_STORED_PRIM) + { + rr_data->stored_prim_in = 0; + } + + /* + * increment Number of the stored primitives which are not + * indicated as to be read again. + */ + rr_data->stored_prim_write++; + + /* + * return the success of storing of the primitive. + */ + return TRUE; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_use_stored_prim | ++--------------------------------------------------------------------+ + + PURPOSE : The function re-send all stored primitives to RR. This + function is called by RR whenever a stored primitive must + be taken in account, e.g. after cell reselection to handle + a stored paging. + +*/ + +GLOBAL void srv_use_stored_prim (void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("srv_use_stored_prim()"); + + ENTITY_DATA->use_stored_entries = FALSE; + + /* + * Only if anything new has been stored + */ + if (rr_data->stored_prim_write > 0) + { + /* + * increment the number of primitives which + * must be re-send to RR by the number of + * newly stored primitives and reset this variable + * to zero. + */ + rr_data->stored_prim_read += + rr_data->stored_prim_write; + rr_data->stored_prim_write = 0; + + /* + * For all stored primitives + */ + while (rr_data->stored_prim_read NEQ 0) + { + T_PRIM * prim; + + rr_data->stored_prim_read--; + + /* + * get the primitive address + */ + prim = rr_data->stored_prim[rr_data->stored_prim_out]; + rr_data->stored_prim[rr_data->stored_prim_out ] = NULL; + rr_data->stored_prim_out++; + /* + * set the stored_prim_out pointer to the start of the + * ring buffer, if it is at the end of the buffer + */ + if (rr_data->stored_prim_out EQ MAX_RR_STORED_PRIM) + rr_data->stored_prim_out = 0; + + /* + * If the stored primitive is a paging_ind clear the stored paging flag + * right away. If not the paging will be thrown away if the flag was + * not reset propperly on the outside + */ + if(prim NEQ NULL AND prim->custom.opc EQ MPH_PAGING_IND) + { + rr_data->pag_rec = FALSE; + } + + /* + * call the protocol entity interface function to handle + * the stored primitive. + */ + rr_pei_primitive (prim); + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_clear_stored_prim | ++--------------------------------------------------------------------+ + + PURPOSE : The function clears all primitives with the given opcode + from the ring buffer. If the opcode matches, it releases + the partition and stores instead a NULL pointer. + +*/ + +GLOBAL void srv_clear_stored_prim (ULONG opc) +{ + GET_INSTANCE_DATA; + USHORT i, out; + + TRACE_FUNCTION ("srv_clear_stored_prim()"); + + /* + * Only if anything is stored + */ + if (rr_data->stored_prim_read + rr_data->stored_prim_write > 0) + { + /* + * Calculate the number of stored primitives and the beginning + */ + i = rr_data->stored_prim_read + rr_data->stored_prim_write; + out = rr_data->stored_prim_out; + + while (i NEQ 0) + { + /* + * for each stored primitive + */ + T_PRIM * prim; + + i--; + + /* + * Get the partition + */ + prim = rr_data->stored_prim[out]; + if (prim NEQ NULL AND prim->custom.opc EQ opc) + { + /* + * If a primitive is stored and it has the + * exspected opcode, release the primitive + * and store instead a NULL pointer. + */ + PFREE (P2D(prim)); + rr_data->stored_prim[out] = NULL; + } + /* + * increment out index and set it to 0 if + * it is on the right boarder of the ring buffer + */ + out++; + if (out EQ MAX_RR_STORED_PRIM) + out = 0; + } + } +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_check_stored_prim | ++--------------------------------------------------------------------+ + + PURPOSE : Check specific stored primitives. Indicates whether + a primitive with opcode opc is already stored. + +*/ + +GLOBAL UBYTE srv_check_stored_prim (ULONG opc) +{ + GET_INSTANCE_DATA; + USHORT i, out; + + TRACE_FUNCTION ("srv_check_stored_prim()"); + + /* + * only if a primitve is stored + */ + if (rr_data->stored_prim_read + rr_data->stored_prim_write > 0) + { + /* + * calculate number of stored primitives and the beginning + */ + i = rr_data->stored_prim_read + rr_data->stored_prim_write; + out = rr_data->stored_prim_out; + + while (i NEQ 0) + { + /* + * for all stored primitives + */ + T_PRIM * prim; + + i--; + /* + * get the primitive address + */ + prim = rr_data->stored_prim[out]; + if (prim NEQ NULL AND prim->custom.opc EQ opc) + { + /* + * return TRUE if a primitive is stored and the opcode + * is as expected. + */ + return TRUE; + } + /* + * increase out index to the next entry + */ + out++; + if (out EQ MAX_RR_STORED_PRIM) + out = 0; + } + } + + /* + * nothing found + */ + return FALSE; +} + +/* ++---------------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_compare_used_frequency_bands | ++---------------------------------------------------------------------------+ + + PURPOSE : Looks at the frequency bands which were used and compares + them with the supported bands. Checks if the MA spans more + then one band (exception is the EGSM part). + +*/ + +LOCAL int srv_compare_used_frequency_bands (int frequency_bands_used) +{ + int nr_of_frequency_bands_used; + switch(frequency_bands_used) + { + case LOW_BAND_USED: + if(std EQ STD_900 OR std EQ STD_EGSM OR std EQ STD_850 OR + std EQ STD_DUAL OR std EQ STD_DUAL_EGSM OR std EQ STD_DUAL_US +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + 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 + ) + nr_of_frequency_bands_used = 1; + else + nr_of_frequency_bands_used = 0; + break; + case HIGH_BAND_USED: + if(std EQ STD_1800 OR std EQ STD_1900 OR + std EQ STD_DUAL OR std EQ STD_DUAL_EGSM OR std EQ STD_DUAL_US +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + 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 + ) + nr_of_frequency_bands_used = 1; + else + nr_of_frequency_bands_used = 0; + break; + case EXT_BAND_USED: + case LOW_BAND_USED|EXT_BAND_USED: + if(std EQ STD_EGSM OR std EQ STD_DUAL_EGSM +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + OR std EQ STD_900_1900 OR std EQ STD_850_900_1800 OR std EQ STD_850_900_1900 +#endif + ) + nr_of_frequency_bands_used = 1; + else + nr_of_frequency_bands_used = 0; + break; + default: + nr_of_frequency_bands_used = 0; + break; + } + + return nr_of_frequency_bands_used; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_create_chan_mob_alloc | ++--------------------------------------------------------------------+ + + PURPOSE : create a frequency hopping list from channel list and + mobile allocation. The mobile allocation is a bitmap. + if the n-th bit of the mobile allocation is set to zero, + the n-th channel in the channel list is not member of the + frequency hopping list. If the n-th bit of the mobile + allocation is set to one, the n-th channel in the channel list + is member of the frequency hopping list. + + e.g: channel list has the members 10,20,30,40,50,60,70 and + in the mobile allocation the bits 1,3 and 4 are set : + + channel list: 10 20 30 40 50 60 70 + mobile allocation: 0 1 0 1 1 0 0 + + that means the hopping list is 20, 40, 50. + + The format of the mobile allocation is an UBYTE array with the + end identifier NOT_PRESENT_8BIT (0xFF). + + The function returns TRUE if the Mobile Allocation is in one + frequency band. If the Mobile Allocation is spread over multiple + frequency bands FALSE is returned and the values returned are + invalid. + +*/ + +GLOBAL int srv_create_chan_mob_alloc (T_LIST *clist, + T_LIST *list, + UBYTE *mobile_alloc) +{ + /* + * index in the mobile allocation list + */ + USHORT ma_index = 0; + /* + * get value of the first bit which is set in the mobile allocation + */ + UBYTE ma_value = mobile_alloc [ma_index++]; + UBYTE x = 0; + UBYTE result; + USHORT arfcn; + UBYTE band_used; + UBYTE freq_band_used = 0; + + TRACE_FUNCTION ("srv_create_chan_mob_alloc()"); + + /* + * clear the result list + */ + srv_clear_list (list); + + /* + * Check all Frequencies. + */ + if(ma_value NEQ NOT_PRESENT_8BIT) + { + for (arfcn=LOW_CHANNEL_900; arfcn<HIGH_CHANNEL_EGSM; arfcn++) + { + result = srv_get_channel (clist, arfcn); + if (result) + { + x++; + } + if (x EQ ma_value) + { + band_used = for_check_frequency(arfcn); + if(band_used <= INVALID_BAND_USED) + return FALSE; + + freq_band_used = freq_band_used | band_used; + + srv_set_channel (list, arfcn); + ma_value = mobile_alloc [ma_index++]; + if (ma_value EQ NOT_PRESENT_8BIT) + break; + } + } + } + else + { + TRACE_EVENT("Mobile Allocation list empty"); + return FALSE; + } + + /* + * at last add channel 0 if needed + */ + + if (ma_value NEQ NOT_PRESENT_8BIT) + { + result = srv_get_channel (clist, CHANNEL_0); + if (result) + { + x++; + } + if (x EQ ma_value) + { + srv_set_channel (list, CHANNEL_0); + band_used = for_check_frequency(CHANNEL_0); + if(band_used <= INVALID_BAND_USED) + return FALSE; + freq_band_used = freq_band_used | EXT_BAND_USED; + } + } + + return srv_compare_used_frequency_bands(freq_band_used); + +} + + +/* ++----------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_check_frequencies_in_list| ++----------------------------------------------------------------------+ + + PURPOSE : Checks used frequencies and returns. Returns number + of frequencies used. + +*/ + +GLOBAL int srv_check_frequencies_in_list(T_LIST *clist) +{ + int frequency_bands_used = 0; + int i; + + TRACE_FUNCTION ("srv_check_frequencies_in_list()"); + + + /* + * Depending on the frequency standard + */ + switch (std) + { + case STD_900: + case STD_EGSM: + case STD_1800: + case STD_DUAL: + case STD_DUAL_EGSM: + /* + * First check GSM 900 + */ + for (i=LOW_CHANNEL_900; i<=HIGH_CHANNEL_900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + + for (i=LOW_CHANNEL_1800; i<=HIGH_CHANNEL_1800; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= HIGH_BAND_USED; + } + for (i=LOW_CHANNEL_EGSM; i<HIGH_CHANNEL_EGSM; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= EXT_BAND_USED; + } + if (srv_get_channel (clist, CHANNEL_0)) + frequency_bands_used |= EXT_BAND_USED; + break; + case STD_850: + case STD_1900: + case STD_DUAL_US: + for (i=LOW_CHANNEL_850; i<=HIGH_CHANNEL_850; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + + for (i=LOW_CHANNEL_1900; i<=HIGH_CHANNEL_1900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= HIGH_BAND_USED; + } + break; +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + case STD_850_1800: + for (i=LOW_CHANNEL_850; i<=HIGH_CHANNEL_850; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + + for (i=LOW_CHANNEL_1800; i<=HIGH_CHANNEL_1800; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= HIGH_BAND_USED; + } + break; + case STD_900_1900: + for (i=LOW_CHANNEL_900; i<=HIGH_CHANNEL_900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + + for (i=LOW_CHANNEL_1900; i<=HIGH_CHANNEL_1900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= HIGH_BAND_USED; + } + for (i=LOW_CHANNEL_EGSM; i<HIGH_CHANNEL_EGSM; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= EXT_BAND_USED; + } + if (srv_get_channel (clist, CHANNEL_0)) + frequency_bands_used |= EXT_BAND_USED; + break; + case STD_850_900_1800: + for (i=LOW_CHANNEL_900; i<=HIGH_CHANNEL_900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + + for (i=LOW_CHANNEL_1800; i<=HIGH_CHANNEL_1800; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= HIGH_BAND_USED; + } + for (i=LOW_CHANNEL_EGSM; i<HIGH_CHANNEL_EGSM; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= EXT_BAND_USED; + } + for (i=LOW_CHANNEL_850; i<=HIGH_CHANNEL_850; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + if (srv_get_channel (clist, CHANNEL_0)) + frequency_bands_used |= EXT_BAND_USED; + break; + case STD_850_900_1900: + for (i=LOW_CHANNEL_900; i<=HIGH_CHANNEL_900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + for (i=LOW_CHANNEL_EGSM; i<HIGH_CHANNEL_EGSM; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= EXT_BAND_USED; + } + for (i=LOW_CHANNEL_850; i<=HIGH_CHANNEL_850; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= LOW_BAND_USED; + } + for (i=LOW_CHANNEL_1900; i<=HIGH_CHANNEL_1900; i++) + { + if (srv_get_channel (clist, i)) + frequency_bands_used |= HIGH_BAND_USED; + } + if (srv_get_channel (clist, CHANNEL_0)) + frequency_bands_used |= EXT_BAND_USED; + break; +#endif + default: + /* + * just for LINT + */ + break; + } + + return srv_compare_used_frequency_bands (frequency_bands_used); +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_remove_frequencies_in_array_gen | ++--------------------------------------------------------------------+ + + PURPOSE : The functions manipulates the neighbourcell list send to + layer 1. It filters out not supported frequencies or if + enabled allows to configure a band restriction, that means that + the mobile camps inside GSM 900 or DCS 1800. The band + restriction can be configured by a dynamic configuration + command. + +*/ + +GLOBAL UBYTE srv_remove_frequencies_in_array_gen (USHORT* arfcn_list, UBYTE c_arfcn_list) +{ + GET_INSTANCE_DATA; + int in,out, ranges; +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + USHORT low[4], high[4]; +#else + USHORT low[3], high[3]; +#endif + UBYTE local_std = std; + + TRACE_FUNCTION ("att_check_band_restrictions()"); + + in = out = ranges = 0; + + memset (low, NOT_PRESENT_8BIT, sizeof (low)); + memset (high, NOT_PRESENT_8BIT, sizeof (high)); + + if(rr_data->dyn_config.set_band) + { + /* set band is activated */ + if (rr_data->dyn_config.set_band EQ 1) local_std = STD_900; + else if (rr_data->dyn_config.set_band EQ 2) local_std = STD_1800; + } + + switch (local_std) + { + case STD_DUAL: + ranges=2; + low[0]=LOW_CHANNEL_1800; + low[1]=LOW_CHANNEL_900; + high[0]=HIGH_CHANNEL_1800; + high[1]=HIGH_CHANNEL_900; + break; + case STD_DUAL_EGSM: + /* shift the ranges to allow CHANNEL_0 */ + ranges=3; + low[0]=LOW_CHANNEL_900-1;/*lint !e778 */ + low[1]=LOW_CHANNEL_EGSM; + low[2]=LOW_CHANNEL_1800; + high[0]=HIGH_CHANNEL_900; + high[1]=HIGH_CHANNEL_EGSM-1; + high[2]=HIGH_CHANNEL_1800; + break; + case STD_DUAL_US: + ranges=2; + low[0]=LOW_CHANNEL_1900; + low[1]=LOW_CHANNEL_850; + high[0]=HIGH_CHANNEL_1900; + high[1]=HIGH_CHANNEL_850; + break; + case STD_EGSM: + low[0] = LOW_CHANNEL_EGSM; + low[1] = LOW_CHANNEL_900-1;/*lint !e778 */ + high[0] = HIGH_CHANNEL_EGSM-1; + high[1] = HIGH_CHANNEL_900; + ranges=2; + break; + case STD_900: + low[0] = LOW_CHANNEL_900; + high[0] = HIGH_CHANNEL_900; + ranges=1; + break; + case STD_1800: + low[0] = LOW_CHANNEL_1800; + high[0] = HIGH_CHANNEL_1800; + ranges=1; + break; + case STD_1900: + low[0] = LOW_CHANNEL_1900; + high[0] = HIGH_CHANNEL_1900; + ranges=1; + break; + case STD_850: + low[0] = LOW_CHANNEL_850; + high[0] = HIGH_CHANNEL_850; + ranges=1; + break; +#ifdef TI_PS_FF_QUAD_BAND_SUPPORT + case STD_850_1800: + ranges=2; + low[0]=LOW_CHANNEL_1800; + low[1]=LOW_CHANNEL_850; + high[0]=HIGH_CHANNEL_1800; + high[1]=HIGH_CHANNEL_850; + break; + case STD_900_1900: + /* shift the ranges to allow CHANNEL_0 */ + ranges=3; + low[0]=LOW_CHANNEL_900-1;/*lint !e778 */ + low[1]=LOW_CHANNEL_EGSM; + low[2]=LOW_CHANNEL_1900; + high[0]=HIGH_CHANNEL_900; + high[1]=HIGH_CHANNEL_EGSM-1; + high[2]=HIGH_CHANNEL_1900; + break; + case STD_850_900_1800: + ranges=4; + low[0]=LOW_CHANNEL_900-1;/*lint !e778 */ + low[1]=LOW_CHANNEL_EGSM; + low[2]=LOW_CHANNEL_1800; + low[3]=LOW_CHANNEL_850; + high[0]=HIGH_CHANNEL_900; + high[1]=HIGH_CHANNEL_EGSM-1; + high[2]=HIGH_CHANNEL_1800; + high[3]=HIGH_CHANNEL_850; + break; + case STD_850_900_1900: + ranges=4; + low[0]=LOW_CHANNEL_900-1;/*lint !e778 */ + low[1]=LOW_CHANNEL_EGSM; + low[2]=LOW_CHANNEL_1900; + low[3]=LOW_CHANNEL_850; + high[0]=HIGH_CHANNEL_900; + high[1]=HIGH_CHANNEL_EGSM-1; + high[2]=HIGH_CHANNEL_1900; + high[3]=HIGH_CHANNEL_850; + break; +#endif + default: + /* default */ + break; + } + + if (ranges) + { + while (arfcn_list[in] NEQ NOT_PRESENT_16BIT AND + in < c_arfcn_list) + { + UBYTE r = ranges; + while(r) + { + if (INRANGE(low[r-1],arfcn_list[in],high[r-1])) + { + arfcn_list[out] = arfcn_list[in]; + out++; + } + r--; + } + in++; + } + arfcn_list[out] = NOT_PRESENT_16BIT; + } + + TRACE_EVENT_WIN_P2 ("%d of %d arfcn's removed", in - out, in); + + return out; +} + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_remove_frequencies_in_array | ++--------------------------------------------------------------------+ + + PURPOSE : The functions manipulates the neighbourcell list send to + layer 1. It filters out not supported frequencies or if + enabled allows to configure a band restriction, that means that + the mobile camps inside GSM 900 or DCS 1800. The band + restriction can be configured by a dynamic configuration + command. + +*/ + +GLOBAL void srv_remove_frequencies_in_array (USHORT* arfcn_list) +{ + srv_remove_frequencies_in_array_gen (arfcn_list, MAX_NEIGHBOURCELLS); +} + +/* ++-------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_trace_black_list| ++-------------------------------------------------------------+ + + PURPOSE : Traces Black list channels +*/ + +GLOBAL void srv_trace_black_list() +{ + GET_INSTANCE_DATA; + U8 i; + T_LIST *list; + + /* Trace Black List Channels */ + for(i=0;i<MAX_REGIONS;i++) + { + list = &rr_data->cs_data.black_list.list[i]; + + TRACE_EVENT_P1("Black List:[%d]Region",i); + + srv_trace_freq_in_list(list); + + } +} + +/* ++--------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_trace_white_list | ++--------------------------------------------------------------+ + + PURPOSE : Traces White list channels +*/ + +GLOBAL void srv_trace_white_list() +{ + GET_INSTANCE_DATA; + T_LIST *list; + + /* Trace White List Channels */ + if(rr_data->cs_data.white_list.region NEQ NOT_PRESENT_8BIT) + { + list = &rr_data->cs_data.white_list.list; + + TRACE_EVENT_P9 ( "[%d]Reg [%d]SC MCC/MNC r=%x%x%x/%x%x%x/%d", + rr_data->cs_data.white_list.region, + rr_data->cs_data.white_list.last_sc_arfcn, + rr_data->cs_data.white_list.last_sc_lac.mcc[0], + rr_data->cs_data.white_list.last_sc_lac.mcc[1], + rr_data->cs_data.white_list.last_sc_lac.mcc[2], + rr_data->cs_data.white_list.last_sc_lac.mnc[0], + rr_data->cs_data.white_list.last_sc_lac.mnc[1], + rr_data->cs_data.white_list.last_sc_lac.mnc[2], + rr_data->cs_data.white_list.last_sc_lac.lac); + + srv_trace_freq_in_list(list); + } + else + { + TRACE_EVENT("White List absent"); + } + +} + +#if !defined(NTRACE) +#if 0 + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_ATT | +| STATE : code ROUTINE : srv_list_channels | ++--------------------------------------------------------------------+ + + PURPOSE : print list of channels to the trace interface. +*/ +#define SRV_LIST_CHANNELS_TMPBUFSIZE 80 /* sprintf is limited to 80 characters */ +static char src_list_channels_tmpbuf[SRV_LIST_CHANNELS_TMPBUFSIZE]; +#if defined(_SIMULATION_) +int sprintf( char *buffer, const char *format, ... ); +#endif + +GLOBAL void srv_list_channels (USHORT* channel_list, USHORT size, char* titel) +{ + UBYTE i,o; + + o = sprintf(src_list_channels_tmpbuf, "%s ", titel); + for (i = 0; i < size; i++) + if (channel_list[i] NEQ NOT_PRESENT_16BIT) + { + if (o>SRV_LIST_CHANNELS_TMPBUFSIZE-5) + { + TRACE_EVENT (src_list_channels_tmpbuf); + o = 0; + } + o += sprintf(src_list_channels_tmpbuf+o, "%u,", channel_list[i]); + } + if (o) + { + src_list_channels_tmpbuf[o-1] = 0; + TRACE_EVENT (src_list_channels_tmpbuf); + } +} +#endif /* !NTRACE */ +#endif + +#ifdef GPRS + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : srv_get_cell_alloc_list | ++--------------------------------------------------------------------+ + + PURPOSE : Access function in RR to get cell alloc list. Needed by GRR to set + up hopping config. + +*/ +/* called by GRR */ +/*lint -esym(714,srv_get_cell_alloc_list) | Symbol not referenced */ +/*lint -esym(765,srv_get_cell_alloc_list) | external could be made static */ +GLOBAL void srv_get_cell_alloc_list (T_LIST * target_list) +{ + GET_INSTANCE_DATA; + srv_merge_list ( target_list, &rr_data->sc_data.cd.cell_chan_desc ); +} + +#endif /* GPRS */ + +#if defined(ARRAY_TRACE) +GLOBAL void array_trace (UBYTE*array, int size, char *titel) +{ +#define MAXCOL 80 + static char buf[MAXCOL+1]; + int col=0, n=0; + UBYTE b, nh, nl; + + memset (buf, 0, MAXCOL+1); + TRACE_EVENT_P2 ("%s size=%u bytes", titel, size); + while (n < size) + { + if (col >= MAXCOL-3) + { + TRACE_EVENT (buf); + col = 0; + memset (buf, 0, MAXCOL+1); + } + b = array[n++]; + nh = b>>4; + nl = b&0x0f; + buf[col++] = nh > 9 ? nh + 'A' - 10 : nh + '0'; + buf[col++] = nl > 9 ? nl + 'A' - 10 : nl + '0'; + buf[col++] = ' '; + } + if (col) + { + TRACE_EVENT (buf); + } +} +#endif /* ARRAY_TRACE */ + +#if defined (REL99) AND defined (TI_PS_FF_EMR) AND defined (GPRS) +#ifdef GPRS + +/* ++--------------------------------------------------------------------+ +| PROJECT : GSM-PS (6147) MODULE : RR_SRV | +| STATE : code ROUTINE : rr_get_support_for_emr | ++--------------------------------------------------------------------+ + + PURPOSE : PS-EMR flag is enabled or not. +*/ +GLOBAL BOOL rr_get_support_for_emr(void) +{ + GET_INSTANCE_DATA; + if(rr_data->ms_data.enable_ps_emr EQ TRUE) /*for grr*/ + { + return TRUE; + } + + return FALSE; +} + +#endif /*GPRS*/ +#endif + +#endif /* !RR_SRV_C */