line source
+ − /*
+ − +-----------------------------------------------------------------------------
+ − | Project :
+ − | Modul :
+ − +-----------------------------------------------------------------------------
+ − | Copyright 2002 Texas Instruments Berlin, AG
+ − | All rights reserved.
+ − |
+ − | This file is confidential and a trade secret of Texas
+ − | Instruments Berlin, AG
+ − | The receipt of or possession of this file does not convey
+ − | any rights to reproduce or disclose its contents or to
+ − | manufacture, use, or sell anything it may describe, in
+ − | whole, or in part, without the specific written consent of
+ − | Texas Instruments Berlin, AG.
+ − +-----------------------------------------------------------------------------
+ − | Purpose : This Modul defines the functions for the data transfer
+ − | capability of the module Radio Resource.
+ − +-----------------------------------------------------------------------------
+ − */
+ −
+ − #ifndef RR_DATS_C
+ − #define RR_DATS_C
+ −
+ − #define ENTITY_RR
+ −
+ − /*==== INCLUDES ===================================================*/
+ −
+ − #include <string.h>
+ − #include <stdlib.h>
+ − #include <stddef.h> /* offsetof */
+ − #include "typedefs.h"
+ − #include "pcm.h"
+ − #include "pconst.cdg"
+ − #include "mconst.cdg"
+ − #include "message.h"
+ − #include "ccdapi.h"
+ − #include "vsi.h"
+ − #include "custom.h"
+ − #include "gsm.h"
+ − #include "prim.h"
+ − #include "cnf_rr.h"
+ − #include "tok.h"
+ − #include "rr.h"
+ − #include "em.h"
+ − #include "rr_em.h"
+ −
+ − /*==== EXPORT =====================================================*/
+ −
+ − /*==== PRIVAT =====================================================*/
+ −
+ − #define TDMA_FRAMES_PER_HYPERFRAME 2715648
+ − #define QUARTER_BITS_PER_FRAME 5000
+ −
+ − /*==== VARIABLES ==================================================*/
+ −
+ − /*==== FUNCTIONS ==================================================*/
+ −
+ − LOCAL BOOL dat_for_handover_mob_alloc(UBYTE *mob_alloc,
+ − T_LIST *hop_list_handover,
+ − T_VOID_STRUCT *mob_alloc_handover,
+ − T_DL_DATA_IND *dl_data_ind);
+ −
+ − LOCAL void dat_cr_data_multirate_conf(U8 v_multirate_conf, T_multirate_conf *multirate_conf);
+ −
+ − LOCAL void dat_dedicated_req_ch_type2(T_ch_type2 *ch_type2, T_chan_desc_before *chan_desc_before,
+ − T_LIST *hop_list_before);
+ − /*
+ − * -------------------------------------------------------------------
+ − * SIGNAL Processing functions
+ − * -------------------------------------------------------------------
+ − */
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_att_cell_selected |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Attachment process indicates that it has camped on a cell.
+ − Data transfer process changes the state and connections
+ − are possible.
+ −
+ − */
+ −
+ − GLOBAL void dat_att_cell_selected (void)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("dat_att_cell_selected()");
+ −
+ − SET_STATE (STATE_DAT, DAT_IDLE);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_att_null |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Attachment process indicates loss of coverage and connections
+ − are not longer possible.
+ −
+ − */
+ −
+ − GLOBAL void dat_att_null (void)
+ − {
+ − GET_INSTANCE_DATA;
+ −
+ − TRACE_FUNCTION ("dat_att_null()");
+ −
+ − SET_STATE (STATE_DAT, DAT_NULL);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_assign_cmd |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : The function handles the reception of a channel
+ − assignment message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_assign_cmd (T_DL_DATA_IND *dl_data_ind,
+ − T_D_ASSIGN_CMD *assign_cmd,
+ − T_LIST *hop_list_after,
+ − T_LIST *hop_list_before,
+ − T_LIST *cell_chan_desc)
+ − {
+ − GET_INSTANCE_DATA;
+ − UBYTE mob_alloc[65];
+ −
+ − PALLOC (dedicated_req, MPH_DEDICATED_REQ);
+ −
+ − TRACE_FUNCTION ("dat_for_assign_cmd()");
+ −
+ − switch (GET_STATE (STATE_DAT))
+ − {
+ − case DAT_DEDICATED:
+ − if (rr_data->ms_data.error.cs)
+ − {
+ − TRACE_EVENT_P1 ("RRC cause = %02x", rr_data->ms_data.error.cs);
+ − }
+ − /*
+ − * dynamic configuration command : IHO
+ − * Lock the DUT to the cell it is already camping -
+ − * Ignore the Channel Assignment command message and send an
+ − * Assignment failure message to the network.
+ − */
+ −
+ − if(rr_data->dyn_config.iho AND (rr_data->sc_data.ch_mode EQ CM_AMR))
+ − {
+ − TRACE_EVENT("D_ASSIGN_CMD : IHO");
+ − for_set_content_error (RRC_CHANNEL_MODE);
+ − }
+ −
+ − switch (rr_data->ms_data.error.cs)
+ − {
+ − /* case RRC_INVALID_MAN_INFO: this value is currently never set */
+ − case RRC_COND_IE_ERROR: /* 0x64 */
+ − {
+ − /*
+ − * If an mandatory info element error or a
+ − * conditional info element error has been detected,
+ − * a RR STATUS message is returned on the existing
+ − * connection before l2 is suspended
+ − */
+ − dat_send_rr_status_msg(rr_data->ms_data.error.cs);
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ − break ;
+ − }
+ −
+ − case RRC_INCORRECT_MSG: /* 0x5f */
+ − {
+ − /*
+ − * If a structurally correct message has been detected,
+ − * containing erroneous data, an Assignment Failure message
+ − * is sent back.
+ − */
+ −
+ − /*
+ − * If the ASSIGNMENT COMMAND is erroneous, then the
+ − * ASSIGNMENT FAILURE command is sent via a priority
+ − * DL_RECONNECT_REQ. This ensures DL will halt processing
+ − * anything in its buffer until it has sent this message
+ − * onto the nw.
+ − *
+ − */
+ − for_suspend_layer_2 ();
+ − dat_send_assign_fail_msg(rr_data->ms_data.error.val);
+ −
+ − RR_EM_SET_ASSIGN_FAIL_CAUSE(rr_data->ms_data.error.val);
+ −
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ − break;
+ − }
+ −
+ − default:
+ − /*
+ − * the initial check was successful and the
+ − * message is processed.
+ − *
+ − */
+ − for_suspend_layer_2 ();
+ −
+ − /*
+ − * use data of the old cell if no new data
+ − * are inserted in the message
+ − */
+ − rr_data->cr_data.ch_mode = rr_data->sc_data.ch_mode;
+ − rr_data->cr_data.ciph_on = rr_data->sc_data.ciph_on;
+ − rr_data->cr_data.algo = rr_data->sc_data.algo;
+ − rr_data->cr_data.cd.v_cell_chan_desc =
+ − rr_data->sc_data.cd.v_cell_chan_desc;
+ − memcpy (&rr_data->cr_data.cd.cell_chan_desc,
+ − &rr_data->sc_data.cd.cell_chan_desc,
+ − sizeof (T_LIST));
+ −
+ − /*
+ − * if AMR is supported set the default values
+ − * to the current serving cell values.
+ − */
+ − if(rr_data->sc_data.ch_mode EQ CM_AMR)
+ − {
+ − memcpy(&rr_data->cr_data.amr_conf,
+ − &rr_data->sc_data.amr_conf,
+ − sizeof (T_multirate_conf));
+ − }
+ − else {
+ − /*
+ − * AMR is not supported, therefore set some dummy values. This is necessary because
+ − * the later Layer1 configuration must include an AMR configuration!!
+ − */
+ − memset(&rr_data->cr_data.amr_conf, 0, sizeof (T_multirate_conf));
+ − }
+ −
+ − if (assign_cmd->v_cell_chan_desc)
+ − {
+ − /*
+ − * If the message contains a cell channel description
+ − * use the new one.
+ − */
+ − memcpy (&rr_data->cr_data.cd.cell_chan_desc,
+ − cell_chan_desc,
+ − sizeof (T_LIST));
+ − rr_data->cr_data.cd.v_cell_chan_desc = WITH_CHANGED_CONTENT;
+ − }
+ −
+ − if (assign_cmd->v_chan_mode)
+ − /*
+ − * if the message contains a channel mode, use the new one.
+ − */
+ − rr_data->cr_data.ch_mode = assign_cmd->chan_mode;
+ −
+ − /*
+ − * If AMR is signalled check if new multi-rate speech codec is part of the assignment cmd
+ − * otherwise use default values set earlier.
+ − */
+ −
+ − /* Implements RR Clone findings #9 */
+ − dat_cr_data_multirate_conf(assign_cmd->v_multirate_conf,&assign_cmd->multirate_conf);
+ −
+ −
+ − if (assign_cmd->v_ciph_mode_set)
+ − {
+ − /*
+ − * If ciphering is defined in the message, handle it.
+ − */
+ − rr_data->cr_data.ciph_on = assign_cmd->ciph_mode_set.sc;
+ − rr_data->cr_data.algo = assign_cmd->ciph_mode_set.algo_ident;
+ −
+ − if (rr_data->cr_data.ciph_on EQ CIPH_ON AND
+ − rr_data->sc_data.ciph_received EQ FALSE)
+ − {
+ − /*
+ − * if ciphering is not active, but set in the message
+ − * this is a failure and the configuration is aborted.
+ − * Instead the reconnection on the old channel is started.
+ − */
+ − dat_send_assign_fail_msg(RRC_PROT_UNSPECIFIED);
+ −
+ − RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_PROT_UNSPECIFIED);
+ −
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ −
+ − return;
+ − }
+ − }
+ −
+ − if (assign_cmd->chan_desc.hop EQ 1 AND
+ − assign_cmd->v_mob_alloc_after)
+ − {
+ − if (rr_data->cr_data.cd.v_cell_chan_desc EQ NO_CONTENT)
+ − {
+ − /*
+ − * If the new channel needs hopping, but there is no
+ − * cell channel description available, the configuration
+ − * is aborted due to a conditional error.
+ − * Instead the reconnection on the old channel is started.
+ − */
+ − dat_send_assign_fail_msg(RRC_NO_CELL_ALLOC);
+ −
+ − RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_NO_CELL_ALLOC);
+ −
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ − return;
+ − }
+ −
+ − /*
+ − * if the message contains a mobile allocation,
+ − * build a list of 1-bits from the bitmap.
+ − */
+ − att_bits_to_byte (mob_alloc,
+ − assign_cmd->mob_alloc_after.c_mac,
+ − assign_cmd->mob_alloc_after.mac);
+ −
+ − /*
+ − * create a hopping list from mobile allocation and cell channel
+ − * description
+ − */
+ − if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc,
+ − hop_list_after,
+ − mob_alloc))
+ − {
+ − dat_send_assign_fail_msg(RRC_FREQ_NOT_IMPL);
+ −
+ − RR_EM_SET_ASSIGN_FAIL_CAUSE(RRC_FREQ_NOT_IMPL);
+ −
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ − return;
+ − }
+ − }
+ −
+ − /*
+ − * clean primitive to layer 1
+ − */
+ − memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ));
+ −
+ − dedicated_req->mod = MODE_CHAN_ASSIGN;
+ −
+ − rr_data->cr_data.chan_desc = assign_cmd->chan_desc;
+ −
+ − /*
+ − * Set Channel Type
+ − */
+ − dedicated_req->ch_type.ch = assign_cmd->chan_desc.chan_type;
+ − dedicated_req->ch_type.tn = assign_cmd->chan_desc.tn;
+ − dedicated_req->ch_type.tsc = assign_cmd->chan_desc.tsc;
+ − dedicated_req->ch_type.h = assign_cmd->chan_desc.hop;
+ − if (assign_cmd->chan_desc.hop EQ H_NO)
+ − {
+ − dedicated_req->ch_type.arfcn = assign_cmd->chan_desc.arfcn;
+ − }
+ − else
+ − {
+ − dedicated_req->ch_type.maio = assign_cmd->chan_desc.maio;
+ − dedicated_req->ch_type.hsn = assign_cmd->chan_desc.hsn;
+ −
+ − /* CSI-LLD section:4.1.1.11
+ − * This function Updates the black list with the MA list received
+ − * inthe assignment command
+ − */
+ − cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list_after);
+ −
+ − srv_create_list (hop_list_after, dedicated_req->ch_type.ma,
+ − MAX_MA_CHANNELS, TRUE, 0);
+ − }
+ −
+ − /*
+ − * set initial power
+ − */
+ − dedicated_req->tr_para.power = assign_cmd->pow_cmd.pow;
+ −
+ − /*
+ − * set starting time if available.
+ − */
+ − if (assign_cmd->v_start_time)
+ − {
+ − dedicated_req->start.v_start = TRUE;
+ − dedicated_req->start.t1 = assign_cmd->start_time.t1;
+ − dedicated_req->start.t2 = assign_cmd->start_time.t2;
+ − dedicated_req->start.t3 = assign_cmd->start_time.t3;
+ − }
+ −
+ − /*
+ − * Setting of before starting time elements !
+ − */
+ − if (assign_cmd->v_chan_desc_before EQ FALSE)
+ − dedicated_req->ch_type2.ch = NOT_PRESENT_8BIT;
+ − else
+ − {
+ − if (assign_cmd->v_mob_alloc_before)
+ − {
+ − att_bits_to_byte (mob_alloc,
+ − assign_cmd->mob_alloc_before.c_mac,
+ − assign_cmd->mob_alloc_before.mac);
+ − if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc,
+ − hop_list_before,
+ − mob_alloc))
+ − {
+ − dat_send_assign_fail_msg(RRC_FREQ_NOT_IMPL);
+ −
+ − RR_EM_SET_ASSIGN_FAIL_CAUSE( RRC_FREQ_NOT_IMPL);
+ −
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ − return;
+ − }
+ − }
+ −
+ − dat_dedicated_req_ch_type2(&dedicated_req->ch_type2, &assign_cmd->chan_desc_before,
+ − hop_list_before );
+ −
+ − }
+ −
+ −
+ − /*
+ − * set dtx depending on the channel type (halfrate or fullrate)
+ − */
+ −
+ − if (dedicated_req->ch_type.ch EQ 2 OR
+ − dedicated_req->ch_type.ch EQ 3)
+ − dedicated_req->tr_para.dtx =
+ − rr_data->sc_data.cd.dtx = rr_data->sc_data.cd.dtx_half;
+ − else
+ − dedicated_req->tr_para.dtx =
+ − rr_data->sc_data.cd.dtx = rr_data->sc_data.cd.dtx_full;
+ −
+ − dedicated_req->arfcn = rr_data->nc_data[SC_INDEX].arfcn;
+ − dedicated_req->tr_para.rlt = rr_data->sc_data.cd.cell_options.rlt;
+ − dedicated_req->tr_para.pwrc = rr_data->sc_data.cd.cell_options.pow_ctrl;
+ − dedicated_req->tr_para.mode = rr_data->cr_data.ch_mode;
+ −
+ − /*
+ − * Set multi-rate speech codec
+ − */
+ − dedicated_req->amr_conf.nscb = rr_data->cr_data.amr_conf.nscb;
+ − dedicated_req->amr_conf.icmi = rr_data->cr_data.amr_conf.icmi;
+ − dedicated_req->amr_conf.st_mode = rr_data->cr_data.amr_conf.st_mode;
+ − dedicated_req->amr_conf.acs = rr_data->cr_data.amr_conf.set_amr;
+ −
+ − /*
+ − * valid flag for the threshold and hystersis values. amr_conf.c_cod_prop
+ − * defines the number of threshold and hystersis values.
+ − */
+ − dedicated_req->amr_conf.v_cod_prop = rr_data->cr_data.amr_conf.v_cod_prop;
+ −
+ − if(dedicated_req->amr_conf.v_cod_prop)
+ − {
+ − int i;
+ − dedicated_req->amr_conf.c_cod_prop = rr_data->cr_data.amr_conf.c_cod_prop;
+ − for(i=0; i<dedicated_req->amr_conf.c_cod_prop; i++)
+ − memcpy(&dedicated_req->amr_conf.cod_prop[i],
+ − &rr_data->cr_data.amr_conf.cod_prop[i],
+ − sizeof(T_cod_prop));
+ − }
+ −
+ − if (rr_data->cr_data.ciph_on)
+ − {
+ − /*
+ − * set cipher parameter if available.
+ − */
+ − dedicated_req->ciph.stat = rr_data->cr_data.ciph_on;
+ − dedicated_req->ciph.algo = rr_data->cr_data.algo;
+ − memcpy (dedicated_req->ciph.kc, rr_data->ms_data.kc, KC_STRING_SIZE);
+ − }
+ −
+ − RR_EM_GET_HOPPING_CHANNEL (dedicated_req->ch_type.ma, dedicated_req->ch_type2.ma,
+ − dedicated_req->start.v_start,dedicated_req->ch_type2.maio);
+ −
+ − EM_ASSIGNMENT_RECEIVED;
+ −
+ − /*
+ − * configure layer 1
+ − */
+ − SET_STATE (STATE_DAT, DAT_CHAN_ASS);
+ − PSENDX (PL, dedicated_req);
+ − PFREE (dl_data_ind);
+ − return;
+ − }
+ − break;
+ −
+ − default:
+ − PFREE (dedicated_req);
+ − PFREE (dl_data_ind);
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_chan_mod |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : The function handles a received channel mode modify message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_chan_mod (T_DL_DATA_IND *dl_data_ind,
+ − T_D_CHAN_MOD *chan_mod)
+ − {
+ − GET_INSTANCE_DATA;
+ − MCAST (chan_mod_ack, U_CHAN_MOD_ACK);
+ −
+ − TRACE_FUNCTION ("dat_for_chan_mod()");
+ −
+ − if (rr_data->ms_data.error.cs EQ 0)
+ − {
+ − /*
+ − * the check in the formatter indicates no problems
+ − * store new channel mode.
+ − */
+ − rr_data->sc_data.ch_mode = chan_mod->chan_mode;
+ −
+ − /*
+ − * the channel mode modify message contains a multi-rate configuration IEI
+ − */
+ − if( chan_mod->v_multirate_conf AND (chan_mod->chan_mode EQ CM_AMR) )
+ − {
+ − int i;
+ − rr_data->sc_data.amr_conf.mr_vers = chan_mod->multirate_conf.mr_vers;
+ − rr_data->sc_data.amr_conf.nscb = chan_mod->multirate_conf.nscb;
+ − rr_data->sc_data.amr_conf.icmi = chan_mod->multirate_conf.icmi;
+ − rr_data->sc_data.amr_conf.st_mode = chan_mod->multirate_conf.st_mode;
+ − rr_data->sc_data.amr_conf.set_amr = chan_mod->multirate_conf.set_amr;
+ −
+ − rr_data->sc_data.amr_conf.v_cod_prop = chan_mod->multirate_conf.v_cod_prop;
+ − if(rr_data->sc_data.amr_conf.v_cod_prop)
+ − {
+ − rr_data->sc_data.amr_conf.c_cod_prop = chan_mod->multirate_conf.c_cod_prop;
+ − for (i=0; i< rr_data->sc_data.amr_conf.c_cod_prop; i++)
+ − memcpy(&rr_data->sc_data.amr_conf.cod_prop[i], &chan_mod->multirate_conf.cod_prop[i], sizeof(T_cod_prop));
+ − }
+ − }
+ −
+ − /*
+ − * configure layer 1
+ − */
+ − dat_code_mph_chan_mode_req (chan_mod);
+ −
+ − EM_CHANNEL_MODE_MODIFY;
+ −
+ − /*
+ − * indicate new channel mode to MM
+ − */
+ − dat_code_channel_mode_to_mm ();
+ − }
+ −
+ − {
+ − /*
+ − * build the answer to the network
+ − * (channel mode modify acknowledge message)
+ − */
+ − PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CHAN_MOD_ACK);
+ −
+ − /*
+ − * set channel type and SAPI
+ − */
+ − dat_code_prr_channel (&dl_data_req->ch_type,
+ − &dl_data_req->sapi,
+ − rr_data->sc_data.chan_desc.chan_type);
+ −
+ − chan_mod_ack->msg_type = U_CHAN_MOD_ACK;
+ − memcpy (&chan_mod_ack->chan_desc,
+ − &rr_data->sc_data.chan_desc,
+ − sizeof (T_chan_desc));
+ −
+ − /*
+ − * set the current channel mode. if the new
+ − * channel mode is supported by the MS, the new
+ − * one is returned, else it is the previous one
+ − * and layer 1 was not re-configured.
+ − */
+ − chan_mod_ack->chan_mode = rr_data->sc_data.ch_mode;
+ −
+ − for_dat_data_req (dl_data_req);
+ −
+ − EM_CHANNEL_MODE_MODIFY_ACK;
+ − }
+ −
+ − PFREE(dl_data_ind);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_chan_rel |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a channel release message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_chan_rel (T_DL_DATA_IND *dl_data_ind,
+ − T_D_CHAN_REL *chan_rel)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("dat_for_chan_rel()");
+ −
+ − if (GET_STATE (STATE_DAT) NEQ DAT_NULL)
+ − {
+ − /*
+ − * disconnect layer 2 link
+ − */
+ − dat_disconnect_link (CAUSE_MAKE (DEFBY_STD,
+ − ORIGSIDE_NET,
+ − RR_ORIGINATING_ENTITY,
+ − chan_rel->rr_cause));
+ −
+ − #ifdef GPRS
+ − if (chan_rel->v_gprs_resum)
+ − {
+ − rr_data->gprs_data.gprs_resump = chan_rel->gprs_resum.res_ack;
+ − }
+ − /*
+ − o if the element is not available but we have send a susp_req
+ − a resumption failure has occured (gprs_resump was already set
+ − on tx of the suspension request)
+ − o if the element is not present and we have not send a suspension
+ − request there is no resumption failure.
+ − o For Ericsson we have to do a RAU after every CS call even if the
+ − call started on a GSM-only cell and we did not send a suspension request */
+ − else
+ − if(att_gprs_is_avail())
+ − rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_NOT_ACK;
+ − #endif
+ −
+ − if (chan_rel->v_ba_range)
+ − {
+ − /*
+ − * convert RR_BA_RANGE to BCCH-LIST and
+ − * send it with RR SYNC IND to MM
+ − */
+ − dat_code_prr_bcch_info (chan_rel->v_ba_range,
+ − &chan_rel->ba_range);
+ − }
+ −
+ − EM_CHANNEL_RELEASE;
+ − }
+ − PFREE (dl_data_ind);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_class_enq |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a classmark enquiry message.
+ −
+ − */
+ −
+ − #ifdef REL99
+ − GLOBAL void dat_for_class_enq (T_DL_DATA_IND *dl_data_ind,
+ − T_D_CLASS_ENQ *class_enq)
+ − #else
+ − GLOBAL void dat_for_class_enq (T_DL_DATA_IND *dl_data_ind)
+ − #endif
+ − {
+ − TRACE_FUNCTION ("dat_for_class_enq()");
+ −
+ −
+ − if (dat_check_error_flag (SEND_RR_STATUS))
+ − {
+ − /*
+ − * The syntax check indicates no problems, then
+ − * process the message.
+ − *
+ − * The MS returns a classmark change message.
+ − */
+ − /* Implements RR Clone findings #15 */
+ − #ifdef REL99
+ − /*Perform checks on classmark enquiry mask IE, if present*/
+ − if ((class_enq->v_class_enq_mask EQ FALSE) OR
+ − ((class_enq->v_class_enq_mask EQ TRUE) AND
+ − (class_enq->class_enq_mask.class_req EQ CLASS_CHANGE_REQ) ) )
+ − #endif
+ − dat_class_chng_data_req();
+ − }
+ −
+ −
+ − EM_CLASSMARK_ENQUIRY;
+ −
+ − PFREE (dl_data_ind);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : send_mph_tch_loop_req |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Send the L1 primitive for close TCH loop.
+ −
+ − */
+ −
+ − static void send_mph_tch_loop_req(T_DL_DATA_IND * dl_data_ind,
+ − UBYTE loop_command)
+ − {
+ − /*
+ − * configure layer 1
+ − */
+ − PREUSE (dl_data_ind, loop_req, MPH_TCH_LOOP_REQ);/* T_MPH_TCH_LOOP_REQ */
+ − loop_req->tch_loop = loop_command;
+ − PSENDX (PL, loop_req);
+ − }
+ −
+ − /*
+ − +-----------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : send_close_tch_loop_ack_to_nw |
+ − +-----------------------------------------------------------------------+
+ −
+ − PURPOSE : Send the CLOSE TCH LOOP ACK message to the network.
+ −
+ − */
+ − static void send_close_tch_loop_ack_to_nw(void)
+ − {
+ − GET_INSTANCE_DATA;
+ − /*
+ − * if the TCH loop is open and a TCH is assigned
+ − */
+ −
+ − PALLOC_SDU (data_req, DL_DATA_REQ, 2*BITS_PER_BYTE);
+ − /*
+ − * set channel type and sapi for the response to the network
+ − */
+ − dat_code_prr_channel (&data_req->ch_type,
+ − &data_req->sapi,
+ − rr_data->sc_data.chan_desc.chan_type);
+ −
+ − /*
+ − * code the message without CCD
+ − */
+ − data_req->sdu.l_buf = 16;
+ − data_req->sdu.o_buf = ENCODE_OFFSET;
+ − data_req->sdu.buf [0] = 0;
+ − /*lint -e415 -e416 Likely access of out-of-bounds pointer*/
+ − data_req->sdu.buf [1] = 0;
+ − data_req->sdu.buf [2] = 0;
+ − data_req->sdu.buf [3] = 0x0F; /* TI=0, PD = TST */
+ − data_req->sdu.buf [4] = 0x01; /* MT = Close TCH Ack */
+ − /*lint +e415 +e416 Likely access of out-of-bounds pointer*/
+ − TRACE_EVENT ("DL_DATA_REQ (RR message)");
+ −
+ − EM_TCH_LOOP_CLOSED;
+ −
+ − PSENDX (DL, data_req);
+ − }
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_close_loop_cmd |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a TCH Close Loop Command message.
+ −
+ − */
+ −
+ − static const UBYTE LOOP_TYPE [32] =
+ − { /* C B A Z Y */
+ − 0x00, /* 0 0 0 0 0 -> Type A */
+ − 0x01, /* 0 0 0 0 1 -> Type B */
+ − 0x02, /* 0 0 0 1 0 -> Type C */
+ − 0x02, /* 0 0 0 1 1 -> Type C */
+ − 0x03, /* 0 0 1 0 0 -> Type D */
+ − 0x03, /* 0 0 1 0 1 -> Type D */
+ − 0x03, /* 0 0 1 1 0 -> Type D */
+ − 0x03, /* 0 0 1 1 1 -> Type D */
+ − 0x04, /* 0 1 0 0 0 -> Type E */
+ − 0x04, /* 0 1 0 0 1 -> Type E */
+ − 0x04, /* 0 1 0 1 0 -> Type E */
+ − 0x04, /* 0 1 0 1 1 -> Type E */
+ − 0x05, /* 0 1 1 0 0 -> Type F */
+ − 0x05, /* 0 1 1 0 1 -> Type F */
+ − 0x05, /* 0 1 1 1 0 -> Type F */
+ − 0x05, /* 0 1 1 1 1 -> Type F */
+ − 0xFF, /* 1 0 0 0 0 -> Not valid */
+ − 0xFF, /* 1 0 0 0 1 -> Not valid */
+ − 0xFF, /* 1 0 0 1 0 -> Not valid */
+ − 0xFF, /* 1 0 0 1 1 -> Not valid */
+ − 0xFF, /* 1 0 1 0 0 -> Not valid */
+ − 0xFF, /* 1 0 1 0 1 -> Not valid */
+ − 0xFF, /* 1 0 1 1 0 -> Not valid */
+ − 0xFF, /* 1 0 1 1 1 -> Not valid */
+ − 0xFF, /* 1 1 0 0 0 -> Not valid */
+ − 0xFF, /* 1 1 0 0 1 -> Not valid */
+ − 0xFF, /* 1 1 0 1 0 -> Not valid */
+ − 0xFF, /* 1 1 0 1 1 -> Not valid */
+ − 0x06, /* 1 1 1 0 0 -> Type I */
+ − 0x06, /* 1 1 1 0 1 -> Type I */
+ − 0x06, /* 1 1 1 1 0 -> Type I */
+ − 0x06 /* 1 1 1 1 1 -> Type I */
+ − };
+ −
+ −
+ − GLOBAL void dat_for_close_loop_cmd (T_DL_DATA_IND * dl_data_ind,
+ − UBYTE subchannel)
+ − {
+ − GET_INSTANCE_DATA;
+ − UBYTE loop_command = NOT_PRESENT_8BIT;
+ −
+ − TRACE_FUNCTION ("dat_for_close_loop_cmd()");
+ −
+ − if (dat_test_sim_available () OR !dat_check_sim_available () )
+ − {
+ − /*
+ − * only if a test SIM card is inserted
+ − */
+ − if ((rr_data->tch_loop_subch EQ NOT_PRESENT_8BIT) AND
+ − rr_data->sc_data.chan_desc.chan_type < CH_SDCCH_4_0)
+ − {
+ − switch ((loop_command = LOOP_TYPE [(subchannel>>1) & 0x1F]))
+ − {
+ − case TCH_LOOP_C: /* Loop C */
+ − /* first send ACK msg, then activate L1 */
+ − send_close_tch_loop_ack_to_nw();
+ − /*
+ − * Delay to allow L1/HW to switch
+ − */
+ − vsi_t_sleep (VSI_CALLER DELAY_CLOSE_TCH_LOOP_ACK);
+ − send_mph_tch_loop_req(dl_data_ind, loop_command);
+ − /* will be needed when TCH Open Loop Command will be received */
+ − rr_data->tch_loop_subch = loop_command;
+ − break;
+ − case TCH_LOOP_I: /* Loop I */
+ − if (rr_data->sc_data.ch_mode NEQ CM_AMR)
+ − {
+ − PFREE (dl_data_ind);
+ − break;
+ − }
+ − case TCH_LOOP_A:
+ − case TCH_LOOP_B:
+ − case TCH_LOOP_D:
+ − case TCH_LOOP_E:
+ − case TCH_LOOP_F:
+ − /* Loop A, B, D, E, F, I */
+ − send_mph_tch_loop_req(dl_data_ind, loop_command);
+ − /*
+ − * Delay to allow L1/HW to switch
+ − */
+ − vsi_t_sleep (VSI_CALLER DELAY_CLOSE_TCH_LOOP_ACK);
+ − send_close_tch_loop_ack_to_nw();
+ − /* will be needed when TCH Open Loop Command will be received */
+ − rr_data->tch_loop_subch = loop_command;
+ − break;
+ − default :
+ − TRACE_EVENT_P1("TCH_LOOP_CLOSE_CMD : wrong subchannel (%x)", subchannel);
+ − PFREE (dl_data_ind);
+ − break;
+ − }
+ − }
+ − else
+ − {
+ − PFREE (dl_data_ind);
+ − }
+ − }
+ − else
+ − {
+ − PFREE (dl_data_ind);
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_test_interface |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a Test-Interface message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_test_interface (T_DL_DATA_IND * dl_data_ind,
+ − UBYTE tested_device)
+ − {
+ − TRACE_FUNCTION ("dat_for_test_interface()");
+ −
+ − if (dat_test_sim_available ())
+ − {
+ − /*
+ − * Only if a test SIM card is inserted
+ − *
+ − * then configure layer 1
+ − */
+ − PREUSE (dl_data_ind, dai_req, MPH_DAI_REQ); /* T_MPH_DAI_REQ */
+ −
+ − dai_req->device = tested_device;
+ −
+ − EM_TEST_INTERFACE;
+ −
+ − PSENDX (PL, dai_req);
+ − }
+ − else
+ − {
+ − /*
+ − * else ignore the message
+ − */
+ − PFREE (dl_data_ind);
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_ciph_cmd |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a cipher mode command message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_ciph_cmd (T_DL_DATA_IND *dl_data_ind,
+ − T_D_CIPH_CMD *ciph_cmd)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("dat_for_cyph_cmd()");
+ −
+ − if (dat_check_error_flag (SEND_RR_STATUS))
+ − {
+ − /*
+ − * the check in the formatter was successful
+ − */
+ − if (
+ − ((rr_data->sc_data.ciph_on EQ CIPH_ON) AND
+ − (ciph_cmd->ciph_mode_set.sc EQ START_CIPH_YES))
+ − OR
+ − ((ciph_cmd->ciph_mode_set.sc EQ START_CIPH_YES) AND
+ − (rr_data->dyn_config.nkc EQ 0 AND rr_data->ms_data.cksn > 6))
+ − )
+ − {
+ − /*
+ − * Respond with RR Status in 2 cases
+ − *
+ − * 1: if NW re-enables ciphering
+ − * 2: if network has enabled ciphering "and" no valid ciphering key
+ − * is available (and user specific handling of cksn is
+ − * disabled (nck==0)).
+ − * If network has not enabled ciphering, then ciphering key
+ − * value is not checked
+ − */
+ − dat_send_rr_status_msg(RRC_PROT_UNSPECIFIED);
+ − }
+ − else
+ − {
+ − MCAST (ciph_comp, U_CIPH_COMP);
+ − PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CIPH_COMP);
+ −
+ − /*
+ − * set channel type and SAPI for response to the network
+ − */
+ − dat_code_prr_channel (&dl_data_req->ch_type,
+ − &dl_data_req->sapi,
+ − rr_data->sc_data.chan_desc.chan_type);
+ −
+ − /*
+ − * store cipher parameter
+ − */
+ − rr_data->sc_data.ciph_on = ciph_cmd->ciph_mode_set.sc;
+ −
+ − rr_data->sc_data.algo = ciph_cmd->ciph_mode_set.algo_ident;
+ − rr_data->sc_data.ciph_received = TRUE;
+ − memcpy (rr_data->ms_data.kc, rr_data->ms_data.new_kc, KC_STRING_SIZE);
+ −
+ − /*
+ − * configure layer 1
+ − */
+ −
+ − if ( rr_data->ms_data.cksn <= 6 )
+ − {
+ − dat_code_mph_ciphering_req (rr_data->sc_data.ciph_on,
+ − rr_data->sc_data.algo,
+ − rr_data->ms_data.kc);
+ − }
+ − else
+ − {
+ − dat_code_mph_ciphering_req (CIPH_OFF, 0, NULL);
+ − }
+ −
+ − if (ciph_cmd->ciph_res.cr EQ INC_IMEISV_YES)
+ − {
+ − /*
+ − * if the response shall contain the IMEI, fill it in.
+ − */
+ − ciph_comp->v_mob_ident = TRUE;
+ − memcpy (&ciph_comp->mob_ident, &rr_data->ms_data.imei,
+ − sizeof (T_mob_ident));
+ − }
+ − else
+ − {
+ − ciph_comp->v_mob_ident = FALSE;
+ − }
+ −
+ − ciph_comp->msg_type = U_CIPH_COMP;
+ −
+ − /*
+ − * send response to the network
+ − */
+ − for_dat_data_req (dl_data_req);
+ −
+ − /*
+ − * Indicate changed ciphering mode to MM.
+ − * Any supression of ciphering information to MMI/ACI will
+ − * be done by the upper layers.
+ − */
+ − dat_code_ciphering_to_mm (rr_data->sc_data.ciph_on);
+ −
+ − EM_CIPHERING_CMD;
+ − }
+ − }
+ −
+ − PFREE (dl_data_ind);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_freq_redef |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a frequency redefinition message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_freq_redef (T_DL_DATA_IND *dl_data_ind,
+ − T_D_FREQ_REDEF *freq_redef,
+ − T_LIST *cell_chan_desc)
+ − {
+ − GET_INSTANCE_DATA;
+ − T_start start;
+ − T_LIST hop_list;
+ − UBYTE mob_alloc[65];
+ −
+ − TRACE_FUNCTION ("dat_for_freq_redef()");
+ −
+ − if (dat_check_error_flag (SEND_RR_STATUS))
+ − {
+ − /*
+ − * the check in the formatter has passed
+ − */
+ − memcpy (&rr_data->sc_data.chan_desc,
+ − &freq_redef->chan_desc,
+ − sizeof (T_chan_desc));
+ −
+ − /*
+ − * convert the mobile allocation from the message format
+ − * to a list of 1-bit positions to build the hopping list.
+ − */
+ − att_bits_to_byte (mob_alloc,
+ − freq_redef->mob_alloc.c_mac,
+ − freq_redef->mob_alloc.mac);
+ −
+ − dat_set_last_used_channel (&rr_data->sc_data.chan_desc);
+ −
+ − if (freq_redef->v_cell_chan_desc)
+ − {
+ − /*
+ − * if the message contains a new cell channel description
+ − * copy the new one, else use the old one.
+ − */
+ − srv_copy_list (&rr_data->sc_data.cd.cell_chan_desc,
+ − cell_chan_desc,
+ − sizeof (T_LIST));
+ − rr_data->sc_data.cd.v_cell_chan_desc = WITH_CONTENT;
+ − }
+ −
+ − if (rr_data->sc_data.cd.v_cell_chan_desc NEQ NO_CONTENT)
+ − {
+ − /*
+ − * create the hopping list from cell channel description and
+ − * mobile allocation.
+ − */
+ − if(! srv_create_chan_mob_alloc (&rr_data->sc_data.cd.cell_chan_desc,
+ − &hop_list,
+ − mob_alloc))
+ − {
+ −
+ − U32 st = 51*((26 + freq_redef->start_time.t3 - freq_redef->start_time.t2 )%26)
+ − + freq_redef->start_time.t3 + 1326*freq_redef->start_time.t1;
+ − U32 ct = dl_data_ind->fn%STARTING_TIME_INTERVAL;
+ −
+ − #if defined(_SIMULATION_)
+ − TRACE_EVENT_WIN_P5 ("D_FREQ_REDEF: t1=%u t2=%u t3=%u, st=%u, ct=%u",
+ − freq_redef->start_time.t1, freq_redef->start_time.t2,
+ − freq_redef->start_time.t3, st, ct);
+ − TRACE_EVENT_WIN_P2 ("D_FREQ_REDEF: (st-ct) %u <= %u ?",
+ − ((STARTING_TIME_INTERVAL + st - ct)%STARTING_TIME_INTERVAL), STARTING_TIME_INTERVAL1);
+ − #endif
+ −
+ − if(((STARTING_TIME_INTERVAL + st - ct)%STARTING_TIME_INTERVAL) <= STARTING_TIME_INTERVAL1)
+ − {
+ − /*XXX this should only be done if the starting time has not yet expired */
+ − dat_send_rr_status_msg(RRC_FREQ_NOT_IMPL);
+ − }
+ − else
+ − {
+ − /*
+ − * 3GPP TS 04.18, section 3.4.5.1
+ − * Frequency redefinition procedure, abnormal cases:
+ − * If the mobile station receives a FREQUENCY REDEFINITION message
+ − * with a Mobile Allocation IE indexing frequencies that are not all
+ − * in one band and a Starting Time IE indicating a time that has
+ − * elapsed, then the mobile station shall locally abort the radio
+ − * connection and, if permitted, attempt Call Re-establishment.
+ − *
+ − * Inform MM about a radio link failure and start cell reselection.
+ − * It would be possible to create a new cause but RLF does exactly
+ − * what is needed and this is really 'some kind of' RLF.
+ − */
+ − rr_data->net_lost = TRUE;
+ − att_code_rr_abort_ind (RRCS_ABORT_RAD_LNK_FAIL);
+ − att_stop_dedicated();
+ − }
+ − }
+ − else
+ − {
+ − /*
+ − * copy start time for the new hopping list
+ − */
+ − start.v_start = TRUE;
+ − start.t1 = freq_redef->start_time.t1;
+ − start.t2 = freq_redef->start_time.t2;
+ − start.t3 = freq_redef->start_time.t3;
+ −
+ − /*
+ − * configure layer 1 with the new hopping list
+ − */
+ − dat_code_mph_freq_redef_req (&start,
+ − &hop_list);
+ − }
+ − }
+ − }
+ −
+ − PFREE (dl_data_ind);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_handov_cmd |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a handover command message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_handov_cmd (T_DL_DATA_IND *dl_data_ind,
+ − T_D_HANDOV_CMD *handov_cmd,
+ − T_LIST *cell_chan_desc,
+ − T_LIST *hop_list_after,
+ − T_LIST *hop_list_before)
+ − {
+ − GET_INSTANCE_DATA;
+ − UBYTE mob_alloc [65];
+ −
+ − TRACE_FUNCTION ("dat_for_handov_cmd()");
+ −
+ − rr_data->dyn_config.fho = 0;
+ −
+ − /*
+ − * dynamic configuration command : IHO
+ − * Lock the DUT to the cell it is already camping -
+ − * Ignore the Handover command message and send an
+ − * Handover failure message to the network.
+ − */
+ −
+ − if(rr_data->dyn_config.iho AND (rr_data->sc_data.ch_mode EQ CM_AMR))
+ − {
+ − TRACE_EVENT("D_HANDOV_CMD : IHO");
+ − for_set_content_error (RRC_CHANNEL_MODE);
+ − }
+ −
+ − switch (rr_data->ms_data.error.cs)
+ − {
+ − /*
+ − * in case of mandatory info element error,
+ − * the message is returned immediately.
+ − */
+ − /* case RRC_INVALID_MAN_INFO: this value is currently never set */
+ − case RRC_COND_IE_ERROR:
+ − {
+ − /*
+ − * build a RR status message.
+ − */
+ − dat_send_rr_status_msg(rr_data->ms_data.error.cs);
+ − PFREE (dl_data_ind);
+ − break;
+ − }
+ −
+ − case RRC_INCORRECT_MSG:
+ − {
+ − /*
+ − * If a structurally correct message has been detected,
+ − * containing erroneous data, an Assignment Failure message
+ − * is sent back.
+ − */
+ −
+ − /*
+ − * Even though it's not possible to go onto the new channel
+ − * we still need to suspend the current link and send the
+ − * HANDOVER FAILURE command via a priority DL_RECONNECT_REQ.
+ − * This ensures DL will halt processing anything in its
+ − * buffer until it has sent this message onto the nw
+ − */
+ − for_suspend_layer_2 ();
+ − dat_send_handov_fail_msg(rr_data->ms_data.error.val);
+ −
+ − RR_EM_SET_HANDOVER_FAIL_CAUSE(rr_data->ms_data.error.val);
+ −
+ − PFREE (dl_data_ind);
+ − break;
+ − }
+ −
+ −
+ − default:
+ − /*
+ − * the message check has passed.
+ − * first of all suspend current layer 2 link
+ − */
+ −
+ − TRACE_EVENT_P1 ("HO:default (%02x)", rr_data->ms_data.error.cs);
+ −
+ − for_suspend_layer_2 ();
+ −
+ − /*
+ − * set for the optional information elements
+ − * of the handover message the default value
+ − * to the current serving cell value.
+ − */
+ − rr_data->cr_data.ch_mode = rr_data->sc_data.ch_mode;
+ − rr_data->cr_data.ciph_on = rr_data->sc_data.ciph_on;
+ − rr_data->cr_data.algo = rr_data->sc_data.algo;
+ − rr_data->cr_data.cd.v_cell_chan_desc =
+ − rr_data->sc_data.cd.v_cell_chan_desc;
+ − memcpy (&rr_data->cr_data.cd.cell_chan_desc,
+ − &rr_data->sc_data.cd.cell_chan_desc,
+ − sizeof (T_LIST));
+ −
+ − /*
+ − * if AMR is supported set the default values
+ − * to the current serving cell values.
+ − */
+ − if(rr_data->sc_data.ch_mode EQ CM_AMR)
+ − {
+ − memcpy(&rr_data->cr_data.amr_conf,
+ − &rr_data->sc_data.amr_conf,
+ − sizeof (T_multirate_conf));
+ − }
+ − else {
+ − /*
+ − * AMR is not supported, therefore set some dummy values. This is necessary because
+ − * the later Layer1 configuration must include an AMR configuration!!
+ − */
+ − memset(&rr_data->cr_data.amr_conf, 0, sizeof (T_multirate_conf));
+ − }
+ −
+ − /*
+ − * set BSIC, BCCH channel number and channel description from
+ − * the handover command.
+ − */
+ − rr_data->nc_data[CR_INDEX].bsic = (handov_cmd->cell_desc.ncc << 3) +
+ − handov_cmd->cell_desc.bcc;
+ − rr_data->nc_data[CR_INDEX].arfcn = handov_cmd->cell_desc.bcch_arfcn_lo +
+ − (handov_cmd->cell_desc.bcch_arfcn_hi << 8);
+ − memcpy (&rr_data->cr_data.chan_desc,
+ − &handov_cmd->chan_desc_after,
+ − sizeof (T_chan_desc));
+ −
+ − if (handov_cmd->v_synch_ind)
+ − {
+ − /*
+ − * store the Handover synchronisation information if available.
+ − */
+ − memcpy (&rr_data->ms_data.ho_type, &handov_cmd->synch_ind,
+ − sizeof (T_synch_ind));
+ − }
+ − else
+ − {
+ − /*
+ − * else set the values to the default values.
+ − */
+ − rr_data->ms_data.ho_type.rot = TIME_DIFF_NO;
+ − rr_data->ms_data.ho_type.nci = TRUE;
+ − rr_data->ms_data.ho_type.si = SYI_NON_SYNCH;
+ − }
+ −
+ − if (rr_data->ms_data.ho_type.si EQ SYI_PSEUDO_SYNCH AND
+ − ! rr_data->ms_data.classmark2.ps)
+ − {
+ − /*
+ − * if the handover requests a pseudo synchronized handover
+ − * and the mobile does not support this, a handover failure
+ − * message is send and the procedure is aborted with
+ − * reconnection to the old channel.
+ − */
+ − dat_send_handov_fail_msg(RRC_INCORRECT_MSG);
+ −
+ − RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_INCORRECT_MSG);
+ −
+ − PFREE (dl_data_ind);
+ − return;
+ − }
+ − else
+ − {
+ − if (handov_cmd->v_cell_chan_desc)
+ − {
+ − /*
+ − * if the handover command contains a new cell channel description
+ − * copy the new list.
+ − */
+ − srv_copy_list (&rr_data->cr_data.cd.cell_chan_desc,
+ − cell_chan_desc,
+ − sizeof (T_LIST));
+ − rr_data->cr_data.cd.v_cell_chan_desc = WITH_CHANGED_CONTENT;
+ − }
+ −
+ − if (handov_cmd->v_chan_mode)
+ − {
+ − /*
+ − * store a new channel mode if available.
+ − */
+ − rr_data->cr_data.ch_mode = handov_cmd->chan_mode;
+ − }
+ −
+ −
+ − /*
+ − * If AMR is signalled check if new multi-rate speech codec is part of the handover cmd
+ − * otherwise use default values set earlier. If AMR is not signalled use the dummy values
+ − * instead either set earlier.
+ − */
+ −
+ − /* Implements RR Clone findings #9 */
+ − dat_cr_data_multirate_conf(handov_cmd->v_multirate_conf, &handov_cmd->multirate_conf);
+ −
+ −
+ − if (handov_cmd->v_ciph_mode_set)
+ − {
+ − /*
+ − * if the message contains cipher mode parameter
+ − * copy the parameters
+ − */
+ − rr_data->cr_data.ciph_on = handov_cmd->ciph_mode_set.sc;
+ − rr_data->cr_data.algo = handov_cmd->ciph_mode_set.algo_ident;
+ −
+ − /*
+ − * if ciphering is already enabled and the handover command
+ − * requests ciphering again, the procedure is aborted with
+ − * a handover failure message.
+ − */
+ − if (rr_data->cr_data.ciph_on EQ CIPH_ON AND
+ − rr_data->sc_data.ciph_received EQ FALSE)
+ − {
+ − dat_send_handov_fail_msg(RRC_PROT_UNSPECIFIED);
+ −
+ − RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_PROT_UNSPECIFIED);
+ −
+ − PFREE (dl_data_ind);
+ − return;
+ − }
+ − }
+ −
+ −
+ − if(handov_cmd->v_mob_alloc_after)
+ − {
+ − if(dat_for_handover_mob_alloc(mob_alloc, hop_list_after, (T_VOID_STRUCT *) &handov_cmd->mob_alloc_after,dl_data_ind))
+ − return;
+ − }
+ −
+ − if(handov_cmd->v_mob_alloc_before)
+ − {
+ − if(dat_for_handover_mob_alloc(mob_alloc, hop_list_before, (T_VOID_STRUCT *) &handov_cmd->mob_alloc_before,dl_data_ind))
+ − return;
+ − }
+ −
+ − /*
+ − * Handover resets a SAPI 3 connection for SMS
+ − */
+ − SET_STATE (STATE_SAPI_3, SMS_IDLE);
+ − PFREE (dl_data_ind);
+ − {
+ − /*
+ − * All Parameters are checked
+ − * Now the handover is started
+ − */
+ − PALLOC (dedicated_req, MPH_DEDICATED_REQ);
+ −
+ − memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ));
+ −
+ − if (handov_cmd->v_start_time)
+ − {
+ − /*
+ − * copy starting time if available.
+ − */
+ − dedicated_req->start.v_start = TRUE;
+ − dedicated_req->start.t1 = handov_cmd->start_time.t1;
+ − dedicated_req->start.t2 = handov_cmd->start_time.t2;
+ − dedicated_req->start.t3 = handov_cmd->start_time.t3;
+ − }
+ −
+ − /*
+ − * Calculate observed time difference
+ − */
+ − {
+ − UBYTE i1;
+ − ULONG fn_offset;
+ −
+ − rr_data->sc_data.observed_ta = 0;
+ − for (i1 = 0; i1< rr_data->ms_data.measurement_report.ncells.no_of_ncells; i1++)
+ − {
+ − /*
+ − * find the handover cell inn the neighbourcells of the last measurement report
+ − */
+ − if (rr_data->nc_data[CR_INDEX].arfcn EQ
+ − rr_data->ms_data.measurement_report.ncells.arfcn[i1])
+ − {
+ − /*
+ − * According to 05.10 OTD is defined as the timing difference
+ − * between BTS0 and BTS1 ( system time in BTS 0 minus that of
+ − * BTS 1..), with BTS1 as the new cell (neighbour cell, HO
+ − * Target cell) and BTS0 and the current cell (serving cell)
+ − */
+ − fn_offset = (HYPERFRAME -
+ − rr_data->ms_data.measurement_report.ncells.frame_offset[i1])
+ − % HYPERFRAME;
+ −
+ − /*
+ − * calculate the observed time difference from the relative
+ − * time difference of neighbourcell and serving cell
+ − * (given by time_alignment and frame offset) and the observed
+ − * time difference of the serving cell (coming from timing advance
+ − * in layer 1 header of the downlink SACCH messages).
+ − */
+ − /*
+ − * A.1.3 of 3GPP TS 05.10
+ − * after successful handover, either synchronized,
+ − * non-synchronized or pseudo-synchronized, the MS shall provide
+ − * to BTS 1 the value of OTD + t0 in the "HANDOVER COMPLETE"
+ − * message.
+ − *
+ − * NOTE : measurement_report.otd is the TA sent by the
+ − * network in downlink SACCH. TA is roundtrip propogation delay in bit periods.
+ − * t0 denotes the "one way" line of sight propagation delay between
+ − * the MS and BTS 0, in "half bits".
+ − * t0 = measurement_report.otd * 2 / 2.
+ − */
+ − rr_data->sc_data.observed_ta =
+ − ( (rr_data->ms_data.measurement_report.ncells.time_alignmt[i1]
+ − + fn_offset* QUARTER_BITS_PER_FRAME)/2
+ − + rr_data->ms_data.measurement_report.otd ) % 2097152;
+ − }
+ − }
+ − }
+ −
+ −
+ − dedicated_req->ho_param.ho_nci = rr_data->ms_data.ho_type.nci;
+ −
+ − /*
+ − * Set the handover mode
+ − */
+ − switch (rr_data->ms_data.ho_type.si)
+ − {
+ − case SYI_NON_SYNCH:
+ − /*
+ − * asynchronous handover
+ − */
+ − dedicated_req->mod = MODE_ASYNC_HANDOVER;
+ − break;
+ −
+ − case SYI_NORM_SYNCH:
+ − /*
+ − * synchronous handover
+ − */
+ − rr_data->sc_data.new_ta = rr_data->ms_data.measurement_report.otd/2;
+ − att_set_tim_advance_info();
+ − dedicated_req->mod = MODE_SYNC_HANDOVER;
+ − break;
+ −
+ − case SYI_PRE_SYNCH:
+ − /*
+ − * pre-synchronized handover
+ − */
+ − dedicated_req->mod = MODE_PRE_SYNC_HANDOVER;
+ −
+ − if (handov_cmd->v_time_advance)
+ − /*
+ − * if the handover command contains a new timing advance
+ − */
+ − dedicated_req->tr_para.tav = handov_cmd->time_advance.ta;
+ − else
+ − /*
+ − * else set the default value 1
+ − */
+ − dedicated_req->tr_para.tav = 1;
+ −
+ − rr_data->sc_data.new_ta = dedicated_req->tr_para.tav * 2;
+ − att_set_tim_advance_info();
+ − break;
+ −
+ − case SYI_PSEUDO_SYNCH:
+ − /*
+ − * pseudo-synchronized handover
+ − */
+ − dedicated_req->mod = MODE_PSEUDO_SYNC_HANDOVER;
+ − dedicated_req->tr_para.tav = handov_cmd->time_diff;
+ − rr_data->sc_data.new_ta = dedicated_req->tr_para.tav;
+ − att_set_tim_advance_info();
+ − break;
+ − }
+ −
+ − /*
+ − * Set Channel Type
+ − */
+ − dedicated_req->ch_type.ch = handov_cmd->chan_desc_after.chan_type;
+ − dedicated_req->ch_type.tn = handov_cmd->chan_desc_after.tn;
+ − dedicated_req->ch_type.tsc = handov_cmd->chan_desc_after.tsc;
+ − dedicated_req->ch_type.h = handov_cmd->chan_desc_after.hop;
+ −
+ − if (handov_cmd->chan_desc_after.hop EQ H_NO)
+ − dedicated_req->ch_type.arfcn = handov_cmd->chan_desc_after.arfcn;
+ − else
+ − {
+ − dedicated_req->ch_type.maio = handov_cmd->chan_desc_after.maio;
+ − dedicated_req->ch_type.hsn = handov_cmd->chan_desc_after.hsn;
+ −
+ − /* CSI-LLD section:4.1.1.11
+ − * This function Updates the black list with the MA list received
+ − * in the handover command
+ − */
+ − cs_remove_BA_MA_from_black_list(rr_data->cs_data.region , hop_list_after);
+ −
+ − srv_create_list (hop_list_after, dedicated_req->ch_type.ma,
+ − MAX_MA_CHANNELS, TRUE, 0);
+ − }
+ −
+ − dedicated_req->bsic = rr_data->nc_data[CR_INDEX].bsic & 0x3F;
+ − dedicated_req->arfcn = rr_data->nc_data[CR_INDEX].arfcn;
+ − dedicated_req->ho_param.ho_ref = handov_cmd->handov_ref;
+ − dedicated_req->ho_param.ho_pow = handov_cmd->pow_cmd_access.pow;
+ − dedicated_req->ho_param.ho_acc_type = handov_cmd->pow_cmd_access.atc;
+ − dedicated_req->tr_para.mode = rr_data->cr_data.ch_mode;
+ −
+ − /*
+ − * Set multi-rate speech codec
+ − */
+ − dedicated_req->amr_conf.nscb = rr_data->cr_data.amr_conf.nscb;
+ − dedicated_req->amr_conf.icmi = rr_data->cr_data.amr_conf.icmi;
+ − dedicated_req->amr_conf.st_mode = rr_data->cr_data.amr_conf.st_mode;
+ − dedicated_req->amr_conf.acs = rr_data->cr_data.amr_conf.set_amr;
+ −
+ − /*
+ − * valid flag for the threshold and hystersis values. amr_conf.c_cod_prop
+ − * defines the number of threshold and hystersis values.
+ − */
+ − dedicated_req->amr_conf.v_cod_prop = rr_data->cr_data.amr_conf.v_cod_prop;
+ − if(dedicated_req->amr_conf.v_cod_prop)
+ − {
+ − int i;
+ − dedicated_req->amr_conf.c_cod_prop = rr_data->cr_data.amr_conf.c_cod_prop;
+ − for(i=0; i<dedicated_req->amr_conf.c_cod_prop; i++)
+ − memcpy(&dedicated_req->amr_conf.cod_prop[i], &rr_data->cr_data.amr_conf.cod_prop[i], sizeof(T_cod_prop));
+ − }
+ −
+ − /*
+ − * Set Channel Type before starting time
+ − */
+ −
+ − if (handov_cmd->v_chan_desc_before EQ FALSE)
+ − dedicated_req->ch_type2.ch = NOT_PRESENT_8BIT;
+ − else
+ − {
+ −
+ − /* Implements RR Clone findings #22 */
+ − dat_dedicated_req_ch_type2(&dedicated_req->ch_type2, &handov_cmd->chan_desc_before,
+ − hop_list_before);
+ − }
+ −
+ − if (rr_data->cr_data.ciph_on)
+ − {
+ − /*
+ − * set cipher parameter
+ − */
+ − dedicated_req->ciph.stat = rr_data->cr_data.ciph_on;
+ − dedicated_req->ciph.algo = rr_data->cr_data.algo;
+ − memcpy (dedicated_req->ciph.kc, rr_data->ms_data.kc, KC_STRING_SIZE);
+ − }
+ −
+ − /*
+ − * clear neighbourcell lists for the new cell.
+ − */
+ − srv_clear_list (&rr_data->sc_data.cd.ncell_list);
+ − srv_clear_list (&rr_data->sc_data.five_ter_list);
+ −
+ − att_clean_buf (IND_ALL_DEDI_SI);
+ −
+ − rr_data->sc_data.cd.sys_info_read &= ~ALL_DEDI_SYS_INFOS;
+ −
+ − SET_STATE (STATE_DAT, DAT_HANDOVER);
+ −
+ − #if defined (REL99) && defined (TI_PS_FF_EMR)
+ − /*clear EMR parameters also, if present*/
+ − if (rr_data->sc_data.enh_para_status EQ ENH_PARA_DEDICATED )
+ − {
+ − /*discard the enhanced para that were related to BA(SACCH) before HO*/
+ − rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE;
+ − memset (rr_data->sc_data.rep_count, NOT_PRESENT_8BIT, MAX_NEIGHBOURCELLS);
+ − for_set_default_emr_data(&rr_data->sc_data.emr_data_current);
+ − /*Indicate to ALR that enhanced para are invalid*/
+ − attf_send_enh_para_to_alr(rr_data->sc_data.emr_data_current.rep_type,
+ − &rr_data->sc_data.emr_data_current.enh_para);
+ − }
+ − #endif
+ −
+ − RR_EM_GET_HOPPING_CHANNEL (dedicated_req->ch_type.ma, dedicated_req->ch_type2.ma,
+ − dedicated_req->start.v_start,dedicated_req->ch_type2.maio);
+ −
+ − EM_HANDOVER_CMD;
+ −
+ − #if defined FF_EOTD
+ − if ( rr_data->eotd_req_id NEQ NOT_PRESENT_16BIT )
+ − {
+ − PALLOC (rrlc_error_ind, RRLC_ERROR_IND);
+ − rrlc_error_ind->cause = LCS_HANDOVER;
+ −
+ − rr_data->eotd_req_id = NOT_PRESENT_16BIT;
+ −
+ − PSENDX (LC, rrlc_error_ind);
+ − }
+ − #endif /* FF_EOTD */
+ −
+ − /*
+ − * configure layer 1.
+ − */
+ − PSENDX (PL, dedicated_req);
+ − }
+ − } /* else */
+ − } /* switch */
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : stop_rach_and_enter_idle |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Invalid frequency list received during Immediate Assignment
+ − procedure. The sending of Channel Request messages is
+ − stopped and Idle Mode entered.
+ − */
+ −
+ − LOCAL void stop_rach_and_enter_idle(void)
+ − {
+ − PALLOC (mph_random_access_req, MPH_RANDOM_ACCESS_REQ);
+ −
+ − TRACE_ERROR ("invalid frequencies (Frequency Hopping)");
+ −
+ − TIMERSTOP (T3122);
+ − TIMERSTOP (T3126);
+ −
+ − /*
+ − * Stop sending Random Burst
+ − */
+ − memset (&mph_random_access_req->send_mode, 0, sizeof (T_send_mode));
+ − PSENDX (PL, mph_random_access_req);
+ −
+ − dat_send_release_ind (RRCS_INVALID_HOP_FREQ);
+ −
+ − /*SET_STATE (STATE_DAT, DAT_IDLE);
+ − att_build_idle_req (SC_INDEX, MODE_CELL_SELECTION);*/
+ −
+ − #ifdef GPRS
+ − att_start_cell_reselection_gprs (CELL_RESELECTION_RACH);
+ − #else
+ − att_start_cell_reselection (CELL_RESELECTION_RACH);
+ − #endif
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_imm_assign |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of an immediate assignment message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_imm_assign (T_MPH_UNITDATA_IND *mph_unitdata_ind,
+ − T_D_IMM_ASSIGN *imm_assign)
+ − {
+ − GET_INSTANCE_DATA;
+ − T_SC_DATA *rrd = &rr_data->sc_data;
+ − T_start start;
+ − UBYTE mob_alloc [65];
+ − T_LIST hop_list_bef;
+ − T_LIST hop_list_after;
+ − UBYTE maio;
+ − T_IA_REST ia_rest;
+ − UBYTE index = 0;
+ −
+ − TRACE_FUNCTION ("dat_for_imm_assign()");
+ −
+ − switch (GET_STATE (STATE_DAT))
+ − {
+ − #ifdef GPRS
+ − case DAT_IDLE:
+ − TRACE_EVENT("check dl idle");
+ − dat_check_imm_assign_pch (mph_unitdata_ind, imm_assign);
+ − break;
+ − #endif
+ −
+ − case DAT_IMM_ASS:
+ − if (dat_check_error_flag (SEND_NO_RR_STATUS))
+ − {
+ − #ifdef GPRS
+ − TRACE_EVENT("check dl pa");
+ − if(GET_STATE(STATE_GPRS) EQ GPRS_PAM_BCCH AND
+ − dat_check_imm_assign_pch(mph_unitdata_ind, imm_assign))
+ − return;
+ − #endif
+ − if (dat_compare_request_ref (&imm_assign->req_ref, &index))
+ − {
+ − /*
+ − * the request reference in the immediate assignment
+ − * message matches to one of the last three channel
+ − * request messages.
+ − */
+ − TRACE_EVENT("matched");
+ − /*
+ − * check the channel description
+ − */
+ − if(imm_assign->v_chan_desc)
+ − for_check_channel_descr (&imm_assign->chan_desc);
+ −
+ − /* was channel description ok? */
+ − if(!dat_check_error_flag (SEND_NO_RR_STATUS))
+ − return;
+ − #ifdef GPRS
+ − if(dat_check_gprs_imm_ass (mph_unitdata_ind,
+ − imm_assign,
+ − index))
+ − return;
+ − #endif
+ − if (imm_assign->v_chan_desc)
+ − {
+ − if (imm_assign->chan_desc.hop AND
+ − imm_assign->mob_alloc.c_mac)
+ − {
+ − TRACE_EVENT ("create mob alloc (after st)");
+ − /*
+ − * if the message contains a mobile allocation
+ − * build a hopping list together with the cell
+ − * channel description of system information
+ − * type 1 message.
+ − */
+ − att_bits_to_byte (mob_alloc,
+ − imm_assign->mob_alloc.c_mac,
+ − imm_assign->mob_alloc.mac);
+ − if( rrd->cd.v_cell_chan_desc EQ NO_CONTENT OR
+ − !srv_create_chan_mob_alloc (&rrd->cd.cell_chan_desc,
+ − &hop_list_after,
+ − mob_alloc))
+ − {
+ − stop_rach_and_enter_idle();
+ − return;
+ − }
+ − }
+ − else
+ − {
+ − /*
+ − * else clear the hopping list
+ − */
+ − srv_clear_list (&hop_list_after);
+ − }
+ − }
+ − else
+ − {
+ − TRACE_EVENT("IMM ASS discarded: neither sent to GRR nor channel description found");
+ − return; /* for non-packet access we need a channel description */
+ − }
+ −
+ − TRACE_EVENT("now get started");
+ − if (imm_assign->v_start_time)
+ − {
+ − /*
+ − * if the message contains a starting time,
+ − * store the starting time.
+ − */
+ − start.v_start = TRUE;
+ − start.t1 = imm_assign->start_time.t1;
+ − start.t2 = imm_assign->start_time.t2;
+ − start.t3 = imm_assign->start_time.t3;
+ − }
+ − else
+ − {
+ − /*
+ − * clear the starting time.
+ − */
+ − memset (&start, 0, sizeof (T_start));
+ − }
+ −
+ − /*
+ − * decode IA Rest Octet
+ − */
+ − memset (&ia_rest, 0, sizeof (T_IA_REST));
+ −
+ − ia_rest.ia_p = imm_assign->ia_rest_oct.flag_2bit;
+ − ia_rest.ia_maio = imm_assign->ia_rest_oct.ia_freq_par.maio;
+ − ia_rest.c_ia_mac = imm_assign->ia_rest_oct.ia_freq_par.c_mac;
+ − if (ia_rest.c_ia_mac > 9)
+ − ia_rest.c_ia_mac = 9;
+ −
+ − memcpy (ia_rest.ia_mac,
+ − &imm_assign->ia_rest_oct.ia_freq_par.mac,
+ − ia_rest.c_ia_mac);
+ −
+ − if (imm_assign->v_start_time AND
+ − imm_assign->chan_desc.hop AND
+ − ia_rest.ia_p EQ 2)
+ − {
+ − /*
+ − * calculate frequency list before starting time
+ − */
+ − TRACE_EVENT("create mob alloc (before st)");
+ − maio = ia_rest.ia_maio;
+ −
+ − att_bits_to_byte (mob_alloc,
+ − ia_rest.c_ia_mac,
+ − ia_rest.ia_mac);
+ − if(rrd->cd.v_cell_chan_desc EQ NO_CONTENT OR
+ − !srv_create_chan_mob_alloc (&rrd->cd.cell_chan_desc,
+ − &hop_list_bef,
+ − mob_alloc))
+ − {
+ − stop_rach_and_enter_idle();
+ − return;
+ − }
+ − }
+ − else
+ − {
+ − maio = 0;
+ − srv_clear_list (&hop_list_bef);
+ − }
+ −
+ −
+ − /*
+ − * stop T3122 and T3126 if they are running.
+ − */
+ − TIMERSTOP (T3122);
+ − TIMERSTOP (T3126);
+ − SET_STATE (STATE_DAT, DAT_IMM_ASS_1);
+ −
+ − /*
+ − * store channel description
+ − */
+ − memcpy (&rrd->chan_desc, &imm_assign->chan_desc,
+ − sizeof (T_chan_desc));
+ −
+ − /*
+ − * the initial channel mode is always signalling only
+ − */
+ − rrd->ch_mode = MODE_SIG_ONLY;
+ −
+ − /*
+ − * set the timing advance
+ − */
+ − rrd->new_ta = imm_assign->time_advance.ta;
+ − att_set_tim_advance_info();
+ − dat_set_last_used_channel (&rrd->chan_desc);
+ −
+ −
+ − /*
+ − * configure layer 1
+ − */
+ − dat_code_mph_imm_assign_req (&start,
+ − rr_data->nc_data[SC_INDEX].select_para.ms_txpwr_max_cch,
+ − maio,
+ − &hop_list_after,
+ − &hop_list_bef);
+ − }
+ − EM_IMMEDIATE_ASSIGNMENT;
+ − }
+ − break;
+ −
+ − default:
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_imm_assign_ext |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of the immediate assignment extended message.
+ −
+ − */
+ −
+ −
+ − GLOBAL void dat_for_imm_assign_ext (T_MPH_UNITDATA_IND *mph_unitdata_ind,
+ − T_D_IMM_ASSIGN_EXT *imm_assign_ext)
+ − {
+ − GET_INSTANCE_DATA;
+ − USHORT i;
+ − T_start start;
+ − UBYTE mob_alloc [65];
+ − T_SC_DATA *rrd = &rr_data->sc_data;
+ − T_LIST hop_list_after;
+ − T_LIST hop_list_bef;
+ − UBYTE index;
+ − T_chan_desc *p_chan_desc;
+ −
+ − TRACE_FUNCTION ("dat_for_imm_assign_ext()");
+ −
+ − switch (GET_STATE (STATE_DAT))
+ − {
+ − case DAT_IMM_ASS:
+ − if (dat_check_error_flag (SEND_NO_RR_STATUS))
+ − {
+ − /*
+ − * the message check in the formatter has passed
+ − */
+ − for (i=0; i<2; i++)
+ − {
+ − /*
+ − * the immediate assignment extended message contains
+ − * two request references.
+ − */
+ − if (dat_compare_request_ref ((i EQ 0)
+ − ? &imm_assign_ext->req_ref
+ − : (T_req_ref *)&imm_assign_ext->req_ref_2,
+ − &index))
+ − {
+ − #ifdef GPRS
+ − dat_check_imm_ass_ext (mph_unitdata_ind,(UBYTE)(i+1));
+ − #endif
+ − /*
+ − * check channel description
+ − */
+ − if(i EQ 0)
+ − p_chan_desc = &imm_assign_ext->chan_desc;
+ − else
+ − p_chan_desc = (T_chan_desc *)&imm_assign_ext->chan_desc_2;
+ − for_check_channel_descr (p_chan_desc);
+ −
+ − if (!dat_check_error_flag (SEND_NO_RR_STATUS))
+ − return;
+ − /*
+ − * the request reference in the immediate assignment
+ − * extended message matches to one of the last three
+ − * channel request messages.
+ − */
+ − if (imm_assign_ext->mob_alloc.c_mac AND p_chan_desc->hop)
+ − {
+ − /*
+ − * if the message contains a mobile allocation and
+ − * the mobile shall hop
+ − * build a frequency hopping list together with
+ − * the cell channel description of system information
+ − * type 1 message.
+ − */
+ − att_bits_to_byte (mob_alloc,
+ − imm_assign_ext->mob_alloc.c_mac,
+ − imm_assign_ext->mob_alloc.mac);
+ − if(rrd->cd.v_cell_chan_desc EQ NO_CONTENT OR
+ − ! srv_create_chan_mob_alloc (&rr_data->sc_data.cd.cell_chan_desc,
+ − &hop_list_after,
+ − mob_alloc))
+ − {
+ − stop_rach_and_enter_idle();
+ − return;
+ − }
+ − }
+ − else
+ − {
+ − /*
+ − * else clear frequency hopping list
+ − */
+ − srv_clear_list (&hop_list_after);
+ − }
+ −
+ − /*
+ − * stop T3122 and T3126 if they are running.
+ − */
+ − TIMERSTOP (T3122);
+ − TIMERSTOP (T3126);
+ − /*
+ − * store channel description
+ − */
+ − memcpy (&rrd->chan_desc,
+ − p_chan_desc,
+ − sizeof (T_chan_desc));
+ −
+ − /*
+ − * the initial channel mode is ever signalling only
+ − */
+ − rrd->ch_mode = MODE_SIG_ONLY;
+ −
+ − /*
+ − * store the new timing advance
+ − */
+ − rrd->new_ta = (i EQ 0)
+ − ? imm_assign_ext->time_advance.ta
+ − : imm_assign_ext->time_advance_2.ta;
+ − att_set_tim_advance_info();
+ − dat_set_last_used_channel (&rrd->chan_desc);
+ −
+ −
+ − if (imm_assign_ext->v_start_time)
+ − {
+ − /*
+ − * copy starting time if available
+ − */
+ − start.v_start = TRUE;
+ − start.t1 = imm_assign_ext->start_time.t1;
+ − start.t2 = imm_assign_ext->start_time.t2;
+ − start.t3 = imm_assign_ext->start_time.t3;
+ − }
+ − else
+ − memset (&start, 0, sizeof (T_start));
+ −
+ − srv_clear_list (&hop_list_bef);
+ − SET_STATE (STATE_DAT, DAT_IMM_ASS_1);
+ −
+ − /*
+ − * configure layer 1.
+ − */
+ − dat_code_mph_imm_assign_req (&start,
+ − rr_data->nc_data[SC_INDEX].select_para.ms_txpwr_max_cch,
+ − 0,
+ − &hop_list_after,
+ − &hop_list_bef);
+ −
+ − EM_IMMEDIATE_ASSIGNMENT_EXT;
+ − return;
+ − }
+ − }
+ − }
+ − break;
+ −
+ − default:
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_imm_assign_rej |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of an immediate assignment reject message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_imm_assign_rej (T_D_IMM_ASSIGN_REJ *imm_assign_rej)
+ − {
+ − GET_INSTANCE_DATA;
+ − UBYTE index;
+ −
+ − TRACE_FUNCTION ("dat_for_imm_assign_rej()");
+ −
+ − switch (GET_STATE (STATE_DAT))
+ − {
+ − case DAT_IMM_ASS:
+ − if (dat_check_error_flag (SEND_NO_RR_STATUS))
+ − {
+ − /*
+ − * the message has passed the checks in the formatter.
+ − */
+ −
+ − if (! IS_TIMER_ACTIVE(T3122))
+ − {
+ − /*
+ − * Only if T3122 is not running, that means there is no
+ − * immediate assignment reject message taken in account
+ − * before.
+ − */
+ − BOOL result = FALSE;
+ − UBYTE t3122 = 0;
+ −
+ − if (dat_compare_request_ref (&imm_assign_rej->req_ref, &index))
+ − {
+ − /*
+ − * if the request reference matches to one of the last
+ − * three channel requests, set the result of TRUE and
+ − * store the timer value. This is checked for the up to
+ − * four request references in the message.
+ − */
+ − result = TRUE;
+ − t3122 = imm_assign_rej->t3122;
+ − }
+ −
+ − else if (dat_compare_request_ref ((T_req_ref *)&imm_assign_rej->req_ref_2, &index))
+ − {
+ − result = TRUE;
+ − t3122 = imm_assign_rej->t3122_2;
+ − }
+ −
+ − else if (dat_compare_request_ref ((T_req_ref *)&imm_assign_rej->req_ref_3, &index))
+ − {
+ − result = TRUE;
+ − t3122 = imm_assign_rej->t3122_3;
+ − }
+ −
+ − else if (dat_compare_request_ref ((T_req_ref *)&imm_assign_rej->req_ref_4, &index))
+ − {
+ − result = TRUE;
+ − t3122 = imm_assign_rej->t3122_4;
+ − }
+ −
+ − if (result)
+ − {
+ − /*
+ − * a request reference has matched
+ − */
+ − #ifdef GPRS
+ − if (dat_check_imm_ass_rej (t3122) EQ FALSE)
+ − #endif
+ − if (t3122 NEQ 0)
+ − {
+ − /*
+ − * start T3122 if a value is defined
+ − */
+ − TIMERSTART (T3122, T3122_VALUE(t3122));
+ − }
+ − TRACE_EVENT("set rej_rec");
+ − rr_data->imm_ass_rej_rec = TRUE;
+ − rr_data->ms_data.all_conf_received = TRUE;
+ −
+ − /*
+ − * Start T3126 if the timer is not running yet.
+ − */
+ − /* Implements Measure#32: Row 217,218 */
+ − (IS_TIMER_ACTIVE(T3126)) ?
+ − TRACE_TIMER ( "T3126 re-start") : TRACE_TIMER ( "T3126 start");
+ −
+ −
+ − if (! IS_TIMER_ACTIVE(T3126))
+ − {
+ − TIMERSTART (T3126, T3126_VALUE);
+ − /*
+ − * Stop sending Random Burst
+ − */
+ − {
+ − PALLOC (mph_random_access_req, MPH_RANDOM_ACCESS_REQ);
+ −
+ − memset (&mph_random_access_req->send_mode, 0, sizeof (T_send_mode));
+ − PSENDX (PL, mph_random_access_req);
+ − }
+ − }
+ − }
+ − EM_IMMEDIATE_ASSIGNMENT_REJECT;
+ − }
+ − }
+ − break;
+ −
+ − default:
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_ext_meas_order |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of an extended measurement order message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_ext_meas_order (T_D_EXT_MEAS_ORDER *ext_meas_order)
+ − {
+ − GET_INSTANCE_DATA;
+ − UBYTE new_seq;
+ − T_LIST *chan_list;
+ −
+ − PALLOC (mph_emo_req, MPH_EMO_REQ);
+ −
+ − TRACE_FUNCTION ("dat_for_ext_meas_order()");
+ −
+ − /*
+ − * Decode EMO: new_seq
+ − */
+ −
+ − ccd_decodeByte (ext_meas_order->ext_meas_freq.b_ext_meas_freq,
+ − (USHORT)(ext_meas_order->ext_meas_freq.o_ext_meas_freq+3),
+ − 1, &new_seq);
+ −
+ − /*
+ − * Ignore EMO if EMO proc already running and new SEQ EQ current SEQ.
+ − */
+ −
+ − if ( rr_data->emo_arfcn NEQ NULL AND rr_data->emo_seq EQ new_seq )
+ − {
+ − PFREE ( mph_emo_req );
+ − return;
+ − }
+ −
+ − /*
+ − * Decode and store EMO frequency list
+ − */
+ −
+ − if ( rr_data->emo_arfcn EQ NULL )
+ − {
+ − MALLOC ( rr_data->emo_arfcn, MAX_EMO_CHANNELS * sizeof (rr_data->emo_arfcn[0]) );
+ − }
+ − rr_data->emo_seq = new_seq;
+ − MALLOC ( chan_list, sizeof ( T_LIST ) );
+ − for_create_channel_list ( (T_f_range*) &ext_meas_order->ext_meas_freq, chan_list);
+ −
+ − /*
+ − * Function srv_create_list_dedicated ensures that the frequencies are sorted
+ − * and the number of frequencies are limited to 21 frequencies
+ − */
+ −
+ − rr_data->c_emo_arfcn = srv_create_list (chan_list,
+ − rr_data->emo_arfcn,
+ − MAX_EMO_CHANNELS,
+ − FALSE,
+ − 0);
+ − MFREE ( chan_list );
+ −
+ − memcpy ( &mph_emo_req->arfcn[0],
+ − &rr_data->emo_arfcn[0],
+ − rr_data->c_emo_arfcn * sizeof (rr_data->emo_arfcn[0]) );
+ −
+ − mph_emo_req->c_arfcn =
+ − srv_remove_frequencies_in_array_gen ( &mph_emo_req->arfcn[0], rr_data->c_emo_arfcn );
+ −
+ − /*
+ − * Create newBA_ID, save as currentBA_ID.
+ − */
+ −
+ − rr_data->ba_id = RR_ALLOCATE_NEW_BA ( rr_data->ba_id );
+ − mph_emo_req->ba_id = rr_data->ba_id;
+ −
+ − /*
+ − * EMOtime = 10 seconds and request PL to perform extended measurement.
+ − */
+ −
+ − TIMERSTART (TIM_EXT_MEAS, 10000);
+ −
+ − PSENDX (PL, mph_emo_req);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_mph_emo_meas_ind |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Measurement report for the Extended Measurment procedure
+ − has been received.
+ −
+ − */
+ −
+ − GLOBAL void dat_mph_emo_meas_ind (T_MPH_EMO_MEAS_IND *mph_emo_meas_ind)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("att_mph_emo_meas_ind()");
+ −
+ − switch (GET_STATE (STATE_DAT))
+ − {
+ − case DAT_DEDICATED:
+ − if ( rr_data->emo_arfcn NEQ NULL AND mph_emo_meas_ind->ba_id EQ rr_data->ba_id )
+ − {
+ − dat_code_ext_meas_report (mph_emo_meas_ind);
+ − dat_emo_stop ( TRUE );
+ − }
+ − else
+ − {
+ − /*
+ − * Build an invalid measurement reports
+ − */
+ − MCAST (meas, U_MEAS_REP);
+ − PALLOC_MSG (dl_unitdata_req, DL_UNITDATA_REQ, U_MEAS_REP);
+ − memset (&dl_unitdata_req->sdu.buf[0], 0, dl_unitdata_req->sdu.o_buf / BITS_PER_BYTE);
+ −
+ − memset (meas, 0, sizeof (T_U_MEAS_REP));
+ − meas->msg_type = U_MEAS_REP;
+ − meas->meas_result.meas_valid = 1;
+ − for_dat_unitdata_req (dl_unitdata_req);
+ − }
+ − break;
+ −
+ − default:
+ − break;
+ − }
+ − PFREE (mph_emo_meas_ind);
+ − }
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_emo_stop |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Stop the Extended Measurement Order procedure.
+ −
+ − */
+ −
+ − GLOBAL void dat_emo_stop (BOOL send_ncell_req )
+ − {
+ − GET_INSTANCE_DATA;
+ − if ( rr_data->emo_arfcn NEQ NULL )
+ − {
+ − MFREE (rr_data->emo_arfcn);
+ − rr_data->emo_arfcn = NULL;
+ −
+ − /* restore the neighbour cell description which was used prior EMO */
+ − if ( send_ncell_req AND
+ − (rr_data->sc_data.cd.sys_info_read & (SYS_INFO_5_READ | SYS_INFO_5BIS_READ | SYS_INFO_5TER_READ) ) )
+ −
+ − att_code_mph_ncell_req_dedicated();
+ − }
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_l3_data_ind |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a layer 3 message for upper layers.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_l3_data_ind (T_DL_DATA_IND *dl_data_ind)
+ − {
+ − GET_INSTANCE_DATA;
+ − /* RR_DATA_IND is not the same as DL_DATA_IND anymore because of the new
+ − * member fn (frame number) of T_DL_DATA_IND which is not contained in
+ − * T_RR_DATA_IND.
+ − */
+ − PALLOC_SDU(rr_data_ind, RR_DATA_IND, (USHORT)(dl_data_ind->sdu.l_buf+dl_data_ind->sdu.o_buf));
+ −
+ − TRACE_FUNCTION ("dat_for_l3_data_ind()");
+ −
+ − if (dl_data_ind->sapi EQ SAPI_3)
+ − {
+ − /*
+ − * if it is a SMS message, this is implicitly an
+ − * indication for an established SAPI 3 link
+ − */
+ − SET_STATE (STATE_SAPI_3, SMS_ESTABLISHED);
+ − }
+ −
+ − rr_data_ind->sdu.l_buf = dl_data_ind->sdu.l_buf;
+ − rr_data_ind->sdu.o_buf = dl_data_ind->sdu.o_buf;
+ − memcpy(rr_data_ind->sdu.buf, dl_data_ind->sdu.buf,
+ − (dl_data_ind->sdu.l_buf+dl_data_ind->sdu.o_buf)>>3);
+ − PFREE (dl_data_ind);
+ − /*
+ − * forward the message to MM for distribution
+ − */
+ − PSENDX (MM, rr_data_ind);
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_FOR |
+ − | STATE : code ROUTINE : dat_for_open_loop_cmd |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : Reception of a TCH OPEN LOOP COMMAND message.
+ −
+ − */
+ −
+ − GLOBAL void dat_for_open_loop_cmd (T_DL_DATA_IND *dl_data_ind)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION ("dat_for_open_loop_cmd()");
+ −
+ − if (dat_test_sim_available () OR !dat_check_sim_available () )
+ − {
+ − /*
+ − * only if a test SIM card is inserted
+ − */
+ − if (rr_data->tch_loop_subch NEQ NOT_PRESENT_8BIT)
+ − {
+ − /*
+ − * A TCH Loop must be closed before, then
+ − * open in layer 1.
+ − */
+ − PREUSE (dl_data_ind, loop_req, MPH_TCH_LOOP_REQ);
+ − loop_req->tch_loop = NOT_PRESENT_8BIT;
+ − PSENDX (PL, loop_req);
+ −
+ − if(rr_data->tch_loop_subch EQ TCH_LOOP_C)
+ − {
+ − /* only TCH_LOOP_C is acknowledged */
+ − PALLOC_SDU (data_req, DL_DATA_REQ, 3*BITS_PER_BYTE);
+ −
+ − /*
+ − * set channel type and SAPI for answer
+ − */
+ − dat_code_prr_channel (&data_req->ch_type,
+ − &data_req->sapi,
+ − rr_data->sc_data.chan_desc.chan_type);
+ −
+ − TRACE_EVENT_P1 ( "Value of tch_loop_subch %x", rr_data->tch_loop_subch);
+ −
+ − /*
+ − * do not use CCD for the response
+ − */
+ − data_req->sdu.l_buf = 24;
+ − data_req->sdu.o_buf = ENCODE_OFFSET;
+ − /*lint -e415 -e416 Likely access of out-of-bounds pointer*/
+ − data_req->sdu.buf [0] = 0;
+ − data_req->sdu.buf [1] = 0;
+ − data_req->sdu.buf [2] = 0;
+ − data_req->sdu.buf [3] = 0x0F; /* TI=0, PD = TST */
+ − data_req->sdu.buf [4] = 0x06; /* MT = Open Loop Cmd */
+ − data_req->sdu.buf [5] = 0x81; /* IE acknowledge */
+ − /*lint +e415 +e416 Likely access of out-of-bounds pointer*/
+ − TRACE_EVENT ("DL_DATA_REQ (RR message)");
+ −
+ − EM_TCH_LOOP_OPEN;
+ −
+ − PSENDX (DL, data_req);
+ − }
+ − /* tch loop "open" */
+ − rr_data->tch_loop_subch = NOT_PRESENT_8BIT;
+ − }
+ − else
+ − {
+ − PFREE (dl_data_ind);
+ − }
+ − }
+ − else
+ − {
+ − PFREE (dl_data_ind);
+ − }
+ − }
+ −
+ − #if defined FF_EOTD
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : rr_applic_rx_init
+ − +------------------------------------------------------------------------------
+ − | Description : Initialize the data structures related to
+ − | Application Information Transfer
+ − | Reference: 3GPP TS 04.18, 3.4.21.3
+ − |
+ − | Parameters : The downlink (RX) part of the APDU structure.
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void rr_applic_rx_init ( T_APPLIC_RX *applic_rx)
+ − {
+ − applic_rx->state = SAI_NULL;
+ − if ( applic_rx->rrrrlp_data_ind NEQ NULL )
+ − {
+ − PFREE ( applic_rx->rrrrlp_data_ind )
+ − }
+ − applic_rx->rrrrlp_data_ind = NULL;
+ − #ifdef REL99
+ − /* Send RRLP procedure stop indication to MM*/
+ − {
+ − PALLOC (rr_rrlp_stop_ind, RR_RRLP_STOP_IND);
+ − PSENDX (MM, rr_rrlp_stop_ind);
+ − }
+ − #endif
+ −
+ − TIMERSTOP ( TAPDU );
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : rr_applic_rx_msg_store
+ − +------------------------------------------------------------------------------
+ − | Description : Store the first segment of an APDU.
+ − | Reference: 3GPP TS 04.18, 3.4.21.3.2
+ − |
+ − | Parameters : The first part of the APDU.
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL void rr_applic_rx_msg_store ( T_B_APPLIC_INFO *b_applic_info )
+ − {
+ − GET_INSTANCE_DATA;
+ − T_APPLIC_RX *applic_rx = &rr_data->applic_rx;
+ − T_apdu_data *apdu_data = &b_applic_info->apdu_data;
+ − UBYTE size = apdu_data->c_apdu_info;
+ − T_sdu *sdu;
+ − PALLOC_SDU ( rrrrlp_data_ind, RRRRLP_DATA_IND, (USHORT)(size * BITS_PER_BYTE) );
+ −
+ − if ( applic_rx->rrrrlp_data_ind NEQ NULL )
+ − {
+ − TRACE_EVENT_P1 ( "APPLIC: non empty store message found", 0 );
+ − PFREE ( applic_rx->rrrrlp_data_ind );
+ − }
+ −
+ − applic_rx->rrrrlp_data_ind = rrrrlp_data_ind;
+ − sdu = &applic_rx->rrrrlp_data_ind->sdu;
+ −
+ − memcpy ( &sdu->buf[0], apdu_data->apdu_info, size );
+ − sdu->l_buf = size * BITS_PER_BYTE;
+ − sdu->o_buf = 0;
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : rr_applic_rx_msg_append
+ − +------------------------------------------------------------------------------
+ − | Description : Append segments to the APDU.
+ − | Reference: 3GPP TS 04.18, 3.4.21.3.2
+ − |
+ − | Parameters : APDU segment to be appended.
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ −
+ − LOCAL int rr_applic_rx_msg_append ( T_B_APPLIC_INFO *b_applic_info )
+ − {
+ − GET_INSTANCE_DATA;
+ − T_APPLIC_RX *applic_rx = &rr_data->applic_rx;
+ − T_apdu_data *apdu_data = &b_applic_info->apdu_data;
+ − T_sdu *sdu = &applic_rx->rrrrlp_data_ind->sdu; /* current APDU */
+ − T_sdu *sdu2; /* new APDU */
+ − USHORT size_cur = (USHORT)(sdu->l_buf/BITS_PER_BYTE); /* Current size of stored APDU */
+ − USHORT size_inf = (USHORT)apdu_data->c_apdu_info; /* size of new APDU INFOrmation */
+ − USHORT size_tot = (USHORT)(size_cur + size_inf); /* total APDU size after append */
+ −
+ − if ( size_tot <= MAX_APDU_SIZE*BITS_PER_BYTE ) /*lint !e648 !e650/ Overflow caused by alternative defines, not applicable to target*/
+ − {
+ − PALLOC_SDU ( rrrrlp_data_ind, RRRRLP_DATA_IND, (USHORT)(size_tot * BITS_PER_BYTE) );
+ −
+ − sdu2 = &rrrrlp_data_ind->sdu;
+ −
+ − memcpy ( &sdu2->buf[ 0 ], &sdu->buf [0], size_cur );
+ − memcpy ( &sdu2->buf[size_cur], &apdu_data->apdu_info[0], size_inf );
+ −
+ − sdu2->l_buf = (USHORT)(size_tot * BITS_PER_BYTE);
+ − sdu2->o_buf = 0;
+ −
+ − PFREE ( applic_rx->rrrrlp_data_ind );
+ − applic_rx->rrrrlp_data_ind = rrrrlp_data_ind;
+ −
+ − return TRUE;
+ − }
+ − else
+ − {
+ − return FALSE;
+ − }
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : rr_applic_rx_msg_send
+ − +------------------------------------------------------------------------------
+ − | Description : Send the re-segmented APDU to RRRRLP.
+ − | Reference: 3GPP TS 04.18, 3.4.21.3.2
+ − |
+ − | Parameters : The C/R bit of the last APDU segment received.
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL void rr_applic_rx_msg_send ( UBYTE cr )
+ − {
+ − GET_INSTANCE_DATA;
+ − T_APPLIC_RX *applic_rx = &rr_data->applic_rx;
+ − T_RRRRLP_DATA_IND *rrrrlp_data_ind = applic_rx->rrrrlp_data_ind;
+ −
+ − rrrrlp_data_ind->cr = cr;
+ − PSENDX ( RRLP, rrrrlp_data_ind );
+ − applic_rx->rrrrlp_data_ind = NULL;
+ − applic_rx->state = SAI_NULL;
+ − TIMERSTOP ( TAPDU );
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : dat_for_applic_info_rrlp_rx_null
+ − +------------------------------------------------------------------------------
+ − | Description : Received the first segment of an APDU.
+ − | Reference: 3GPP TS 04.18, 3.4.21.3.2
+ − |
+ − | Parameters : b_applic_info: The first segment of an APDU.
+ − | seg: the combinbed APDU control flags
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL void dat_for_applic_info_rrlp_rx_null ( T_B_APPLIC_INFO * b_applic_info, UBYTE seg )
+ − {
+ − GET_INSTANCE_DATA;
+ − T_APPLIC_RX *applic_rx = &rr_data->applic_rx;
+ −
+ − TRACE_ASSERT ( applic_rx->rrrrlp_data_ind EQ NULL );
+ −
+ − switch ( seg )
+ − {
+ − case FIRST_SEG | LAST_SEG :
+ − /* Allowed, simple case. Forward segment and stay in state SAI_NULL */
+ − rr_applic_rx_msg_store ( b_applic_info );
+ − #ifdef REL99
+ − /* Send RRLP procedure start indication to MM*/
+ − {
+ − PALLOC (rr_rrlp_start_ind, RR_RRLP_START_IND);
+ − PSENDX (MM, rr_rrlp_start_ind);
+ − }
+ − #endif
+ − rr_applic_rx_msg_send ( b_applic_info->apdu_flags.c_r );
+ − break;
+ −
+ − case FIRST_SEG | NOT_LAST_SEG:
+ − /* Allowed, standard case of APDU segmentation. */
+ − /* Check length of this segment -> L2 frame must be 251 bytes,
+ − otherwise protocol error as described in 3GPP 04.18, section 3.4.21.3.3 a) */
+ −
+ − if ( b_applic_info->apdu_data.c_apdu_info EQ APDU_FULL_L2_FRAME )
+ − {
+ − /* store this segment, start de-segmentation */
+ − rr_applic_rx_msg_store ( b_applic_info );
+ − TIMERSTART ( TAPDU, 2500 /* milli seconds */ ); /* 3GPP TS 04.18, 3.4.21.3.2 */
+ − applic_rx->state = SAI_SEGM;
+ − #ifdef REL99
+ − /* Send RRLP procedure start indication to MM*/
+ − {
+ − PALLOC (rr_rrlp_start_ind, RR_RRLP_START_IND);
+ − PSENDX (MM, rr_rrlp_start_ind);
+ − }
+ − #endif
+ − }
+ − else
+ − {
+ − /* Protocol error occured, remain in state SAI_NULL,
+ − discard segment (cf 3.4.21.3.3, last clause). */
+ − }
+ − break;
+ −
+ − case NOT_FIRST_SEG | LAST_SEG :
+ − case NOT_FIRST_SEG | NOT_LAST_SEG:
+ − /* Not allowed. Protocol error as described in 3GPP 04.18, section 3.4.21.3.3 c),
+ − discard segment as described in last sentence of 3.4.21.3.3 */
+ − break;
+ −
+ − default:
+ − TRACE_EVENT_P1 ("unexpected 'default:' seg=%d", seg );
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : dat_for_applic_info_rrlp_rx_segm
+ − +------------------------------------------------------------------------------
+ − | Description : Received second and subsequent segments of an APDU.
+ − | Reference: 3GPP TS 04.18, 3.4.21.3.2
+ − |
+ − | Parameters : b_applic_info: A segment of an APDU.
+ − | seg: the combinbed APDU control flags
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL void dat_for_applic_info_rrlp_rx_segm ( T_B_APPLIC_INFO * b_applic_info, UBYTE seg )
+ − {
+ − GET_INSTANCE_DATA;
+ − T_APPLIC_RX *applic_rx = &rr_data->applic_rx;
+ −
+ − TRACE_ASSERT ( applic_rx->rrrrlp_data_ind NEQ NULL );
+ −
+ − switch ( seg )
+ − {
+ − case FIRST_SEG | LAST_SEG :
+ − case FIRST_SEG | NOT_LAST_SEG:
+ −
+ − /* Abnormal case, refer to 3GPP TS 04.18, 3.4.21.3.3 b), clause 2 */
+ − /* Discard any partially reassembed APDU, enter state SAI_NULL */
+ −
+ − rr_applic_rx_init ( applic_rx );
+ −
+ − /* Now (re-)use the current segment, refer to 3GPP TS 04.18, 3.4.21.3.3:
+ − "...reprocess any received APDU or APDU segment that caused the error... " */
+ −
+ − dat_for_applic_info_rrlp_rx_null ( b_applic_info, seg );
+ − break;
+ −
+ − case NOT_FIRST_SEG | LAST_SEG :
+ −
+ − /* Normal case, end of re-segmentation, TAPDU stop,
+ − send the message to the application entity.
+ − Enter state SAI_NULL. */
+ −
+ − if ( rr_applic_rx_msg_append ( b_applic_info ) EQ FALSE )
+ − rr_applic_rx_init ( applic_rx );
+ − else
+ − rr_applic_rx_msg_send ( b_applic_info->apdu_flags.c_r );
+ − break;
+ −
+ − case NOT_FIRST_SEG | NOT_LAST_SEG:
+ −
+ − /* Normal case, re-segmetation is still ongoing.
+ − If 'append' operation fails, then return to state SAI_NULL. */
+ −
+ − if ( rr_applic_rx_msg_append ( b_applic_info ) EQ FALSE )
+ − rr_applic_rx_init ( applic_rx );
+ − break;
+ −
+ − default:
+ − break;
+ − }
+ − }
+ −
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : dat_for_applic_info_rrlp
+ − +------------------------------------------------------------------------------
+ − | Description : Application Information Transfer (RX) for RRRLP
+ − | Reference: 3GPP TS 04.18, 3.4.21.3
+ − |
+ − | Parameters : b_applic_info: Segment of an APDU.
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − LOCAL void dat_for_applic_info_rrlp ( T_B_APPLIC_INFO * b_applic_info )
+ − {
+ − GET_INSTANCE_DATA;
+ − T_APPLIC_RX *applic_rx = &rr_data->applic_rx;
+ −
+ − UBYTE seg = ((b_applic_info->apdu_flags.f_seg << 1) |
+ − (b_applic_info->apdu_flags.l_seg ) ) & 0x03;
+ −
+ − switch ( applic_rx->state )
+ − {
+ − case SAI_NULL :
+ − dat_for_applic_info_rrlp_rx_null ( b_applic_info, seg );
+ − break;
+ −
+ − case SAI_SEGM :
+ − dat_for_applic_info_rrlp_rx_segm ( b_applic_info, seg );
+ − break;
+ −
+ − default:
+ − break;
+ − }
+ − }
+ −
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : dat_for_applic_info
+ − +------------------------------------------------------------------------------
+ − | Description : Main entry point for Application Information Transfer (RX)
+ − | Reference: 3GPP TS 04.18, 3.4.21.3
+ − |
+ − | Parameters : b_applic_info: Segment of an APDU.
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL void dat_for_applic_info ( T_B_APPLIC_INFO * b_applic_info )
+ − {
+ − /*
+ − * handle RRLP, all other protocols are not supported
+ − */
+ − if ( b_applic_info->apdu_id.protoc_ident EQ RRLP_LCS )
+ − {
+ − dat_for_applic_info_rrlp ( b_applic_info );
+ − }
+ − else
+ − {
+ − TRACE_EVENT_P1 ( "unsupported protocol %x", b_applic_info->apdu_id.protoc_ident );
+ − }
+ − }
+ − #endif /* FF_EOTD */
+ −
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_for_handover_mob_alloc |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : This function generates a frequency hopping list for handover
+ −
+ − */
+ −
+ − LOCAL BOOL dat_for_handover_mob_alloc(UBYTE *mob_alloc,
+ − T_LIST *hop_list_handover,
+ − T_VOID_STRUCT *mob_alloc_handover,
+ − T_DL_DATA_IND *dl_data_ind)
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION("dat_for_handover_mob_alloc()");
+ − /*
+ − * the handover command contains a mobile allocation.
+ − * Convert the bitmap to a list of the 1-bits in the
+ − * bitmap for generating a frequency hopping list.
+ − */
+ − att_bits_to_byte (mob_alloc,
+ − ((T_mob_alloc *)mob_alloc_handover)->c_mac,
+ − ((T_mob_alloc *)mob_alloc_handover)->mac);
+ −
+ − /*
+ − * Now create the frequency hopping list
+ − */
+ − if(!srv_create_chan_mob_alloc (&rr_data->cr_data.cd.cell_chan_desc,
+ − hop_list_handover,
+ − mob_alloc))
+ − {
+ − dat_send_handov_fail_msg(RRC_FREQ_NOT_IMPL);
+ −
+ − RR_EM_SET_HANDOVER_FAIL_CAUSE(RRC_FREQ_NOT_IMPL);
+ −
+ − PFREE (dl_data_ind);
+ − return TRUE;
+ − }
+ − return FALSE;
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_cr_data_multirate_conf |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : This function extracts the multirate configuration and stores
+ − it in the rr_data.
+ −
+ − */
+ − LOCAL void dat_cr_data_multirate_conf(U8 v_multirate_conf, T_multirate_conf *multirate_conf)
+ −
+ − {
+ − GET_INSTANCE_DATA;
+ − TRACE_FUNCTION("dat_cr_data_multirate_conf()");
+ −
+ − if(rr_data->cr_data.ch_mode EQ CM_AMR)
+ − {
+ − if (v_multirate_conf)
+ − {
+ − /*
+ − * store a new multi-rate speech codec if available.
+ − */
+ − UBYTE i;
+ −
+ − rr_data->cr_data.amr_conf.mr_vers = multirate_conf->mr_vers;
+ − rr_data->cr_data.amr_conf.nscb = multirate_conf->nscb;
+ − rr_data->cr_data.amr_conf.icmi = multirate_conf->icmi;
+ − rr_data->cr_data.amr_conf.st_mode = multirate_conf->st_mode;
+ − rr_data->cr_data.amr_conf.set_amr = multirate_conf->set_amr;
+ −
+ − /*
+ − * valid flag for the threshold and hystersis values. multirate_conf.c_cod_prop
+ − * defines the number of threshold and hystersis values.
+ − */
+ − rr_data->cr_data.amr_conf.v_cod_prop = multirate_conf->v_cod_prop;
+ −
+ − if(rr_data->cr_data.amr_conf.v_cod_prop)
+ − {
+ − rr_data->cr_data.amr_conf.c_cod_prop = multirate_conf->c_cod_prop;
+ −
+ − for (i=0; i< multirate_conf->c_cod_prop; i++)
+ − memcpy(&rr_data->cr_data.amr_conf.cod_prop[i], &multirate_conf->cod_prop[i], sizeof(T_cod_prop));
+ − } /* if(rr_data->cr_data.amr_conf.v_cod_prop) */
+ − } /* if (assign_cmd->v_multirate_conf) */
+ − } /* if (rr_data->cr_data.ch_mode EQ CM_AMR) */
+ − }
+ −
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_class_chng_data_req |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : This function forms a peer CLASSMARK CHANGE request
+ −
+ − */
+ − GLOBAL void dat_class_chng_data_req(void)
+ − {
+ − GET_INSTANCE_DATA;
+ −
+ − TRACE_FUNCTION("dat_class_chng_data_req()");
+ − /*
+ − * The syntax check indicates no problems, then
+ − * process the message.
+ − *
+ − * The MS returns a classmark change message.
+ − */
+ − {
+ − MCAST (class_chng, U_CLASS_CHNG);/* T_U_CLASS_CHNG */
+ − PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_CLASS_CHNG);
+ −
+ − /*
+ − * set channel type and sapi
+ − */
+ − dat_code_prr_channel (&dl_data_req->ch_type,
+ − &dl_data_req->sapi, rr_data->sc_data.chan_desc.chan_type);
+ −
+ − class_chng->msg_type = U_CLASS_CHNG;
+ − class_chng->mob_class_2 = rr_data->ms_data.classmark2;
+ − class_chng->mob_class_2.rf_pow_cap = att_get_power ();
+ − class_chng->mob_class_3 = rr_data->ms_data.classmark3;
+ − class_chng->v_mob_class_3 = rr_data->ms_data.classmark2.class3;
+ −
+ − for_dat_data_req (dl_data_req);
+ − }
+ − }
+ − /*
+ − +--------------------------------------------------------------------+
+ − | PROJECT : GSM-PS (6147) MODULE : RR_DAT |
+ − | STATE : code ROUTINE : dat_dedicated_req_ch_type2 |
+ − +--------------------------------------------------------------------+
+ −
+ − PURPOSE : This function extracts the channle type from the channel
+ − description IE .
+ −
+ − */
+ − LOCAL void dat_dedicated_req_ch_type2(T_ch_type2 *ch_type2, T_chan_desc_before *chan_desc_before,
+ − T_LIST *hop_list_before)
+ − {
+ − GET_INSTANCE_DATA;
+ −
+ − TRACE_FUNCTION("dat_dedicated_req_ch_type2()");
+ −
+ − ch_type2->ch = chan_desc_before->chan_type;
+ − ch_type2->tn = chan_desc_before->tn;
+ − ch_type2->tsc = chan_desc_before->tsc;
+ − ch_type2->h = chan_desc_before->hop;
+ − if(ch_type2->h EQ H_NO)
+ − ch_type2->arfcn = chan_desc_before->arfcn;
+ − else
+ − {
+ − ch_type2->maio = chan_desc_before->maio;
+ − ch_type2->hsn = chan_desc_before->hsn;
+ −
+ − /* CSI-LLD section:4.1.1.11
+ − * This function Updates the black list with the MA list received
+ − * in the assignment command
+ − */
+ − cs_remove_BA_MA_from_black_list(rr_data->cs_data.region,hop_list_before);
+ −
+ − srv_create_list (hop_list_before, ch_type2->ma,
+ − MAX_MA_CHANNELS, TRUE, 0);
+ − }
+ − }
+ −
+ − #if defined (REL99) && defined (TI_PS_FF_EMR)
+ − /*
+ − +------------------------------------------------------------------------------
+ − | Function : dat_for_meas_inf
+ − +------------------------------------------------------------------------------
+ − | Description : Processing of measurement information message is done in this function.
+ − | All possible errors, if present, are detected and an error free MI-message
+ − | instance is decoded and data base updated with the enhanced measurement parameters.
+ − | Parameters : MI-message pointer
+ − |
+ − +------------------------------------------------------------------------------
+ − */
+ − GLOBAL BOOL dat_for_meas_inf (T_D_MEAS_INF *p_mi)
+ − {
+ − GET_INSTANCE_DATA;
+ − T_rr_enh_para *p_cur = &rr_data->sc_data.emr_data_current;
+ − T_rr_enh_para *p_temp = &rr_data->sc_data.emr_data_temp;
+ − BOOL send_enh_para = FALSE;
+ − T_gprs_rep_prio *p_rep = NULL;
+ − T_gprs_bsic *p_bl = NULL;
+ −
+ − #if defined (TI_PS_FF_RTD) AND defined (REL99)
+ − UBYTE i,j;
+ − #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+ −
+ −
+ − /* Step 1: Check if we received right BA_IND */
+ − if( (rr_data->sc_data.ba_list_ded EQ TRUE) AND
+ − (p_mi->ba_ind NEQ rr_data->sc_data.ba_index ) )
+ − {
+ − rr_data->sc_data.ba_list_ded = FALSE;
+ − rr_data->sc_data.ba_index = p_mi->ba_ind ;
+ − srv_clear_list (&rr_data->sc_data.cd.ncell_list);
+ − #ifdef TI_PS_FF_REL4
+ − srv_clear_list (&rr_data->sc_data.cd.multiband_ncell_list);
+ − #else
+ − srv_clear_list (&rr_data->sc_data.five_ter_list);
+ − #endif
+ − att_clean_buf (IND_ALL_DEDI_SI);
+ − rr_data->sc_data.cd.sys_info_read &= ~ALL_DEDI_SYS_INFOS;
+ − TRACE_EVENT("Flushed off the entire dedicated mode BA-LIST as the BA-IND got changed");
+ − }
+ −
+ − /* Step 2: Check report type.
+ − IMPORTANT ASSUMPTION: We will not process the other parameters if report type is Normal*/
+ − if( p_mi->report_type NEQ ENHANCED_MEAS )
+ − {
+ − /*check whether there are enhanced parameters and BA list, already.
+ − If present then it means that report type is changing from
+ − Enhanced to Normal*/
+ − if ( p_cur->is_data_valid EQ TRUE )
+ − {
+ − for_set_default_emr_data(p_cur);
+ − return TRUE; /*send enh para update to indicate change in report type*/
+ − }
+ − else
+ − return send_enh_para;
+ − }
+ −
+ − /* Step 3: Check if we already have enh_para in current or temp
+ − and if there is change in parameters or continuation of reception*/
+ − if(p_temp->is_data_valid EQ FALSE )
+ − {
+ − /*This means we were not in the process of receiving. Check whether there
+ − is already information in current and if so, is there change in mp_change_mark*/
+ − if( (p_cur->is_data_valid EQ TRUE ) AND
+ − (p_cur->mp_change_mark EQ p_mi->mp_cm ) )
+ − {
+ − TRACE_EVENT("No change in Enhanced measurement parameters -ignore ");
+ − return send_enh_para;
+ − }
+ − /* This means there's either a change in MP change mark or receiving EMP for first time */
+ − /* Decode rest of the parameters*/
+ − p_temp->is_data_valid = TRUE;
+ − rr_data->sc_data.enh_para_status = ENH_PARA_INVALID_STATE;
+ − p_temp->enh_para.ncc_permitted = rr_data->sc_data.cd.ncc_permitted;
+ − }
+ −
+ − /*Note :If different values occur for the same parameter in different instances of a message,
+ − the instance with the highest index shall be used (sec.3.4.1.2.1, 4.18)*/
+ − if ( (p_mi->mi_idx > rr_data->sc_data.prev_highest_index ) OR
+ − (rr_data->sc_data.prev_highest_index EQ NOT_PRESENT_8BIT) )
+ − {
+ − p_temp->enh_para.rep_rate = p_mi->rep_rate;
+ − p_temp->enh_para.inv_bsic_enabled = p_mi->inv_bsic_rep;
+ − p_temp->mp_change_mark = p_mi->mp_cm;
+ − p_temp->msg_count = p_mi->mi_c;
+ − p_temp->rep_type = p_mi->report_type;
+ − if (p_mi->v_emp EQ TRUE ) /* This is updation of parameters other than BSIC list*/
+ − {
+ − dat_update_emr_rep_para(&p_mi->emp,&p_temp->enh_para);
+ − }
+ − rr_data->sc_data.prev_highest_index = p_mi->mi_idx;
+ − }
+ −
+ − #if defined (TI_PS_FF_RTD) AND defined (REL99)
+ − if(p_mi->v_rtdd)
+ − dat_update_rtd_data(p_mi,p_temp);
+ − #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+ −
+ −
+ − /*Get relevant parameters to pass to BSIC and report priority list handler*/
+ − if(p_mi->v_gprs_rep_prio EQ TRUE)
+ − p_rep = &p_mi->gprs_rep_prio;
+ −
+ − if( p_mi->v_gprs_bsic EQ TRUE)
+ − p_bl = &p_mi->gprs_bsic;
+ −
+ − if (for_dat_process_common_emr_data(p_rep,p_bl,p_mi->mi_idx,
+ − rr_data->sc_data.ba_list_ded) )
+ − {
+ − rr_data->sc_data.enh_para_status = ENH_PARA_DEDICATED;
+ −
+ − if ( rr_data->sc_data.ba_list_ded EQ TRUE)
+ − send_enh_para = TRUE;
+ − }
+ −
+ − #if defined (TI_PS_FF_RTD) AND defined (REL99)
+ − if(p_mi->v_rtdd)
+ − {
+ − /* reset the temporary storage to RTD value not available */
+ − for(j = 0;j < MAX_NR_OF_NCELL; j++ )
+ − {
+ − p_temp->enh_para.enh_cell_list[j].v_rtd = FALSE;
+ − for(i = 0;i < MAX_NUM_OF_RTD_VALUES; i++)
+ − p_temp->enh_para.enh_cell_list[j].rtd[i]= RTD_NOT_AVAILABLE;
+ − }/*for*/
+ − }/*if*/
+ − #endif /* #if defined (TI_PS_FF_RTD) AND defined (REL99) */
+ −
+ − return send_enh_para;
+ − }
+ − #endif
+ −
+ − #endif