FreeCalypso > hg > fc-magnetite
view src/g23m-gprs/grr/grr_tcf.c @ 480:41f2cc21bca9
hybrid fw: code change to support allowing GSM APDUs in AT+CSIM
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 19 Jun 2018 06:27:16 +0000 |
parents | 219afcfc6250 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | 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 TC of | entity GRR. +----------------------------------------------------------------------------- */ #ifndef GRR_TCF_C #define GRR_TCF_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" /* to get air message definitions */ #include "grr.h" /* to get the global entity definitions */ #include "grr_f.h" /* to get Process GRR global function definitions */ #include "grr_tcf.h" /* to get Service TC global function definitions */ #include "grr_tcs.h" /* to get Service TC inter signal definitions */ #include "grr_ctrls.h" /* to get interface to service CTRL */ #include "grr_cpaps.h" /* to get interface to service CPAP */ #include "grr_meass.h" /* to get the definitions for interference measurements */ #include "cl_rlcmac.h" /*==== CONST ================================================================*/ typedef enum { GRR_STORE_TYPE_NONE, GRR_STORE_TYPE_TN_ALLOC_PWR, GRR_STORE_TYPE_ALF_GAM, GRR_STORE_TYPE_PWR_PAR } T_GRR_STORE_TYPE; /* * used in tc_calc_req * */ #define RANDOM_VALUE 0xAAAA #define RANDOM_2BIT (RANDOM_VALUE & 0x0003) #define RANDOM_3BIT (RANDOM_VALUE & 0x0007) #define RANDOM_5BIT (RANDOM_VALUE & 0x001F) #define ONE_PHASE_MASK_11BIT (0x0000 | RANDOM_3BIT ) #define SHORT_ACCESS_MASK_11BIT (0x0400 | RANDOM_3BIT ) #define TWO_PHASE_MASK_11BIT (0x0600 | RANDOM_3BIT ) #define PAGE_RESPONSE_MASK_11BIT (0x0620 | RANDOM_5BIT ) #define CELL_UPDATE_MASK_11BIT (0x0640 | RANDOM_5BIT ) #define MM_PROCEDURE_MASK_11BIT (0x0660 | RANDOM_5BIT ) #define SINGLE_BLOCK_MASK_11BIT (0x0680 | RANDOM_5BIT ) #define ONE_PHASE_MASK_8BIT (0x0080 | RANDOM_2BIT ) #define SHORT_ACCESS_MASK_8BIT (0x0000 | RANDOM_3BIT ) #define TWO_PHASE_MASK_8BIT (0x0040 | RANDOM_3BIT ) #define PAGE_RESPONSE_MASK_8BIT (0x0048 | RANDOM_3BIT ) #define CELL_UPDATE_MASK_8BIT (0x0050 | RANDOM_3BIT ) #define MM_PROCEDURE_MASK_8BIT (0x0058 | RANDOM_3BIT ) #define SINGLE_BLOCK_MASK_8BIT (0x0060 | RANDOM_3BIT ) /* * used in tc_handle_ra_con */ const UBYTE max_retrans_table[4] = {1,2,4,7}; const UBYTE tx_int_table[16] = {2,3,4,5,6,7,8,9,10,12,14,16,20,25,32,50}; const UBYTE s_table[16] = {12,15,20,30,41,55,76,109,163,217, S_VALUE_RESERVED,S_VALUE_RESERVED,S_VALUE_RESERVED, S_VALUE_RESERVED,S_VALUE_RESERVED,S_VALUE_RESERVED }; /*==== DIAGNOSTICS ==========================================================*/ /*==== LOCAL VARS ===========================================================*/ /*==== PRIVATE FUNCTIONS ====================================================*/ LOCAL void tc_set_da_assignment (T_MPHP_ASSIGNMENT_REQ * ptr2prim_i); LOCAL void tc_set_fa_assignment (T_MPHP_ASSIGNMENT_REQ * ptr2prim_i); LOCAL void tc_set_dl_assignment (T_MPHP_ASSIGNMENT_REQ * ptr2prim_i); LOCAL void tc_close_gaps_in_ctrl_blk_seq( UBYTE index ); LOCAL void tc_prepare_send_tbf_release_req( T_TBF_TYPE tbf_type ); LOCAL BOOL tc_check_and_save_freq (void); LOCAL USHORT grr_convert_11bit_2_etsi ( USHORT eleven_bit ); LOCAL USHORT tc_one_phase_mask_11bit (void) { #ifdef _TARGET_ return (0x0000 | (USHORT)grr_random_value(PCR_RND_INDEX, 8)); #else return ONE_PHASE_MASK_11BIT; #endif } LOCAL SHORT tc_short_access_mask_11bit (void) { #ifdef _TARGET_ return (0x0400 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return SHORT_ACCESS_MASK_11BIT; #endif } LOCAL SHORT tc_two_phase_mask_11bit (void) { #ifdef _TARGET_ return (0x0600 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return TWO_PHASE_MASK_11BIT; #endif } LOCAL SHORT tc_page_response_mask_11bit (void) { #ifdef _TARGET_ return (0x0620 | (USHORT)grr_random_value(PCR_RND_INDEX, 32) ); #else return PAGE_RESPONSE_MASK_11BIT; #endif } LOCAL SHORT tc_cell_update_mask_11bit (void) { #ifdef _TARGET_ return (0x0640 | (USHORT)grr_random_value(PCR_RND_INDEX, 32) ); #else return CELL_UPDATE_MASK_11BIT; #endif } LOCAL SHORT tc_mm_procedure_mask_11bit (void) { #ifdef _TARGET_ return (0x0660 |(USHORT)grr_random_value(PCR_RND_INDEX, 32) ); #else return MM_PROCEDURE_MASK_11BIT; #endif } LOCAL SHORT tc_single_block_mask_11bit (void) { #ifdef _TARGET_ return (0x0680 | (USHORT)grr_random_value(PCR_RND_INDEX, 32) ); #else return SINGLE_BLOCK_MASK_11BIT; #endif } LOCAL SHORT tc_one_phase_mask_8bit (void) { #ifdef _TARGET_ return (0x0080 | (USHORT)grr_random_value(PCR_RND_INDEX, 4) ); #else return ONE_PHASE_MASK_8BIT; #endif } LOCAL SHORT tc_short_access_mask_8bit (void) { #ifdef _TARGET_ return (0x0000 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return SHORT_ACCESS_MASK_8BIT; #endif } LOCAL SHORT tc_two_phase_mask_8bit (void) { #ifdef _TARGET_ return (0x0040 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return TWO_PHASE_MASK_8BIT; #endif } LOCAL SHORT tc_page_response_mask_8bit (void) { #ifdef _TARGET_ return (0x0048 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return PAGE_RESPONSE_MASK_8BIT; #endif } LOCAL SHORT tc_cell_update_mask_8bit (void) { #ifdef _TARGET_ return (0x0050 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return CELL_UPDATE_MASK_8BIT; #endif } LOCAL SHORT tc_mm_procedure_mask_8bit (void) { #ifdef _TARGET_ return (0x0058 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return MM_PROCEDURE_MASK_8BIT; #endif } LOCAL SHORT tc_single_block_mask_8bit (void) { #ifdef _TARGET_ return (0x0060 | (USHORT)grr_random_value(PCR_RND_INDEX, 8) ); #else return SINGLE_BLOCK_MASK_8BIT; #endif } /* +------------------------------------------------------------------------------ | Function : tc_set_hopping_par +------------------------------------------------------------------------------ | Description : This function handles the frequency parameters in a ul or dl | assignment or ts reconfigure. | | Parameters : ptr2prim - pointer to the MPHP_ASSIGNMENT_REQ prim | that has to be set up. | freq_par - pointer to the received frequency parameter struct. | +------------------------------------------------------------------------------ */ GLOBAL BOOL tc_set_hopping_par ( T_freq_par *freq_par ) { BOOL result = FALSE; T_p_frequency_par frequency_par; TRACE_FUNCTION( "tc_set_hopping_par" ); memset( &frequency_par, 0, sizeof( frequency_par ) ); if(freq_par->v_indi_encod) { result = grr_validate_ma_num_in_freq_par(freq_par,GRR_FREQ_PARAM_RECEIVED_IN_ASSIGNMENT); if(result) { result = grr_create_freq_list( freq_par->indi_encod.ma_num, freq_par->indi_encod.maio, &frequency_par.p_chan_sel, &frequency_par.p_freq_list ); } else { TRACE_ERROR("error creating frequency list"); result = FALSE; } } /* if(freq_par->v_indi_encod) */ else if(freq_par->v_di_encod1) { memcpy(&psc_db->gprs_ms_alloc_in_assignment.gprs_ms_alloc_ie, &freq_par->di_encod1.gprs_ms_alloc_ie, sizeof(T_gprs_ms_alloc_ie)); psc_db->gprs_ms_alloc_in_assignment.ma_num = MA_NUMBER_4_ASSIGNMENT; psc_db->rfl[MAX_RFL].num = NOT_SET; result = grr_create_freq_list( psc_db->gprs_ms_alloc_in_assignment.ma_num, freq_par->di_encod1.maio, &frequency_par.p_chan_sel, &frequency_par.p_freq_list ); } /* if(freq_par->v_di_encod1) */ else if(freq_par->v_di_encod2) { /* * processing of T_freq_par from assignment and non-assignment messages * when direct encoding 2 is used, should be done in same object module as * this involvs use of static array variables which are local to the * object module they are used in(_local_dummy_list and _local_rfl_contents. * Hence processing for both assignment and non-assignement messages is done * in grr_f.c. If they are put in different files, we will have to duplicate * the static arrays. */ result = grr_cnv_freq_para_in_assignment_direct_enc_2(&frequency_par,freq_par); } /* if(freq_par->v_di_encod2) */ else { TRACE_ERROR("FATAL ERROR: no frequency params in ul assignment!"); } if( result EQ TRUE ) { grr_data->tc.freq_set.freq_par = frequency_par; grr_data->tc.freq_set.tsc = freq_par->tsc; } grr_data->tc.v_freq_set = result; return ( result ); }/* tc_set_hopping_par */ /* +------------------------------------------------------------------------------ | Function : tc_get_send_nb_prim_and_set_freq +------------------------------------------------------------------------------ | Description : This function allocates a primitve depending on the hopping status | and sets the frequency parameter of T_MPHP_SINGLE_BLOCK_REQ | | Parameters : | +------------------------------------------------------------------------------ */ LOCAL T_MPHP_SINGLE_BLOCK_REQ * tc_get_send_nb_prim_and_set_freq ( void ) { PALLOC( mphp_single_block_req, MPHP_SINGLE_BLOCK_REQ ); TRACE_FUNCTION( "tc_get_send_nb_prim_and_set_freq" ); memset( mphp_single_block_req, 0, sizeof( T_MPHP_SINGLE_BLOCK_REQ ) ); mphp_single_block_req->tsc = grr_data->tc.freq_set.tsc; grr_set_freq_par( &mphp_single_block_req->p_frequency_par ); return( mphp_single_block_req ); }/* tc_get_send_nb_prim_and_set_freq */ /* +------------------------------------------------------------------------------ | Function : tc_check_and_save_freq +------------------------------------------------------------------------------ | Description : This function check if the freq_par is valid or not.. | If it is hopping case, save the hoppinging freq. | | Parameters : void | +------------------------------------------------------------------------------ */ LOCAL BOOL tc_check_and_save_freq (void) { MCAST(d_dl_assign,D_DL_ASSIGN); /* T_D_DL_ASSIGN T_D_UL_ASSIGN T_D_TS_RECONFIG */ MCAST(d_ul_assign,D_UL_ASSIGN); MCAST(d_ts_reconfig,D_TS_RECONFIG); BOOL result = FALSE; T_freq_par *freq_par = NULL; BOOL mode_check = FALSE; TRACE_FUNCTION( "tc_check_and_save_freq" ); /* * store frequeny parameters, if present. * If not present, take from data base */ switch(d_dl_assign->msg_type) { case D_DL_ASSIGN: /* T_D_DL_ASSIGN */ if(d_dl_assign->pda_trnc_grp.v_freq_par) { /* replace possibly earlier stored freq params */ freq_par = &d_dl_assign->pda_trnc_grp.freq_par; } if((grr_data->tbf_type EQ CGRLC_TBF_MODE_UL) OR (grr_data->tbf_type EQ CGRLC_TBF_MODE_DL_UL) ) { mode_check = TRUE; } break; case D_UL_ASSIGN: /* T_D_UL_ASSIGN */ if(d_ul_assign->v_freq_par) { /* replace possibly earlier stored freq params */ freq_par = &d_ul_assign->freq_par; } if((grr_data->tbf_type EQ CGRLC_TBF_MODE_DL) OR (grr_data->tbf_type EQ CGRLC_TBF_MODE_DL_UL)) { mode_check = TRUE; } break; case D_TS_RECONFIG: /* T_D_TS_RECONFIG */ if(d_ts_reconfig->v_freq_par) { /* replace possibly earlier stored freq params */ freq_par = &d_ts_reconfig->freq_par; } break; case D_UL_ACK: /* T_D_UL_ACK */ break; default: TRACE_ERROR ( "Wrong message type in _decodedMsg" ); break; } /* If frequency parameter element present, assigns frequency parameters to the uplink TBF. If this information element is not present the mobile station shall use its previously assigned frequency parameters.*/ if( freq_par )/* save the hopping frequency */ { if(freq_par->v_arfcn) /*static*/ { T_FREQ_SET temp_freq_set; temp_freq_set.freq_par.p_chan_sel.hopping = FALSE; temp_freq_set.tsc = freq_par->tsc; temp_freq_set.freq_par.p_chan_sel.p_rf_ch.arfcn = grr_g23_arfcn_to_l1(freq_par->arfcn); /* variable needed by hopping case must be reset.*/ memset(&(temp_freq_set.freq_par.p_freq_list.p_rf_chan_no.p_radio_freq), 0, sizeof(temp_freq_set.freq_par.p_freq_list.p_rf_chan_no.p_radio_freq)); temp_freq_set.freq_par.p_freq_list.p_rf_chan_cnt = 0; if ( mode_check EQ TRUE ) { /* checking the params already exist or not */ if ( ( grr_data->tc.freq_set.freq_par.p_chan_sel.hopping EQ FALSE) AND (temp_freq_set.tsc EQ grr_data->tc.freq_set.tsc) AND ( temp_freq_set.freq_par.p_chan_sel.p_rf_ch.arfcn EQ grr_data->tc.freq_set.freq_par.p_chan_sel.p_rf_ch.arfcn ) ) { TRACE_EVENT ("Frequency parameters are same"); result = TRUE; } else { TRACE_EVENT ("Frequency parameters are changed, So discard it"); result = FALSE; } } else { /* If it is new entry, storing in the grr_data */ result = TRUE; grr_data->tc.v_freq_set = TRUE; grr_data->tc.freq_set = temp_freq_set; } } else { /* hopping cases */ result = tc_set_hopping_par( freq_par ); } } else if ( grr_data->tc.v_freq_set )/* if it is a two phase assignment or there is already another TBF running*/ { result = TRUE; } else { result = FALSE; TRACE_ERROR("FATAL ERROR: no freq params in assignment but needed!"); } if(result EQ TRUE) { grr_data->pwr_ctrl_valid_flags.v_glbl_pwr_ctrl_param = TRUE; grr_data->pwr_ctrl_valid_flags.v_freq_param = TRUE; } return(result); }/* tc_check_and_save_freq */ /* +------------------------------------------------------------------------------ | Function : tc_set_da_assignment +------------------------------------------------------------------------------ | Description : This function sets some parameter of T_MPHP_ASSIGNMENT_REQ is | case of uplink dynamic allocation. | | Parameters : ptr2prim_i - ptr to MPHP_ASSIGNMENT_REQ | +------------------------------------------------------------------------------ */ LOCAL void tc_set_da_assignment (T_MPHP_ASSIGNMENT_REQ * ptr2prim_i) { MCAST(d_ul_assign,D_UL_ASSIGN);/* T_D_UL_ASSIGN */ MCAST(d_ts_reconfig,D_TS_RECONFIG); TRACE_FUNCTION( "tc_set_da_assignment" ); if( d_ul_assign->msg_type EQ D_UL_ASSIGN_c) { /* * timing advance */ grr_handle_ta ( d_ul_assign->pta.v_ta_value, d_ul_assign->pta.ta_value, d_ul_assign->pta.v_ta_index_tn, d_ul_assign->pta.ta_index_tn.ta_index, d_ul_assign->pta.ta_index_tn.ta_tn, 0xFF, 0, 0, &ptr2prim_i->p_timing_advance); /* bts output power control */ if(d_ul_assign->dyn_alloc_p.v_p0) { ptr2prim_i->p_dl_power.p0 = d_ul_assign->dyn_alloc_p.p0; ptr2prim_i->p_dl_power.pr_mode = d_ul_assign->dyn_alloc_p.pr_mode; /* dynamic allocation must use mode a */ ptr2prim_i->p_dl_power.bts_pwr_ctl_mode = MODE_A; } else { ptr2prim_i->p_dl_power.p0 = 0xff; /* 0xff -> invalid value */ /* -> pr_mode and bts_pwr_ctl_mode don't care */ } /* * TBF starting time */ if(d_ul_assign->dyn_alloc_p.v_tbf_s_time) { ptr2prim_i->p_tbf_start.tbf_start_present = 1; if(d_ul_assign->dyn_alloc_p.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ul_assign->dyn_alloc_p.tbf_s_time.abs); } else if (d_ul_assign->dyn_alloc_p.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, d_ul_assign->dyn_alloc_p.tbf_s_time.rel); } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = grr_data->dl_fn; TRACE_ERROR("UL v_start_tbf but either rel nor abs tbf included"); } } else if(grr_data->l1_del_tbf_start_fn NEQ GRR_INVALID_FN) { ptr2prim_i->p_tbf_start.tbf_start_present = 1; ptr2prim_i->p_tbf_start.fn = grr_data->l1_del_tbf_start_fn; } else { ptr2prim_i->p_tbf_start.tbf_start_present = 0; } /* * mac mode */ if (d_ul_assign->dyn_alloc_p.xdyn_alloc) { ptr2prim_i->mac_mode = EDA; } else { ptr2prim_i->mac_mode = DA; } /* * uplink allocation structure */ if(d_ul_assign->dyn_alloc_p.v_ul_tfi_assign) { ptr2prim_i->p_ul_alloc.ul_tfi = d_ul_assign->dyn_alloc_p.ul_tfi_assign; } else { ptr2prim_i->p_ul_alloc.ul_tfi = grr_data->uplink_tbf.tfi; } ptr2prim_i->p_ul_alloc.ts_mask = grr_data->uplink_tbf.ts_usage; /* * dynamic allocation structure */ ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_gran = d_ul_assign->dyn_alloc_p.usf_grant; if(d_ul_assign->dyn_alloc_p.v_tn_alloc EQ 1) { UBYTE i; for(i = 0;i < 8;i++) { if(d_ul_assign->dyn_alloc_p.tn_alloc[i].v_usf) { ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_table[i] = d_ul_assign->dyn_alloc_p.tn_alloc[i].usf; } } } else if (d_ul_assign->dyn_alloc_p.v_tn_alloc_pwr) { UBYTE i; for(i = 0;i < 8;i++) { if(d_ul_assign->dyn_alloc_p.tn_alloc_pwr.usf_array[i].v_usf_g) { ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_table[i] = d_ul_assign->dyn_alloc_p.tn_alloc_pwr.usf_array[i].usf_g.usf; } } grr_store_type_tn_alloc_pwr( &d_ul_assign->dyn_alloc_p.tn_alloc_pwr ); } else { ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_table[0] = 5; TRACE_EVENT("USF-Error: set (hardcoded) USF_TN0 = 0x05"); } } else if ( d_ts_reconfig->msg_type EQ D_TS_RECONFIG_c) { /* * timing advance is handled in tc_set_dl_assignment */ /* grr_handle_ta ( d_ts_reconfig->gpta.v_ta_value, d_ts_reconfig->gpta.ta_value, d_ts_reconfig->gpta.v_ul_ta_index, d_ts_reconfig->gpta.ul_ta_index, d_ts_reconfig->gpta.ul_ta_tn, 0, 0, 0, ptr2prim_i->p_timing_advance); */ /* bts output power control */ if(d_ts_reconfig->dyn_alloc_ts.v_p0) { ptr2prim_i->p_dl_power.p0 = d_ts_reconfig->dyn_alloc_ts.p0; ptr2prim_i->p_dl_power.pr_mode = d_ts_reconfig->dyn_alloc_ts.pr_mode; /* dynamic allocation must use mode a */ ptr2prim_i->p_dl_power.bts_pwr_ctl_mode = MODE_A; } else { ptr2prim_i->p_dl_power.p0 = 0xff; /* 0xff -> invalid value */ /* -> pr_mode and bts_pwr_ctl_mode don't care */ } /* * TBF starting time */ if(d_ts_reconfig->dyn_alloc_ts.v_tbf_s_time) { ptr2prim_i->p_tbf_start.tbf_start_present= 1; if(d_ts_reconfig->dyn_alloc_ts.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ts_reconfig->dyn_alloc_ts.tbf_s_time.abs); } else if (d_ts_reconfig->dyn_alloc_ts.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, d_ts_reconfig->dyn_alloc_ts.tbf_s_time.rel); } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = grr_data->dl_fn%FN_MAX; TRACE_ERROR("TS RECON UL v_start_tbf but either rel nor abs tbf included"); } } else if(grr_data->l1_del_tbf_start_fn NEQ GRR_INVALID_FN) { ptr2prim_i->p_tbf_start.tbf_start_present = 1; ptr2prim_i->p_tbf_start.fn = grr_data->l1_del_tbf_start_fn; } else { ptr2prim_i->p_tbf_start.tbf_start_present = 0; } /* * mac mode */ if (d_ts_reconfig->dyn_alloc_ts.xdyn_alloc) { ptr2prim_i->mac_mode = EDA; } else { ptr2prim_i->mac_mode = DA; } /* * uplink allocation structure */ if(d_ts_reconfig->v_ul_tfi) { ptr2prim_i->p_ul_alloc.ul_tfi = d_ts_reconfig->ul_tfi; } else { ptr2prim_i->p_ul_alloc.ul_tfi = grr_data->uplink_tbf.tfi; } ptr2prim_i->p_ul_alloc.ts_mask = grr_data->uplink_tbf.ts_usage; /* * dynamic allocation structure */ ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_gran = d_ts_reconfig->dyn_alloc_ts.usf_grant; if(d_ts_reconfig->dyn_alloc_ts.v_tn_alloc EQ 1) { UBYTE i; for(i = 0;i < 8;i++) { if(d_ts_reconfig->dyn_alloc_ts.tn_alloc[i].v_usf) { ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_table[i] = d_ts_reconfig->dyn_alloc_ts.tn_alloc[i].usf; } } } else if (d_ts_reconfig->dyn_alloc_ts.v_tn_alloc_pwr) { UBYTE i; for(i = 0;i < 8;i++) { if(d_ts_reconfig->dyn_alloc_ts.tn_alloc_pwr.usf_array[i].v_usf_g) { ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_table[i] = d_ts_reconfig->dyn_alloc_ts.tn_alloc_pwr.usf_array[i].usf_g.usf; } } grr_store_type_tn_alloc_pwr( &d_ts_reconfig->dyn_alloc_ts.tn_alloc_pwr ); } else { ptr2prim_i->p_ul_alloc.p_dynamic_alloc.usf_table[0] = 5; TRACE_EVENT("USF-Error: set (hardcoded) USF_TN0 = 0x05"); } } else { TRACE_ERROR ( "Wrong message type in _decodedCtrlMsg" ); } if(ptr2prim_i->p_tbf_start.tbf_start_present) grr_data->uplink_tbf.tbf_start_fn = ptr2prim_i->p_tbf_start.fn; else grr_data->uplink_tbf.tbf_start_fn = CGRLC_STARTING_TIME_NOT_PRESENT; grr_data->uplink_tbf.st_tfi = ptr2prim_i->p_ul_alloc.ul_tfi; return; }/*tc_set_da_assignment*/ /* +------------------------------------------------------------------------------ | Function : tc_calc_fa_bitmap +------------------------------------------------------------------------------ | Description : This function calculates rhe allocation bitmap in | case of fixed allocation | | Parameters : blks_or_blkps - indicates if blocks(0) or block periods(1) is used | len - len of the allocation bitmap | ptr2_alloc_map - ptr to the allocation bitmap array | ptr2_fix_alloc - ptr to the fixed allocation struct | +------------------------------------------------------------------------------ */ GLOBAL void tc_calc_fa_bitmap (ULONG tbf_start, UBYTE blks_or_blkps, USHORT len, UBYTE * ptr2_alloc_map, T_p_fixed_alloc * ptr2_fix_alloc) { UBYTE i; UBYTE help; UBYTE tn[8]; UBYTE x,y; UBYTE len_1; USHORT index; TRACE_FUNCTION( "tc_calc_fa_bitmap" ); /* TRACE_EVENT_P9("FA bitmap: start_fn=%ld, blk=%d len=%ld bitmap: %d %d %d %d %d %d", tbf_start, blks_or_blkps, len, ptr2_alloc_map[0], ptr2_alloc_map[1], ptr2_alloc_map[2], ptr2_alloc_map[3], ptr2_alloc_map[4], ptr2_alloc_map[5]); TRACE_EVENT_P9("%d %d %d %d %d %d %d %d %d", ptr2_alloc_map[6], ptr2_alloc_map[7], ptr2_alloc_map[8], ptr2_alloc_map[9], ptr2_alloc_map[10], ptr2_alloc_map[11], ptr2_alloc_map[12], ptr2_alloc_map[13], ptr2_alloc_map[14]); TRACE_EVENT_P9("%d %d %d %d %d %d %d %d %d", ptr2_alloc_map[15], ptr2_alloc_map[16], ptr2_alloc_map[17], ptr2_alloc_map[18], ptr2_alloc_map[19], ptr2_alloc_map[20], ptr2_alloc_map[21], ptr2_alloc_map[22], ptr2_alloc_map[23]); TRACE_EVENT_P9("%d %d %d %d %d %d %d %d %d", ptr2_alloc_map[24], ptr2_alloc_map[25], ptr2_alloc_map[26], ptr2_alloc_map[27], ptr2_alloc_map[28], ptr2_alloc_map[29], ptr2_alloc_map[30], ptr2_alloc_map[31], ptr2_alloc_map[32]); */ memset( tn, 0, sizeof(tn) ); if(blks_or_blkps) { /* * block periods are used */ for(i=0;i<len;i++) { if(ptr2_alloc_map[i]) { ptr2_fix_alloc->bitmap[i] = grr_data->uplink_tbf.ts_usage; } else ptr2_fix_alloc->bitmap[i] = 0; } ptr2_fix_alloc->size_bitmap = (UBYTE)len; } else { UBYTE L; /* * blocks are used */ /* * determinate the timeslot positions */ help = grr_data->uplink_tbf.ts_usage; index = 0; for(i=0;i<=7;i++) { if(help >= (0x80 >> i)) { tn[index]=i; index++; help -= (0x80 >> i); } } memset(ptr2_fix_alloc->bitmap,0,sizeof(ptr2_fix_alloc->bitmap)); L = len - 1; for(i=0;i<=L;i++) { if(ptr2_alloc_map[i]) { x = i / grr_data->uplink_tbf.nts; y = i % grr_data->uplink_tbf.nts; ptr2_fix_alloc->bitmap[x] |= 0x80 >> tn[y]; } } ptr2_fix_alloc->size_bitmap = (UBYTE)len / grr_data->uplink_tbf.nts; } /* * set fa_ctrl */ grr_data->tc.fa_ctrl.fa_type = FA_BITMAP; grr_data->tc.fa_ctrl.current_alloc.alloc_start_fn = tbf_start; /* store end of fixed allocation */ len_1 = ptr2_fix_alloc->size_bitmap - 1; grr_data->tc.fa_ctrl.current_alloc.alloc_end_fn = grr_decode_tbf_start_rel(grr_data->tc.fa_ctrl.current_alloc.alloc_start_fn,(USHORT)(len_1-1)); memcpy( &grr_data->tc.fa_ctrl.current_alloc.alloc, ptr2_fix_alloc, sizeof(T_p_fixed_alloc)); /* TRACE_EVENT_P9("L1 bitmap %d %d %d %d %d %d %d %d %d", ptr2_fix_alloc->bitmap[0], ptr2_fix_alloc->bitmap[1], ptr2_fix_alloc->bitmap[2], ptr2_fix_alloc->bitmap[3], ptr2_fix_alloc->bitmap[4], ptr2_fix_alloc->bitmap[5], ptr2_fix_alloc->bitmap[6], ptr2_fix_alloc->bitmap[7], ptr2_fix_alloc->bitmap[8]); TRACE_EVENT_P9("%d %d %d %d %d %d %d %d %d", ptr2_fix_alloc->bitmap[9], ptr2_fix_alloc->bitmap[10], ptr2_fix_alloc->bitmap[11], ptr2_fix_alloc->bitmap[12], ptr2_fix_alloc->bitmap[13], ptr2_fix_alloc->bitmap[14], ptr2_fix_alloc->bitmap[15], ptr2_fix_alloc->bitmap[16], ptr2_fix_alloc->bitmap[17]); TRACE_EVENT_P9("%d %d %d %d %d %d %d %d %d", ptr2_fix_alloc->bitmap[18], ptr2_fix_alloc->bitmap[19], ptr2_fix_alloc->bitmap[20], ptr2_fix_alloc->bitmap[21], ptr2_fix_alloc->bitmap[22], ptr2_fix_alloc->bitmap[23], ptr2_fix_alloc->bitmap[24], ptr2_fix_alloc->bitmap[25], ptr2_fix_alloc->bitmap[26]); */ } /* tc_calc_fa_bitmap() */ /* +------------------------------------------------------------------------------ | Function : tc_handle_final_alloc +------------------------------------------------------------------------------ | Description : This function handles the final allocation bit. | | Parameters : - | +------------------------------------------------------------------------------ */ GLOBAL void tc_handle_final_alloc (UBYTE final_allocation) { TRACE_FUNCTION( "tc_handle_final_alloc" ); } /* tc_handle_final_alloc() */ /* +------------------------------------------------------------------------------ | Function : tc_set_fa_assignment +------------------------------------------------------------------------------ | Description : This function sets some parameter of T_MPHP_ASSIGNMENT_REQ is | case of fixed allocation | | Parameters : ptr2prim_i - ptr to MPHP_ASSIGNMENT_REQ | +------------------------------------------------------------------------------ */ LOCAL void tc_set_fa_assignment (T_MPHP_ASSIGNMENT_REQ * ptr2prim_i) { /* ULONG var; */ MCAST(d_ul_assign,D_UL_ASSIGN); /* T_D_UL_ASSIGN */ MCAST(d_ts_reconfig,D_TS_RECONFIG); /* T_TS_RECONFIG */ MCAST(d_ul_ack,D_UL_ACK); /* T_D_UL_ACK */ TRACE_FUNCTION( "tc_set_fa_assignment" ); #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH if((d_ul_assign->msg_type EQ D_UL_ASSIGN_c) AND (ptr2prim_i->assign_cmd EQ UL_TP_ACCESS)) { /* training sequence code */ ptr2prim_i->tsc = d_ul_assign->freq_par.tsc; /* handle timing advance */ grr_handle_ta ( d_ul_assign->pta.v_ta_value, d_ul_assign->pta.ta_value, d_ul_assign->pta.v_ta_index_tn, d_ul_assign->pta.ta_index_tn.ta_index, d_ul_assign->pta.ta_index_tn.ta_tn, 0xFF, 0, 0, &ptr2prim_i->p_timing_advance); /* Mac mode */ ptr2prim_i->mac_mode = FA; /* Handle single block allocation */ if(d_ul_assign->v_sin_alloc EQ TRUE ) { /* timeslot mask */ ptr2prim_i->p_ul_alloc.ts_mask = 0x80>>d_ul_assign->sin_alloc.tn; /* PO, BTS_POWER_MODE and PR_ MODE */ if(d_ul_assign->sin_alloc.v_bts_pwr_ctrl EQ TRUE ) { ptr2prim_i->p_dl_power.p0 = d_ul_assign->sin_alloc.bts_pwr_ctrl.p0; ptr2prim_i->p_dl_power.bts_pwr_ctl_mode = d_ul_assign->sin_alloc.bts_pwr_ctrl.mode; ptr2prim_i->p_dl_power.pr_mode = d_ul_assign->sin_alloc.bts_pwr_ctrl.pr_mode; } else { ptr2prim_i->p_dl_power.p0 = 0xff; } /* Downlink Control Timeslot */ ptr2prim_i->p_ul_alloc.p_fixed_alloc.dl_ctrl_ts = d_ul_assign->sin_alloc.tn; /* * handle TBF starting time * is always present in single block allocation */ if(d_ul_assign->sin_alloc.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ul_assign->sin_alloc.tbf_s_time.abs); if(!grr_check_if_tbf_start_is_elapsed ( ptr2prim_i->p_tbf_start.fn, grr_data->ul_fn)) { /*Allocated Number of time slots are 1 */ ptr2prim_i->p_ul_alloc.p_fixed_alloc.size_bitmap = 1; ptr2prim_i->p_tbf_start.tbf_start_present=TRUE; ptr2prim_i->p_ul_alloc.p_fixed_alloc.bitmap[0] = 0x80 >> d_ul_assign->sin_alloc.tn; } else { TRACE_ERROR("TBF Starting time is ELAPSED in single block allocation!"); } } else if (d_ul_assign->sin_alloc.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, (USHORT)(d_ul_assign->sin_alloc.tbf_s_time.rel)); if(!grr_check_if_tbf_start_is_elapsed ( ptr2prim_i->p_tbf_start.fn, grr_data->ul_fn)) { /*Allocated Number of time slots are 1 */ ptr2prim_i->p_ul_alloc.p_fixed_alloc.size_bitmap = 1; ptr2prim_i->p_tbf_start.tbf_start_present=TRUE; ptr2prim_i->p_ul_alloc.p_fixed_alloc.bitmap[0] = 0x80 >> d_ul_assign->sin_alloc.tn; } else { TRACE_ERROR("TBF Starting time is ELAPSED in single block allocation!"); } } }/* single block */ } else #endif if( d_ul_assign->msg_type EQ D_UL_ASSIGN_c) { /* * timing advance */ grr_handle_ta ( d_ul_assign->pta.v_ta_value, d_ul_assign->pta.ta_value, d_ul_assign->pta.v_ta_index_tn, d_ul_assign->pta.ta_index_tn.ta_index, d_ul_assign->pta.ta_index_tn.ta_tn, 0xFF, 0, 0, &ptr2prim_i->p_timing_advance); if(d_ul_assign->f_alloc_ul.v_bts_pwr_ctrl) { ptr2prim_i->p_dl_power.p0 = d_ul_assign->f_alloc_ul.bts_pwr_ctrl.p0; ptr2prim_i->p_dl_power.bts_pwr_ctl_mode = d_ul_assign->f_alloc_ul.bts_pwr_ctrl.mode; ptr2prim_i->p_dl_power.pr_mode = d_ul_assign->f_alloc_ul.bts_pwr_ctrl.pr_mode; } else { ptr2prim_i->p_dl_power.p0 = 0xff; } /* * mac mode */ ptr2prim_i->mac_mode = FA; /* * uplink allocation structure */ if(d_ul_assign->f_alloc_ul.v_ul_tfi_assign) { ptr2prim_i->p_ul_alloc.ul_tfi = d_ul_assign->f_alloc_ul.ul_tfi_assign; } else { ptr2prim_i->p_ul_alloc.ul_tfi = grr_data->uplink_tbf.tfi; } ptr2prim_i->p_ul_alloc.ts_mask = grr_data->uplink_tbf.ts_usage; /* * fixed allocation structure * half duplex mode is ignored, only valid for MS class 19 to 29 */ /* * TBF STARTING TIME for fixed allocation structure */ if(d_ul_assign->f_alloc_ul.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ul_assign->f_alloc_ul.tbf_s_time.abs); } else if (d_ul_assign->f_alloc_ul.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, d_ul_assign->f_alloc_ul.tbf_s_time.rel); } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = (grr_data->dl_fn+13)%FN_MAX; TRACE_ERROR("NO STARTING TIME IN FIXED ALLOCATION!!"); } ptr2prim_i->p_tbf_start.tbf_start_present = 1; /* * Downlink Control Timeslot */ ptr2prim_i->p_ul_alloc.p_fixed_alloc.dl_ctrl_ts = d_ul_assign->f_alloc_ul.dl_ctrl_ts; grr_data->tc.fa_ctrl.dl_ctrl_ts = d_ul_assign->f_alloc_ul.dl_ctrl_ts; /* * ALLOCATION BITMAP */ if(d_ul_assign->f_alloc_ul.v_block_struct) { tc_calc_fa_bitmap(ptr2prim_i->p_tbf_start.fn, /*starting time of cuurent tbf*/ d_ul_assign->f_alloc_ul.block_struct.bl_o_bl_per,/* blocks or block periods*/ d_ul_assign->f_alloc_ul.block_struct.a_map_len, /* bitmap length*/ d_ul_assign->f_alloc_ul.block_struct.alloc_map, /* ptr to alloc struct*/ &ptr2prim_i->p_ul_alloc.p_fixed_alloc); /* ptr to fix sttruct*/ } else if(d_ul_assign->f_alloc_ul.v_alloc_map) { tc_calc_fa_bitmap(ptr2prim_i->p_tbf_start.fn, /*starting time of cuurent tbf*/ 0, /* blocks : default*/ d_ul_assign->f_alloc_ul.c_alloc_map, /* bitmap length*/ d_ul_assign->f_alloc_ul.alloc_map, /* ptr to alloc struct*/ &ptr2prim_i->p_ul_alloc.p_fixed_alloc); /* ptr to fix sttruct*/ } /* * check final allocation */ grr_data->tc.fa_ctrl.current_alloc.final_alloc = d_ul_assign->f_alloc_ul.final_alloc; } else if ( d_ts_reconfig->msg_type EQ D_TS_RECONFIG_c) { /* * timing advance is handled in tc_set_dl_assignment */ if(d_ts_reconfig->f_alloc_re.v_bts_pwr_ctrl) { ptr2prim_i->p_dl_power.p0 = d_ts_reconfig->f_alloc_re.bts_pwr_ctrl.p0; ptr2prim_i->p_dl_power.bts_pwr_ctl_mode = d_ts_reconfig->f_alloc_re.bts_pwr_ctrl.mode; ptr2prim_i->p_dl_power.pr_mode = d_ts_reconfig->f_alloc_re.bts_pwr_ctrl.pr_mode; } else { ptr2prim_i->p_dl_power.p0 = 0xff; } /* * mac mode */ ptr2prim_i->mac_mode = FA; /* * uplink allocation structure */ if(d_ts_reconfig->v_ul_tfi) { ptr2prim_i->p_ul_alloc.ul_tfi = d_ts_reconfig->ul_tfi; } else { ptr2prim_i->p_ul_alloc.ul_tfi = grr_data->uplink_tbf.tfi; } ptr2prim_i->p_ul_alloc.ts_mask = grr_data->uplink_tbf.ts_usage; /* * fixed allocation structure * half duplex mode is ignored, only valid for MS class 19 to 29 */ /* * TBF STARTING TIME for fixed allocation structure */ if(d_ts_reconfig->f_alloc_re.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ts_reconfig->f_alloc_re.tbf_s_time.abs); } else if (d_ts_reconfig->f_alloc_re.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, d_ts_reconfig->f_alloc_re.tbf_s_time.rel); } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = (grr_data->dl_fn+13)%FN_MAX; TRACE_ERROR("NO STARTING TIME IN FIXED ALLOCATION!!"); } ptr2prim_i->p_tbf_start.tbf_start_present = 1; /* * Downlink Control Timeslot */ ptr2prim_i->p_ul_alloc.p_fixed_alloc.dl_ctrl_ts = d_ts_reconfig->f_alloc_re.dl_ctrl_ts; grr_data->tc.fa_ctrl.dl_ctrl_ts = d_ts_reconfig->f_alloc_re.dl_ctrl_ts; /* * ALLOCATION BITMAP */ if(d_ts_reconfig->f_alloc_re.v_block_struct) { tc_calc_fa_bitmap(ptr2prim_i->p_tbf_start.fn, /*starting time of cuurent tbf*/ d_ts_reconfig->f_alloc_re.block_struct.bl_o_bl_per, /* blocks or block periods*/ d_ts_reconfig->f_alloc_re.block_struct.a_map_len, /* bitmap length*/ d_ts_reconfig->f_alloc_re.block_struct.alloc_map, /* ptr to alloc struct*/ &ptr2prim_i->p_ul_alloc.p_fixed_alloc); /* ptr to fix sttruct*/ } else if(d_ts_reconfig->f_alloc_re.v_alloc_map) { tc_calc_fa_bitmap(ptr2prim_i->p_tbf_start.fn, /*starting time of cuurent tbf*/ 0, /* blocks : default*/ d_ts_reconfig->f_alloc_re.c_alloc_map, /* bitmap length*/ d_ts_reconfig->f_alloc_re.alloc_map, /* ptr to alloc struct*/ &ptr2prim_i->p_ul_alloc.p_fixed_alloc); /* ptr to fix sttruct*/ } /* * check final allocation */ grr_data->tc.fa_ctrl.current_alloc.final_alloc = d_ts_reconfig->f_alloc_re.final_alloc; } else if ( d_ul_ack->msg_type EQ D_UL_ACK_c) { /* * Timing Advance in packet uplink ack/nack with fixed allocation */ if(d_ul_ack->gprs_ul_ack_nack_info.v_pta) { grr_handle_ta ( d_ul_ack->gprs_ul_ack_nack_info.pta.v_ta_value, d_ul_ack->gprs_ul_ack_nack_info.pta.ta_value, d_ul_ack->gprs_ul_ack_nack_info.pta.v_ta_index_tn, d_ul_ack->gprs_ul_ack_nack_info.pta.ta_index_tn.ta_index, d_ul_ack->gprs_ul_ack_nack_info.pta.ta_index_tn.ta_tn, 0xFF, 0, 0, &ptr2prim_i->p_timing_advance); } else { grr_handle_ta ( 0, 0, 0xFF, 0, 0, 0xFF, 0, 0, &ptr2prim_i->p_timing_advance); } /* * mac mode */ ptr2prim_i->mac_mode = FA; /* * uplink allocation structure */ /*no change, therefore take from database*/ ptr2prim_i->p_ul_alloc.ul_tfi = grr_data->uplink_tbf.tfi; ptr2prim_i->p_ul_alloc.ts_mask = grr_data->uplink_tbf.ts_usage; /* * fixed allocation structure * half duplex mode is ignored, only valid for MS class 19 to 29 */ /* * TBF STARTING TIME for fixed allocation structure */ if(d_ul_ack->gprs_ul_ack_nack_info.v_f_alloc_ack AND d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.v_fa_s2) { if(d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.tbf_s_time.abs); } else if (d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.tbf_s_time.rel); } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = (grr_data->dl_fn+13)%FN_MAX; TRACE_ERROR("NO STARTING TIME IN FIXED ALLOCATION!! struct problem"); } } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = (grr_data->dl_fn+13)%FN_MAX; TRACE_ERROR("NO STARTING TIME IN FIXED ALLOCATION!!"); } ptr2prim_i->p_tbf_start.tbf_start_present = 1; /* * Downlink Control Timeslot, take from database */ ptr2prim_i->p_ul_alloc.p_fixed_alloc.dl_ctrl_ts = grr_data->tc.fa_ctrl.dl_ctrl_ts; /* * ALLOCATION BITMAP */ if(d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.v_block_struct) { tc_calc_fa_bitmap(ptr2prim_i->p_tbf_start.fn, /* starting time of cuurent tbf*/ d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.block_struct.bl_o_bl_per,/* blocks or block periods*/ d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.block_struct.a_map_len, /* bitmap length */ d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.block_struct.alloc_map, /* ptr to alloc struct*/ &ptr2prim_i->p_ul_alloc.p_fixed_alloc); /* ptr to fix sttruct*/ } else if(d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.v_alloc_map) { tc_calc_fa_bitmap(ptr2prim_i->p_tbf_start.fn, /*starting time of cuurent tbf*/ 0, /* blocks : default*/ d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.c_alloc_map, /* bitmap length*/ d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.fa_s2.alloc_map, /* ptr to alloc struct*/ &ptr2prim_i->p_ul_alloc.p_fixed_alloc); /* ptr to fix sttruct*/ } /* * check final allocation */ grr_data->tc.fa_ctrl.current_alloc.final_alloc = d_ul_ack->gprs_ul_ack_nack_info.f_alloc_ack.final_alloc; } else { TRACE_ERROR ( "Wrong message type in _decodedCtrlMsg" ); } if(ptr2prim_i->p_tbf_start.tbf_start_present) grr_data->uplink_tbf.tbf_start_fn = ptr2prim_i->p_tbf_start.fn; else grr_data->uplink_tbf.tbf_start_fn = CGRLC_STARTING_TIME_NOT_PRESENT; grr_data->uplink_tbf.st_tfi = ptr2prim_i->p_ul_alloc.ul_tfi; return; } /* tc_set_fa_assignment() */ /* +------------------------------------------------------------------------------ | Function : tc_set_dl_assignment +------------------------------------------------------------------------------ | Description : This function sets some parameter of T_MPHP_ASSIGNMENT_REQ is | case of downlink allocation | | Parameters : ptr2prim_i - ptr to MPHP_ASSIGNMENT_REQ | +------------------------------------------------------------------------------ */ LOCAL void tc_set_dl_assignment (T_MPHP_ASSIGNMENT_REQ * ptr2prim_i) { MCAST(d_dl_assign, D_DL_ASSIGN); /* T_D_DL_ASSIGN */ MCAST(d_ts_reconfig,D_TS_RECONFIG); TRACE_FUNCTION( "tc_set_dl_assignment" ); if( d_dl_assign->msg_type EQ D_DL_ASSIGN_c) { /* * timing advance */ grr_handle_ta ( d_dl_assign->pta.v_ta_value, d_dl_assign->pta.ta_value, 0xFF, 0, 0, d_dl_assign->pta.v_ta_index_tn, d_dl_assign->pta.ta_index_tn.ta_index, d_dl_assign->pta.ta_index_tn.ta_tn, &ptr2prim_i->p_timing_advance); /* * TBF starting time */ if(d_dl_assign->pda_trnc_grp.v_tbf_s_time) { ptr2prim_i->p_tbf_start.tbf_start_present = 1; if(d_dl_assign->pda_trnc_grp.tbf_s_time.v_abs) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_dl_assign->pda_trnc_grp.tbf_s_time.abs); } else if (d_dl_assign->pda_trnc_grp.tbf_s_time.v_rel) { ptr2prim_i->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, d_dl_assign->pda_trnc_grp.tbf_s_time.rel); } else { /* this shall never happen */ ptr2prim_i->p_tbf_start.fn = grr_data->dl_fn%FN_MAX; TRACE_ERROR("DL v_start_tbf but either rel nor abs tbf included"); } } else if(grr_data->l1_del_tbf_start_fn NEQ GRR_INVALID_FN) { ptr2prim_i->p_tbf_start.tbf_start_present = 1; ptr2prim_i->p_tbf_start.fn = grr_data->l1_del_tbf_start_fn; } else { ptr2prim_i->p_tbf_start.tbf_start_present = 0; } if(d_dl_assign->v_bts_pwr_ctrl) { ptr2prim_i->p_dl_power.p0 = d_dl_assign->bts_pwr_ctrl.p0; ptr2prim_i->p_dl_power.bts_pwr_ctl_mode = d_dl_assign->bts_pwr_ctrl.mode; ptr2prim_i->p_dl_power.pr_mode = d_dl_assign->bts_pwr_ctrl.pr_mode; } else { ptr2prim_i->p_dl_power.p0 = 0xff; } /* * mac mode */ ptr2prim_i->mac_mode = d_dl_assign->mac_mode; /* * downlink allocation structure */ if(d_dl_assign->pda_trnc_grp.v_dl_tfi_assign) { ptr2prim_i->p_dl_alloc.dl_tfi = d_dl_assign->pda_trnc_grp.dl_tfi_assign; } else { ptr2prim_i->p_dl_alloc.dl_tfi = grr_data->downlink_tbf.tfi; } ptr2prim_i->p_dl_alloc.ts_mask = d_dl_assign->ts_alloc; } else if ( d_ts_reconfig->msg_type EQ D_TS_RECONFIG_c) { /* TS Reconfigure allways contains ul assign -> TBF starting time * is handled there */ if(d_ts_reconfig->v_dl_tfi) { ptr2prim_i->p_dl_alloc.dl_tfi = d_ts_reconfig->dl_tfi; } else { ptr2prim_i->p_dl_alloc.dl_tfi = grr_data->downlink_tbf.tfi; } ptr2prim_i->p_dl_alloc.ts_mask = grr_data->downlink_tbf.ts_usage; /* * timing advance */ grr_handle_ta ( d_ts_reconfig->gpta.v_ta_value, d_ts_reconfig->gpta.ta_value, d_ts_reconfig->gpta.v_ul_ta_index, d_ts_reconfig->gpta.ul_ta_index, d_ts_reconfig->gpta.ul_ta_tn, d_ts_reconfig->gpta.v_dl_ta_index, d_ts_reconfig->gpta.dl_ta_index, d_ts_reconfig->gpta.dl_ta_tn, &ptr2prim_i->p_timing_advance); } else { TRACE_ERROR ( "Wrong message type in _decodedCtrlMsg" ); } if(ptr2prim_i->p_tbf_start.tbf_start_present) grr_data->downlink_tbf.tbf_start_fn = ptr2prim_i->p_tbf_start.fn; else grr_data->downlink_tbf.tbf_start_fn = CGRLC_STARTING_TIME_NOT_PRESENT; grr_data->downlink_tbf.st_tfi = ptr2prim_i->p_dl_alloc.dl_tfi; grr_data->downlink_tbf.polling_bit = 0xFF; return; } /* tc_set_dl_assignment() */ /*==== PUBLIC FUNCTIONS =====================================================*/ /* +------------------------------------------------------------------------------ | Function : tc_gen_rand +------------------------------------------------------------------------------ | Description : This function generates a random value between db.prach.s | and (db.prach.tx_int -1) | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL USHORT tc_gen_rand ( void ) { USHORT result ; UBYTE i; TRACE_FUNCTION( "tc_gen_rand" ); /* * the "-1" defined in ETS 04.60 will be done by tc_random_value() * */ i = tx_int_table[psc_db->prach.tx_int]; result = (USHORT)grr_random_value (S_T_RND_INDEX, i ); result += s_table[psc_db->prach.s_prach]; #ifndef _TARGET_ TRACE_EVENT_P2("S, S+1 ..:%d tx_init:%d",result, i); #endif /* _TARGET_ */ return (result); } /* tc_gen_rand() */ /* +------------------------------------------------------------------------------ | Function : tc_calc_req +------------------------------------------------------------------------------ | Description : The function tc_calc_req() generate the message | Packet Access Request. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL USHORT tc_calc_req ( void ) { USHORT channel_request_data = 0; TRACE_FUNCTION( "tc_calc_req" ); switch(psc_db->gprs_cell_opt.ab_type) { case AB_8_BIT: switch(grr_data->uplink_tbf.access_type) { case CGRLC_AT_ONE_PHASE: channel_request_data = tc_one_phase_mask_8bit(); channel_request_data |= ((grr_get_gprs_ms_class( )-1)<<2); break; case CGRLC_AT_SHORT_ACCESS: channel_request_data = tc_short_access_mask_8bit(); channel_request_data |= ((grr_data->uplink_tbf.nr_blocks-1)<<3); break; case CGRLC_AT_TWO_PHASE: channel_request_data=tc_two_phase_mask_8bit(); break; case CGRLC_AT_PAGE_RESPONSE: channel_request_data=tc_page_response_mask_8bit(); break; case CGRLC_AT_CELL_UPDATE: channel_request_data=tc_cell_update_mask_8bit(); break; case CGRLC_AT_MM_PROCEDURE: channel_request_data=tc_mm_procedure_mask_8bit(); break; case CGRLC_AT_SINGLE_BLOCK: channel_request_data=tc_single_block_mask_8bit(); break; default: break; } break; case AB_11_BIT: switch(grr_data->uplink_tbf.access_type) { case CGRLC_AT_ONE_PHASE: channel_request_data=tc_one_phase_mask_11bit(); channel_request_data |= ((grr_get_gprs_ms_class( )-1)<<5); channel_request_data |= (grr_data->uplink_tbf.prio<<3); break; case CGRLC_AT_SHORT_ACCESS: channel_request_data=tc_short_access_mask_11bit(); channel_request_data |= (grr_data->uplink_tbf.prio<<3); channel_request_data |= ((grr_data->uplink_tbf.nr_blocks-1)<<5); break; case CGRLC_AT_TWO_PHASE: channel_request_data=tc_two_phase_mask_11bit(); channel_request_data |= (grr_data->uplink_tbf.prio<<3); break; case CGRLC_AT_PAGE_RESPONSE: channel_request_data=tc_page_response_mask_11bit(); break; case CGRLC_AT_CELL_UPDATE: channel_request_data=tc_cell_update_mask_11bit(); break; case CGRLC_AT_MM_PROCEDURE: channel_request_data=tc_mm_procedure_mask_11bit(); break; case CGRLC_AT_SINGLE_BLOCK: channel_request_data=tc_single_block_mask_11bit(); break; default: channel_request_data = 0; break; } channel_request_data = grr_convert_11bit_2_etsi(channel_request_data); TRACE_EVENT_P1("11 bit Channel Request: 0x%X", channel_request_data); break; default: break; } return(channel_request_data); } /* tc_calc_req() */ /* +------------------------------------------------------------------------------ | Function : tc_check_p_level +------------------------------------------------------------------------------ | Description : The function tc_check_p_level() checks the p-level for the | PDU's radio priority aigainst a random value and returns | wheather to send the random access or to continue with | calculating. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL T_CHECK_P_LEVEL tc_check_p_level ( void ) { UBYTE p_level,i; T_CHECK_P_LEVEL result; TRACE_FUNCTION( "tc_check_p_level" ); /* * get value between 0 and 15 */ i = (UBYTE) grr_random_value (PLEV_RND_INDEX, 16); p_level = psc_db->prach.pers_lev.plev[grr_data->uplink_tbf.prio]; if(p_level EQ 15) { /* * transmission in every case forbitten, because refer to ETS the value 0xf * have to be interpreted as 16 and i is in every case more little (0 <= i <= 15). * This case should be avoided (dead lock!) and have to be checked * in tc_start_access() */ TRACE_ERROR("unexpected persistence_level_value"); result = C_P_LEVEL_DO_NOT_SEND; } else { result = ( (i >= p_level) ? C_P_LEVEL_SEND : C_P_LEVEL_DO_NOT_SEND ); } return( result ); } /* tc_check_p_level() */ /* +------------------------------------------------------------------------------ | Function : tc_send_assign_req +------------------------------------------------------------------------------ | Description : The function tc_send_assign_req() builds MPHP_ASSIGNMENT_REQ | and send it. | | Parameters : tbf_type_i - type of TBF that is to activate | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_assign_req ( T_TBF_TYPE tbf_type_i ) { TRACE_FUNCTION( "tc_send_assign_req" ); { T_MPHP_ASSIGNMENT_REQ * ptr2prim;//=NULL; ptr2prim=tc_set_freq(); grr_set_tbf_cfg_req_param( ptr2prim ); switch( tbf_type_i ) { case CGRLC_TBF_MODE_DL: ptr2prim->assign_cmd = DL_ASSIGNMENT; tc_set_dl_assignment(ptr2prim); break; case CGRLC_TBF_MODE_UL: ptr2prim->assign_cmd = UL_ASSIGNMENT; if(grr_data->uplink_tbf.mac_mode EQ DA) tc_set_da_assignment(ptr2prim); else tc_set_fa_assignment(ptr2prim); break; case CGRLC_TBF_MODE_DL_UL: ptr2prim->assign_cmd = UL_DL_ASSIGNMENT; if(grr_data->uplink_tbf.mac_mode EQ DA) tc_set_da_assignment(ptr2prim); else tc_set_fa_assignment(ptr2prim); tc_set_dl_assignment(ptr2prim); break; #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: ptr2prim->assign_cmd = UL_TP_ACCESS; tc_set_fa_assignment(ptr2prim); break; #endif default: break; } /* switch (tbf_type_i) */ PSEND(hCommL1,ptr2prim); } } /* tc_send_assign_req() */ /* +------------------------------------------------------------------------------ | Function : tc_send_tbf_rel +------------------------------------------------------------------------------ | Description : The function tc_send_tbf_rel() builds MPHP_TBF_RELEASE_REQ | and send it. | | Parameters : TBP-Type - that have to be deleted | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_tbf_rel ( T_TBF_TYPE tbf_i ) { UBYTE dummy = grr_data->tc.num_of_rels_running; TRACE_FUNCTION( "tc_send_tbf_rel" ); tc_prepare_send_tbf_release_req( tbf_i ); { T_RELEASE_STATE rel_state= REL_PERFORMED; if(dummy NEQ grr_data->tc.num_of_rels_running) { rel_state = REL_RUNNING; } sig_tc_ctrl_rel_state(rel_state); } } /* tc_send_tbf_rel() */ /* +------------------------------------------------------------------------------ | Function : tc_send_pdch_rel +------------------------------------------------------------------------------ | Description : The function tc_send_pdch_rel() builds MPHP_PDCH_RELEASE_REQ | and send it. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_pdch_rel ( UBYTE ts_available ) { PALLOC(mphp_pdch_release_req,MPHP_PDCH_RELEASE_REQ); TRACE_FUNCTION( "tc_send_pdch_rel" ); mphp_pdch_release_req->assign_id = 0; mphp_pdch_release_req->ts_mask = ts_available; PSEND(hCommL1,mphp_pdch_release_req); } /* tc_send_pdch_rel() */ /* +------------------------------------------------------------------------------ | Function : tc_abort_tbf +------------------------------------------------------------------------------ | Description : The function tc_abort_tbf() stops a TBF. | | Parameters : tbf_i - TBF type to abort | +------------------------------------------------------------------------------ */ GLOBAL void tc_abort_tbf ( T_TBF_TYPE tbf_i ) { TRACE_FUNCTION( "tc_abort_tbf" ); switch( tbf_i ) { case CGRLC_TBF_MODE_NULL: TRACE_EVENT("NULL TBF active: check if tbf starting time is running"); tc_cgrlc_ul_tbf_res ( CGRLC_TBF_MODE_ACCESS_FAILED, CGRLC_PRIM_STATUS_NULL ); break; #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: tc_send_tbf_rel(tbf_i); tc_cgrlc_tbf_rel_req(tbf_i,CGRLC_TBF_REL_ABNORMAL,CGRLC_STARTING_TIME_NOT_PRESENT); tc_deactivate_tbf(tbf_i); break; #endif case CGRLC_TBF_MODE_UL: tc_send_tbf_rel(tbf_i); tc_cgrlc_tbf_rel_req(tbf_i,CGRLC_TBF_REL_ABNORMAL,CGRLC_STARTING_TIME_NOT_PRESENT); tc_deactivate_tbf(tbf_i); break; case CGRLC_TBF_MODE_DL: tc_send_tbf_rel(tbf_i); tc_cgrlc_tbf_rel_req(tbf_i,CGRLC_TBF_REL_ABNORMAL,CGRLC_STARTING_TIME_NOT_PRESENT); tc_deactivate_tbf(tbf_i); break; case CGRLC_TBF_MODE_DL_UL: tc_send_tbf_rel(tbf_i); tc_cgrlc_tbf_rel_req(tbf_i,CGRLC_TBF_REL_ABNORMAL,CGRLC_STARTING_TIME_NOT_PRESENT); tc_deactivate_tbf(tbf_i); break; default: TRACE_ERROR ( "tc_abort_tbf: TBF type is invalid" ); break; } } /* tc_abort_tbf() */ /* +------------------------------------------------------------------------------ | Function : tc_build_res_req +------------------------------------------------------------------------------ | Description : The function tc_build_res_req() builds Packet Resource Request. | | Parameters : reason_i - the reason for building that packet resouce | reallocation | src_info_i - indicates where to get the carrier information | regarding the assigned TBF | +------------------------------------------------------------------------------ */ GLOBAL void tc_build_res_req (T_U_RESOURCE_REQ *ptr2res_req, T_REASON_BUILD reason_i, T_SRC_TBF_INFO src_info_i ) { UBYTE change_mark; TRACE_FUNCTION( "tc_build_res_req" ); memset(ptr2res_req,0,sizeof(T_U_RESOURCE_REQ) ); /* processing of messsage type */ ptr2res_req->msg_type = U_RESOURCE_REQ_c; /* processing of change mark */ if( grr_is_pbcch_present( ) ) { change_mark = psc_db->psi2_params.psi2_change_mark; } else { change_mark = psc_db->psi13_params.si13_change_mark; } if( change_mark EQ NOT_SET ) { ptr2res_req->v_ma_ch_mark = 0; } else { ptr2res_req->v_ma_ch_mark = 1; ptr2res_req->ma_ch_mark = change_mark; } if(reason_i EQ R_BUILD_2PHASE_ACCESS) { /* 1 - processing of ACCESS_TYPE */ ptr2res_req->v_access_type = 1; ptr2res_req->access_type = TWO_PHASE; /* 2 - processing of global TFI and TLLI */ ptr2res_req->flag = 1; ptr2res_req->v_glob_tfi = 0; ptr2res_req->v_tlli_value = 1; grr_set_buf_tlli( &ptr2res_req->tlli_value, grr_data->db.ms_id.new_tlli ); /* 3 - processing of radio access capabilities */ if( rr_csf_get_radio_access_capability( &ptr2res_req->ra_cap ) EQ 0 ) { ptr2res_req->v_ra_cap = TRUE; } else { ptr2res_req->v_ra_cap = FALSE; TRACE_ERROR( "tc_build_res_req: radio access capabilities invalid" ); } /* 4 - processing of channel request description */ ptr2res_req->chan_req_des.peak_thr_class = (UBYTE) grr_data->uplink_tbf.peak; ptr2res_req->chan_req_des.radio_prio = grr_data->uplink_tbf.prio; if(grr_data->uplink_tbf.prim_type EQ CGRLC_LLC_PRIM_TYPE_UNITDATA_REQ) { ptr2res_req->chan_req_des.rlc_mode = CGRLC_RLC_MODE_UACK; } else { ptr2res_req->chan_req_des.rlc_mode = CGRLC_RLC_MODE_ACK; } ptr2res_req->chan_req_des.llc_pdu_type = LLC_NOT_ACK; ptr2res_req->chan_req_des.rlc_octet_cnt = grr_data->uplink_tbf.rlc_oct_cnt; /* 5 - processing of signal variance */ ptr2res_req->v_signvar = FALSE; } /* processing of C value */ { ptr2res_req->c_value = meas_c_get_value( ); } /* processing of relative interference levels */ { T_p_frequency_par freq_par; T_MEAS_IM_CARRIER ma; switch( src_info_i ) { case( SRC_TBF_INFO_RE_ASSIGN ): case( SRC_TBF_INFO_IMM_ASSIGN ): case( SRC_TBF_INFO_UL_ASSIGN ): grr_set_freq_par( &freq_par ); meas_im_set_carrier( &ma, &freq_par ); break; default: TRACE_ASSERT( src_info_i EQ SRC_TBF_INFO_RE_ASSIGN OR src_info_i EQ SRC_TBF_INFO_IMM_ASSIGN OR src_info_i EQ SRC_TBF_INFO_UL_ASSIGN ); break; } meas_im_get_rel_i_level( &ma, &ptr2res_req->ilev ); } #ifdef REL99 ptr2res_req->v_release_99_str_prr = FALSE; ptr2res_req->release_99_str_prr.flag = 0; ptr2res_req->release_99_str_prr.flag2 = 0; ptr2res_req->release_99_str_prr.v_pfi = 0; ptr2res_req->release_99_str_prr.add_ms_rac = 0; ptr2res_req->release_99_str_prr.retrans_of_prr = 0; #endif } /* tc_build_res_req() */ /* +------------------------------------------------------------------------------ | Function : tc_eval_pdch_rel +------------------------------------------------------------------------------ | Description : The function tc_eval_pdch_rel() evaluate a | Packet PDCH Release. | | Parameters : slot_i - the slot where the message was received | +------------------------------------------------------------------------------ */ GLOBAL T_EVAL_PDCH_REL tc_eval_pdch_rel ( UBYTE slot_i ) { MCAST(d_pdch_release,D_PDCH_RELEASE); /* T_D_PDCH_RELEASE */ UBYTE mask,help=0xFF, help2=0xFF; T_EVAL_PDCH_REL result=E_PDCH_REL_NULL; TRACE_FUNCTION( "tc_eval_pdch_rel" ); if(!d_pdch_release->v_ts_available) { mask = 0x80; mask >>= slot_i; mask ^= 0xFF; TRACE_EVENT_P7("NO TS PDCH REL: slot=%d ->mask=%x ul=%x st_ul=%x dl=%x st_dl=%x c_fn=%ld" ,slot_i ,mask ,grr_data->uplink_tbf.ts_mask ,grr_data->uplink_tbf.ts_usage ,grr_data->downlink_tbf.ts_mask ,grr_data->downlink_tbf.ts_usage , grr_data->ul_fn); } else { mask = d_pdch_release->ts_available; TRACE_EVENT_P7("ts PDCH REL: mask=%x ul=%x st_ul=%x dl=%x st_dl=%x c_fn=%ld" ,slot_i ,mask ,grr_data->uplink_tbf.ts_mask ,grr_data->uplink_tbf.ts_usage ,grr_data->downlink_tbf.ts_mask ,grr_data->downlink_tbf.ts_usage , grr_data->ul_fn); } grr_data->pdch_rel_ts_mask = mask; switch(grr_data->tbf_type) { case CGRLC_TBF_MODE_UL: help = grr_data->uplink_tbf.ts_mask; grr_data->uplink_tbf.ts_mask &= mask; if(!grr_data->uplink_tbf.ts_mask) { result = E_PDCH_REL_RELEASE_UL; } else if(grr_data->uplink_tbf.ts_mask NEQ help) { grr_data->uplink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->uplink_tbf.ts_mask); result = E_PDCH_REL_RECONF; tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_UL,CGRLC_PRIM_STATUS_NULL); } else { TRACE_EVENT("NO change in pdch rel for ul tbf"); result = E_PDCH_REL_NULL; } break; case CGRLC_TBF_MODE_DL: help = grr_data->downlink_tbf.ts_mask; grr_data->downlink_tbf.ts_mask &= mask; if(!grr_data->downlink_tbf.ts_mask) { result = E_PDCH_REL_RELEASE_DL; } else if(grr_data->downlink_tbf.ts_mask NEQ help) { grr_data->downlink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->downlink_tbf.ts_mask); tc_cgrlc_dl_tbf_req(); result = E_PDCH_REL_RECONF; } else { TRACE_EVENT("NO change in pdch rel for dl tbf"); result = E_PDCH_REL_IGNORE; } break; case CGRLC_TBF_MODE_DL_UL: help = grr_data->uplink_tbf.ts_mask; help2 = grr_data->downlink_tbf.ts_mask; grr_data->uplink_tbf.ts_mask &= mask; grr_data->downlink_tbf.ts_mask &= mask; if( !handle_ms_cap(UL_DL_ASSIGNMENT)) { result = E_PDCH_REL_RELEASE_BOTH; TRACE_EVENT_P3("MS CLASS ERROR in PDCH assignment ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } else if(!grr_data->downlink_tbf.ts_mask AND !grr_data->uplink_tbf.ts_mask) { result = E_PDCH_REL_RELEASE_BOTH; TRACE_EVENT_P3("rel of UL and DL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } else if(!grr_data->downlink_tbf.ts_mask) { /*DL release*/ if(grr_data->uplink_tbf.ts_mask EQ help) { /* no change for uplink*/ result = E_PDCH_REL_RELEASE_DL; TRACE_EVENT_P3("rel of DL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } else { /*uplink reconfigure*/ result = E_PDCH_REL_RELEASE_DL_RECONF_UL; grr_data->uplink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->uplink_tbf.ts_mask); tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_UL,CGRLC_PRIM_STATUS_NULL); TRACE_EVENT_P3("rel of DL, conf UL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } } else if(!grr_data->uplink_tbf.ts_mask) { /*UL release*/ if(grr_data->downlink_tbf.ts_mask EQ help2) { /* no change for downlink*/ result = E_PDCH_REL_RELEASE_UL; TRACE_EVENT_P3("rel of UL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } else { /*downlink reconfigure*/ result = E_PDCH_REL_RELEASE_UL_RECONF_DL; grr_data->downlink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->downlink_tbf.ts_mask); tc_cgrlc_dl_tbf_req(); TRACE_EVENT_P3("rel of UL, conf DL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } } else if(grr_data->downlink_tbf.ts_mask NEQ help2) { /*change in DL*/ result = E_PDCH_REL_RECONF; grr_data->downlink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->downlink_tbf.ts_mask); tc_cgrlc_dl_tbf_req(); if(grr_data->uplink_tbf.ts_mask EQ help) { /* no change for uplink*/ TRACE_EVENT_P3("conf of DL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } else { /*uplink reconfigure*/ grr_data->uplink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->uplink_tbf.ts_mask); tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_UL,CGRLC_PRIM_STATUS_NULL); TRACE_EVENT_P3("conf ofDL/UL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } } else { /* no change in DL*/ if(grr_data->uplink_tbf.ts_mask EQ help) { /* no change for uplink*/ result = E_PDCH_REL_IGNORE; TRACE_EVENT_P3("NO conf UL/DL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } else { /*uplink reconfigure*/ result = E_PDCH_REL_RECONF; grr_data->uplink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->uplink_tbf.ts_mask); tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_UL,CGRLC_PRIM_STATUS_NULL); TRACE_EVENT_P3("conf of UL ul_mask=%x, dl_mask=%x, pdch_mask=%x", grr_data->uplink_tbf.ts_mask, grr_data->downlink_tbf.ts_mask, mask); } } break; default: TRACE_ERROR("unknown tbf type in tc_eval_pdch_rel"); break; } return(result); } /* tc_eval_pdch_rel() */ /* +------------------------------------------------------------------------------ | Function : tc_eval_ul_assign +------------------------------------------------------------------------------ | Description : The function tc_eval_ul_assign() evaluates a | Packet Uplink Assignment. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL T_EVAL_UL_ASSIGN tc_eval_ul_assign ( void ) { MCAST(d_ul_assign,D_UL_ASSIGN); /* T_D_UL_ASSIGN */ T_EVAL_UL_ASSIGN result = E_UL_ASSIGN_NULL; UBYTE tx_slots = 0; UBYTE i,mask; T_GRR_STORE_TYPE grr_store_type = GRR_STORE_TYPE_NONE; TRACE_FUNCTION( "tc_eval_ul_assign" ); #ifdef REL99 if(d_ul_assign->egprs_flag) { TRACE_ERROR("EGPRS TBF received in UL ASSIGNMENT"); if(grr_data->tbf_type EQ CGRLC_TBF_MODE_NULL) { /* TBF is not active. Handling abnormal case * 7.1.4 If the mobile station has been assigned a TBF in EGPRS mode and * the MS does not support EGPRS, or has been assigned an MCS (e.g. 8-PSK * in the Uplink) that the MS does not support, the MS shall return to packet * idle mode and notify higher layers (TBF establishment failure) */ return E_UL_ASSIGN_ERROR_RA; } else { /* TBF is active. Handling abnormal case * 8.7 While a TBF is in progress, if a mobile station receives a * PACKET UPLINK ASSIGNMENT, PACKET UPLINK ACK/NACK or PACKET TIMESLOT RECONFIGURE * message with message escape bit indicating EGPRS (resp. GPRS) contents whereas * the current TBF mode is GPRS (resp. EGPRS), the mobile station shall ignore the * message. */ return E_UL_ASSIGN_IGNORE; } } #endif /* * Handle mac mode */ switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_DL: grr_data->uplink_tbf.ti = 0; /* contention resolution NOT required */ /*lint -fallthrough*/ case CGRLC_TBF_MODE_NULL: if(d_ul_assign->v_dyn_alloc_p) { if(!d_ul_assign->dyn_alloc_p.xdyn_alloc) grr_data->uplink_tbf.mac_mode = DA; else { grr_data->uplink_tbf.mac_mode = EDA; } } else if(d_ul_assign->v_f_alloc_ul) grr_data->uplink_tbf.mac_mode = FA; break; case CGRLC_TBF_MODE_UL: if( grr_data->uplink_tbf.mac_mode NEQ DA AND d_ul_assign->v_dyn_alloc_p ) { TRACE_ERROR("dynamic alloc received while fixed is running in uplink"); return E_UL_ASSIGN_ERROR_RA; } else if( grr_data->uplink_tbf.mac_mode NEQ FA AND d_ul_assign->v_f_alloc_ul ) { TRACE_ERROR("fixed alloc received while dynamic is running in uplink"); return E_UL_ASSIGN_ERROR_RA; } break; default: break; } grr_data->uplink_tbf.cs_mode = d_ul_assign->chan_coding_cmd; grr_data->uplink_tbf.tlli_cs_mode = d_ul_assign->tlli_chan_coding; grr_data->uplink_tbf.polling_bit = 0xFF; if(d_ul_assign->v_dyn_alloc_p) { if( grr_data->uplink_tbf.mac_mode NEQ DA) { result = E_UL_ASSIGN_ERROR_RA; TRACE_ERROR("dyn alloc received but diff mac mode"); TRACE_EVENT_P3("MAC_MODE: ms=%d, Ex.DA=%d tbf_mode=%d" ,grr_data->uplink_tbf.mac_mode ,d_ul_assign->dyn_alloc_p.xdyn_alloc ,grr_data->tbf_type); } else { result = E_UL_ASSIGN_DYNAMIC; /* SZML-TC/071*/ if (d_ul_assign->dyn_alloc_p.v_rlc_db_granted)/* close-ended TBF*/ { UBYTE data_size=20; switch( grr_data->uplink_tbf.cs_mode) { case CGRLC_CS_MODE_1: data_size = 20; break; case CGRLC_CS_MODE_2: data_size = 30; break; case CGRLC_CS_MODE_3: data_size = 36; break; case CGRLC_CS_MODE_4: data_size = 50; break; default: TRACE_ERROR("unknown Coding Scheme"); break; } data_size -= grr_data->uplink_tbf.ti*4; /* CR TLLI */ grr_data->uplink_tbf.rlc_db_granted = (d_ul_assign->dyn_alloc_p.rlc_db_granted + 9); if (grr_data->uplink_tbf.rlc_db_granted * data_size < grr_data->uplink_tbf.rlc_oct_cnt) /* granted rlc blocks in bytes are not enough to transmit the first pdu*/ { result = E_UL_ASSIGN_ERROR_RA; TRACE_EVENT_P3("granted rlc blocks are not enough to transmit the first pdu rlc_g=%ld sdu_len =%ld data_size=%d" ,grr_data->uplink_tbf.rlc_db_granted * data_size ,grr_data->uplink_tbf.rlc_oct_cnt ,data_size); return(result); } } else { /* * open ended TBF */ grr_data->uplink_tbf.rlc_db_granted = 0; } grr_data->uplink_tbf.ts_usage = 0; if(d_ul_assign->dyn_alloc_p.v_tn_alloc) { for(i = 0,mask = 0x80;i < 8;i++) { if(d_ul_assign->dyn_alloc_p.tn_alloc[i].v_usf) { grr_data->uplink_tbf.ts_usage |= mask; tx_slots++; } mask >>= 1; } } else if(d_ul_assign->dyn_alloc_p.v_tn_alloc_pwr) { for(i = 0,mask = 0x80;i < 8;i++) { if(d_ul_assign->dyn_alloc_p.tn_alloc_pwr.usf_array[i].v_usf_g) { grr_data->uplink_tbf.ts_usage |= mask; tx_slots++; } mask >>= 1; } grr_store_type = GRR_STORE_TYPE_TN_ALLOC_PWR; } grr_data->uplink_tbf.nts = tx_slots; } } else if(d_ul_assign->v_sin_alloc) { if( grr_data->tc.v_sb_without_tbf ) { result = E_UL_ASSIGN_SB_WITHOUT_TBF; } else { result = E_UL_ASSIGN_SB_2PHASE_ACCESS ; grr_data->uplink_tbf.ti = 0; } /* * estimate timeslot */ grr_data->uplink_tbf.ts_usage = (0x80 >> d_ul_assign->sin_alloc.tn); tx_slots=1; grr_data->uplink_tbf.nts = tx_slots; if(d_ul_assign->sin_alloc.v_alf_gam) { grr_store_type = GRR_STORE_TYPE_ALF_GAM; } /* starting time allready elapsed? */ if(d_ul_assign->sin_alloc.tbf_s_time.v_abs) { ULONG fn_out; fn_out = grr_decode_tbf_start_abs(&d_ul_assign->sin_alloc.tbf_s_time.abs); TRACE_EVENT_P5("eval_ul fn_out:%ld fn_in:%d %d %d data->fn:%ld", fn_out, d_ul_assign->sin_alloc.tbf_s_time.abs.t1, d_ul_assign->sin_alloc.tbf_s_time.abs.t2, d_ul_assign->sin_alloc.tbf_s_time.abs.t3, grr_data->dl_fn); if(grr_check_if_tbf_start_is_elapsed ( fn_out, grr_data->ul_fn)) { TRACE_ERROR("TBF Starting time is ELAPSED in single block allocation!"); TRACE_EVENT_P2("CPAP SBR TBF ST ELAPSED st=%ld c_fn=%ld ", fn_out,grr_data->ul_fn); result = E_UL_ASSIGN_ERROR_RA; } } else if(d_ul_assign->sin_alloc.tbf_s_time.v_rel AND !d_ul_assign->sin_alloc.tbf_s_time.rel) { TRACE_ERROR("rel. TBF Starting time in single block allocation k=0 NOT ALLOWED"); TRACE_EVENT_P1("k=%d ", d_ul_assign->sin_alloc.tbf_s_time.rel); result = E_UL_ASSIGN_ERROR_RA; } else if(!d_ul_assign->sin_alloc.tbf_s_time.v_rel) { TRACE_ERROR("NO TBF Starting time in single block allocation "); TRACE_EVENT_P2("v_abs=%d v_rel=%d ", d_ul_assign->sin_alloc.tbf_s_time.v_abs , d_ul_assign->sin_alloc.tbf_s_time.v_rel); result = E_UL_ASSIGN_ERROR_RA; } } else if(d_ul_assign->v_f_alloc_ul) { if( grr_data->uplink_tbf.mac_mode EQ DA ) { result = E_UL_ASSIGN_ERROR_RA; TRACE_ERROR("fixed alloc received while dynamic is running in uplink"); } else { result = E_UL_ASSIGN_FIXED; grr_data->uplink_tbf.ts_usage = 0; tx_slots=0; if(d_ul_assign->f_alloc_ul.v_ts_alloc) { grr_data->uplink_tbf.ts_usage = d_ul_assign->f_alloc_ul.ts_alloc; /*calculate number of timeslots*/ tx_slots = grr_calc_nr_of_set_bits(grr_data->uplink_tbf.ts_usage); } else if(d_ul_assign->f_alloc_ul.v_pwr_par) { for(i = 0,mask = 0x80;i < 8;i++) { if(d_ul_assign->f_alloc_ul.pwr_par.gamma_tn[i].v_gamma) { grr_data->uplink_tbf.ts_usage |= mask; tx_slots++; } mask >>= 1; } grr_store_type = GRR_STORE_TYPE_PWR_PAR; } grr_data->uplink_tbf.nts = tx_slots; } } else { TRACE_ERROR ("Packet Uplink Assignment without allocation type - corrupt airmessage!"); } if( !handle_ms_cap(UL_ASSIGNMENT) ) { result = E_UL_ASSIGN_ERROR_RA; TRACE_EVENT("tc_eval_.. will return E_UL_ASSIGN_ERROR_RA (tx_slots wrong)"); } if ( !tc_check_and_save_freq ()) { if ((grr_data->tbf_type EQ CGRLC_TBF_MODE_DL) OR (grr_data->tbf_type EQ CGRLC_TBF_MODE_DL_UL) ) { result = E_UL_ASSIGN_IGNORE; TRACE_EVENT("tc_eval_.. will return E_UL_ASSIGN_IGNORE , DL ACTIVE (frequencies wrong)"); } else { result = E_UL_ASSIGN_ERROR_RA; TRACE_EVENT("tc_eval_.. will return E_UL_ASSIGN_ERROR_RA (frequencies wrong)"); } return result; } if( result NEQ E_UL_ASSIGN_ERROR_RA AND result NEQ E_UL_ASSIGN_NULL ) { switch( grr_store_type ) { case GRR_STORE_TYPE_TN_ALLOC_PWR: grr_store_type_tn_alloc_pwr( &d_ul_assign->dyn_alloc_p.tn_alloc_pwr ); break; case GRR_STORE_TYPE_ALF_GAM: grr_store_type_alf_gam( &d_ul_assign->sin_alloc.alf_gam, d_ul_assign->sin_alloc.tn ); break; case GRR_STORE_TYPE_PWR_PAR: grr_store_type_pwr_par( &d_ul_assign->f_alloc_ul.pwr_par, FALSE ); break; default: /* do nothing */ break; } } return(result); } /* tc_eval_ul_assign() */ /* +------------------------------------------------------------------------------ | Function : tc_eval_dl_assign +------------------------------------------------------------------------------ | Description : The function tc_eval_dl_assign() evaluates a | Packet Downlink Assignment. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL T_EVAL_DL_ASSIGN tc_eval_dl_assign () { MCAST(d_dl_assign,D_DL_ASSIGN); /* T_D_DL_ASSIGN */ T_EVAL_DL_ASSIGN result = E_DL_ASSIGN_IGNORE; TRACE_FUNCTION( "tc_eval_dl_assign" ); /* SZML-TC/072: check for things that results in E_DL_ASSIGN_ERROR_RA */ grr_data->downlink_tbf.ctrl_ack_bit= 0; /* * compare uplink and new assigned downlink mac mode * and set downlink mac mode */ switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_NULL: grr_data->downlink_tbf.mac_mode = d_dl_assign->mac_mode; grr_data->downlink_tbf.t3192 = FALSE; /* indicates if t3192 is running*/ grr_data->downlink_tbf.rlc_mode = d_dl_assign->rlc_mode; result = E_DL_ASSIGN; break; case CGRLC_TBF_MODE_UL: grr_data->downlink_tbf.mac_mode = d_dl_assign->mac_mode; grr_data->downlink_tbf.t3192 = FALSE; /* indicates if t3192 is running*/ grr_data->downlink_tbf.rlc_mode = d_dl_assign->rlc_mode; /*lint -fallthrough*/ case CGRLC_TBF_MODE_DL_UL: if(d_dl_assign->mac_mode NEQ grr_data->uplink_tbf.mac_mode) { result = E_DL_ASSIGN_IGNORE; TRACE_EVENT_P2("Ignore DL_ASS, Diff MAC Mode UL=%d DL=%d ",grr_data->uplink_tbf.mac_mode,d_dl_assign->mac_mode); return result; } if ((grr_data->downlink_tbf.rlc_mode NEQ d_dl_assign->rlc_mode) AND !d_dl_assign->ctrl_ack) { TRACE_ERROR("Diff rlc mode in downlink ass..aborting tbf"); result = E_DL_ASSIGN_ABORT_DL; return result; } grr_data->downlink_tbf.rlc_mode = d_dl_assign->rlc_mode; result = E_DL_ASSIGN; break; case CGRLC_TBF_MODE_DL: if ((grr_data->downlink_tbf.rlc_mode NEQ d_dl_assign->rlc_mode) AND !d_dl_assign->ctrl_ack) { TRACE_ERROR("Diff rlc mode in downlink ass..aborting tbf"); result = E_DL_ASSIGN_ABORT_DL; return result; } grr_data->downlink_tbf.rlc_mode = d_dl_assign->rlc_mode; result = E_DL_ASSIGN; break; default: result = E_DL_ASSIGN; break; } /* * compare old and new mac mode for downlink */ if ( d_dl_assign->mac_mode EQ FA_HALF_DUPLEX) { result = E_DL_ASSIGN_IGNORE; TRACE_EVENT( "DL ASS: Half duplex not supported" ); return result; } else if(d_dl_assign->mac_mode NEQ grr_data->downlink_tbf.mac_mode) { result = E_DL_ASSIGN_IGNORE; TRACE_EVENT_P3( "DL ASS: current mac mode= %d differs from commanded =%d tbf_type=%d" ,grr_data->downlink_tbf.mac_mode ,d_dl_assign->mac_mode ,grr_data->tbf_type ); return result; } /* * ckeck if tfi is present while no downlink tbf is active */ switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_UL: case CGRLC_TBF_MODE_NULL: if(!d_dl_assign->pda_trnc_grp.v_dl_tfi_assign) { result = E_DL_ASSIGN_IGNORE; TRACE_EVENT("Ignore DL_ASS, no dl_tfi in P DL Ass(no dl tbf active) "); return result; } result = E_DL_ASSIGN; break; default: result = E_DL_ASSIGN; break; } if(d_dl_assign->ctrl_ack) { if(grr_data->downlink_tbf.t3192) { grr_data->downlink_tbf.ctrl_ack_bit= 1; grr_data->downlink_tbf.t3192 = FALSE; /* indicates if t3192 is running*/ } else { result = E_DL_ASSIGN_IGNORE; TRACE_EVENT("DL ASS IGNORED, ctrl ack bit set but t3192 is not running"); return result; } } else if(grr_data->downlink_tbf.t3192) { TRACE_EVENT("DL assignment:ctrl ack bit is not set but t3192 is running"); } grr_data->downlink_tbf.ts_usage = d_dl_assign->ts_alloc; grr_data->downlink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->downlink_tbf.ts_usage); if( !handle_ms_cap(DL_ASSIGNMENT)) { result = E_DL_ASSIGN_ERROR_RA; TRACE_EVENT("tc_eval_.. will return E_DL_ASSIGN_ERROR_RA (ms class error)"); return result; } if( tc_check_and_save_freq( ) EQ FALSE ) { if ((grr_data->tbf_type EQ CGRLC_TBF_MODE_UL) OR (grr_data->tbf_type EQ CGRLC_TBF_MODE_DL_UL)) { result = E_DL_ASSIGN_IGNORE; TRACE_EVENT("tc_eval_.. will return E_DL_ASSIGN_IGNORE , UL ACTIVE (frequencies wrong)"); } else { result = E_DL_ASSIGN_ERROR_RA; TRACE_EVENT("tc_eval_.. will return E_DL_ASSIGN_ERROR_RA (frequencies wrong)"); } return result; } if( d_dl_assign->pda_trnc_grp.v_pwr_par EQ TRUE ) { grr_store_type_pwr_par( &d_dl_assign->pda_trnc_grp.pwr_par, FALSE ); } return(result); } /* tc_eval_dl_assign() */ /* +------------------------------------------------------------------------------ | Function : tc_eval_access_rej +------------------------------------------------------------------------------ | Description : The function tc_eval_access_rej() evaluates a | Packet Access Reject. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL T_EVAL_ACCESS_REJ tc_eval_access_rej ( ULONG * t3172_value_i) { MCAST(d_access_rej,D_ACCESS_REJ); T_EVAL_ACCESS_REJ result = E_ACCESS_REJ_NULL; TRACE_FUNCTION( "tc_eval_access_rej" ); /*SZML-TC/122*/ if(d_access_rej->reject.v_wait) { result = E_ACCESS_REJ_WAIT; *t3172_value_i = d_access_rej->reject.wait.wait_ind; if( d_access_rej->reject.wait.waitsize ) { *t3172_value_i *= 20; } else { *t3172_value_i *= 1000; } } else { result = E_ACCESS_REJ_NO_WAIT; } return(result); } /* tc_eval_access_rej() */ /* +------------------------------------------------------------------------------ | Function : tc_send_ra_req +------------------------------------------------------------------------------ | Description : The function tc_send_ra_req() starts the build-process for a | Packet Access Request and send a MPHP_RA_REQ. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_ra_req ( void ) { TRACE_FUNCTION( "tc_send_ra_req" ); while( (grr_data->tc.n_acc_req < max_retrans_table[psc_db->prach.max_retrans[grr_data->uplink_tbf.prio]]+1) AND (tc_check_p_level() EQ C_P_LEVEL_DO_NOT_SEND) ) { TRACE_EVENT("C_P_LEVEL_DO_NOT_SEND"); grr_data->tc.n_acc_req++; } if (grr_data->tc.n_acc_req < max_retrans_table[psc_db->prach.max_retrans[grr_data->uplink_tbf.prio]]+1) { PALLOC(mphp_ra_req,MPHP_RA_REQ); memset(mphp_ra_req,0x00,sizeof(T_MPHP_RA_REQ)); /* * The powervalue txpwr_max_cch in DB is always a useful value. * The value is set by PSI. First a useful initial value. * After that a value from RR and after reception of PSI3 txpwr_max_cch * is set to a value from the scell-structure. */ mphp_ra_req->txpwr = grr_get_ms_txpwr_max_cch ( psc_db->pbcch.bcch.arfcn, grr_data->meas.pwr_offset, psc_db->scell_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch ); if(grr_data->tc.sending_req EQ TRUE) { mphp_ra_req->rand = (USHORT)tc_gen_rand(); } else { /* The first PCR may be sent immediately when ready. Only the second PCR */ /* needs a random value which has to have uniform probability distribution */ mphp_ra_req->rand = 1; } mphp_ra_req->channel_request_data = tc_calc_req(); mphp_ra_req->bs_prach_blks = psc_db->pccch.bs_prach_blks; mphp_ra_req->burst_type = psc_db->gprs_cell_opt.ab_type; { UBYTE channel_request_data[RLC_MAC_MAX_LEN_CHANNEL_REQ]; channel_request_data[0] = ( mphp_ra_req->channel_request_data >> 8 ); channel_request_data[1] = ( UBYTE )mphp_ra_req->channel_request_data; TRACE_BINDUMP ( hCommGRR, TC_USER4, cl_rlcmac_get_msg_name( U_MSG_TYPE_CHANNEL_REQ_c, RLC_MAC_ROUTE_UL ), channel_request_data, RLC_MAC_MAX_LEN_CHANNEL_REQ ); /*lint !e569*/ } PSEND(hCommL1,mphp_ra_req); grr_data->tc.sending_req = TRUE; } else { vsi_t_start(GRR_handle,T3170,tc_get_t3170_value()); vsi_t_stop(GRR_handle,T3186); tc_send_ra_stop_req(); } } /* tc_send_ra_req() */ /* +------------------------------------------------------------------------------ | Function : tc_send_ra_stop_req +------------------------------------------------------------------------------ | Description : The function tc_send_ra_stop_req() stops the | sending of packet access requests. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_ra_stop_req ( void ) { TRACE_FUNCTION( "tc_send_ra_stop_req" ); /* * This timer might be run - in case of MPHP_RA_CON has not been received by GRR. * If it does not run the stop-command will be ignored by vsi. */ vsi_t_stop(GRR_handle,T3186); if(grr_data->tc.sending_req) { PALLOC(mphp_ra_stop_req,MPHP_RA_STOP_REQ); PSEND(hCommL1,mphp_ra_stop_req); /* * reset number of access in this procedure */ grr_data->tc.n_acc_req =0; /* * to make sure that TC only stops * the sending procedure if it * is running */ grr_data->tc.sending_req = FALSE; } } /* tc_send_ra_stop_req() */ /* +------------------------------------------------------------------------------ | Function : tc_send_polling_res +------------------------------------------------------------------------------ | Description : The function tc_send_polling_res() sends the primitive | MPHP_POLLING_RESPONSE_REQ. | | Parameters : ctrl_ack_type_i - indicates if normal or access burst shall sent | rrbp_i - depending on this variable the send frame number is computed | fn_i - frame number where Packet Polling Request was received | ctrl_ack_i - this value is sent within the pca, depends frim mac header | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_polling_res (UBYTE poll_type_i, ULONG fn_i, UBYTE rrbp_i,UBYTE ctrl_ack_i ) { PALLOC( mphp_polling_response_req, MPHP_POLLING_RESPONSE_REQ ); TRACE_FUNCTION( "tc_send_polling_res" ); mphp_polling_response_req->fn = grr_calc_new_poll_pos( fn_i, rrbp_i ); mphp_polling_response_req->txpwr = grr_get_ms_txpwr_max_cch ( psc_db->pbcch.bcch.arfcn, grr_data->meas.pwr_offset, psc_db->scell_par.cr_par_1.cr_pow_par.gprs_ms_txpwr_max_cch ); if(poll_type_i EQ CGRLC_POLL_RES_NB) { mphp_polling_response_req->poll_resp_type = POLL_RESP_NB_CS1; memset( mphp_polling_response_req->poll_data, 0x2b, sizeof(mphp_polling_response_req->poll_data) ); mphp_polling_response_req->poll_data[23] = 0 ; /* Byte is not used, set to 0 for test purposes */ /* code without CCD, air message buffer is used by other service*/ mphp_polling_response_req->poll_data[0] = 0x40 | grr_data->r_bit; mphp_polling_response_req->poll_data[1] = 0x04 |((UBYTE)(grr_data->db.ms_id.new_tlli>>30)); mphp_polling_response_req->poll_data[2] = ((UBYTE)(grr_data->db.ms_id.new_tlli>>22)); mphp_polling_response_req->poll_data[3] = ((UBYTE)(grr_data->db.ms_id.new_tlli>>14)); mphp_polling_response_req->poll_data[4] = ((UBYTE)(grr_data->db.ms_id.new_tlli>>06)); mphp_polling_response_req->poll_data[5] = ((UBYTE)(grr_data->db.ms_id.new_tlli<<2)) + ctrl_ack_i; /* * get TA from paxket uplink/downlink assignment */ if(grr_data->ta_params.ta_value EQ 0xFF) { MCAST( d_ul_assign, D_UL_ASSIGN ); MCAST( d_dl_assign, D_DL_ASSIGN); if(( d_dl_assign->msg_type EQ D_DL_ASSIGN_c) AND d_dl_assign->pta.v_ta_value) { mphp_polling_response_req->ta_index = d_dl_assign->pta.ta_value; } else if(( d_ul_assign->msg_type EQ D_UL_ASSIGN_c) AND d_ul_assign->pta.v_ta_value) { mphp_polling_response_req->ta_index = d_ul_assign->pta.ta_value; } else { TRACE_ERROR("NO TA IN MPHP_POLLING_REQ"); TRACE_EVENT_P5("msg_typ=%d, v_pta_dl=%d v_pta_ul=%d v_ptai_dl=%d v_ptai_ul=%d" ,d_ul_assign->msg_type ,d_dl_assign->pta.v_ta_value ,d_ul_assign->pta.v_ta_value ,d_dl_assign->pta.v_ta_index_tn ,d_ul_assign->pta.v_ta_index_tn); } } else { mphp_polling_response_req->ta_index = grr_data->ta_params.ta_value; TRACE_EVENT_P1("valid ta in database at sending MPHP_POLLING_RES_REQ ta=%d",grr_data->ta_params.ta_value); } TRACE_BINDUMP ( hCommGRR, TC_USER4, cl_rlcmac_get_msg_name ( ( UBYTE )( mphp_polling_response_req->poll_data[1] >> 2 ), RLC_MAC_ROUTE_UL ), mphp_polling_response_req->poll_data, MAX_L2_FRAME_SIZE ); /*lint !e569*/ } else { USHORT data; /* * initalize channel request data array */ memset( mphp_polling_response_req->poll_data, 0, sizeof(mphp_polling_response_req->poll_data) ); /* * format is four access bursts */ if(psc_db->gprs_cell_opt.ab_type EQ AB_8_BIT) { /* * 8 Bit access burst */ mphp_polling_response_req->poll_resp_type = POLL_RESP_AB_8_BIT; data =0x0000; data|=0x7f; /*TRACE_EVENT_P1("POLL_RESP_8BIT_AB: FN %Ld", mphp_polling_response_req->fn);*/ } else { /* * 11 Bit access burst */ mphp_polling_response_req->poll_resp_type = POLL_RESP_AB_11_BIT; data = (0x07<<8); data|=0xe7; data = grr_convert_11bit_2_etsi(data); /*TRACE_EVENT_P1("POLL_RESP_11BIT_AB: FN %Ld", mphp_polling_response_req->fn);*/ } mphp_polling_response_req->poll_data[0]= (UBYTE)(data & 0x00ff); mphp_polling_response_req->poll_data[1]= (UBYTE)((data & 0xff00) >> 8); TRACE_BINDUMP ( hCommGRR, TC_USER4, cl_rlcmac_get_msg_name( U_MSG_TYPE_CHANNEL_REQ_c, RLC_MAC_ROUTE_UL ), mphp_polling_response_req->poll_data, RLC_MAC_MAX_LEN_CHANNEL_REQ ); /*lint !e569*/ } PSEND( hCommL1, mphp_polling_response_req ); } /* tc_send_polling_res() */ /* +------------------------------------------------------------------------------ | Function : tc_send_single_block +------------------------------------------------------------------------------ | Description : The function tc_send_single_block() sends the primitive | MPHP_SINGLE_BLOCK_REQ with measurement report. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_single_block ( void ) { MCAST(d_ul_assign,D_UL_ASSIGN); T_MPHP_SINGLE_BLOCK_REQ * ptr2prim; TRACE_FUNCTION( "tc_send_single_block" ); ptr2prim = tc_get_send_nb_prim_and_set_freq( ); ptr2prim->assign_id = 0; ptr2prim->purpose = SINGLE_BLOCK_TRANSFER_UL; ptr2prim->pc_meas_chan = psc_db->g_pwr_par.pc_meas_chan; ptr2prim->burst_type = ( psc_db->gprs_cell_opt.ab_type EQ AB_8_BIT ) ? AB_8_BIT : AB_11_BIT; /* timing advance */ if (d_ul_assign->pta.v_ta_value) { ptr2prim->p_timing_advance.ta_value = d_ul_assign->pta.ta_value; } else { ptr2prim->p_timing_advance.ta_value = 0xff; } if(d_ul_assign->pta.v_ta_index_tn) { ptr2prim->p_timing_advance.ta_index = d_ul_assign->pta.ta_index_tn.ta_index; } else { ptr2prim->p_timing_advance.ta_index = 0xff; } /* trainings sequence */ ptr2prim->tsc = d_ul_assign->freq_par.tsc; /* handle TBF starting time (is always present in single block allocation) */ if(d_ul_assign->sin_alloc.tbf_s_time.v_abs) { ptr2prim->p_tbf_start.tbf_start_present = 1; ptr2prim->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ul_assign->sin_alloc.tbf_s_time.abs); if(grr_check_if_tbf_start_is_elapsed ( ptr2prim->p_tbf_start.fn, grr_data->ul_fn)) { /* SZML-TC/077: drop message, enter pim */ TRACE_ERROR("TBF Starting time is ELAPSED in single block allocation!"); TRACE_EVENT_P2("CPAP SBR TBF ST ELAPSED st=%ld c_fn=%ld ", ptr2prim->p_tbf_start.fn,grr_data->ul_fn); } } else if (d_ul_assign->sin_alloc.tbf_s_time.v_rel) { ptr2prim->p_tbf_start.tbf_start_present = 1; /* * For the relative position set d_ul_assign->sin_alloc.tbf_s_time.rel-1, because grr_data->fn is * received from mphp_data_ind. This fn is the current fn, and not the received fn. */ ptr2prim->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, (USHORT)(d_ul_assign->sin_alloc.tbf_s_time.rel)); } else { TRACE_ERROR("TBF Starting time is missing in single block allocation!"); /* SZML-TC/078: drop message, enter pim ! */ } /* timeslot number */ ptr2prim->tn=d_ul_assign->sin_alloc.tn; /* put measurement report into buffer */ tc_cpy_ctrl_blk_to_buffer( ptr2prim->l2_frame ); sig_tc_meas_update_pch( ); TRACE_BINDUMP ( hCommGRR, TC_USER4, cl_rlcmac_get_msg_name ( ( UBYTE )( ptr2prim->l2_frame[1] >> 2 ), RLC_MAC_ROUTE_UL ), ptr2prim->l2_frame, MAX_L2_FRAME_SIZE ); /*lint !e569*/ PSEND(hCommL1,ptr2prim); } /* tc_send_single_block() */ /* +------------------------------------------------------------------------------ | Function : tc_send_resource_request_p +------------------------------------------------------------------------------ | Description : The function tc_send_resource_request_p() sends the primitive | MPHP_SINGLE_BLOCK_REQ with Packet Resource Request for | two phase access due to reception of airmessage packet uplink | assignment. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_resource_request_p ( void ) { MCAST(d_ul_assign,D_UL_ASSIGN); T_MPHP_SINGLE_BLOCK_REQ * ptr2prim; TRACE_FUNCTION( "tc_send_resource_request_p" ); ptr2prim = tc_get_send_nb_prim_and_set_freq( ); /* * mark that single block is because of two phase access procedure */ ptr2prim->assign_id = 0; ptr2prim->purpose = TWO_PHASE_ACESS; ptr2prim->pc_meas_chan = psc_db->g_pwr_par.pc_meas_chan; ptr2prim->burst_type = (psc_db->gprs_cell_opt.ab_type EQ AB_8_BIT) ?AB_8_BIT :AB_11_BIT; if (d_ul_assign->pta.v_ta_value) { ptr2prim->p_timing_advance.ta_value = d_ul_assign->pta.ta_value; } else { ptr2prim->p_timing_advance.ta_value = 0xff; } if(d_ul_assign->pta.v_ta_index_tn) { ptr2prim->p_timing_advance.ta_index =d_ul_assign->pta.ta_index_tn.ta_index; } else { ptr2prim->p_timing_advance.ta_index =0xff; } /* * trainings sequence */ ptr2prim->tsc = d_ul_assign->freq_par.tsc; /* * handle TBF starting time * is always present in single block allocation */ if(d_ul_assign->sin_alloc.tbf_s_time.v_abs) { ptr2prim->p_tbf_start.tbf_start_present = 1; ptr2prim->p_tbf_start.fn = grr_decode_tbf_start_abs(&d_ul_assign->sin_alloc.tbf_s_time.abs); if(grr_check_if_tbf_start_is_elapsed ( ptr2prim->p_tbf_start.fn, grr_data->ul_fn)) { /* SZML-TC/079 */ TRACE_ERROR("TBF Starting time is ELAPSED in single block allocation!"); TRACE_EVENT_P2("CPAP SBR TBF ST ELAPSED st=%ld c_fn=%ld ", ptr2prim->p_tbf_start.fn,grr_data->ul_fn); } TRACE_EVENT_P5("res_req fn_out:%ld fn_in:%d %d %d data->fn:%ld", ptr2prim->p_tbf_start.fn, d_ul_assign->sin_alloc.tbf_s_time.abs.t1, d_ul_assign->sin_alloc.tbf_s_time.abs.t2, d_ul_assign->sin_alloc.tbf_s_time.abs.t3, grr_data->dl_fn); } else if (d_ul_assign->sin_alloc.tbf_s_time.v_rel) { ptr2prim->p_tbf_start.tbf_start_present = 1; /* * For the relative position set d_ul_assign->sin_alloc.tbf_s_time.rel-1, because grr_data->fn is * received from mphp_data_ind. This fn is the current fn, and not the received fn. */ ptr2prim->p_tbf_start.fn = grr_decode_tbf_start_rel(grr_data->dl_fn, (USHORT)(d_ul_assign->sin_alloc.tbf_s_time.rel)); TRACE_EVENT_P3("REL: ST_TIME for PRR: fn_i=%ld rel=%ld fn_out=%ld" ,grr_data->dl_fn ,d_ul_assign->sin_alloc.tbf_s_time.rel ,ptr2prim->p_tbf_start.fn); } else { TRACE_ERROR("TBF Starting time is missing in single block allocation!"); } ptr2prim->tn = d_ul_assign->sin_alloc.tn; { T_U_RESOURCE_REQ resource_req; tc_build_res_req( &resource_req, R_BUILD_2PHASE_ACCESS, SRC_TBF_INFO_UL_ASSIGN ); grr_encode_ul_ctrl_block( ptr2prim->l2_frame, ( UBYTE* )&resource_req ); } sig_tc_meas_update_pch( ); TRACE_BINDUMP ( hCommGRR, TC_USER4, cl_rlcmac_get_msg_name ( ( UBYTE )( ptr2prim->l2_frame[1] >> 2 ), RLC_MAC_ROUTE_UL ), ptr2prim->l2_frame, MAX_L2_FRAME_SIZE ); /*lint !e569*/ PSEND(hCommL1,ptr2prim); return; } /* tc_send_resource_request_p() */ /* +------------------------------------------------------------------------------ | Function : tc_handle_ra_con +------------------------------------------------------------------------------ | Description : The function tc_handle_ra_con() checks wheather there is to send | another Packet Access Request or not. | | Parameters : void +------------------------------------------------------------------------------ */ GLOBAL T_HANDLE_RA_CON tc_handle_ra_con ( void ) { T_HANDLE_RA_CON result; UBYTE max_retrans; TRACE_FUNCTION( "tc_handle_ra_con" ); /* * stop T3186 becauce packet access request was sent */ /* * get current max. retransmissson value */ max_retrans = max_retrans_table[psc_db->prach.max_retrans[grr_data->uplink_tbf.prio]]; if(grr_data->tc.n_acc_req >= max_retrans + 1) { result = H_RA_CON_STOP_REQ; vsi_t_start(GRR_handle,T3170,tc_get_t3170_value()); vsi_t_stop(GRR_handle,T3186); } else { result = H_RA_CON_CONTINUE; } return(result); } /* tc_handle_ra_con() */ /* +------------------------------------------------------------------------------ | Function : tc_init +------------------------------------------------------------------------------ | Description : The function tc_init() initialize the TC data structure. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_init ( void ) { UBYTE i; TRACE_FUNCTION( "tc_init" ); /* * set some values */ grr_data->tc.disable_callback_func = NULL; grr_data->tc.disable_class = CGRLC_DISABLE_CLASS_CR; grr_data->tbf_type = CGRLC_TBF_MODE_NULL; grr_data->tc.dcch_present = FALSE; grr_data->tc.v_freq_set = FALSE; /* * values for fixed alloc */ grr_data->tc.fa_ctrl.fa_type = FA_NO_CURRENT; grr_data->tc.fa_ctrl.repeat_alloc = FALSE; grr_data->tc.fa_ctrl.ts_overr = 0; grr_data->tc.num_of_rels_running = 0; /* initialize the relevant data for uplink control block */ grr_data->tc.v_sb_without_tbf = FALSE; grr_data->tc.ul_ctrl_blk.seq[0] = MAX_CTRL_BLK_NUM; for( i = 0; i < MAX_CTRL_BLK_NUM; i++ ) { grr_data->tc.ul_ctrl_blk.blk[i].state = BLK_STATE_NONE; grr_data->tc.ul_ctrl_blk.blk[i].owner = CGRLC_BLK_OWNER_NONE; } grr_data->tc.two_2p_w_4_tbf_con = TRUE; grr_data->tc.two_2p_w_4_tbf_con = TRUE; /* * Initialise service name (uses define SERVICE_NAME_* in GRR.H); */ INIT_STATE(TC,TC_ACCESS_DISABLED); /* * initialize primitive queue */ grr_data->tc.p_assign = NULL; grr_data->uplink_tbf.ts_mask = 0; grr_data->uplink_tbf.ts_usage = 0; grr_data->downlink_tbf.ts_mask = 0; grr_data->downlink_tbf.ts_usage = 0; grr_data->tc.n_acc_req = 0; #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH grr_data->tc.tbf_est_pacch = FALSE; #endif } /* tc_init() */ /* +------------------------------------------------------------------------------ | Function : tc_handle_error_pim +------------------------------------------------------------------------------ | Description : The function tc_handle_error_pim() ... | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_handle_error_pim ( void ) { TRACE_FUNCTION( "tc_handle_error_pim" ); TRACE_EVENT( "tc_handle_error_pim" ); if( grr_data->tc.v_sb_without_tbf ) { tc_set_stop_ctrl_blk( FALSE, CGRLC_BLK_OWNER_NONE, 0 ); tc_cgrlc_access_status_req(); } else { tc_cgrlc_ul_tbf_res ( CGRLC_TBF_MODE_ESTABLISHMENT_FAILURE, CGRLC_PRIM_STATUS_ONE ); } } /* tc_handle_error_pim() */ /* +------------------------------------------------------------------------------ | Function : tc_handle_error_ra +------------------------------------------------------------------------------ | Description : The function tc_handle_error_ra() handles actions related | to errors that leads to randam access procedure | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_handle_error_ra ( void ) { TRACE_FUNCTION( "tc_handle_error_ra" ); /* * - called in case of contention resulution failed in RU * - t3168 expires contention resulution failed in 2P-Access * - If the mobile station has been assigned more PDCHs than it supports according * to its MS multislot class, the mobile station shall reinitiate the packet access * procedure unless it has already been repeated 4 times. In that * case, TBF failure has occurred. */ /* * cancel access procedure if running */ if(grr_is_pbcch_present() #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH AND !grr_data->tc.tbf_est_pacch #endif ) { tc_send_ra_stop_req(); } /* * Kill TBF if running */ tc_abort_tbf(grr_data->tbf_type); SET_STATE(TC,TC_PIM); } /* tc_handle_error_ra() */ /* +------------------------------------------------------------------------------ | Function : tc_activate_tbf +------------------------------------------------------------------------------ | Description : The function tc_activate_tbf() set the assigned TBF | into the data structures | | Parameters : tbf_type_i - type of TBF to deactivate | +------------------------------------------------------------------------------ */ GLOBAL void tc_activate_tbf ( T_TBF_TYPE tbf_type_i ) { TRACE_FUNCTION( "tc_activate_tbf" ); /* * Reset of n_acc_req_procedures because of the fact that number of * access procedures during pacet access procedures must not considered in * a error with random access occured during running TBF. */ /* grr_data->tc.n_acc_req_procedures = 0;*/ switch( tbf_type_i ) { case CGRLC_TBF_MODE_UL: switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_DL: grr_data->tbf_type = CGRLC_TBF_MODE_DL_UL; break; case CGRLC_TBF_MODE_NULL: #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: #endif grr_data->tbf_type = CGRLC_TBF_MODE_UL; break; default: break; } break; case CGRLC_TBF_MODE_DL: switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_UL: grr_data->tbf_type = CGRLC_TBF_MODE_DL_UL; break; case CGRLC_TBF_MODE_NULL: grr_data->tbf_type = CGRLC_TBF_MODE_DL; break; default: break; } break; case CGRLC_TBF_MODE_DL_UL: switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_UL: case CGRLC_TBF_MODE_DL: case CGRLC_TBF_MODE_DL_UL: grr_data->tbf_type = CGRLC_TBF_MODE_DL_UL; break; default: { TRACE_ERROR("FATAL ERROR: tc_activate_tbf called with wrong tbf_type"); } break; } break; #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_UL: if (grr_data->tc.tbf_est_pacch) { grr_data->tbf_type = CGRLC_TBF_MODE_2PA; } else { TRACE_ERROR("FATAL ERROR: tc_activate_tbf called with wrong tbf_type"); } break; default: TRACE_ERROR("FATAL ERROR: tc_activate_tbf called with wrong tbf_type:CGRLC_TBF_MODE_2PA"); break; } break; #endif default: { TRACE_ERROR("FATAL ERROR: tc_activate_tbf called with wrong tbf_type"); } break; } /* switch (tbf_type_i) */ } /* tc_activate_tbf() */ /* +------------------------------------------------------------------------------ | Function : tc_deactivate_tbf +------------------------------------------------------------------------------ | Description : The function tc_deactivate_tbf() removes a TBF logical from TC | end estimates how to continue. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_deactivate_tbf ( T_TBF_TYPE tbf_i ) { TRACE_FUNCTION( "tc_deactivate_tbf" ); #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH if((tbf_i EQ CGRLC_TBF_MODE_UL) OR (tbf_i EQ CGRLC_TBF_MODE_2PA )) { grr_data->tc.tbf_est_pacch = FALSE; } #endif switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_DL_UL: switch( tbf_i ) { case CGRLC_TBF_MODE_UL: grr_data->tbf_type = CGRLC_TBF_MODE_DL; break; case CGRLC_TBF_MODE_DL: grr_data->tbf_type = CGRLC_TBF_MODE_UL; break; case CGRLC_TBF_MODE_DL_UL: grr_data->tbf_type = CGRLC_TBF_MODE_NULL; break; } break; case CGRLC_TBF_MODE_DL: case CGRLC_TBF_MODE_UL: #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: #endif grr_data->tbf_type = CGRLC_TBF_MODE_NULL; break; default: break; } switch( grr_data->tbf_type ) { case CGRLC_TBF_MODE_DL: SET_STATE(TC,TC_TBF_ACTIVE); /* * downlink tbf is running --> TC_TBF_ACTIVE */ break; case CGRLC_TBF_MODE_UL: /* * uplink tbf is running, no state change required */ break; case CGRLC_TBF_MODE_NULL: SET_STATE(TC,TC_PIM); /* * no tbf is running, enter TC_PIM */ break; default: break; } } /* tc_deactivate_tbf() */ /* +------------------------------------------------------------------------------ | Function : tc_start_timer_t3172 +------------------------------------------------------------------------------ | Description : The function tc_start_timer_t3172() | SZML-TC/085 this timer start | caused p access reject will be done | with cell reselection procedures | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void tc_start_timer_t3172 ( ULONG t3172_value_i ) { if(t3172_value_i > 10000) { TRACE_EVENT_P1( "T3172 start %d s", (t3172_value_i/1000)); } else { TRACE_EVENT_P1( "T3172 start %d ms", t3172_value_i); } vsi_t_start(GRR_handle,T3172_1,t3172_value_i); } /* tc_start_timer_t3172() */ /* +------------------------------------------------------------------------------ | Function : tc_handle_tbf_start |------------------------------------------------------------------------------ | Description : The function tc_handle_tbf_start() handles the TBF-Starting- | Time in a Packet Uplink Assignment. | | Parameters : tbf_type - type of tbf to be handled, | tbf_wait - pointer to variable to store the calculated timmer | value +------------------------------------------------------------------------------ */ GLOBAL void tc_handle_tbf_start( T_TBF_TYPE tbf_type ) { TRACE_FUNCTION( "tc_handle_tbf_start" ); tc_send_assign_req(tbf_type); tc_activate_tbf(tbf_type); if((tbf_type EQ CGRLC_TBF_MODE_UL)) { vsi_t_stop(GRR_handle,T3162); vsi_t_stop(GRR_handle,T3168); vsi_t_stop(GRR_handle,T3170); vsi_t_stop(GRR_handle,T3186); tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_UL,CGRLC_PRIM_STATUS_NULL); } else if(tbf_type EQ CGRLC_TBF_MODE_DL) { tc_cgrlc_dl_tbf_req(); if(grr_data->tc.v_sb_without_tbf EQ TRUE) { /*When Single Block is request for Measurement Report but network has sent the DL assignment, then this measurement report is sent to GRLC to be sent as normal control block*/ tc_send_control_msg_to_grlc(); grr_data->tc.v_sb_without_tbf = FALSE; } } else if(tbf_type EQ CGRLC_TBF_MODE_DL_UL) { vsi_t_stop(GRR_handle,T3168); tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_UL,CGRLC_PRIM_STATUS_NULL); tc_cgrlc_dl_tbf_req(); } #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH else if(tbf_type EQ CGRLC_TBF_MODE_2PA) { tc_cgrlc_ul_tbf_res(CGRLC_TBF_MODE_2PA,CGRLC_PRIM_STATUS_NULL); } #endif } /* tc_handle_tbf_start() */ /* +------------------------------------------------------------------------------ | Function : tc_prepare_handle_tbf_start |------------------------------------------------------------------------------ | Description : | | Parameters : +------------------------------------------------------------------------------ */ GLOBAL void tc_prepare_handle_tbf_start ( T_TBF_TYPE tbf_type, UBYTE new_state, UBYTE old_state ) { MCAST( p_d_dl_assign, D_DL_ASSIGN ); TRACE_FUNCTION( "tc_prepare_handle_tbf_start" ); if( grr_is_pbcch_present( ) AND ( old_state EQ TC_PIM OR old_state EQ TC_WAIT_ASSIGN OR old_state EQ TC_WAIT_2P_ASSIGN OR old_state EQ TC_POLLING OR old_state EQ TC_WAIT_STOP_TASK_CNF ) ) { UBYTE ccch_read; if( p_d_dl_assign->msg_type EQ D_DL_ASSIGN ) { ccch_read = ( p_d_dl_assign->pda_trnc_grp.v_tbf_s_time ? DONT_STOP_CCCH : STOP_CCCH ); } else { MCAST( p_d_ul_assign, D_UL_ASSIGN ); if( ( p_d_ul_assign->v_dyn_alloc_p AND p_d_ul_assign->dyn_alloc_p.v_tbf_s_time ) OR p_d_ul_assign->v_sin_alloc OR p_d_ul_assign->v_f_alloc_ul ) { ccch_read = DONT_STOP_CCCH; } else { ccch_read = STOP_CCCH; } } grr_data->tc.last_eval_assign.ccch_read = ccch_read; grr_data->tc.last_eval_assign.tbf_type = tbf_type; grr_data->tc.last_eval_assign.state = new_state; SET_STATE( TC, TC_WAIT_STOP_TASK_CNF ); tc_malloc_assign( ); if(old_state NEQ TC_WAIT_STOP_TASK_CNF) { sig_tc_ctrl_set_pckt_mode( GLBL_PCKT_MODE_ASSIGNED, ccch_read ); } } else { tc_handle_tbf_start( tbf_type ); #ifdef _TARGET_ if( p_d_dl_assign->msg_type EQ D_DL_ASSIGN AND grr_data->downlink_tbf.tbf_start_fn NEQ 0xFFFFFFFF ) { sig_tc_ctrl_set_pckt_mode( GLBL_PCKT_MODE_ACCESS, TASK_STOP_DUMMY_VALUE ); } #endif } } /* tc_prepare_handle_tbf_start() */ /* +------------------------------------------------------------------------------ | Function : tc_set_fa_bitmap +------------------------------------------------------------------------------ | Description : sets fixed allocation bitmap for requested allocation after | receiving a repeat allocation with ts_override | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL USHORT tc_set_fa_bitmap( UBYTE ts_mask, T_FIX_ALLOC* ptr_alloc) { UBYTE i; USHORT tx_slots=0; TRACE_FUNCTION( "tc_set_fa_bitmap" ); if (ts_mask) { /* * add new time slots to current allocation */ for(i=0;i<grr_data->tc.fa_ctrl.current_alloc.alloc.size_bitmap;i++) { ptr_alloc->alloc.bitmap[i] = grr_data->tc.fa_ctrl.current_alloc.alloc.bitmap[i] | ts_mask; } } return (tx_slots); } /* tc_set_fa_bitmap() */ /* +------------------------------------------------------------------------------ | Function : tc_send_ul_repeat_alloc_req +------------------------------------------------------------------------------ | Description : send the primitive MPHP_REPEAT_UL_FIXED_ALLOC_REQ | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_ul_repeat_alloc_req( void) { PALLOC(ptr_2prim,MPHP_REPEAT_UL_FIXED_ALLOC_REQ); TRACE_FUNCTION( "tc_send_ul_repeat_alloc_req" ); ptr_2prim->repeat_alloc = grr_data->tc.fa_ctrl.repeat_alloc; ptr_2prim->ts_override = grr_data->tc.fa_ctrl.ts_overr; if(grr_data->tc.fa_ctrl.repeat_alloc) { ptr_2prim->p_tbf_start.tbf_start_present = 1; ptr_2prim->p_tbf_start.fn = grr_data->tc.fa_ctrl.current_alloc.alloc_start_fn; } else { ptr_2prim->p_tbf_start.tbf_start_present = 0; ptr_2prim->p_tbf_start.fn = 0xffffffff; } PSEND(hCommL1,ptr_2prim); } /* tc_send_ul_repeat_alloc_req() */ /* +------------------------------------------------------------------------------ | Function : tc_eval_ts_reconf +------------------------------------------------------------------------------ | Description : The function tc_eval_ts_reconf() evaluates a | Packet Timeslot reconfigure. | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL T_EVAL_TS_RECONFIG tc_eval_ts_reconf ( void ) { MCAST(d_ts_reconfig,D_TS_RECONFIG); /* T_D_TS_RECONFIG */ T_EVAL_TS_RECONFIG result = E_TS_IGNORE; UBYTE tx_slots; UBYTE i,mask; T_GRR_STORE_TYPE grr_store_type = GRR_STORE_TYPE_NONE; TRACE_FUNCTION( "tc_eval_ts_reconf" ); grr_data->downlink_tbf.ctrl_ack_bit = 0; #ifdef REL99 /* This function is called only when TBF is active. Handling abnormal case * 8.7 While a TBF is in progress, if a mobile station receives a * PACKET UPLINK ASSIGNMENT, PACKET UPLINK ACK/NACK or PACKET TIMESLOT RECONFIGURE * message with message escape bit indicating EGPRS (resp. GPRS) contents whereas * the current TBF mode is GPRS (resp. EGPRS), the mobile station shall ignore the * message. */ if(d_ts_reconfig->egprs_flag) { TRACE_ERROR( " EGPRS TBF received in TS_RECONFIGURE " ); return E_TS_IGNORE; } #endif switch(grr_data->tbf_type) { case CGRLC_TBF_MODE_UL: /* * reassignment of uplink and downlink assignment */ grr_data->downlink_tbf.mac_mode = grr_data->uplink_tbf.mac_mode; grr_data->downlink_tbf.t3192 = FALSE; /* indicates if t3192 is running*/ grr_data->downlink_tbf.rlc_mode = d_ts_reconfig->dl_rlc_mode; if(d_ts_reconfig->v_dl_tfi EQ 0) { TRACE_ERROR( "No downlnik assignment in TS_RECONFIGURE " ); result = E_TS_RECONFIG_ERROR_RA; return result; } if((d_ts_reconfig->v_dyn_alloc_ts EQ 1) AND grr_data->uplink_tbf.mac_mode EQ FIXED_ALLOCATION) { TRACE_ERROR( "fixed alloc expected but dynamic alloc received" ); result = E_TS_RECONFIG_ERROR_RA; return result; } if(d_ts_reconfig->v_f_alloc_re EQ 1 AND grr_data->uplink_tbf.mac_mode EQ DYNAMIC_ALLOCATION) { TRACE_ERROR( "dynamic alloc expected but fixed alloc received" ); result = E_TS_RECONFIG_ERROR_RA; return result; } result = E_TS_UL_REASSIG_NEW_DL; break; case CGRLC_TBF_MODE_DL: grr_data->uplink_tbf.ti = 0; /* contention resolution NOT required */ if(d_ts_reconfig->v_dyn_alloc_ts) { if(d_ts_reconfig->dyn_alloc_ts.xdyn_alloc) grr_data->uplink_tbf.mac_mode =EDA; else grr_data->uplink_tbf.mac_mode =DA; } else if(d_ts_reconfig->v_f_alloc_re) { grr_data->uplink_tbf.mac_mode = FA; } /* * downlink tbf active, * assignment of uplink and downlink reassignment */ if(d_ts_reconfig->v_ul_tfi EQ 0) { TRACE_ERROR( "No uplnik tfi in TS_RECONFIGURE" ); result = E_TS_RECONFIG_ERROR_RA; return result; } if ((grr_data->downlink_tbf.rlc_mode NEQ d_ts_reconfig->dl_rlc_mode) AND !d_ts_reconfig->ctrl_ack) { TRACE_ERROR("Diff rlc mode in TS_RECONFIGURE..msg rejected..aborting"); result = E_TS_RECONFIG_ERROR_RA; return result; } grr_data->downlink_tbf.rlc_mode = d_ts_reconfig->dl_rlc_mode; result = E_TS_NEW_UL_DL_REASSIG; break; case CGRLC_TBF_MODE_DL_UL: if((d_ts_reconfig->v_dyn_alloc_ts EQ 1) AND grr_data->uplink_tbf.mac_mode EQ FIXED_ALLOCATION) { TRACE_ERROR( "fixed alloc expected but dynamic alloc received" ); result = E_TS_RECONFIG_ERROR_RA; return result; } if(d_ts_reconfig->v_f_alloc_re EQ 1 AND grr_data->uplink_tbf.mac_mode EQ DYNAMIC_ALLOCATION) { TRACE_ERROR( "dynamic alloc expected but fixed alloc received" ); result = E_TS_RECONFIG_ERROR_RA; return result; } if ((grr_data->downlink_tbf.rlc_mode NEQ d_ts_reconfig->dl_rlc_mode) AND !d_ts_reconfig->ctrl_ack) { TRACE_ERROR("Diff rlc mode in TS_RECONFIGURE..msg rejected..aborting"); result = E_TS_RECONFIG_ERROR_RA; return result; } grr_data->downlink_tbf.rlc_mode = d_ts_reconfig->dl_rlc_mode; result = E_TS_UL_REASSIG_DL_REASSIG; break; default: { TRACE_ERROR( " tc_eval_ts_reconf unexpected" ); return E_TS_IGNORE; } } /* * set DOWNLINK data base */ grr_data->downlink_tbf.ts_usage = d_ts_reconfig->dl_tn_alloc; grr_data->downlink_tbf.nts = grr_calc_nr_of_set_bits(grr_data->downlink_tbf.ts_usage); if(d_ts_reconfig->ctrl_ack) { if(grr_data->downlink_tbf.t3192) { grr_data->downlink_tbf.ctrl_ack_bit= 1; grr_data->downlink_tbf.t3192 = FALSE; } else { result = E_TS_RECONFIG_ERROR_RA; TRACE_EVENT("TS_RECONF INVALID->error_ra, ctrl ack bit set but t3192 is not running"); return result; } } /* * set UPLINK data base */ grr_data->uplink_tbf.cs_mode = d_ts_reconfig->chan_coding_cmd; grr_data->uplink_tbf.tlli_cs_mode = 1; grr_data->uplink_tbf.polling_bit = 0xFF; grr_data->uplink_tbf.ti = 0; /* * set glob parameters */ if(d_ts_reconfig->v_freq_par) { /* SZML-TC/091 */ /* * here is also to consider a possiblely existing dl_tbf slot ussage:SZML-TC/092 */ } if(d_ts_reconfig->v_dyn_alloc_ts) { tx_slots = 0; grr_data->uplink_tbf.ts_usage = 0; if(d_ts_reconfig->dyn_alloc_ts.v_tn_alloc) { for(i = 0,mask = 0x80;i < 8;i++) { if(d_ts_reconfig->dyn_alloc_ts.tn_alloc[i].v_usf) { grr_data->uplink_tbf.ts_usage |= mask; tx_slots++; } mask >>= 1; } } else if(d_ts_reconfig->dyn_alloc_ts.v_tn_alloc_pwr) { for(i = 0,mask = 0x80;i < 8;i++) { if(d_ts_reconfig->dyn_alloc_ts.tn_alloc_pwr.usf_array[i].v_usf_g) { grr_data->uplink_tbf.ts_usage |= mask; tx_slots++; } mask >>= 1; } grr_store_type = GRR_STORE_TYPE_TN_ALLOC_PWR; } grr_data->uplink_tbf.nts = tx_slots; } else if(d_ts_reconfig->v_f_alloc_re) { grr_data->uplink_tbf.ts_usage = 0; tx_slots=0; if(d_ts_reconfig->f_alloc_re.v_ul_ts_alloc) { grr_data->uplink_tbf.ts_usage = d_ts_reconfig->f_alloc_re.ul_ts_alloc; /*calculate number of timeslots*/ tx_slots = grr_calc_nr_of_set_bits(grr_data->uplink_tbf.ts_usage); } else if(d_ts_reconfig->f_alloc_re.v_pwr_par) { for(i = 0,mask = 0x80;i < 8;i++) { if(d_ts_reconfig->f_alloc_re.pwr_par.gamma_tn[i].v_gamma) { grr_data->uplink_tbf.ts_usage |= mask; tx_slots++; } mask >>= 1; } grr_store_type = GRR_STORE_TYPE_PWR_PAR; } grr_data->uplink_tbf.nts = tx_slots; } else { TRACE_ERROR ("Packet Timeslot Reconfigure without allocation type - corrupt airmessage!"); } if( !handle_ms_cap(UL_DL_ASSIGNMENT) ) { result = E_TS_RECONFIG_ERROR_RA; TRACE_EVENT("tc_eval_.. will return E_TS_RECONFIG_ERROR_RA (ms class error)"); } if( tc_check_and_save_freq( ) EQ FALSE ) { result = E_TS_RECONFIG_ERROR_RA; TRACE_EVENT("tc_eval_.. will return E_TS_RECONFIG_ERROR_RA (frequencies wrong)"); } if( result NEQ E_TS_RECONFIG_ERROR_RA AND result NEQ E_TS_IGNORE ) { switch( grr_store_type ) { case GRR_STORE_TYPE_TN_ALLOC_PWR: grr_store_type_tn_alloc_pwr( &d_ts_reconfig->dyn_alloc_ts.tn_alloc_pwr ); break; case GRR_STORE_TYPE_PWR_PAR: grr_store_type_pwr_par( &d_ts_reconfig->f_alloc_re.pwr_par, FALSE ); break; default: /* do nothing */ break; } } return result; } /* tc_eval_ts_reconf() */ /* +------------------------------------------------------------------------------ | Function : tc_stop_timer_t3172 +------------------------------------------------------------------------------ | Description : The function tc_stop_timer_t3172() | SZML-TC/094 this timer start | caused p access reject will be done | with cell reselection procedures | | Parameters : none | +------------------------------------------------------------------------------ */ GLOBAL void tc_stop_timer_t3172 ( void ) { TRACE_FUNCTION( "tc_stop_timer_t3172" ); vsi_t_stop(GRR_handle,T3172_1); } /* tc_stop_timer_t3172() */ /* +------------------------------------------------------------------------------ | Function : tc_close_gaps_in_ctrl_blk_seq +------------------------------------------------------------------------------ | Description : The function tc_close_gaps_in_ctrl_blk_seq reorders the queue | holding the order which is used to identify the next control | block to sent. | | Parameters : index - at this index the reordering starts | +------------------------------------------------------------------------------ */ LOCAL void tc_close_gaps_in_ctrl_blk_seq ( UBYTE index ) { TRACE_FUNCTION( "tc_close_gaps_in_ctrl_blk_seq" ); while( index < MAX_CTRL_BLK_NUM AND grr_data->tc.ul_ctrl_blk.seq[index] NEQ MAX_CTRL_BLK_NUM ) { grr_data->tc.ul_ctrl_blk.seq[index-1] = grr_data->tc.ul_ctrl_blk.seq[index]; index++; } grr_data->tc.ul_ctrl_blk.seq[index-1] = MAX_CTRL_BLK_NUM; } /* tc_close_gaps_in_ctrl_blk_seq() */ /* +------------------------------------------------------------------------------ | Function : tc_store_ctrl_blk +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL BOOL tc_store_ctrl_blk ( T_BLK_OWNER blk_owner, void *blk_struct ) { UBYTE i; /* used for counting */ BOOL result = FALSE; /* indicates whether control block is */ /* stored successfully or not */ T_BLK_INDEX blk_index; /* index to the control block buffer */ TRACE_FUNCTION( "tc_store_ctrl_msg" ); /* * we have to find a free buffer for the control block which is * indicated by the index to the control block buffer */ blk_index = MAX_CTRL_BLK_NUM; switch( blk_owner ) { case( CGRLC_BLK_OWNER_CTRL ): if( grr_data->tc.ul_ctrl_blk.blk[BLK_INDEX_CTRL].state EQ BLK_STATE_NONE ) { blk_index = BLK_INDEX_CTRL; } break; case( CGRLC_BLK_OWNER_CS ): if( grr_data->tc.ul_ctrl_blk.blk[BLK_INDEX_CS].state EQ BLK_STATE_NONE ) { blk_index = BLK_INDEX_CS; } break; case( CGRLC_BLK_OWNER_TM ): if( grr_data->tc.ul_ctrl_blk.blk[BLK_INDEX_TC].state EQ BLK_STATE_NONE ) { blk_index = BLK_INDEX_TC; } break; case( CGRLC_BLK_OWNER_MEAS ): blk_index = BLK_INDEX_MEAS; while( blk_index < MAX_CTRL_BLK_NUM AND grr_data->tc.ul_ctrl_blk.blk[blk_index].state NEQ BLK_STATE_NONE ) { blk_index++; } break; default: /* do nothing */ break; } /* * check whether the control block buffer is free, */ if( blk_index < MAX_CTRL_BLK_NUM ) { /* * check the queue holding the order which is used to identify the next * control block to send */ i = 0; while( i < MAX_CTRL_BLK_NUM AND grr_data->tc.ul_ctrl_blk.seq[i] NEQ MAX_CTRL_BLK_NUM ) { i++; } /* * check whether there is a free entry in the order queue, * in case the check fails, there is something wrong with the concept */ if( i < MAX_CTRL_BLK_NUM ) { /* * store the control block data and state in the queues */ grr_encode_ul_ctrl_block ( ( UBYTE* )&grr_data->tc.ul_ctrl_blk.blk[blk_index].data[0], ( UBYTE* )blk_struct ); grr_data->tc.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_ALLOCATED; grr_data->tc.ul_ctrl_blk.blk[blk_index].owner = blk_owner; grr_data->tc.ul_ctrl_blk.seq[i] = blk_index; if( i < MAX_CTRL_BLK_NUM - 1 ) { grr_data->tc.ul_ctrl_blk.seq[i+1] = MAX_CTRL_BLK_NUM; } result = TRUE; } else { TRACE_ERROR( "tc_store_ctrl_blk: no free entry in queue found" ); } } if( result EQ FALSE ) { if( blk_owner EQ CGRLC_BLK_OWNER_MEAS ) { TRACE_EVENT( "tc_store_ctrl_blk: no table entry allocated" ); } else { TRACE_ERROR( "tc_store_ctrl_blk: no table entry allocated" ); } } return( result ); } /* tc_store_ctrl_blk() */ /* +------------------------------------------------------------------------------ | Function : tc_cancel_ctrl_blk +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL BOOL tc_cancel_ctrl_blk ( T_BLK_OWNER blk_owner ) { BOOL result = FALSE; UBYTE i = 0; UBYTE blk_index = grr_data->tc.ul_ctrl_blk.seq[i]; TRACE_FUNCTION( "tc_cancel_ctrl_blk" ); while( blk_index NEQ MAX_CTRL_BLK_NUM AND result EQ FALSE ) { if( grr_data->tc.ul_ctrl_blk.blk[blk_index].owner EQ blk_owner AND grr_data->tc.ul_ctrl_blk.blk[blk_index].state EQ BLK_STATE_ALLOCATED ) { /* * mark the entry in the queue as free */ grr_data->tc.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_NONE; grr_data->tc.ul_ctrl_blk.blk[blk_index].owner = CGRLC_BLK_OWNER_NONE; tc_close_gaps_in_ctrl_blk_seq( (UBYTE)( i + 1 ) ); /* * notify owner of the control block, TC always runs in unacknowledged mode */ if( blk_owner NEQ CGRLC_BLK_OWNER_TM ) { sig_tc_ctrl_control_block_result( blk_owner, FALSE ); } result = TRUE; } i++; if( i < MAX_CTRL_BLK_NUM ) { blk_index = grr_data->tc.ul_ctrl_blk.seq[i]; } else { blk_index = MAX_CTRL_BLK_NUM; } } if( result EQ FALSE ) { TRACE_EVENT( "tc_cancel_ctrl_blk: no block found" ); } return( result ); } /* tc_cancel_ctrl_blk() */ /* +------------------------------------------------------------------------------ | Function : tc_set_start_ctrl_blk +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL UBYTE* tc_set_start_ctrl_blk ( UBYTE *index ) { UBYTE i = 0; T_BLK_INDEX blk_index = MAX_CTRL_BLK_NUM; TRACE_FUNCTION( "tc_set_start_ctrl_blk" ); while( i < MAX_CTRL_BLK_NUM AND grr_data->tc.ul_ctrl_blk.seq[i] NEQ MAX_CTRL_BLK_NUM AND blk_index EQ MAX_CTRL_BLK_NUM ) { blk_index = grr_data->tc.ul_ctrl_blk.seq[i]; if( grr_data->tc.ul_ctrl_blk.blk[blk_index].state EQ BLK_STATE_ALLOCATED ) { grr_data->tc.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_SENT_REQ; /* * the control block was encoded without having correct information * about the value of the R bit. So we have to set the correct value now. */ grr_data->tc.ul_ctrl_blk.blk[blk_index].data[0] = grr_get_ul_ctrl_block_header( grr_data->r_bit ); } else { blk_index = MAX_CTRL_BLK_NUM; } i++; } *index = blk_index; return( blk_index EQ MAX_CTRL_BLK_NUM ? NULL : grr_data->tc.ul_ctrl_blk.blk[blk_index].data ); } /* tc_set_start_ctrl_blk() */ /* +------------------------------------------------------------------------------ | Function : tc_set_stop_ctrl_blk +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL T_BLK_INDEX tc_set_stop_ctrl_blk ( BOOL is_tx_success, T_BLK_OWNER srch_owner, T_BLK_INDEX start_index ) { T_BLK_INDEX blk_index = grr_data->tc.ul_ctrl_blk.seq[start_index]; T_BLK_INDEX nxt_index; TRACE_FUNCTION( "tc_set_stop_ctrl_blk" ); if( blk_index < MAX_CTRL_BLK_NUM ) { T_BLK_OWNER blk_owner = grr_data->tc.ul_ctrl_blk.blk[blk_index].owner; if( srch_owner EQ CGRLC_BLK_OWNER_NONE OR srch_owner EQ blk_owner ) { /* * mark the entry in the queue as free */ grr_data->tc.ul_ctrl_blk.blk[blk_index].state = BLK_STATE_NONE; grr_data->tc.ul_ctrl_blk.blk[blk_index].owner = CGRLC_BLK_OWNER_NONE; tc_close_gaps_in_ctrl_blk_seq( 1 ); /* * notify owner of the control block, TC always runs in unacknowledged mode */ if( blk_owner NEQ CGRLC_BLK_OWNER_TM ) { sig_tc_ctrl_control_block_result( blk_owner, is_tx_success ); } nxt_index = start_index; } else { nxt_index = start_index + 1; } } else { nxt_index = MAX_CTRL_BLK_NUM; } return( nxt_index ); } /* tc_set_stop_ctrl_blk() */ /* +------------------------------------------------------------------------------ | Function : tc_set_stop_tc_ctrl_blk +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_set_stop_tc_ctrl_blk ( void ) { T_BLK_INDEX start_index = 0; TRACE_FUNCTION( "tc_set_stop_tc_ctrl_blk" ); while ( ( start_index = tc_set_stop_ctrl_blk( FALSE, CGRLC_BLK_OWNER_TM, start_index ) ) NEQ MAX_CTRL_BLK_NUM ){}; } /* tc_set_stop_tc_ctrl_blk() */ /* +------------------------------------------------------------------------------ | Function : tc_set_stop_all_ctrl_blk +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_set_stop_all_ctrl_blk ( void ) { T_BLK_INDEX start_index = 0; TRACE_FUNCTION( "tc_set_stop_all_ctrl_blk" ); while ( ( start_index = tc_set_stop_ctrl_blk( FALSE, CGRLC_BLK_OWNER_NONE, start_index ) ) NEQ MAX_CTRL_BLK_NUM ){}; } /* tc_set_stop_all_ctrl_blk() */ /* +------------------------------------------------------------------------------ | Function : tc_check_access_is_needed +------------------------------------------------------------------------------ | Description : The function tc_check_access_is_needed () .... | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL void tc_check_access_is_needed ( T_CHECK_ACCESS_CAUSE cause ) { TRACE_FUNCTION( "tc_check_access_is_needed " ); if( ((grr_t_status( T3172_1 ) > 0) OR (grr_t_status( T3170 ) > 0) ) AND (grr_t_status( T3176 ) EQ 0)) { if( cause EQ CAC_T3170_EXPIRED ) { sig_tc_ctrl_set_pckt_mode( GLBL_PCKT_MODE_IDLE, TASK_STOP_DUMMY_VALUE ); } TRACE_EVENT_P3("ACCESS_REJ RUNNING t3170=%d t3172=%d t3176=%d",grr_t_status( T3170 ) ,grr_t_status( T3172_1 ) ,grr_t_status( T3176 )); return; } switch(grr_data->tbf_type) { case CGRLC_TBF_MODE_NULL: if(grr_data->tc.num_of_rels_running) { TRACE_EVENT_P1("WAIT FOR %d REL CON ", grr_data->tc.num_of_rels_running); return; } SET_STATE( TC, TC_WAIT_STOP_TASK_CNF ); sig_tc_ctrl_set_pckt_mode( GLBL_PCKT_MODE_ACCESS, TASK_STOP_DUMMY_VALUE ); break; case CGRLC_TBF_MODE_DL: case CGRLC_TBF_MODE_UL: case CGRLC_TBF_MODE_DL_UL: #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: #endif break; default: TRACE_ERROR("unknown tbf type during uplink access"); break; } } /* tc_check_access_is_needed */ /* +------------------------------------------------------------------------------ | Function : tc_stop_normal_burst_req +------------------------------------------------------------------------------ | Description : this function sends the primitive MPHP_STOP_SINGLE_BLOCK_REQ | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_stop_normal_burst_req ( void ) { TRACE_FUNCTION( "tc_stop_normal_burst_req" ); { PALLOC(mphp_stop_single_block_req,MPHP_STOP_SINGLE_BLOCK_REQ); PSEND(hCommL1,mphp_stop_single_block_req); } } /* tc_stop_normal_burst_req() */ /* +------------------------------------------------------------------------------ | Function : tc_malloc_assign +------------------------------------------------------------------------------ | Description : The function tc_malloc_assign() .... | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_malloc_assign ( void ) { MCAST( p_d_dl_assign, D_DL_ASSIGN ); TRACE_FUNCTION( "tc_malloc_assign" ); if( grr_data->tc.p_assign EQ NULL ) { if( p_d_dl_assign->msg_type EQ D_DL_ASSIGN ) { MALLOC( grr_data->tc.p_assign, sizeof( T_D_DL_ASSIGN ) ); } else { MALLOC( grr_data->tc.p_assign, sizeof( T_D_UL_ASSIGN ) ); } } else { TRACE_ERROR( "tc_malloc_assign: fatal error, memory reallocation not implemented" ); } if( p_d_dl_assign->msg_type EQ D_DL_ASSIGN ) { *grr_data->tc.p_assign = *( ( T_D_DL_ASSIGN * )_decodedMsg ); } else { *( ( T_D_UL_ASSIGN * )grr_data->tc.p_assign ) = *( ( T_D_UL_ASSIGN * )_decodedMsg ); } } /* tc_malloc_assign() */ /* +------------------------------------------------------------------------------ | Function : tc_mfree_assign +------------------------------------------------------------------------------ | Description : The function tc_mfree_assign() .... | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_mfree_assign ( BOOL restore_data ) { TRACE_FUNCTION( "tc_mfree_assign" ); if( grr_data->tc.p_assign NEQ NULL ) { if( restore_data ) { if( grr_data->tc.p_assign->msg_type EQ D_DL_ASSIGN ) { *( ( T_D_DL_ASSIGN * )_decodedMsg ) = *grr_data->tc.p_assign; } else { *( ( T_D_UL_ASSIGN * )_decodedMsg ) = *( ( T_D_UL_ASSIGN * )grr_data->tc.p_assign ); } } MFREE( grr_data->tc.p_assign ); grr_data->tc.p_assign = NULL; } else { TRACE_ERROR( "tc_mfree_assign: fatal error, no memory allocated" ); } } /* tc_mfree_assign() */ /* +------------------------------------------------------------------------------ | Function : tc_prepare_send_tbf_release_req +------------------------------------------------------------------------------ | Description : The function tc_prepare_send_tbf_release_req() .... | | Parameters : | +------------------------------------------------------------------------------ */ LOCAL void tc_prepare_send_tbf_release_req( T_TBF_TYPE tbf_type ) { TRACE_FUNCTION( "tc_prepare_send_tbf_release_req" ); if( grr_is_pbcch_present( ) AND tbf_type EQ grr_data->tbf_type ) { grr_data->tc.last_tbf_type = tbf_type; grr_data->tc.num_of_rels_running++; sig_tc_ctrl_set_pckt_mode( GLBL_PCKT_MODE_RELEASED, TASK_STOP_DUMMY_VALUE ); } else { tc_send_tbf_release_req( tbf_type, TRUE ); } } /* tc_prepare_send_tbf_release_req() */ /* +------------------------------------------------------------------------------ | Function : tc_send_tbf_release_req +------------------------------------------------------------------------------ | Description : The function tc_send_tbf_release_req() .... | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_tbf_release_req( T_TBF_TYPE tbf_type, BOOL is_synchron ) { UBYTE rel_req_tbf_type; UBYTE transid; TRACE_FUNCTION( "tc_send_tbf_release_req" ); switch( tbf_type ) { case CGRLC_TBF_MODE_UL: rel_req_tbf_type = UL_ASSIGNMENT; break; case CGRLC_TBF_MODE_DL: rel_req_tbf_type = DL_ASSIGNMENT; break; case CGRLC_TBF_MODE_DL_UL: rel_req_tbf_type = UL_DL_ASSIGNMENT; break; #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case CGRLC_TBF_MODE_2PA: rel_req_tbf_type = UL_TP_ACCESS; break; #endif default: TRACE_ERROR( "tc_send_tbf_release_req: unknown tbf type" ); return; } { PALLOC(mphp_tbf_release_req,MPHP_TBF_RELEASE_REQ); mphp_tbf_release_req->tbf_type = rel_req_tbf_type; PSEND(hCommL1,mphp_tbf_release_req); if( is_synchron ) { grr_data->tc.num_of_rels_running++; } } switch(rel_req_tbf_type) { case UL_ASSIGNMENT: #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case UL_TP_ACCESS: #endif memset(&grr_data->uplink_tbf,0xEE,sizeof(T_UL_TBF)); grr_data->test_mode = CGRLC_NO_TEST_MODE; break; case DL_ASSIGNMENT: transid = grr_data->downlink_tbf.trans_id; memset(&grr_data->downlink_tbf,0xEE,sizeof(T_DL_TBF)); grr_data->downlink_tbf.trans_id = transid; break; case UL_DL_ASSIGNMENT: transid = grr_data->downlink_tbf.trans_id; memset(&grr_data->uplink_tbf,0xEE,sizeof(T_UL_TBF)); memset(&grr_data->downlink_tbf,0xEE,sizeof(T_DL_TBF)); grr_data->test_mode = CGRLC_NO_TEST_MODE; grr_data->downlink_tbf.trans_id = transid; break; } } /* tc_send_tbf_release_req() */ /* +------------------------------------------------------------------------------ | Function : tc_get_t3170_value +------------------------------------------------------------------------------ | Description : The function tc_get_t3170_value() calculates T3170 and returns it | | Parameters : return T_TIME | +------------------------------------------------------------------------------ */ GLOBAL T_TIME tc_get_t3170_value(void) { T_TIME t3170_value; t3170_value = s_table[psc_db->prach.s_prach]; if(S_VALUE_RESERVED EQ t3170_value) t3170_value = 0; t3170_value *= 2; t3170_value += tx_int_table[psc_db->prach.tx_int]; /* T3170 value = TX_INT + 2 * S from prach control parameters */ /* see gsm 04.60 13.1 */ t3170_value *= 5; /* 1 tdma frame ~ 5ms */ TRACE_EVENT_P1("T3170: %ld", t3170_value); return t3170_value; } /* +------------------------------------------------------------------------------ | Function : tc_call_disable_callback_func +------------------------------------------------------------------------------ | Description : | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_call_disable_callback_func ( void ) { if( grr_data->tc.disable_callback_func NEQ NULL ) { T_TC_DISABLE_CALLBACK_FUNC disable_callback_func; TRACE_EVENT( "Call disable_callback_func after TBF release" ); disable_callback_func = grr_data->tc.disable_callback_func; grr_data->tc.disable_callback_func = NULL; disable_callback_func( ); } } /* tc_call_disable_callback_func */ /* +------------------------------------------------------------------------------ | Function : tc_set_freq +------------------------------------------------------------------------------ | Description : This function allocates a primitve depending on the hopping status | and sets the frequency parameter of T_MPHP_ASSIGNMENT_REQ | | Parameters : void | +------------------------------------------------------------------------------ */ GLOBAL T_MPHP_ASSIGNMENT_REQ * tc_set_freq ( void ) { PALLOC( ptr2prim, MPHP_ASSIGNMENT_REQ ); TRACE_FUNCTION( "tc_set_freq" ); memset( ptr2prim, 0, sizeof( T_MPHP_ASSIGNMENT_REQ ) ); ptr2prim->tsc = grr_data->tc.freq_set.tsc; grr_set_freq_par( &ptr2prim->p_frequency_par ); return( ptr2prim ); }/* tc_set_freq */ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_disable_req +------------------------------------------------------------------------------ | Description : This function allocates sends the the primtive CGRLC_DISABLE_REQ | to GRLC | | Parameters : prim_st - indicates if a primitive shall be deleted or not | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_disable_req ( UBYTE prim_st ) { PALLOC(cgrlc_disable_req,CGRLC_DISABLE_REQ); /*T_CGRLC_DISABLE_REQ*/ TRACE_FUNCTION( "tc_cgrlc_disable_req" ); cgrlc_disable_req->disable_class = grr_data->tc.disable_class; cgrlc_disable_req->prim_status = prim_st; PSEND(hCommGRLC,cgrlc_disable_req); }/* tc_cgrlc_disable_req */ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_ul_tbf_res +------------------------------------------------------------------------------ | Description : This function | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_ul_tbf_res ( UBYTE tbf_mode, UBYTE prim_status ) { PALLOC(cgrlc_ul_tbf_res,CGRLC_UL_TBF_RES); /*T_CGRLC_UL_TBF_RES*/ TRACE_FUNCTION( "tc_cgrlc_ul_tbf_res" ); cgrlc_ul_tbf_res->starting_time = grr_data->uplink_tbf.tbf_start_fn; cgrlc_ul_tbf_res->tbf_mode = tbf_mode; cgrlc_ul_tbf_res->prim_status = prim_status; cgrlc_ul_tbf_res->polling_bit = grr_data->uplink_tbf.polling_bit; cgrlc_ul_tbf_res->cs_mode = grr_data->uplink_tbf.cs_mode; cgrlc_ul_tbf_res->mac_mode = grr_data->uplink_tbf.mac_mode; cgrlc_ul_tbf_res->nts_max = grr_data->uplink_tbf.nts; cgrlc_ul_tbf_res->rlc_db_granted= grr_data->uplink_tbf.rlc_db_granted; if(grr_data->uplink_tbf.ts_usage) { cgrlc_ul_tbf_res->tn_mask = grr_data->uplink_tbf.ts_usage; } else { cgrlc_ul_tbf_res->tn_mask = grr_data->uplink_tbf.ts_mask; TRACE_EVENT("UL tn mask passed to grlc instead of ts_usage"); } if(grr_data->uplink_tbf.st_tfi EQ 0xFF) cgrlc_ul_tbf_res->tfi = grr_data->uplink_tbf.tfi; else cgrlc_ul_tbf_res->tfi = grr_data->uplink_tbf.st_tfi; cgrlc_ul_tbf_res->ti = grr_data->uplink_tbf.ti; cgrlc_ul_tbf_res->bs_cv_max = psc_db->gprs_cell_opt.bs_cv_max; cgrlc_ul_tbf_res->tlli_cs_mode = grr_data->uplink_tbf.tlli_cs_mode; cgrlc_ul_tbf_res->r_bit = grr_data->r_bit; if(cgrlc_ul_tbf_res->mac_mode EQ FA) { cgrlc_ul_tbf_res->fix_alloc_struct.bitmap_len = grr_data->tc.fa_ctrl.current_alloc.alloc.size_bitmap; cgrlc_ul_tbf_res->fix_alloc_struct.end_fn = grr_data->tc.fa_ctrl.current_alloc.alloc_end_fn; cgrlc_ul_tbf_res->fix_alloc_struct.final_alloc = grr_data->tc.fa_ctrl.current_alloc.final_alloc; memcpy (cgrlc_ul_tbf_res->fix_alloc_struct.bitmap_array, grr_data->tc.fa_ctrl.current_alloc.alloc.bitmap, MAX_ALLOC_BITMAP); } grr_prcs_pwr_ctrl ( &cgrlc_ul_tbf_res->pwr_ctrl, FALSE ); /*Reset the GRR database for parameters which are used only once*/ grr_data->uplink_tbf.polling_bit=0xFF; PSEND(hCommGRLC,cgrlc_ul_tbf_res); }/* tc_cgrlc_ul_tbf_res */ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_access_status_req +------------------------------------------------------------------------------ | Description : This function | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_access_status_req ( void ) { PALLOC(cgrlc_access_status_req,CGRLC_ACCESS_STATUS_REQ); /*T_CGRLC_ACCESS_STATUS_REQ*/ TRACE_FUNCTION( "tc_cgrlc_access_status_req" ); PSEND(hCommGRLC,cgrlc_access_status_req); }/* tc_cgrlc_access_status_req*/ /* +------------------------------------------------------------------------------ | Function : tc_send_control_msg_to_grlc +------------------------------------------------------------------------------ | Description : This function | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_send_control_msg_to_grlc ( void ) { UBYTE i= 0; TRACE_FUNCTION( "tc_send_control_msg_to_grlc" ); while( i < MAX_CTRL_BLK_NUM AND grr_data->tc.ul_ctrl_blk.seq[i] NEQ MAX_CTRL_BLK_NUM ) { if( grr_data->tc.ul_ctrl_blk.blk[grr_data->tc.ul_ctrl_blk.seq[i]].state EQ BLK_STATE_ALLOCATED ) { PALLOC(cgrlc_data_req,CGRLC_DATA_REQ); /* T_CGRLC_DATA_REQ */ cgrlc_data_req->blk_owner = grr_data->tc.ul_ctrl_blk.blk[grr_data->tc.ul_ctrl_blk.seq[i]].owner; memcpy(cgrlc_data_req->data_array,grr_data->tc.ul_ctrl_blk.blk[grr_data->tc.ul_ctrl_blk.seq[i]].data,23); PSEND(hCommGRLC,cgrlc_data_req); /* remove control block */ tc_cancel_ctrl_blk(grr_data->tc.ul_ctrl_blk.blk[grr_data->tc.ul_ctrl_blk.seq[i]].owner); } } }/* tc_send_control_msg_to_grlc*/ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_dl_tbf_req +------------------------------------------------------------------------------ | Description : This function | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_dl_tbf_req ( void ) { PALLOC(cgrlc_dl_tbf_req,CGRLC_DL_TBF_REQ); /*T_CGRLC_DL_TBF_REQ*/ TRACE_FUNCTION( "tc_cgrlc_dl_tbf_req" ); grr_data->downlink_tbf.trans_id++; cgrlc_dl_tbf_req->starting_time = grr_data->downlink_tbf.tbf_start_fn; cgrlc_dl_tbf_req->rlc_mode = grr_data->downlink_tbf.rlc_mode; cgrlc_dl_tbf_req->mac_mode = grr_data->downlink_tbf.mac_mode; cgrlc_dl_tbf_req->polling_bit = grr_data->downlink_tbf.polling_bit; cgrlc_dl_tbf_req->nts_max = grr_data->downlink_tbf.nts; if(grr_data->downlink_tbf.ts_usage) { cgrlc_dl_tbf_req->tn_mask = grr_data->downlink_tbf.ts_usage; grr_data->downlink_tbf.ts_mask = grr_data->downlink_tbf.ts_usage; /* set before starting time is elapsed */ } else { cgrlc_dl_tbf_req->tn_mask = grr_data->downlink_tbf.ts_mask; TRACE_EVENT("DL tn mask passed to grlc instead of ts_usage"); } if(grr_data->downlink_tbf.st_tfi EQ 0xFF) cgrlc_dl_tbf_req->tfi = grr_data->downlink_tbf.tfi; else cgrlc_dl_tbf_req->tfi = grr_data->downlink_tbf.st_tfi; cgrlc_dl_tbf_req->t3192_val = psc_db->gprs_cell_opt.t3192; cgrlc_dl_tbf_req->ctrl_ack_bit = grr_data->downlink_tbf.ctrl_ack_bit; grr_prcs_pwr_ctrl ( &cgrlc_dl_tbf_req->pwr_ctrl, FALSE ); /*Reset the GRR database for parameters which are used only once*/ grr_data->downlink_tbf.ctrl_ack_bit=0; grr_data->downlink_tbf.polling_bit=0xFF; PSEND(hCommGRLC,cgrlc_dl_tbf_req); }/* tc_cgrlc_dl_tbf_req*/ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_tbf_rel_res +------------------------------------------------------------------------------ | Description : This function | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_tbf_rel_res ( UBYTE tbf_type ) { PALLOC(cgrlc_tbf_rel_res,CGRLC_TBF_REL_RES); TRACE_FUNCTION( "tc_cgrlc_tbf_rel_res" ); switch( tbf_type ) { case DL_ASSIGNMENT: cgrlc_tbf_rel_res->tbf_mode = CGRLC_TBF_MODE_DL; break; case UL_ASSIGNMENT: cgrlc_tbf_rel_res->tbf_mode = CGRLC_TBF_MODE_UL; break; case UL_DL_ASSIGNMENT: cgrlc_tbf_rel_res->tbf_mode = CGRLC_TBF_MODE_DL_UL; break; #if defined REL99 AND defined TI_PS_FF_TBF_EST_PACCH case UL_TP_ACCESS: cgrlc_tbf_rel_res->tbf_mode = CGRLC_TBF_MODE_2PA; break; #endif } PSEND(hCommGRLC,cgrlc_tbf_rel_res); }/* tc_cgrlc_tbf_rel_res*/ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_tbf_rel_req +------------------------------------------------------------------------------ | Description : This function | | Parameters : | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_tbf_rel_req ( UBYTE tbf_type, UBYTE rel_cause, ULONG rel_fn ) { PALLOC(cgrlc_tbf_rel_req,CGRLC_TBF_REL_REQ); /*T_CGRLC_TBF_REL_REQ*/ TRACE_FUNCTION( "tc_cgrlc_tbf_rel_req" ); cgrlc_tbf_rel_req->tbf_mode = tbf_type; cgrlc_tbf_rel_req->tbf_rel_cause = rel_cause; cgrlc_tbf_rel_req->rel_fn = rel_fn; PSEND(hCommGRLC,cgrlc_tbf_rel_req); }/* tc_cgrlc_tbf_rel_req*/ /* +------------------------------------------------------------------------------ | Function : tc_cgrlc_enable_req +------------------------------------------------------------------------------ | Description : This function sends the primitive cgrlc_enable_req to GRLC | | Parameters : queue_mode - indicates the queue mode | cu_cause - indicates if cell update is required or not | +------------------------------------------------------------------------------ */ GLOBAL void tc_cgrlc_enable_req ( UBYTE queue_mode, UBYTE cu_cause, BOOL cell_has_changed, UBYTE enable_cause ) { PALLOC(cgrlc_enable_req,CGRLC_ENABLE_REQ); /*T_CGRLC_ENABLE_REQ*/ TRACE_FUNCTION( "tc_cgrlc_enable_req" ); cgrlc_enable_req->enable_cause = enable_cause; cgrlc_enable_req->queue_mode = queue_mode; cgrlc_enable_req->cu_cause = cu_cause; /* cell update request will be handled sig_ctrl_tc_enable_grlc */ /*************Burst type handling********************************/ cgrlc_enable_req->burst_type = psc_db->gprs_cell_opt.ctrl_ack_type; cgrlc_enable_req->ab_type = psc_db->gprs_cell_opt.ab_type; /*************Counter N3102 handling*****************************/ cgrlc_enable_req->v_pan_struct = psc_db->gprs_cell_opt.v_pan_struct; cgrlc_enable_req->pan_struct.inc = psc_db->gprs_cell_opt.pan_struct.inc; cgrlc_enable_req->pan_struct.dec = psc_db->gprs_cell_opt.pan_struct.dec; if(cell_has_changed) cgrlc_enable_req->pan_struct.pmax = (psc_db->gprs_cell_opt.pan_struct.pmax + 1 ) *4; else cgrlc_enable_req->pan_struct.pmax = CGRLC_NO_UPDATE_N3102; cgrlc_enable_req->ul_tlli = grr_data->db.ms_id.new_tlli; cgrlc_enable_req->dl_tlli = grr_data->db.ms_id.received_tlli; cgrlc_enable_req->t3168_val = psc_db->gprs_cell_opt.t3168; if(grr_is_pbcch_present()) { cgrlc_enable_req->change_mark = psc_db->psi2_params.psi2_change_mark; if(grr_data->ms.access_ctrl_class & ~psc_db->prach.ac_class) { cgrlc_enable_req->ac_class = CGRLC_PCCCH_AC_ALLOWED; } else { cgrlc_enable_req->ac_class = CGRLC_PCCCH_AC_NOT_ALLOWED; TRACE_EVENT_P3("ACCESS NOT ALLOWED PBCCH: ms_acc=%d prach_ac=%d tc_state=%d" ,grr_data->ms.access_ctrl_class ,psc_db->prach.ac_class ,grr_data->tc.state); } } else { cgrlc_enable_req->change_mark = psc_db->psi13_params.si13_change_mark; if(grr_data->ms.access_ctrl_class & ~psc_db->prach.ac_class) { cgrlc_enable_req->ac_class = psc_db->net_ctrl.priority_access_thr; } else { cgrlc_enable_req->ac_class = CGRLC_PCCCH_AC_NOT_ALLOWED; TRACE_EVENT_P3("ACCESS NOT ALLOWED CCCH: ms_acc=%d prach_ac=%d tc_state=%d" ,grr_data->ms.access_ctrl_class ,psc_db->prach.ac_class ,grr_data->tc.state); } } #ifdef REL99 cgrlc_enable_req->pfi_support = psc_db->gprs_cell_opt.gprs_ext_bits.gprs_ext_info.pfc_feature_mode; cgrlc_enable_req->nw_rel = psc_db->network_rel; /*Network Release Order*/ #endif PSEND(hCommGRLC,cgrlc_enable_req); }/* tc_cgrlc_enable_req*/ /* +------------------------------------------------------------------------------ | Function : grr_convert_11bit_2_etsi +------------------------------------------------------------------------------ | Description : Converts the 11 bit access burst value into ETSI format | | Parameters : In: eleven bit value | Out: converted eleven bit | +------------------------------------------------------------------------------ */ LOCAL USHORT grr_convert_11bit_2_etsi ( USHORT eleven_bit ) { USHORT etsi11bit; USHORT dummy1 = 0, dummy2 = 0; TRACE_FUNCTION( "grr_convert_11bit_2_etsi" ); /* * 11 Bit access burst * b: bit * b10 b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 * should be sent to the network -according 04.60 and 0404- in the * following 16-bit format: * 0 0 0 0 0 b2 b1 b0 b10 b9 b8 b7 b6 b5 b4 b3 */ /* * get b2 b1 b0 */ dummy1 = 0x0007 & eleven_bit; /* * shift it 8 bits to left */ dummy1 = ( dummy1 << 8 ); /* * get b10 b9 b8 b7 b6 b5 b4 b3 */ dummy2 = 0xFFF8 & eleven_bit; /* * shift it 3 bits to right */ dummy2 = ( dummy2 >> 3 ); /* * compose dummy1 and dummy2 to the target 16-bit format */ etsi11bit = dummy1 | dummy2; return etsi11bit; } /* grr_convert_11bit_2_etsi() */