FreeCalypso > hg > fc-selenite
view src/g23m-gsm/alr2/alr_dedi.c @ 40:614668bbbc4f
Nucleus: tmt.s ported over from FreeNucleus by XVilka
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 17 Jul 2018 07:55:01 +0000 |
parents | b4c81ea2d291 |
children |
line wrap: on
line source
/* +----------------------------------------------------------------------------- | Project : GSM-PS | Modul : alr_DEDI +----------------------------------------------------------------------------- | 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 Modul defines the SDL process Dedicated_Control. +----------------------------------------------------------------------------- */ #ifndef ALR_DEDI_C #define ALR_DEDI_C #define ENTITY_PL /*==== INCLUDES ===================================================*/ #include <string.h> #include <stdlib.h> #include <ctype.h> #include "typedefs.h" #include "pconst.cdg" #include "mconst.cdg" #include "message.h" #include "ccdapi.h" #include "vsi.h" #include "custom.h" #include "gsm.h" #include "prim.h" #include "cnf_alr.h" #include "mon_alr.h" #include "pei.h" #include "tok.h" #include "pcm.h" #ifdef GPRS #include "alr_gprs.h" #endif #include "alr.h" #include "alr_em.h" /*=== Constrains =======================================*/ #define TCH_F_INDEX 1 /*==== EXPORT =====================================================*/ /*==== PRIVAT =====================================================*/ LOCAL UBYTE dedi_channel_mode (UBYTE channel_mode, UBYTE channel_type); LOCAL void dedi_convert_chan_desc (T_channel_desc * channel_desc); LOCAL void dedi_convert_frequency_list (T_frequency_list * frequency_list); LOCAL UBYTE dedi_conversion_needed (void); LOCAL void dedi_chan_ass_fail (void); LOCAL void dedi_pdch_ass_fail (void); LOCAL void dedi_cco_fail (void); LOCAL void dedi_handover_fail (void); LOCAL void dedi_async_handover (T_MPH_DEDICATED_REQ *dedicated_req); LOCAL void dedi_chan_ass (T_MPH_DEDICATED_REQ *dedicated_req); LOCAL void dedi_fill_ma (USHORT *ma, T_frequency_list *rf); LOCAL void dedi_imm_ass (T_MPH_DEDICATED_REQ *dedicated_req); LOCAL void dedi_pdch_ass (T_MPH_DEDICATED_REQ *dedicated_req); LOCAL void dedi_pre_sync_handover (T_MPH_DEDICATED_REQ *dedicated_req); LOCAL void dedi_sync_handover (T_MPH_DEDICATED_REQ *dedicated_req); /*==== VARIABLES ==================================================*/ LOCAL UBYTE actual_channel; /*==== FUNCTIONS ==================================================*/ #if defined (WIN32) #define TRACING #endif #if defined (TRACING) #define ALR_TRACE_DEDI(a) ALR_TRACE(a) #else #define ALR_TRACE_DEDI(a) #endif #if defined (TRACING) #define ALR_TRACE_DEDI_DTX(a1) TRACE_EVENT_P1 ("DTX = %d", a1); #define ALR_TRACE_DEDI_PARA(h, rf, _ch, sub, _tno, _tsc, _ta, _st, _dtx, _maio)\ {if (h){\ TRACE_EVENT_P9 ("immass:hop[%04x] ch/s=%u/%u tno=%u tsc=%u ta=%u st=%u dtx=%u maio=%u",\ rf, _ch, sub, _tno, _tsc, _ta, _st, _dtx, _maio);\ }else{\ TRACE_EVENT_P9 ("immass:[%u] ch/s=%u/%u tno=%u tsc=%u ta=%u st=%u dtx=%u maio=%u",\ rf, _ch, sub, _tno, _tsc, _ta, _st, _dtx, _maio);}} #define ALR_TRACE_DEDI_HO_1(p1,p2,p3,p4,p5,p6) \ TRACE_EVENT_P6 ("d rf=%d bsic=%d sti=%d ch2=%d ch=%d tsc=%d",\ p1, p2, p3, p4, p5, p6) #define ALR_TRACE_DEDI_HO_2(p1,p2,p3,p4,p5,p6) \ TRACE_EVENT_P6 ("d tn=%d arf=%d pow=%d ref=%d acc=%d nci=%d", \ p1, p2, p3, p4, p5, p6) #define ALR_TRACE_DEDI_HO_3(p1,p2,p3,p4,p5,p6) \ TRACE_EVENT_P6 ("d mode=%d power=%d dtx=%d rlt=%d tav=%d pwrc=%d", \ p1, p2, p3, p4, p5, p6) #define ALR_TRACE_DEDI_HO_4(p1,p2,p3) \ TRACE_EVENT_P3 ("d mode=%d stat=%d algo=%d", p1, p2, p3); #define ALR_TRACE_DEDI_HO_5(p1,p2,p3,p4,p5,p6) \ TRACE_EVENT_P6 ("a h=%d maio=0x%x hsn=%d chty=%d subch=%d tno=%d", \ p1, p2, p3, p4, p5, p6) #define ALR_TRACE_DEDI_HO_6(p1,p2,p3,p4,p5,p6) \ TRACE_EVENT_P6 ("a tsc=%d txpwr=%d ho_acc=%d sti_p=%d ncc=%d bcc=%d", \ p1, p2, p3, p4, p5, p6) #define ALR_TRACE_DEDI_HO_7(p1,p2,p3,p4) \ TRACE_EVENT_P4 ("a rf=%d chmo1=%d ciphmo=%d a5=%d", \ p1, p2, p3, p4) #define ALR_TRACE_DEDI_FREQ_LIST() TRACE_EVENT_P2 ("HOP = %d %d", \ frequency_list->rf_chan_no.radio_freq[j], \ ARFCN_TO_L1 (frequency_list->rf_chan_no.radio_freq[j])) #else #define ALR_TRACE_DEDI_DTX(d) #define ALR_TRACE_DEDI_PARA(hop,p1,p2,p3,p4,p5,p6,p7,p8,p9) #define ALR_TRACE_DEDI_HO_1(p1,p2,p3,p4,p5,p6) #define ALR_TRACE_DEDI_HO_2(p1,p2,p3,p4,p5,p6) #define ALR_TRACE_DEDI_HO_3(p1,p2,p3,p4,p5,p6) #define ALR_TRACE_DEDI_HO_4(p1,p2,p3) #define ALR_TRACE_DEDI_HO_5(p1,p2,p3,p4,p5,p6) #define ALR_TRACE_DEDI_HO_6(p1,p2,p3,p4,p5,p6) #define ALR_TRACE_DEDI_HO_7(p1,p2,p3,p4) #define ALR_TRACE_DEDI_FREQ_LIST() #endif /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_init | +--------------------------------------------------------------------+ PURPOSE : Initialize Dedicated Control Process. */ GLOBAL void dedi_init (void) { alr_data->state[STATE_DEDI] = DEDI_INACTIVE; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_req from SDL process Main_Control. RR configures a dedicated channel. */ /* * Conversion Channel Type Air Interface to TI definition */ LOCAL const UBYTE CH_TYPE [16] = { 0, /* undefined */ 1, /* TCH fullrate */ 2, /* TCH halfrate (0) */ 2, /* TCH halfrate (1) */ 3, /* SDCCH/4 (0) */ 3, /* SDCCH/4 (1) */ 3, /* SDCCH/4 (2) */ 3, /* SDCCH/4 (3) */ 4, /* SDCCH/8 (0) */ 4, /* SDCCH/8 (1) */ 4, /* SDCCH/8 (2) */ 4, /* SDCCH/8 (3) */ 4, /* SDCCH/8 (4) */ 4, /* SDCCH/8 (5) */ 4, /* SDCCH/8 (6) */ 4 /* SDCCH/8 (7) */ }; /* * Conversion Sub Channel Air Interface to TI definition */ LOCAL const UBYTE SUB_TYPE [16] = { 0, /* undefined */ 0, /* TCH fullrate */ 0, /* TCH halfrate (0) */ 1, /* TCH halfrate (1) */ 0, /* SDCCH/4 (0) */ 1, /* SDCCH/4 (1) */ 2, /* SDCCH/4 (2) */ 3, /* SDCCH/4 (3) */ 0, /* SDCCH/8 (0) */ 1, /* SDCCH/8 (1) */ 2, /* SDCCH/8 (2) */ 3, /* SDCCH/8 (3) */ 4, /* SDCCH/8 (4) */ 5, /* SDCCH/8 (5) */ 6, /* SDCCH/8 (6) */ 7 /* SDCCH/8 (7) */ }; GLOBAL void dedi_req (T_MPH_DEDICATED_REQ * dedicated_req) { /* * RR signals which procedure is processed */ USHORT mode = dedicated_req->mod; switch (mode) { case MODE_SYS_INFO_CHANGE: /* * Changed values for DTX, PWRC and Radio Link Timeout */ ALR_TRACE_DEDI_DTX(dedicated_req->tr_para.dtx); nc_update_dedicated (dedicated_req->tr_para.dtx, dedicated_req->tr_para.pwrc); alr_data->dedi_data.rlt = alr_data->dedi_data.act_rlt = (UBYTE)((dedicated_req->tr_para.rlt + 1) * 4); ALR_EM_SET_EM_ACT_RLT; break; case MODE_IMM_ASSIGN: /* * Immediate Assignment Procedure */ dedi_imm_ass (dedicated_req); break; case MODE_CHAN_ASSIGN: /* * Intracell Handover */ dedi_chan_ass (dedicated_req); /* * reset radio link timeout counter */ alr_data->dedi_data.act_rlt = alr_data->dedi_data.rlt; ALR_EM_SET_EM_ACT_RLT; break; #ifdef GPRS case MODE_PDCH_ASSIGN: /* * Packet Data CHannel Assignment */ dedi_pdch_ass (dedicated_req); break; #endif case MODE_ASYNC_HANDOVER: case MODE_SYNC_HANDOVER: case MODE_PRE_SYNC_HANDOVER: { ULONG dummy1, dummy2; if( nc_get_fn_time(dedicated_req->arfcn, &dummy1, &dummy2) EQ FALSE) { /* * Timing Information not present for the cell */ ALR_TRACE_DEDI("Handover to a cell - whose SYNC is not done"); ma_dedi_cnf(DEDI_RES_CELL_NOT_SYNC); } else { nc_suspend_handover(); switch(mode) { case MODE_ASYNC_HANDOVER: /* * Asynchronous handover */ dedi_async_handover (dedicated_req); break; case MODE_SYNC_HANDOVER: /* * Synchronous handover */ dedi_sync_handover (dedicated_req); break; case MODE_PRE_SYNC_HANDOVER: /* * Pre-synchronous handover */ dedi_pre_sync_handover (dedicated_req); break; default : break; } alr_data->dedi_data.act_rlt = alr_data->dedi_data.rlt; ALR_EM_SET_EM_ACT_RLT; } } break; default: break; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_fail_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_fail_req from SDL process Main_Control. RR signals that going back to the old channel after channel assignment or handover is necessary. */ GLOBAL void dedi_fail_req (void) { /* * RR signals which procedure is running */ switch (alr_data->dedi_data.act_mode) { case MODE_CHAN_ASSIGN: /* * channel assignment procedure */ dedi_chan_ass_fail (); break; case MODE_PDCH_ASSIGN: dedi_pdch_ass_fail(); break; case MODE_CELL_CHANGE_ORDER: dedi_cco_fail(); break; case MODE_ASYNC_HANDOVER: case MODE_SYNC_HANDOVER: case MODE_PRE_SYNC_HANDOVER: case MODE_PSEUDO_SYNC_HANDOVER: /* * one of the handover procedures */ dedi_handover_fail (); break; default: break; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_ta_fail_ind | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_ta_fail_ind from SDL process Main_Control. Layer 1 signals that the timing advance is out of range during handover. This will be forwarded to RR and switching back to the old channel is initiated by RR. */ GLOBAL void dedi_ta_fail_ind (void) { ma_dedi_cnf (DEDI_RES_TA_OUT_OF_RANGE); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_ho_finished | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_ho_finished from SDL process Main_Control. Layer 1 signals that the handover has finished successful. This is forwarded to RR which starts resumption of the link on the new channel. */ GLOBAL void dedi_ho_finished (UBYTE cause) { ma_clean_dedi_sys_buffer (); if (cause EQ 0) { ALR_TRACE_DEDI ("ho ok"); /* * handover successfull */ ma_dedi_cnf (DEDI_RES_OK); } else { ALR_TRACE_DEDI ("ho fail"); /* * handover failed */ nc_update_list (alr_data->dedi_data.old_bcch); ma_dedi_cnf (DEDI_RES_TIMEOUT); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_chan_ass_fail | +--------------------------------------------------------------------+ PURPOSE : Process Channel Assignment Failure (back to old dedicated channel). In fact this is a new configuration of the layer 1. The parameters of the old channel are stored in TI++. */ LOCAL void dedi_chan_ass_fail (void) { PALLOC (chan_ass, MPHC_CHANNEL_ASSIGN_REQ); memset (chan_ass, 0, sizeof (T_MPHC_CHANNEL_ASSIGN_REQ)); if (alr_data->dedi_data.redef_starting_time.start_time_present) { /* * Special case: frequency redefinition values ares stored. */ memcpy (&chan_ass->channel_desc_1, &alr_data->dedi_data.redef_channel_desc, sizeof (T_channel_desc)); memcpy (&chan_ass->frequency_list, &alr_data->dedi_data.redef_frequency_list, sizeof (T_frequency_list)); memcpy (&chan_ass->channel_desc_1_bef_sti, &alr_data->dedi_data.old_channel_desc, sizeof (T_channel_desc)); memcpy (&chan_ass->frequency_list_bef_sti, &alr_data->dedi_data.old_frequency_list, sizeof (T_frequency_list)); memcpy (&chan_ass->starting_time, &alr_data->dedi_data.redef_starting_time, sizeof (T_starting_time)); /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc ((T_channel_desc *)&chan_ass->channel_desc_1); dedi_convert_frequency_list (&chan_ass->frequency_list); dedi_convert_chan_desc ((T_channel_desc *)&chan_ass->channel_desc_1_bef_sti); dedi_convert_frequency_list ((T_frequency_list *)&chan_ass->frequency_list_bef_sti); } } else { /* * Normal case */ memcpy (&chan_ass->channel_desc_1, &alr_data->dedi_data.old_channel_desc, sizeof (T_channel_desc)); memcpy (&chan_ass->frequency_list, &alr_data->dedi_data.old_frequency_list, sizeof (T_frequency_list)); /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc ((T_channel_desc *)&chan_ass->channel_desc_1); dedi_convert_frequency_list (&chan_ass->frequency_list); } } chan_ass->txpwr = alr_data->dedi_data.old_power; chan_ass->cipher_mode = alr_data->dedi_data.old_cipher_mode; chan_ass->channel_mode_1 = alr_data->dedi_data.old_channel_mode; chan_ass->a5_algorithm = alr_data->dedi_data.old_a5_algorithm; chan_ass->cipher_key = alr_data->dedi_data.old_cipher_key; chan_ass->dtx_allowed = alr_data->dedi_data.old_dtx_allowed; chan_ass->amr_configuration = alr_data->dedi_data.old_amr_configuration; /* * store actual channel for layer 2 channel decision */ actual_channel = alr_data->dedi_data.old_channel; /* * store actual channel parameter in ALR. In fact they are * the old values. */ if (alr_data->dedi_data.redef_starting_time.start_time_present) { /* * Special case: frequency redefinition values ares stored. */ memcpy (&alr_data->dedi_data.act_channel_desc, &alr_data->dedi_data.redef_channel_desc, sizeof (T_channel_desc)); memcpy (&alr_data->dedi_data.act_frequency_list, &alr_data->dedi_data.redef_frequency_list, sizeof (T_frequency_list)); } else { /* * Normal case */ memcpy (&alr_data->dedi_data.act_channel_desc, &alr_data->dedi_data.old_channel_desc, sizeof (T_channel_desc)); memcpy (&alr_data->dedi_data.act_frequency_list, &alr_data->dedi_data.old_frequency_list, sizeof (T_frequency_list)); } alr_data->dedi_data.act_power = alr_data->dedi_data.old_power; alr_data->dedi_data.act_cipher_mode = alr_data->dedi_data.old_cipher_mode; alr_data->dedi_data.act_channel_mode = alr_data->dedi_data.old_channel_mode; alr_data->dedi_data.act_a5_algorithm = alr_data->dedi_data.old_a5_algorithm; alr_data->dedi_data.act_cipher_key = alr_data->dedi_data.old_cipher_key; alr_data->dedi_data.act_dtx_allowed = alr_data->dedi_data.old_dtx_allowed; alr_data->dedi_data.act_amr_configuration = alr_data->dedi_data.old_amr_configuration; alr_data->dedi_data.act_mode = MODE_CHAN_ASS_FAIL; /* * send data to layer 1 */ ma_dedi_chan_ass_req (chan_ass); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_dedi | | STATE : code ROUTINE : dedi_pdch_ass_fail | +--------------------------------------------------------------------+ PURPOSE : PDCH Assignment Failure (back to old dedicated channel). Use the channel configuration in alr_data->dedi_data.act* with MPHC-IMMED-ASSIGN-REQ. With the subsequent MPHC-IMMED-ASSIGN-CON alr_data->dedi_data.temp* is NOT assigned to alr_data->dedi_data.act*, refer to function dedi_imm_ass_cnf. The actual switch back to the original channel is performed via a channel assignment procedure carried out by dedi_chan_ass_fail which is called in dedi_imm_ass_cnf. */ LOCAL void dedi_pdch_ass_fail (void) { T_DEDI_DATA *d = &alr_data->dedi_data; PALLOC (immed_assign_req, MPHC_IMMED_ASSIGN_REQ); memset ( immed_assign_req, 0 , sizeof *immed_assign_req ); immed_assign_req->channel_desc = d->old_channel_desc; immed_assign_req->timing_advance = (UBYTE)alr_data->nc_data.tav; immed_assign_req->frequency_list = d->old_frequency_list; immed_assign_req->starting_time = d->old_starting_time; immed_assign_req->frequency_list_bef_sti = d->old_frequency_list_bef_sti; immed_assign_req->maio_bef_sti = d->old_channel_desc.chan_sel.rf_channel.maio; /* immed_assign_req->bcch_allocation = ... not used in current implementation immed_assign_req->ba_id = ... not used in current implementation */ immed_assign_req->dtx_allowed = d->old_dtx_allowed; immed_assign_req->pwrc = d->old_pwrc; SET_STATE (STATE_DEDI, DEDI_IMM_ASS_RECONN); PSENDX (L1, immed_assign_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_dedi | | STATE : code ROUTINE : dedi_cco_fail | +--------------------------------------------------------------------+ PURPOSE : Cell Change Order Failure (back to old dedicated channel). */ LOCAL void dedi_cco_fail (void) { dedi_pdch_ass_fail(); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_handover_fail | +--------------------------------------------------------------------+ PURPOSE : Process Handover Failure (back to old dedicated channel). For handover switching back is carried out autonomously by layer 1. Only the configuration data in ALR is updated to the parameters of the old channel. */ LOCAL void dedi_handover_fail (void) { /* * store actual channel value for layer 2 channel selection */ actual_channel = alr_data->dedi_data.old_channel; /* * update actual channel parameters to the old values */ alr_data->serving_cell = alr_data->dedi_data.act_bcch = alr_data->dedi_data.old_bcch; alr_data->dedi_data.act_channel_desc = alr_data->dedi_data.old_channel_desc; alr_data->dedi_data.act_frequency_list = alr_data->dedi_data.old_frequency_list; alr_data->dedi_data.act_cipher_mode = alr_data->dedi_data.old_cipher_mode; alr_data->dedi_data.act_channel_mode = alr_data->dedi_data.old_channel_mode; alr_data->dedi_data.act_a5_algorithm = alr_data->dedi_data.old_a5_algorithm; alr_data->dedi_data.act_cipher_key = alr_data->dedi_data.old_cipher_key; alr_data->dedi_data.act_amr_configuration = alr_data->dedi_data.old_amr_configuration; alr_data->dedi_data.act_mode = MODE_HANDOVER_FAIL; /* * Inform layer 1 about handover failure */ nc_suspend_handover(); ma_dedi_ho_fail_req (); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_imm_ass | +--------------------------------------------------------------------+ PURPOSE : Converts MPH_DEDICATED_REQ to MPHC_IMMED_ASSIGN_REQ. This function is used during Immediate Assignment procedure. */ LOCAL void dedi_imm_ass (T_MPH_DEDICATED_REQ *dedicated_req) { T_DEDI_DATA *dd = &alr_data->dedi_data; PALLOC (imm_ass, MPHC_IMMED_ASSIGN_REQ); /* T_MPHC_IMMED_ASSIGN_REQ */ ALR_EM_CONFIGURE_IMMIDIATE_ASSIGNMENT; memset (imm_ass, 0, sizeof (T_MPHC_IMMED_ASSIGN_REQ)); if (dedicated_req->ch_type.h EQ 1) { /* * with frequency hopping */ imm_ass->channel_desc.chan_sel.h = 1; imm_ass->channel_desc.chan_sel.rf_channel.maio = dedicated_req->ch_type.maio; imm_ass->channel_desc.chan_sel.rf_channel.hsn = dedicated_req->ch_type.hsn; dedi_fill_ma (dedicated_req->ch_type.ma, &imm_ass->frequency_list); dedi_fill_ma (dedicated_req->ch_type2.ma, (T_frequency_list *)&imm_ass->frequency_list_bef_sti); } else { ALR_TRACE_DEDI ("no hopping"); /* * Avoid the union, arfcn is mapped to maio and hsn * in the non-hopping case. */ imm_ass->channel_desc.chan_sel.h = 0; imm_ass->channel_desc.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type.arfcn & 0xFF); imm_ass->channel_desc.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type.arfcn >> 8) & 0xFF); } /* * set the actual channel for layer 2 channel selection */ actual_channel = imm_ass->channel_desc.channel_type = CH_TYPE [dedicated_req->ch_type.ch]; /* * set the rest of parameters */ imm_ass->channel_desc.sub_channel = SUB_TYPE [dedicated_req->ch_type.ch]; imm_ass->channel_desc.timeslot_no = dedicated_req->ch_type.tn; imm_ass->channel_desc.tsc = dedicated_req->ch_type.tsc; imm_ass->timing_advance = dedicated_req->tr_para.tav; nc_store_tav(dedicated_req->tr_para.tav); imm_ass->starting_time.start_time_present = dedicated_req->start.v_start; imm_ass->starting_time.start_time.t1 = dedicated_req->start.t1; imm_ass->starting_time.start_time.t3 = dedicated_req->start.t3; imm_ass->starting_time.start_time.t2 = dedicated_req->start.t2; imm_ass->maio_bef_sti = dedicated_req->ch_type2.maio; imm_ass->dtx_allowed = dedicated_req->tr_para.dtx; /* * calculate radio link timeout value */ dd->rlt = dd->act_rlt = (UBYTE)((dedicated_req->tr_para.rlt + 1) * 4); ALR_EM_SET_EM_ACT_RLT_2; memset (&imm_ass->bcch_allocation, 0, sizeof (T_bcch_allocation)); imm_ass->ba_id = ALR_BA_LOW; imm_ass->pwrc = dedicated_req->tr_para.pwrc; /* * store new parameters as temporary channel configuration */ dd->temp_bcch = dedicated_req->arfcn; dd->temp_channel_desc = imm_ass->channel_desc; dd->temp_channel_mode = dedi_channel_mode (MODE_SIG_ONLY, 0); dd->temp_frequency_list = imm_ass->frequency_list; dd->temp_starting_time = imm_ass->starting_time; dd->temp_frequency_list_bef_sti = imm_ass->frequency_list_bef_sti; dd->temp_channel_desc_bef_sti = imm_ass->channel_desc; dd->temp_channel_desc_bef_sti.chan_sel.rf_channel.maio = imm_ass->maio_bef_sti; dd->temp_pwrc = imm_ass->pwrc; dd->temp_cipher_mode = CI_NO_CIPHERING; dd->temp_a5_algorithm = 0; memset ( &dd->temp_cipher_key, 0, sizeof (T_cipher_key) ); SET_STATE (STATE_DEDI, DEDI_IMM_ASS); /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc (&imm_ass->channel_desc); dedi_convert_frequency_list (&imm_ass->frequency_list); dedi_convert_frequency_list ((T_frequency_list *)&imm_ass->frequency_list_bef_sti); } /* * send parameters to layer 1 */ ALR_TRACE_DEDI_PARA(imm_ass->channel_desc.chan_sel.h, imm_ass->channel_desc.chan_sel.rf_channel.maio+ (imm_ass->channel_desc.chan_sel.rf_channel.hsn<<8), imm_ass->channel_desc.channel_type, imm_ass->channel_desc.sub_channel, imm_ass->channel_desc.timeslot_no, imm_ass->channel_desc.tsc, imm_ass->timing_advance, imm_ass->starting_time.start_time_present, imm_ass->dtx_allowed, imm_ass->maio_bef_sti); ma_dedi_imm_ass_req (imm_ass); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_chan_ass | +--------------------------------------------------------------------+ PURPOSE : Converts MPH_DEDICATED_REQ to MPHC_CHANNEL_ASSIGN_REQ. This function is used during channel assignment procedure. */ LOCAL void dedi_chan_ass (T_MPH_DEDICATED_REQ *dedicated_req) { int i; PALLOC (chan_ass, MPHC_CHANNEL_ASSIGN_REQ); ALR_EM_CONFIGURE_CHANNEL_ASSIGNMENT; memset (chan_ass, 0, sizeof (T_MPHC_CHANNEL_ASSIGN_REQ)); if (dedicated_req->ch_type.h EQ 1) { /* * with frequency hopping */ chan_ass->channel_desc_1.chan_sel.h = 1; chan_ass->channel_desc_1.chan_sel.rf_channel.maio = dedicated_req->ch_type.maio; chan_ass->channel_desc_1.chan_sel.rf_channel.hsn = dedicated_req->ch_type.hsn; dedi_fill_ma (dedicated_req->ch_type.ma, &chan_ass->frequency_list); } else { /* * Avoid the union in the non-hopping case and * map arfcn to maio and hsn. */ chan_ass->channel_desc_1.chan_sel.h = 0; chan_ass->channel_desc_1.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type.arfcn & 0xFF); chan_ass->channel_desc_1.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type.arfcn >> 8) & 0xFF); } /* * fill the layer 1 structure */ alr_data->dedi_data.temp_channel = chan_ass->channel_desc_1.channel_type = CH_TYPE [dedicated_req->ch_type.ch]; chan_ass->channel_desc_1.sub_channel = SUB_TYPE [dedicated_req->ch_type.ch]; chan_ass->channel_desc_1.timeslot_no = dedicated_req->ch_type.tn; chan_ass->channel_desc_1.tsc = dedicated_req->ch_type.tsc; chan_ass->txpwr = cut_power_value (dedicated_req->tr_para.power, dedicated_req); chan_ass->channel_mode_1 = dedi_channel_mode(dedicated_req->tr_para.mode, alr_data->dedi_data.temp_channel); chan_ass->amr_configuration.noise_suppression_control_bit = dedicated_req->amr_conf.nscb; chan_ass->amr_configuration.initial_codec_mode_indicator = dedicated_req->amr_conf.icmi; chan_ass->amr_configuration.initial_codec_mode = dedicated_req->amr_conf.st_mode; chan_ass->amr_configuration.active_codec_set = dedicated_req->amr_conf.acs; /* Traces only needed for IOT session */ TRACE_EVENT_P1("*AMR NSCB %d", chan_ass->amr_configuration.noise_suppression_control_bit); TRACE_EVENT_P1("*AMR ICMI %d", chan_ass->amr_configuration.initial_codec_mode_indicator); TRACE_EVENT_P1("*AMR ICM %d", chan_ass->amr_configuration.initial_codec_mode); TRACE_EVENT_P1("*AMR ACS %d", chan_ass->amr_configuration.active_codec_set); for (i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) { memcpy(&chan_ass->amr_configuration.threshold[i], &dedicated_req->amr_conf.cod_prop[i].codec_thr, 1); memcpy(&chan_ass->amr_configuration.hysteresis[i], &dedicated_req->amr_conf.cod_prop[i].codec_hyst, 1); TRACE_EVENT_P2("*AMR threshold[%d] %d", i, chan_ass->amr_configuration.threshold[i]); TRACE_EVENT_P2("*AMR hysteresis[%d] %d", i, chan_ass->amr_configuration.hysteresis[i]); } chan_ass->starting_time.start_time_present = dedicated_req->start.v_start; chan_ass->starting_time.start_time.t1 = dedicated_req->start.t1; chan_ass->starting_time.start_time.t3 = dedicated_req->start.t3; chan_ass->starting_time.start_time.t2 = dedicated_req->start.t2; if (dedicated_req->ch_type2.ch NEQ NOT_PRESENT_8BIT) { if (dedicated_req->ch_type2.h EQ 1) { chan_ass->channel_desc_1_bef_sti.chan_sel.h = 1; chan_ass->channel_desc_1_bef_sti.chan_sel.rf_channel.maio = dedicated_req->ch_type2.maio; chan_ass->channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = dedicated_req->ch_type2.hsn; dedi_fill_ma (dedicated_req->ch_type2.ma, (T_frequency_list *)&chan_ass->frequency_list_bef_sti); } else { /* * Avoid the union !!! */ chan_ass->channel_desc_1_bef_sti.chan_sel.h = 0; chan_ass->channel_desc_1_bef_sti.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type2.arfcn & 0xFF); chan_ass->channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type2.arfcn >> 8) & 0xFF); } chan_ass->channel_desc_1_bef_sti.channel_type = CH_TYPE [dedicated_req->ch_type2.ch]; chan_ass->channel_desc_1_bef_sti.sub_channel = SUB_TYPE [dedicated_req->ch_type2.ch]; chan_ass->channel_desc_1_bef_sti.timeslot_no = dedicated_req->ch_type2.tn; chan_ass->channel_desc_1_bef_sti.tsc = dedicated_req->ch_type2.tsc; } chan_ass->cipher_mode = dedicated_req->ciph.stat; chan_ass->a5_algorithm = dedicated_req->ciph.algo; memcpy (&chan_ass->cipher_key, dedicated_req->ciph.kc, sizeof(T_cipher_key)); chan_ass->dtx_allowed = dedicated_req->tr_para.dtx; /* * store the new configuration as temporary configuration */ alr_data->dedi_data.temp_bcch = dedicated_req->arfcn; memcpy (&alr_data->dedi_data.temp_channel_desc, &chan_ass->channel_desc_1, sizeof (T_channel_desc)); alr_data->dedi_data.temp_channel_mode = chan_ass->channel_mode_1; alr_data->dedi_data.temp_frequency_list = chan_ass->frequency_list; alr_data->dedi_data.temp_cipher_mode = chan_ass->cipher_mode; alr_data->dedi_data.temp_a5_algorithm = chan_ass->a5_algorithm; alr_data->dedi_data.temp_cipher_key = chan_ass->cipher_key; alr_data->dedi_data.temp_power = chan_ass->txpwr; alr_data->dedi_data.temp_dtx_allowed = chan_ass->dtx_allowed; alr_data->dedi_data.act_mode = MODE_CHAN_ASSIGN; alr_data->dedi_data.temp_amr_configuration = chan_ass->amr_configuration; /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc ((T_channel_desc *)&chan_ass->channel_desc_1); dedi_convert_chan_desc ((T_channel_desc *)&chan_ass->channel_desc_1_bef_sti); dedi_convert_frequency_list (&chan_ass->frequency_list); dedi_convert_frequency_list ((T_frequency_list *)&chan_ass->frequency_list_bef_sti); } /* * inform layer 1 about the new channel configuration */ ma_dedi_chan_ass_req (chan_ass); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_dedi | | STATE : code ROUTINE : dedi_pdch_ass | +--------------------------------------------------------------------+ PURPOSE : "Deactivation of previously assigned channels (layer1)" according to GSM 04.18, clause 3.4.19 during a PDCH Assignment procedure. */ LOCAL void dedi_pdch_ass (T_MPH_DEDICATED_REQ *dedicated_req) { T_DEDI_DATA *d = &alr_data->dedi_data; /* * The PDCH Assignment Procedure is similar to the Channel Assignment * Procedure. Both are perfomred in dedicated state in order to switch * to a 'new' channel. "Normal operation" is suspend during the procedure. * In case of failure the old channel is activated and the message * ASSIGNMENT FAILURE is sent. */ ma_stop_active_procs ( STOP_PCH_READING ); /* Current state is now DEDI_INACTIVE. * In Layer 1 SDCCH or TCH is stopped. In order to re-activate the channel * (failure to TBF establishment), the Current Channel Configuration must be * stored. This configuration will then be used to re-establish the channel. * The Current Channel Configuration is provided in the last successful * Immediate Assignment, Channel Assignment or Handover in the variables * alr_data->dedi_data.act***. The re-activation can be done with the * Immediate Assignment Procedure followed by a Channel Assignment Procedure. * However there is the prerequisite that L1 must be in Idle Mode to perform * Immediate Assignment. This will be achieved by sending MPH-IDLE-REQ. */ d->old_channel = actual_channel; d->old_bcch = d->act_bcch; d->old_channel_desc = d->act_channel_desc; d->old_channel_mode = d->act_channel_mode; d->old_frequency_list = d->act_frequency_list; d->old_starting_time = d->act_starting_time; d->old_frequency_list_bef_sti = d->act_frequency_list_bef_sti; d->old_channel_desc_bef_sti = d->act_channel_desc_bef_sti; d->old_pwrc = d->act_pwrc; d->old_cipher_mode = d->act_cipher_mode; d->old_a5_algorithm = d->act_a5_algorithm; d->old_cipher_key = d->act_cipher_key; d->old_power = d->act_power; d->old_dtx_allowed = d->act_dtx_allowed; /* * Save the activation mode for Resume / Reconnection */ alr_data->dedi_data.act_mode = MODE_PDCH_ASSIGN; } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_async_handover | +--------------------------------------------------------------------+ PURPOSE : Converts MPH_DEDICATED_REQ to MPHC_ASYNC_HO_REQ. This function is used during asynchronous handover. */ LOCAL void dedi_async_handover (T_MPH_DEDICATED_REQ * dedicated_req) { int i; PALLOC (async, MPHC_ASYNC_HO_REQ); ALR_EM_CONFIGURE_HANDOVER(EM_HANDOVER_ASYNC); memset (async, 0, sizeof (T_MPHC_ASYNC_HO_REQ)); if (dedicated_req->ch_type.h EQ 1) { ALR_TRACE_DEDI ("hopping"); /* * new channel with frequency hopping. */ async->handover_command.channel_desc_1.chan_sel.h = 1; async->handover_command.channel_desc_1.chan_sel.rf_channel.maio = dedicated_req->ch_type.maio; async->handover_command.channel_desc_1.chan_sel.rf_channel.hsn = dedicated_req->ch_type.hsn; dedi_fill_ma (dedicated_req->ch_type.ma, &async->handover_command.frequency_list); } else { ALR_TRACE_DEDI ("no hop"); /* * Avoid the union in the non-hopping case. Mapping * of arfcn to maio and hsn. */ async->handover_command.channel_desc_1.chan_sel.h = 0; async->handover_command.channel_desc_1.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type.arfcn & 0xFF); async->handover_command.channel_desc_1.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type.arfcn >> 8) & 0xFF); } /* * convert the parameters to the layer 1 structure */ alr_data->dedi_data.temp_channel = async->handover_command.channel_desc_1.channel_type = CH_TYPE [dedicated_req->ch_type.ch]; async->handover_command.channel_desc_1.sub_channel = SUB_TYPE [dedicated_req->ch_type.ch]; async->handover_command.channel_desc_1.timeslot_no = dedicated_req->ch_type.tn; async->handover_command.channel_desc_1.tsc = dedicated_req->ch_type.tsc; async->handover_command.txpwr = cut_power_value (dedicated_req->ho_param.ho_pow, dedicated_req); async->handover_command.ho_acc = dedicated_req->ho_param.ho_ref; async->handover_command.starting_time.start_time_present = dedicated_req->start.v_start; if (dedicated_req->start.v_start) { ALR_TRACE_DEDI ("start time"); async->handover_command.starting_time.start_time.t1 = dedicated_req->start.t1; async->handover_command.starting_time.start_time.t3 = dedicated_req->start.t3; async->handover_command.starting_time.start_time.t2 = dedicated_req->start.t2; } async->handover_command.cell_description.ncc = (UBYTE)(dedicated_req->bsic >> 3); async->handover_command.cell_description.bcc = (UBYTE)(dedicated_req->bsic & 7); async->handover_command.cell_description.bcch_carrier = ARFCN_TO_L1 (dedicated_req->arfcn); async->handover_command.channel_mode_1 = dedi_channel_mode (dedicated_req->tr_para.mode, alr_data->dedi_data.temp_channel); async->amr_configuration.noise_suppression_control_bit = dedicated_req->amr_conf.nscb; async->amr_configuration.initial_codec_mode_indicator = dedicated_req->amr_conf.icmi; async->amr_configuration.initial_codec_mode = dedicated_req->amr_conf.st_mode; async->amr_configuration.active_codec_set = dedicated_req->amr_conf.acs; /* Traces only needed for IOT session */ TRACE_EVENT_P1("*AMR NSCB %d", async->amr_configuration.noise_suppression_control_bit); TRACE_EVENT_P1("*AMR ICMI %d", async->amr_configuration.initial_codec_mode_indicator); TRACE_EVENT_P1("*AMR ICM %d", async->amr_configuration.initial_codec_mode); TRACE_EVENT_P1("*AMR ACS %d", async->amr_configuration.active_codec_set); for (i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) { memcpy(&async->amr_configuration.threshold[i], &dedicated_req->amr_conf.cod_prop[i].codec_thr, 1); memcpy(&async->amr_configuration.hysteresis[i], &dedicated_req->amr_conf.cod_prop[i].codec_hyst, 1); TRACE_EVENT_P2("*AMR threshold[%d] %d", i, async->amr_configuration.threshold[i]); TRACE_EVENT_P2("*AMR hysteresis[%d] %d", i, async->amr_configuration.hysteresis[i]); } if (dedicated_req->start.v_start AND dedicated_req->ch_type2.ch NEQ NOT_PRESENT_8BIT) { ALR_TRACE_DEDI ("bef sti"); /* * before starting time elements are available */ if (dedicated_req->ch_type2.h EQ 1) { async->handover_command.channel_desc_1_bef_sti.chan_sel.h = 1; async->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.maio = dedicated_req->ch_type2.maio; async->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = dedicated_req->ch_type2.hsn; dedi_fill_ma (dedicated_req->ch_type2.ma, (T_frequency_list *) &async->handover_command.frequency_list_bef_sti); } else { /* * Avoid the union !!! */ async->handover_command.channel_desc_1_bef_sti.chan_sel.h = 0; async->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type2.arfcn & 0xFF); async->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type2.arfcn >> 8) & 0xFF); } async->handover_command.channel_desc_1_bef_sti.channel_type = CH_TYPE [dedicated_req->ch_type2.ch]; async->handover_command.channel_desc_1_bef_sti.sub_channel = SUB_TYPE [dedicated_req->ch_type2.ch]; async->handover_command.channel_desc_1_bef_sti.timeslot_no = dedicated_req->ch_type2.tn; async->handover_command.channel_desc_1_bef_sti.tsc = dedicated_req->ch_type2.tsc; } async->handover_command.cipher_mode = dedicated_req->ciph.stat; async->handover_command.a5_algorithm = dedicated_req->ciph.algo; memcpy (&async->cipher_key, dedicated_req->ciph.kc, sizeof(T_cipher_key)); /* * store the new parameters as temporary configuration. */ alr_data->dedi_data.temp_bcch = dedicated_req->arfcn; memcpy (&alr_data->dedi_data.temp_channel_desc, &async->handover_command.channel_desc_1, sizeof (T_channel_desc)); alr_data->dedi_data.temp_channel_mode = async->handover_command.channel_mode_1; alr_data->dedi_data.temp_frequency_list = async->handover_command.frequency_list; alr_data->dedi_data.temp_cipher_mode = async->handover_command.cipher_mode; alr_data->dedi_data.temp_a5_algorithm = async->handover_command.a5_algorithm; alr_data->dedi_data.temp_cipher_key = async->cipher_key; alr_data->dedi_data.temp_power = async->handover_command.txpwr; alr_data->dedi_data.temp_bsic = dedicated_req->bsic; alr_data->dedi_data.temp_amr_configuration = async->amr_configuration; alr_data->dedi_data.act_mode = MODE_ASYNC_HANDOVER; nc_get_fn_time (alr_data->dedi_data.temp_bcch, (ULONG *)&async->fn_offset, (ULONG *)&async->time_alignmnt); /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc ((T_channel_desc *)&async->handover_command.channel_desc_1); dedi_convert_chan_desc ((T_channel_desc *)&async->handover_command.channel_desc_1_bef_sti); dedi_convert_frequency_list (&async->handover_command.frequency_list); dedi_convert_frequency_list ((T_frequency_list *)&async->handover_command.frequency_list_bef_sti); } /* * forward the parameters to layer 1 */ ALR_TRACE_DEDI_HO_1 (dedicated_req->arfcn, dedicated_req->bsic, dedicated_req->start.v_start, dedicated_req->ch_type2.ch, dedicated_req->ch_type.ch, dedicated_req->ch_type.tsc); ALR_TRACE_DEDI_HO_2 (dedicated_req->ch_type.tn, dedicated_req->ch_type.arfcn, dedicated_req->ho_param.ho_pow, dedicated_req->ho_param.ho_ref, dedicated_req->ho_param.ho_acc_type, dedicated_req->ho_param.ho_nci); ALR_TRACE_DEDI_HO_3 (dedicated_req->tr_para.mode, dedicated_req->tr_para.power, dedicated_req->tr_para.dtx, dedicated_req->tr_para.rlt, dedicated_req->tr_para.tav, dedicated_req->tr_para.pwrc); ALR_TRACE_DEDI_HO_4 (dedicated_req->tr_para.mode, dedicated_req->ciph.stat, dedicated_req->ciph.algo); ALR_TRACE_DEDI_HO_5 (async->handover_command.channel_desc_1.chan_sel.h, async->handover_command.channel_desc_1.chan_sel.rf_channel.maio, async->handover_command.channel_desc_1.chan_sel.rf_channel.hsn, async->handover_command.channel_desc_1.channel_type, async->handover_command.channel_desc_1.sub_channel, async->handover_command.channel_desc_1.timeslot_no); ALR_TRACE_DEDI_HO_6 (async->handover_command.channel_desc_1.tsc, async->handover_command.txpwr, async->handover_command.ho_acc, async->handover_command.starting_time.start_time_present, async->handover_command.cell_description.ncc, async->handover_command.cell_description.bcc); ALR_TRACE_DEDI_HO_7 (async->handover_command.cell_description.bcch_carrier, async->handover_command.channel_mode_1, async->handover_command.cipher_mode, async->handover_command.a5_algorithm); ma_dedi_async_ho_req (async); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_sync_handover | +--------------------------------------------------------------------+ PURPOSE : Converts MPH_DEDICATED_REQ to MPHC_SYNC_HO_REQ. This function is used during synchronous handover. */ LOCAL void dedi_sync_handover (T_MPH_DEDICATED_REQ *dedicated_req) { int i; PALLOC (sync, MPHC_SYNC_HO_REQ); ALR_EM_CONFIGURE_HANDOVER(EM_HANDOVER_SYNC); memset (sync, 0, sizeof (T_MPHC_SYNC_HO_REQ)); if (dedicated_req->ch_type.h EQ 1) { /* * new cell with frequency hopping */ sync->handover_command.channel_desc_1.chan_sel.h = 1; sync->handover_command.channel_desc_1.chan_sel.rf_channel.maio = dedicated_req->ch_type.maio; sync->handover_command.channel_desc_1.chan_sel.rf_channel.hsn = dedicated_req->ch_type.hsn; dedi_fill_ma (dedicated_req->ch_type.ma, &sync->handover_command.frequency_list); } else { /* * Avoid the union in the non-hopping case, map arfcn to * maio and hsn */ sync->handover_command.channel_desc_1.chan_sel.h = 0; sync->handover_command.channel_desc_1.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type.arfcn & 0xFF); sync->handover_command.channel_desc_1.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type.arfcn >> 8) & 0xFF); } /* * fill layer 1 structure with the new parameters */ alr_data->dedi_data.temp_channel = sync->handover_command.channel_desc_1.channel_type = CH_TYPE [dedicated_req->ch_type.ch]; sync->handover_command.channel_desc_1.sub_channel = SUB_TYPE [dedicated_req->ch_type.ch]; sync->handover_command.channel_desc_1.timeslot_no = dedicated_req->ch_type.tn; sync->handover_command.channel_desc_1.tsc = dedicated_req->ch_type.tsc; sync->handover_command.txpwr = cut_power_value (dedicated_req->ho_param.ho_pow, dedicated_req); sync->handover_command.ho_acc = dedicated_req->ho_param.ho_ref; sync->handover_command.starting_time.start_time_present = dedicated_req->start.v_start; sync->handover_command.starting_time.start_time.t1 = dedicated_req->start.t1; sync->handover_command.starting_time.start_time.t3 = dedicated_req->start.t3; sync->handover_command.starting_time.start_time.t2 = dedicated_req->start.t2; sync->nci = dedicated_req->ho_param.ho_nci; sync->handover_command.cell_description.ncc = (UBYTE)(dedicated_req->bsic >> 3); sync->handover_command.cell_description.bcc = (UBYTE)(dedicated_req->bsic & 7); sync->handover_command.cell_description.bcch_carrier = ARFCN_TO_L1(dedicated_req->arfcn); sync->handover_command.channel_mode_1 = dedi_channel_mode (dedicated_req->tr_para.mode, alr_data->dedi_data.temp_channel); sync->amr_configuration.noise_suppression_control_bit = dedicated_req->amr_conf.nscb; sync->amr_configuration.initial_codec_mode_indicator = dedicated_req->amr_conf.icmi; sync->amr_configuration.initial_codec_mode = dedicated_req->amr_conf.st_mode; sync->amr_configuration.active_codec_set = dedicated_req->amr_conf.acs; /* Traces only needed for IOT session */ TRACE_EVENT_P1("*AMR NSCB %d", sync->amr_configuration.noise_suppression_control_bit); TRACE_EVENT_P1("*AMR ICMI %d", sync->amr_configuration.initial_codec_mode_indicator); TRACE_EVENT_P1("*AMR ICM %d", sync->amr_configuration.initial_codec_mode); TRACE_EVENT_P1("*AMR ACS %d", sync->amr_configuration.active_codec_set); for (i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) { memcpy(&sync->amr_configuration.threshold[i], &dedicated_req->amr_conf.cod_prop[i].codec_thr, 1); memcpy(&sync->amr_configuration.hysteresis[i], &dedicated_req->amr_conf.cod_prop[i].codec_hyst, 1); TRACE_EVENT_P2("*AMR threshold[%d] %d", i, sync->amr_configuration.threshold[i]); TRACE_EVENT_P2("*AMR hysteresis[%d] %d", i, sync->amr_configuration.hysteresis[i]); } if (dedicated_req->start.v_start AND dedicated_req->ch_type2.ch NEQ NOT_PRESENT_8BIT) { if (dedicated_req->ch_type2.h EQ 1) { sync->handover_command.channel_desc_1_bef_sti.chan_sel.h = 1; sync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.maio = dedicated_req->ch_type2.maio; sync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = dedicated_req->ch_type2.hsn; dedi_fill_ma (dedicated_req->ch_type2.ma, (T_frequency_list *) &sync->handover_command.frequency_list_bef_sti); } else { /* * Avoid the union !!! */ sync->handover_command.channel_desc_1_bef_sti.chan_sel.h = 0; sync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type2.arfcn & 0xFF); sync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type2.arfcn >> 8) & 0xFF); } sync->handover_command.channel_desc_1_bef_sti.channel_type = CH_TYPE [dedicated_req->ch_type2.ch]; sync->handover_command.channel_desc_1_bef_sti.sub_channel = SUB_TYPE [dedicated_req->ch_type2.ch]; sync->handover_command.channel_desc_1_bef_sti.timeslot_no = dedicated_req->ch_type2.tn; sync->handover_command.channel_desc_1_bef_sti.tsc = dedicated_req->ch_type2.tsc; } sync->handover_command.cipher_mode = dedicated_req->ciph.stat; sync->handover_command.a5_algorithm = dedicated_req->ciph.algo; memcpy (&sync->cipher_key, dedicated_req->ciph.kc, sizeof(T_cipher_key)); /* * store the new values as temporary configuration */ alr_data->dedi_data.temp_bcch = dedicated_req->arfcn; memcpy (&alr_data->dedi_data.temp_channel_desc, &sync->handover_command.channel_desc_1, sizeof (T_channel_desc)); alr_data->dedi_data.temp_channel_mode = sync->handover_command.channel_mode_1; alr_data->dedi_data.temp_frequency_list = sync->handover_command.frequency_list; alr_data->dedi_data.temp_cipher_mode = sync->handover_command.cipher_mode; alr_data->dedi_data.temp_a5_algorithm = sync->handover_command.a5_algorithm; alr_data->dedi_data.temp_cipher_key = sync->cipher_key; alr_data->dedi_data.temp_power = sync->handover_command.txpwr; alr_data->dedi_data.temp_bsic = dedicated_req->bsic; alr_data->dedi_data.temp_amr_configuration = sync->amr_configuration; alr_data->dedi_data.act_mode = MODE_SYNC_HANDOVER; nc_get_fn_time (alr_data->dedi_data.temp_bcch, (ULONG *)&sync->fn_offset, (ULONG *)&sync->time_alignmnt); /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc ((T_channel_desc *)&sync->handover_command.channel_desc_1); dedi_convert_chan_desc ((T_channel_desc *)&sync->handover_command.channel_desc_1_bef_sti); dedi_convert_frequency_list (&sync->handover_command.frequency_list); dedi_convert_frequency_list ((T_frequency_list *)&sync->handover_command.frequency_list_bef_sti); } /* * forward the new configuration to layer 1 */ ma_dedi_sync_ho_req (sync); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_pre_sync_handover | +--------------------------------------------------------------------+ PURPOSE : Converts MPH_DEDICATED_REQ to MPHC_PRE_SYNC_HO_REQ. This function is used during pre-synchronous handover. */ LOCAL void dedi_pre_sync_handover (T_MPH_DEDICATED_REQ *dedicated_req) { int i; PALLOC (presync, MPHC_PRE_SYNC_HO_REQ); ALR_EM_CONFIGURE_HANDOVER(EM_HANDOVER_PRE_SYNC); memset (presync, 0, sizeof (T_MPHC_PRE_SYNC_HO_REQ)); if (dedicated_req->ch_type.h EQ 1) { /* * new channel uses frequency hopping */ presync->handover_command.channel_desc_1.chan_sel.h = 1; presync->handover_command.channel_desc_1.chan_sel.rf_channel.maio = dedicated_req->ch_type.maio; presync->handover_command.channel_desc_1.chan_sel.rf_channel.hsn = dedicated_req->ch_type.hsn; dedi_fill_ma (dedicated_req->ch_type.ma, &presync->handover_command.frequency_list); } else { /* * Avoid the union in the non-hopping case. Map arfcn to * maio and hsn. */ presync->handover_command.channel_desc_1.chan_sel.h = 0; presync->handover_command.channel_desc_1.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type.arfcn & 0xFF); presync->handover_command.channel_desc_1.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type.arfcn >> 8) & 0xFF); } /* * fill layer 1 structure with the new parameters */ alr_data->dedi_data.temp_channel = presync->handover_command.channel_desc_1.channel_type = CH_TYPE [dedicated_req->ch_type.ch]; presync->handover_command.channel_desc_1.sub_channel = SUB_TYPE [dedicated_req->ch_type.ch]; presync->handover_command.channel_desc_1.timeslot_no = dedicated_req->ch_type.tn; presync->handover_command.channel_desc_1.tsc = dedicated_req->ch_type.tsc; presync->handover_command.txpwr = cut_power_value (dedicated_req->ho_param.ho_pow, dedicated_req); presync->handover_command.ho_acc = dedicated_req->ho_param.ho_ref; presync->handover_command.starting_time.start_time_present = dedicated_req->start.v_start; presync->handover_command.starting_time.start_time.t1 = dedicated_req->start.t1; presync->handover_command.starting_time.start_time.t3 = dedicated_req->start.t3; presync->handover_command.starting_time.start_time.t2 = dedicated_req->start.t2; presync->handover_command.cell_description.ncc = (UBYTE)(dedicated_req->bsic >> 3); presync->handover_command.cell_description.bcc = (UBYTE)(dedicated_req->bsic & 7); presync->handover_command.cell_description.bcch_carrier = ARFCN_TO_L1(dedicated_req->arfcn); presync->nci = dedicated_req->ho_param.ho_nci; presync->handover_command.channel_mode_1 = dedi_channel_mode (dedicated_req->tr_para.mode, alr_data->dedi_data.temp_channel); presync->amr_configuration.noise_suppression_control_bit = dedicated_req->amr_conf.nscb; presync->amr_configuration.initial_codec_mode_indicator = dedicated_req->amr_conf.icmi; presync->amr_configuration.initial_codec_mode = dedicated_req->amr_conf.st_mode; presync->amr_configuration.active_codec_set = dedicated_req->amr_conf.acs; /* Traces only needed for IOT session */ TRACE_EVENT_P1("*AMR NSCB %d", presync->amr_configuration.noise_suppression_control_bit); TRACE_EVENT_P1("*AMR ICMI %d", presync->amr_configuration.initial_codec_mode_indicator); TRACE_EVENT_P1("*AMR ICM %d", presync->amr_configuration.initial_codec_mode); TRACE_EVENT_P1("*AMR ACS %d", presync->amr_configuration.active_codec_set); for (i=0; i<dedicated_req->amr_conf.c_cod_prop; i++) { memcpy(&presync->amr_configuration.threshold[i], &dedicated_req->amr_conf.cod_prop[i].codec_thr, 1); memcpy(&presync->amr_configuration.hysteresis[i], &dedicated_req->amr_conf.cod_prop[i].codec_hyst, 1); TRACE_EVENT_P2("*AMR threshold[%d] %d", i, presync->amr_configuration.threshold[i]); TRACE_EVENT_P2("*AMR hysteresis[%d] %d", i, presync->amr_configuration.hysteresis[i]); } presync->timing_advance_valid = TRUE; presync->timing_advance = dedicated_req->tr_para.tav; if (dedicated_req->start.v_start AND dedicated_req->ch_type2.ch NEQ NOT_PRESENT_8BIT) { if (dedicated_req->ch_type2.h EQ 1) { presync->handover_command.channel_desc_1_bef_sti.chan_sel.h = 1; presync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.maio = dedicated_req->ch_type2.maio; presync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = dedicated_req->ch_type2.hsn; dedi_fill_ma (dedicated_req->ch_type2.ma, (T_frequency_list *) &presync->handover_command.frequency_list_bef_sti); } else { /* * Avoid the union !!! */ presync->handover_command.channel_desc_1_bef_sti.chan_sel.h = 0; presync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.maio = (UBYTE)(dedicated_req->ch_type2.arfcn & 0xFF); presync->handover_command.channel_desc_1_bef_sti.chan_sel.rf_channel.hsn = (UBYTE)((dedicated_req->ch_type2.arfcn >> 8) & 0xFF); } presync->handover_command.channel_desc_1_bef_sti.channel_type = CH_TYPE [dedicated_req->ch_type2.ch]; presync->handover_command.channel_desc_1_bef_sti.sub_channel = SUB_TYPE [dedicated_req->ch_type2.ch]; presync->handover_command.channel_desc_1_bef_sti.timeslot_no = dedicated_req->ch_type2.tn; presync->handover_command.channel_desc_1_bef_sti.tsc = dedicated_req->ch_type2.tsc; } presync->handover_command.cipher_mode = dedicated_req->ciph.stat; presync->handover_command.a5_algorithm = dedicated_req->ciph.algo; memcpy (&presync->cipher_key, dedicated_req->ciph.kc, sizeof(T_cipher_key)); /* * store the new parameters as temporary configuration. */ alr_data->dedi_data.temp_bcch = dedicated_req->arfcn; memcpy (&alr_data->dedi_data.temp_channel_desc, &presync->handover_command.channel_desc_1, sizeof (T_channel_desc)); alr_data->dedi_data.temp_channel_mode = presync->handover_command.channel_mode_1; alr_data->dedi_data.temp_frequency_list = presync->handover_command.frequency_list; alr_data->dedi_data.temp_cipher_mode = presync->handover_command.cipher_mode; alr_data->dedi_data.temp_a5_algorithm = presync->handover_command.a5_algorithm; alr_data->dedi_data.temp_cipher_key = presync->cipher_key; alr_data->dedi_data.temp_power = presync->handover_command.txpwr; alr_data->dedi_data.temp_bsic = dedicated_req->bsic; alr_data->dedi_data.temp_amr_configuration = presync->amr_configuration; alr_data->dedi_data.act_mode = MODE_PRE_SYNC_HANDOVER; nc_get_fn_time (alr_data->dedi_data.temp_bcch, (ULONG *)&presync->fn_offset, (ULONG *)&presync->time_alignmnt); /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc ((T_channel_desc *)&presync->handover_command.channel_desc_1); dedi_convert_chan_desc ((T_channel_desc *)&presync->handover_command.channel_desc_1_bef_sti); dedi_convert_frequency_list (&presync->handover_command.frequency_list); dedi_convert_frequency_list ((T_frequency_list *)&presync->handover_command.frequency_list_bef_sti); } /* * forward the parameters to layer 1 */ ma_dedi_pre_sync_ho_req (presync); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_freq_redef_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_freq_redef_req from SDL Process alr_MAIN. This function is used during frequency redefinition. */ GLOBAL void dedi_freq_redef_req (T_MPH_FREQ_REDEF_REQ *freq) { PALLOC (change, MPHC_CHANGE_FREQUENCY); ALR_EM_CONFIGURE_FREQUENCY_REDEFINITION; memset (change, 0, sizeof (T_MPHC_CHANGE_FREQUENCY)); if (freq->ch_type.h EQ 1) { /* * new channel uses frequency hopping */ change->channel_desc.chan_sel.h = 1; change->channel_desc.chan_sel.rf_channel.maio = freq->ch_type.maio; change->channel_desc.chan_sel.rf_channel.hsn = freq->ch_type.hsn; dedi_fill_ma (freq->ch_type.ma, &change->frequency_list); } else { /* * Avoid the union for the non-hopping case */ change->channel_desc.chan_sel.h = 0; change->channel_desc.chan_sel.rf_channel.maio = (UBYTE)(freq->ch_type.arfcn & 0xFF); change->channel_desc.chan_sel.rf_channel.hsn = (UBYTE)((freq->ch_type.arfcn >> 8) & 0xFF); } /* * fill layer 1 structure with the parameters. */ change->channel_desc.channel_type = CH_TYPE [freq->ch_type.ch]; change->channel_desc.sub_channel = SUB_TYPE [freq->ch_type.ch]; change->channel_desc.timeslot_no = freq->ch_type.tn; change->channel_desc.tsc = freq->ch_type.tsc; change->starting_time.start_time_present = freq->start.v_start; change->starting_time.start_time.t1 = freq->start.t1; change->starting_time.start_time.t3 = freq->start.t3; change->starting_time.start_time.t2 = freq->start.t2; /* * store new values as temporary configuration */ alr_data->dedi_data.redef_channel_desc = change->channel_desc; alr_data->dedi_data.redef_frequency_list = change->frequency_list; alr_data->dedi_data.redef_starting_time = change->starting_time; /* * convert channel numbers if needed */ if (dedi_conversion_needed ()) { dedi_convert_chan_desc (&change->channel_desc); dedi_convert_frequency_list (&change->frequency_list); } /* * forward parameters to layer 1 */ ma_dedi_change_freq_req (change); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_chan_mode_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_chan_mode_req from SDL Process alr_MAIN. This function is used during channel mode modify procedure. */ GLOBAL void dedi_chan_mode_req (T_MPH_CHANNEL_MODE_REQ *ch_mode) { int i; PALLOC (chm, MPHC_CHANNEL_MODE_MODIFY_REQ); ALR_EM_CONFIGURE_CHANNEL_MODE_MODIFY; memset (chm, 0, sizeof (T_MPHC_CHANNEL_MODE_MODIFY_REQ)); /* * convert parameters */ chm->sub_channel = SUB_TYPE [ch_mode->ch]; alr_data->dedi_data.act_channel_mode = chm->channel_mode = dedi_channel_mode (ch_mode->mode, actual_channel); /* * set multirate configuration parameters */ if(ch_mode->mode EQ CM_AMR) { alr_data->dedi_data.act_amr_configuration.noise_suppression_control_bit = chm->amr_configuration.noise_suppression_control_bit = ch_mode->amr_conf.nscb; alr_data->dedi_data.act_amr_configuration.initial_codec_mode_indicator = chm->amr_configuration.initial_codec_mode_indicator = ch_mode->amr_conf.icmi; alr_data->dedi_data.act_amr_configuration.initial_codec_mode = chm->amr_configuration.initial_codec_mode = ch_mode->amr_conf.st_mode; alr_data->dedi_data.act_amr_configuration.active_codec_set = chm->amr_configuration.active_codec_set = ch_mode->amr_conf.acs; /* Traces only needed for IOT session */ TRACE_EVENT_P1("*AMR NSCB %d", chm->amr_configuration.noise_suppression_control_bit); TRACE_EVENT_P1("*AMR ICMI %d", chm->amr_configuration.initial_codec_mode_indicator); TRACE_EVENT_P1("*AMR ICM %d", chm->amr_configuration.initial_codec_mode); TRACE_EVENT_P1("*AMR ACS %d", chm->amr_configuration.active_codec_set); for (i=0; i<ch_mode->amr_conf.c_cod_prop; i++) { memcpy(&alr_data->dedi_data.act_amr_configuration.threshold[i], &ch_mode->amr_conf.cod_prop[i].codec_thr, 1); memcpy(&alr_data->dedi_data.act_amr_configuration.hysteresis[i], &ch_mode->amr_conf.cod_prop[i].codec_hyst, 1); memcpy(&chm->amr_configuration.threshold[i], &ch_mode->amr_conf.cod_prop[i].codec_thr, 1); memcpy(&chm->amr_configuration.hysteresis[i], &ch_mode->amr_conf.cod_prop[i].codec_hyst, 1); TRACE_EVENT_P2("*AMR threshold[%d] %d", i, chm->amr_configuration.threshold[i]); TRACE_EVENT_P2("*AMR hysteresis[%d] %d", i, chm->amr_configuration.hysteresis[i]); } } /* * forward new channel mode to layer 1 */ ma_dedi_chan_mode_req (chm); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_ciph_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_ciph_req from SDL Process alr_MAIN. This function is used during cipher mode setting procedure. */ GLOBAL void dedi_ciph_req (T_MPH_CIPHERING_REQ *ciph_req) { PALLOC (set_ciph, MPHC_SET_CIPHERING_REQ); ALR_EM_CONFIGURE_CIPHER_MODE_SETTING; memset (set_ciph, 0, sizeof (T_MPHC_SET_CIPHERING_REQ)); /* * convert the parameters to the layer 1 structure */ set_ciph->cipher_mode = ciph_req->ciph.stat; set_ciph->a5_algorithm = ciph_req->ciph.algo; memcpy (set_ciph->new_ciph_param.A, ciph_req->ciph.kc, sizeof(T_cipher_key)); alr_data->dedi_data.act_cipher_mode = set_ciph->cipher_mode; alr_data->dedi_data.act_a5_algorithm = set_ciph->a5_algorithm; memcpy (&alr_data->dedi_data.act_cipher_key, &set_ciph->new_ciph_param, sizeof(T_cipher_key)); /* * forward the parameters to layer 1 */ ma_dedi_ciph_req (set_ciph); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_imm_ass_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_imm_ass_cnf from SDL process Main_Control. Layer 1 confirms the configuration of a dedicated channel during the immediate assignment procedure. */ GLOBAL void dedi_imm_ass_cnf (void) { T_DEDI_DATA * d = &alr_data->dedi_data; if (GET_STATE (STATE_DEDI) EQ DEDI_IMM_ASS) { /* * the response of layer 1 is expected */ ma_clean_dedi_sys_buffer (); SET_STATE (STATE_DEDI, DEDI_ACTIVE); /* * store temporary parameters as actual channel configuration */ d->act_bcch = d->temp_bcch; d->act_channel_desc = d->temp_channel_desc; d->act_channel_mode = d->temp_channel_mode; d->act_frequency_list = d->temp_frequency_list; d->act_starting_time = d->temp_starting_time; d->act_frequency_list_bef_sti = d->temp_frequency_list_bef_sti; d->act_channel_desc_bef_sti = d->temp_channel_desc_bef_sti; d->act_pwrc = d->temp_pwrc; d->act_cipher_mode = d->temp_cipher_mode; d->act_a5_algorithm = d->temp_a5_algorithm; d->act_cipher_key = d->temp_cipher_key; d->act_power = cut_power_value (alr_data->rach_data.max_tx_pwr_ccch, NULL); /* * Send a MPH_DEDICATED_CNF to RR to * start the establishment of the * layer 2 connection. */ ma_dedi_cnf (DEDICATED_SUCCESS); } else if (GET_STATE (STATE_DEDI) EQ DEDI_IMM_ASS_RECONN) { ma_clean_dedi_sys_buffer (); dedi_chan_ass_fail(); /* act_mode will take on MODE_CHAN_ASS_FAIL */ SET_STATE (STATE_DEDI, DEDI_ACTIVE); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_change_freq_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_change_freq_cnf from SDL process Main_Control. Layer 1 confirms setting of the new parameters during a frequency redefinition procedure. */ GLOBAL void dedi_change_freq_cnf (void) { T_DEDI_DATA *d = &alr_data->dedi_data; d->act_channel_desc = d->redef_channel_desc; d->act_frequency_list = d->redef_frequency_list; memset (&d->redef_channel_desc, 0, sizeof (T_channel_desc)); memset (&d->redef_frequency_list, 0, sizeof (T_frequency_list)); memset (&d->redef_starting_time, 0, sizeof (T_starting_time)); ma_clean_dedi_sys_buffer (); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_chan_ass_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_chan_ass_cnf from SDL process Main_Control. Layer 1 confirms setting of a new channel configuration during a channel assignment procedure. */ GLOBAL void dedi_chan_ass_cnf (void) { if (GET_STATE (STATE_DEDI) EQ DEDI_ACTIVE) { if (alr_data->dedi_data.act_mode EQ MODE_CHAN_ASSIGN) { /* * the response of layer 1 was exspected in the * positive case of switching to a new channel. */ T_DEDI_DATA *d = &alr_data->dedi_data; /* * store actual parameters as old parameters */ d->old_channel = actual_channel; d->old_bcch = d->act_bcch; d->old_channel_desc = d->act_channel_desc; d->old_channel_mode = d->act_channel_mode; d->old_frequency_list = d->act_frequency_list; d->old_cipher_mode = d->act_cipher_mode; d->old_a5_algorithm = d->act_a5_algorithm; d->old_cipher_key = d->act_cipher_key; d->old_power = d->act_power; d->old_dtx_allowed = d->act_dtx_allowed; d->old_amr_configuration = d->act_amr_configuration; /* * store temporary parameters as actual channel configuration */ actual_channel = d->temp_channel; d->act_bcch = d->temp_bcch; d->act_channel_desc = d->temp_channel_desc; d->act_channel_mode = d->temp_channel_mode; d->act_frequency_list = d->temp_frequency_list; d->act_cipher_mode = d->temp_cipher_mode; d->act_a5_algorithm = d->temp_a5_algorithm; d->act_cipher_key = d->temp_cipher_key; d->act_power = d->temp_power; d->act_dtx_allowed = d->temp_dtx_allowed; d->act_amr_configuration = d->temp_amr_configuration; ma_dedi_cnf (DEDICATED_SUCCESS); } else /* * the response of layer 1 was exspected in the * negative case of switching to the old channel. */ { ma_dedi_fail_cnf (); memset (&alr_data->dedi_data.redef_channel_desc, 0, sizeof (T_channel_desc)); memset (&alr_data->dedi_data.redef_frequency_list, 0, sizeof (T_frequency_list)); memset (&alr_data->dedi_data.redef_starting_time, 0, sizeof (T_starting_time)); } } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_ho_fail_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_ho_fail_cnf from SDL process Main_Control. Layer 1 signals that the handover has failed. */ GLOBAL void dedi_ho_fail_cnf (void) { /* * recalculate all timing advances to the old bcch. */ nc_update_list (alr_data->dedi_data.act_bcch); /* * signal dedicated failure to RR */ nc_resume_dedicated(); ma_dedi_fail_cnf (); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_async_ho_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_async_ho_cnf from SDL process Main_Control. This function handles the positive end of an asynchronous handover. */ GLOBAL void dedi_async_ho_cnf (void) { T_DEDI_DATA *d = &alr_data->dedi_data; /* * All timing advances are now calculated relative * to the new dedicated channel */ nc_update_list (alr_data->dedi_data.temp_bcch); ma_clean_dedi_sys_buffer (); /* * store actual parameters as old parameters */ d->old_channel = actual_channel; d->old_bcch = d->act_bcch; d->old_bsic = alr_data->bsic; d->old_channel_desc = d->act_channel_desc; d->old_channel_mode = d->act_channel_mode; d->old_frequency_list = d->act_frequency_list; d->old_cipher_mode = d->act_cipher_mode; d->old_a5_algorithm = d->act_a5_algorithm; d->old_cipher_key = d->act_cipher_key; d->old_power = d->act_power; d->old_amr_configuration = d->act_amr_configuration; /* * store temporary parameters as actual channel configuration */ actual_channel = d->temp_channel; alr_data->serving_cell = d->act_bcch = d->temp_bcch; alr_data->sc_band = get_band(d->act_bcch); alr_data->bsic = alr_data->dedi_data.temp_bsic; d->act_channel_desc = d->temp_channel_desc; d->act_channel_mode = d->temp_channel_mode; d->act_frequency_list = d->temp_frequency_list; d->act_cipher_mode = d->temp_cipher_mode; d->act_a5_algorithm = d->temp_a5_algorithm; d->act_cipher_key = d->temp_cipher_key; d->act_power = d->temp_power; d->old_amr_configuration = d->act_amr_configuration; if (alr_data->nc_data.dtx) nc_update_dedicated (alr_data->nc_data.dtx, alr_data->nc_data.pwrc); nc_resume_dedicated(); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_sync_ho_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_sync_ho_cnf from SDL process Main_Control. This function handles the positive end of a synchronous handover. */ GLOBAL void dedi_sync_ho_cnf (void) { T_DEDI_DATA *d = &alr_data->dedi_data; /* * All timing advances are now calculated relative * to the new dedicated channel */ nc_update_list (alr_data->dedi_data.temp_bcch); ma_clean_dedi_sys_buffer (); /* * store actual parameters as old parameters */ d->old_channel = actual_channel; d->old_bcch = d->act_bcch; d->old_bsic = alr_data->bsic; d->old_channel_desc = d->act_channel_desc; d->old_channel_mode = d->act_channel_mode; d->old_frequency_list = d->act_frequency_list; d->old_cipher_mode = d->act_cipher_mode; d->old_a5_algorithm = d->act_a5_algorithm; d->old_cipher_key = d->act_cipher_key; d->old_power = d->act_power; d->old_amr_configuration = d->act_amr_configuration; /* * store temporary parameters as actual channel configuration */ actual_channel = d->temp_channel; alr_data->serving_cell = d->act_bcch = d->temp_bcch; alr_data->sc_band = get_band(d->act_bcch); alr_data->bsic = alr_data->dedi_data.temp_bsic; d->act_channel_desc = d->temp_channel_desc; d->act_channel_mode = d->temp_channel_mode; d->act_frequency_list = d->temp_frequency_list; d->act_cipher_mode = d->temp_cipher_mode; d->act_a5_algorithm = d->temp_a5_algorithm; d->act_cipher_key = d->temp_cipher_key; d->act_power = d->temp_power; d->act_amr_configuration = d->temp_amr_configuration; if (alr_data->nc_data.dtx) nc_update_dedicated (alr_data->nc_data.dtx, alr_data->nc_data.pwrc); nc_resume_dedicated(); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_pre_sync_ho_cnf | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_pre_sync_ho_cnf from SDL process Main_Control. This function handles the positive end of a pre-synchronous handover. */ GLOBAL void dedi_pre_sync_ho_cnf (void) { T_DEDI_DATA *d = &alr_data->dedi_data; /* * All timing advances are now calculated relative * to the new dedicated channel */ nc_update_list (alr_data->dedi_data.temp_bcch); ma_clean_dedi_sys_buffer (); /* * store actual parameters as old parameters */ d->old_channel = actual_channel; d->old_bcch = d->act_bcch; d->old_bsic = alr_data->bsic; d->old_channel_desc = d->act_channel_desc; d->old_channel_mode = d->act_channel_mode; d->old_frequency_list = d->act_frequency_list; d->old_cipher_mode = d->act_cipher_mode; d->old_a5_algorithm = d->act_a5_algorithm; d->old_cipher_key = d->act_cipher_key; d->old_power = d->act_power; d->old_amr_configuration = d->act_amr_configuration; /* * store temporary parameters as actual channel configuration */ actual_channel = d->temp_channel; alr_data->serving_cell = d->act_bcch = d->temp_bcch; alr_data->sc_band = get_band(d->act_bcch); alr_data->bsic = alr_data->dedi_data.temp_bsic; d->act_channel_desc = d->temp_channel_desc; d->act_channel_mode = d->temp_channel_mode; d->act_frequency_list = d->temp_frequency_list; d->act_cipher_mode = d->temp_cipher_mode; d->act_a5_algorithm = d->temp_a5_algorithm; d->act_cipher_key = d->temp_cipher_key; d->act_power = d->temp_power; d->old_amr_configuration = d->act_amr_configuration; if (alr_data->nc_data.dtx) nc_update_dedicated (alr_data->nc_data.dtx, alr_data->nc_data.pwrc); nc_resume_dedicated(); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_fill_ma | +--------------------------------------------------------------------+ PURPOSE : Fills a frequency list for layer 1. Condatīs representation is a list of USHORT with 0xFFFF as delimiter. TIīs representation is different from this. */ LOCAL void dedi_fill_ma (USHORT * ma, T_frequency_list * rf) { UBYTE i = 0; memset (rf, 0, sizeof (T_frequency_list)); while (ma[i] NEQ NOT_PRESENT_16BIT AND i < MAX_MA_CARRIER) { rf->rf_chan_no.radio_freq[i] = ma[i]; i++; rf->rf_chan_cnt++; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_tch_loop_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_tch_loop_req from SDL Process alr_MAIN. */ GLOBAL void dedi_tch_loop_req (T_MPH_TCH_LOOP_REQ *tloop) { if (tloop->tch_loop EQ NOT_PRESENT_8BIT) { /* * Open TCH loop */ ma_dedi_open_tch_loop_req (); ALR_EM_CONFIGURE_TCH_LOOP(EM_TCH_OPEN); } else { /* * Close TCH loop */ PALLOC (loop, OML1_CLOSE_TCH_LOOP_REQ); /* * Format of tch_loop in according to 3GPP 04.14, 8.1 CLOSE_TCH_LOOP_CMD */ loop->sub_channel = alr_data->dedi_data.act_channel_desc.sub_channel; loop->frame_erasure = tloop->tch_loop; ma_dedi_close_tch_loop_req (loop); ALR_EM_CONFIGURE_TCH_LOOP(EM_TCH_CLOSE); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_dai_req | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_dai_req from SDL Process alr_MAIN. RR requests configuration of the digital audio interface. */ GLOBAL void dedi_dai_req (T_MPH_DAI_REQ * dai) { if (dai->device EQ DAI_NO_TEST) { /* * Stop DAI test */ ma_dedi_stop_dai_req (); ALR_EM_CONFIGURE_DAI_TESTING(EM_DAI_STOP); } else { PALLOC (dai_req, OML1_START_DAI_TEST_REQ); /* * Start DAI test */ dai_req->tested_device = dai->device; ma_dedi_start_dai_req (dai_req); ALR_EM_CONFIGURE_DAI_TESTING(EM_DAI_START); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_channel_mode | +--------------------------------------------------------------------+ PURPOSE : The function converts the channel mode representation from Condatīs notation (equal to GSM) to TIīs values. */ LOCAL UBYTE dedi_channel_mode (UBYTE channel_mode, UBYTE channel_type) { switch (channel_mode) { case MODE_SIG_ONLY: /* signalling only */ return CM_SIGNALLING_ONLY; case MODE_SPEECH_VER1: /* Speech */ if (channel_type EQ CH_TYPE[TCH_F_INDEX]) /* TCH fullrate */ return CM_TCH_FS; /* TCH fullrate speech */ else return CM_TCH_HS; /* TCH halfrate speech */ case MODE_DATA_12_0: /* Data 12 k */ return CM_TCH_96; case MODE_DATA_6_0: /* Data 6 k */ if (channel_type EQ CH_TYPE[TCH_F_INDEX]) /* TCH fullrate */ return CM_TCH_F_48; /* TCH fullrate data 6 k */ else return CM_TCH_H_48; /* TCH halfrate data 6 k */ case MODE_DATA_3_6: /* Data 3.6 k */ if (channel_type EQ CH_TYPE[TCH_F_INDEX]) /* TCH fullrate */ return CM_TCH_F_24; /* TCH fullrate data 3.6 k */ else return CM_TCH_H_24; /* TCH halfrate data 3.6 k */ case MODE_DATA_14_5: /* Data 14.5 k */ return CM_TCH_144; /* TCH fullrate data 14.5 k*/ case MODE_SPEECH_VER2: /* enhanced full rate */ return CM_TCH_EFR; case MODE_SPEECH_VER3: /* adaptiv multi-rate */ if (channel_type EQ CH_TYPE[TCH_F_INDEX]) /* TCH fullrate */ return CM_TCH_AFS; /* TCH/AFS fullrate */ else return CM_TCH_AHS; /* TCH/AHS halfrate */ default: return CM_SIGNALLING_ONLY; /* all other set to signalling only */ } } /* +------------------------------ --------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_increment_rlt | +--------------------------------------------------------------------+ PURPOSE : A valid block has received on SACCH. The radio link counter is incremented if possible. */ GLOBAL void dedi_increment_rlt (void) { /* * increase radio link timeout counter if necessary */ if (alr_data->dedi_data.act_rlt NEQ alr_data->dedi_data.rlt) { alr_data->dedi_data.act_rlt += 2; if (alr_data->dedi_data.act_rlt > alr_data->dedi_data.rlt) alr_data->dedi_data.act_rlt = alr_data->dedi_data.rlt; #if !defined NTRACE trc_mon_counter_dedi (alr_data->dedi_data.act_rlt, alr_data->dedi_data.rlt); #endif /* (!defined NTRACE) */ ALR_EM_SET_EM_ACT_RLT; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_decrement_rlt | +--------------------------------------------------------------------+ PURPOSE : An invalid block has received on SACCH. The radio link counter is decremented. If the value is zero an error indication is send to RR. */ GLOBAL void dedi_decrement_rlt (void) { /* * invalid block received. Decrement radio link timeout counter. */ if (alr_data->dedi_data.act_rlt > 1) { #if !defined NTRACE trc_mon_counter_dedi (alr_data->dedi_data.act_rlt, alr_data->dedi_data.rlt); #endif /* (!defined NTRACE */ alr_data->dedi_data.act_rlt--; ALR_EM_SET_EM_ACT_RLT; } else { /* * radio link failure detected */ ma_error_ind (CS_RADIO_LINK_FAIL, alr_data->serving_cell); alr_data->dedi_data.act_rlt = alr_data->dedi_data.rlt; #if !defined NTRACE trc_mon_counter_dedi (alr_data->dedi_data.act_rlt, alr_data->dedi_data.rlt); #endif ALR_EM_SET_EM_ACT_RLT; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_convert_frequency_list| +--------------------------------------------------------------------+ PURPOSE : converts the channel numbers of a frequency list in the non-hopping case for DCS 1800 channel numbers in the dualband variants. */ LOCAL void dedi_convert_frequency_list (T_frequency_list * frequency_list) { UBYTE i, j; i = (UBYTE)frequency_list->rf_chan_cnt; if (i >= 64) i = 63; ALR_TRACE_DEDI ("-----------"); for (j = 0; j < i; j++) { ALR_TRACE_DEDI_FREQ_LIST (); frequency_list->rf_chan_no.radio_freq[j] = ARFCN_TO_L1 (frequency_list->rf_chan_no.radio_freq[j]); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : ALR_DEDI | | STATE : code ROUTINE : dedi_stop | +--------------------------------------------------------------------+ PURPOSE : Process signal dedi_stop from SDL process Main_Control. This signal stops all dedicated activities of ALR. */ GLOBAL void dedi_stop (void) { if (GET_STATE (STATE_DEDI) NEQ DEDI_INACTIVE) { /* * if dedicated mode is active, * the process and layer 1 are set to idle. */ SET_STATE (STATE_DEDI, DEDI_INACTIVE); ma_dedi_stop_req (); alr_data->dedi_data.act_mode = NOT_PRESENT_8BIT; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_convert_chan_desc | +--------------------------------------------------------------------+ PURPOSE : converts the channel number of a channel description in the non-hopping case for DCS 1800 channel numbers in the dualband variants. */ LOCAL void dedi_convert_chan_desc (T_channel_desc * channel_desc) { USHORT channel; if (channel_desc->chan_sel.h EQ 0) { channel = (USHORT)(channel_desc->chan_sel.rf_channel.maio + (channel_desc->chan_sel.rf_channel.hsn << 8)); channel_desc->chan_sel.rf_channel.maio = (UBYTE)(ARFCN_TO_L1(channel) & 0xFF); channel_desc->chan_sel.rf_channel.hsn = (UBYTE)(ARFCN_TO_L1(channel) >> 8); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (8403) MODULE : alr_DEDI | | STATE : code ROUTINE : dedi_conversion_needed | +--------------------------------------------------------------------+ PURPOSE : Checks whether conversion is needed or not. */ LOCAL UBYTE dedi_conversion_needed (void) { if ((std EQ STD_EGSM) OR (std EQ STD_DUAL) OR (std EQ STD_DUAL_EGSM) OR (std EQ STD_DUAL_US)) return TRUE; else return FALSE; } #endif