FreeCalypso > hg > fc-magnetite
view src/g23m-gsm/rr/rr_datp.c @ 481:24078551b620
build system: set ALLOW_CSIM_GSM=1 by default for hybrid configs
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 19 Jun 2018 06:39:18 +0000 |
parents | 27a4235405c6 |
children |
line wrap: on
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_DATP_C #define RR_DATP_C #define ENTITY_RR /*==== INCLUDES ===================================================*/ #include <string.h> #include <stdlib.h> #include <stddef.h> /* offsetof */ #include <stdio.h> /* sprintf */ #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 "rr_em.h" /*==== EXPORT =====================================================*/ #if defined (REL99) && defined (TI_PS_FF_EMR) #define MAX_MSTRUCT_CCD_RR MAXIMUM(MAX_MSTRUCT_LEN_RR_SHORT, MAX_MSTRUCT_LEN_RR) GLOBAL UBYTE _decodedMsg [MAX_MSTRUCT_CCD_RR]; #else GLOBAL UBYTE _decodedMsg [MAX_MSTRUCT_LEN_RR]; #endif /*==== PRIVAT =====================================================*/ /*==== VARIABLES ==================================================*/ /*==== FUNCTIONS ==================================================*/ /* * ------------------------------------------------------------------- * PRIMITIVE Processing functions * ------------------------------------------------------------------- */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_init_rr_data | +--------------------------------------------------------------------+ PURPOSE : Initialize the RR data for the module data transfer. */ GLOBAL void dat_init_rr_data (void) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_init_rr_data()"); SET_STATE (STATE_DAT, DAT_NULL); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_dl_establish_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive DL_ESTABLISH_CNF received from DL. */ GLOBAL void dat_dl_establish_cnf (T_DL_ESTABLISH_CNF *dl_establish_cnf_orig) { GET_INSTANCE_DATA; /* * sys infos during l2 establishment are * lost, inform layer 1 to send them again */ PPASS(dl_establish_cnf_orig, dl_establish_cnf, DL_ESTABLISH_CNF); TRACE_FUNCTION ("dat_dl_establish_cnf()"); rr_data->net_lost = FALSE; TRACE_EVENT_P1("rr_data->net_lost = %u", rr_data->net_lost); switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_ASS_1: case DAT_CHAN_ASS_2: case DAT_IMM_ASS_1: break; default : if (dl_establish_cnf->sapi EQ SAPI_0) { PALLOC (mph_sync_req, MPH_SYNC_REQ); mph_sync_req->cs = CS_CLEAN_SYS_INFO; PSENDX (PL, mph_sync_req); } break; } switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_ASS_1: /* * successfull establishment of new layer 2 connection * after channel assignment */ EM_DL_ESTABLISH_CNF; PFREE (dl_establish_cnf); if (rr_data->sc_data.ch_mode NEQ rr_data->cr_data.ch_mode) { /* * a changed channel mode has been detected. * update channel description and channel mode * for the serving cell and inform MM about the * new channel mode. */ memcpy (&rr_data->sc_data.chan_desc, &rr_data->cr_data.chan_desc, sizeof (T_chan_desc)); rr_data->sc_data.ch_mode = rr_data->cr_data.ch_mode; dat_code_channel_mode_to_mm (); } if (rr_data->cr_data.ciph_on NEQ rr_data->sc_data.ciph_on) { /* * the ciphering has changed. Inform MM about the new * ciphering. */ dat_code_ciphering_to_mm (rr_data->cr_data.ciph_on); } /* * copy cr data to sc data and go back to normal dedicated mode. */ rr_data->sc_data.ciph_on = rr_data->cr_data.ciph_on; rr_data->sc_data.algo = rr_data->cr_data.algo; rr_data->sc_data.ch_mode = rr_data->cr_data.ch_mode; rr_data->sc_data.cd.v_cell_chan_desc = rr_data->cr_data.cd.v_cell_chan_desc; memcpy (&rr_data->sc_data.cd.cell_chan_desc, &rr_data->cr_data.cd.cell_chan_desc, sizeof (T_LIST)); memcpy (&rr_data->sc_data.chan_desc, &rr_data->cr_data.chan_desc, sizeof (T_chan_desc)); memcpy (&rr_data->sc_data.amr_conf, &rr_data->cr_data.amr_conf, sizeof (T_multirate_conf)); rr_data->nc_data[CR_INDEX].arfcn = NOT_PRESENT_16BIT; att_remove_multiple_channels (); SET_STATE (STATE_SAPI_3, SMS_IDLE); srv_use_stored_prim (); dat_set_last_used_channel (&rr_data->sc_data.chan_desc); att_dat_dedicated (); dat_emo_stop ( TRUE ); SET_STATE (STATE_DAT, DAT_DEDICATED); rr_data->mode_after_dedi = MODE_CELL_RESELECTION; break; case DAT_CHAN_ASS_2: /* * successfull reconnection on old channel after failed * channel assignment * * update some parameters to go back to normal dedicated mode. */ PFREE (dl_establish_cnf); srv_use_stored_prim (); SET_STATE (STATE_SAPI_3, SMS_IDLE); att_dat_dedicated (); rr_data->nc_data[CR_INDEX].arfcn = NOT_PRESENT_16BIT; SET_STATE (STATE_DAT, DAT_DEDICATED); rr_data->mode_after_dedi = MODE_CELL_RESELECTION; EM_ASS_FAILURE_RECONNECT_SUCCESS; break; case DAT_DEDICATED: /* * An establish confirm in normal dedicated mode is only * expected for short messages (SAPI 3) */ if (dl_establish_cnf->sapi EQ SAPI_3) { SET_STATE (STATE_SAPI_3, SMS_ESTABLISHED); srv_use_stored_prim (); } PFREE (dl_establish_cnf); break; case DAT_HANDOVER_4: TRACE_EVENT ("DL_ESTABLISH_CNF"); EM_L2_CONNECTION_ESTABLISHED; PFREE (dl_establish_cnf); /* * successfull establishment of new layer 2 connection * after handover */ if (rr_data->sc_data.ch_mode NEQ rr_data->cr_data.ch_mode) { /* * a changed channel mode has been detected. * update channel description and channel mode * for the serving cell and inform MM about the * new channel mode. */ memcpy (&rr_data->sc_data.chan_desc, &rr_data->cr_data.chan_desc, sizeof (T_chan_desc)); rr_data->sc_data.ch_mode = rr_data->cr_data.ch_mode; dat_code_channel_mode_to_mm (); } if (rr_data->cr_data.ciph_on NEQ rr_data->sc_data.ciph_on) { /* * the ciphering has changed. Inform MM about the new * ciphering. */ dat_code_ciphering_to_mm (rr_data->cr_data.ciph_on); } /* * copy cr data to sc data and go back to normal dedicated mode. */ rr_data->sc_data.ciph_on = rr_data->cr_data.ciph_on; rr_data->sc_data.algo = rr_data->cr_data.algo; rr_data->sc_data.ch_mode = rr_data->cr_data.ch_mode; rr_data->sc_data.cd.v_cell_chan_desc = rr_data->cr_data.cd.v_cell_chan_desc; memcpy (&rr_data->sc_data.cd.cell_chan_desc, &rr_data->cr_data.cd.cell_chan_desc, sizeof (T_LIST)); memcpy (&rr_data->sc_data.chan_desc, &rr_data->cr_data.chan_desc, sizeof (T_chan_desc)); memcpy (&rr_data->sc_data.amr_conf, &rr_data->cr_data.amr_conf, sizeof (T_multirate_conf)); rr_data->nc_data[SC_INDEX].bsic = rr_data->nc_data[CR_INDEX].bsic; rr_data->nc_data[SC_INDEX].arfcn = rr_data->nc_data[CR_INDEX].arfcn; rr_data->nc_data[CR_INDEX].arfcn = NOT_PRESENT_16BIT; /* * after a handover we cannot come back directly to the * cell instead we have to do a normal cell reselection */ rr_data->mode_after_dedi = MODE_CELL_RESELECTION; att_remove_multiple_channels (); SET_STATE (STATE_SAPI_3, SMS_IDLE); srv_use_stored_prim (); dat_set_last_used_channel (&rr_data->sc_data.chan_desc); att_dat_dedicated (); dat_emo_stop ( TRUE ); SET_STATE (STATE_DAT, DAT_DEDICATED); break; case DAT_HANDOVER_5: TRACE_EVENT ("DL_ESTABLISH_CNF"); /* * successfull reconnection on old channel after failed * handover * * update some parameters to go back to normal dedicated mode. */ PFREE (dl_establish_cnf); srv_use_stored_prim (); SET_STATE (STATE_SAPI_3, SMS_IDLE); att_dat_dedicated (); rr_data->nc_data[CR_INDEX].arfcn = NOT_PRESENT_16BIT; SET_STATE (STATE_DAT, DAT_DEDICATED); rr_data->mode_after_dedi = MODE_CELL_RESELECTION; EM_HO_FAILURE_RECONNECT_SUCCESS; break; case DAT_IMM_ASS_1: /* * successfull establishment of a dedicated connection. * Depending on the originator of the connection MM * is informed. */ EM_L2_CONNECTION_ESTABLISHED; #ifdef GPRS if(! dat_check_packet_access()) { #endif if (rr_data->ms_data.establish_cause EQ ESTCS_PAGING) { PREUSE (dl_establish_cnf, rr_establish_ind, RR_ESTABLISH_IND); PSENDX (MM, rr_establish_ind); } else { PREUSE (dl_establish_cnf, rr_establish_cnf, RR_ESTABLISH_CNF); PSENDX (MM, rr_establish_cnf); } #ifdef GPRS } else { /* packet access */ PFREE (dl_establish_cnf); } #endif /* * initialize some variables for the dedicated mode. */ rr_data->dyn_config.fho = 0; rr_data->dyn_config.fca = 0; rr_data->tch_loop_subch = NOT_PRESENT_8BIT; rr_data->sc_data.ciph_received = FALSE; rr_data->rel_cause = RRCS_INT_NOT_PRESENT; rr_data->sc_data.ciph_on = CIPH_OFF; att_copy_old_lai_rac(SC_INDEX); #if 0 memcpy (&rr_data->old_lai, &rr_data->nc_data[SC_INDEX].lai, sizeof (rr_data->old_lai)); rr_data->old_cell_id = rr_data->nc_data[SC_INDEX].cell_id; #endif SET_STATE (STATE_SAPI_3, SMS_IDLE); att_dat_dedicated (); SET_STATE (STATE_DAT, DAT_DEDICATED); /* * Early classmark Sending is performed if the mobile supports it * and the network requests it. */ if (rr_data->ms_data.classmark2.es_ind AND rr_data->nc_data[SC_INDEX].c2_par.ecsc) { /* * building of the Early Classmark Sending message */ /* Implements RR Clone findings #15 */ dat_class_chng_data_req(); } #ifdef GPRS dat_gprs_suspend_req (); #endif EM_EARLY_CLASSMARK_SENDING; break; #ifdef GPRS case DAT_PDCH_ASS_4: dat_rrgrr_reconnect_dcch_cnf (RECONN_OK); SET_STATE (STATE_DAT, DAT_DEDICATED); PFREE (dl_establish_cnf); break; case DAT_CCO_4: if ( rr_data->gprs_data.cco_need_reconnect_cnf ) { dat_rrgrr_reconnect_dcch_cnf (RECONN_OK); } else { /* * GRR has received d_change_order message, * but the BCCH reading in the new cell failed. * The connection is resumed on the old channel * in dedicated mode. */ PALLOC (rrgrr_sync_ind, RRGRR_SYNC_IND); rrgrr_sync_ind->sync_res = SYNC_FAILED; PSENDX (GRR, rrgrr_sync_ind); } SET_STATE (STATE_DAT, DAT_DEDICATED); PFREE (dl_establish_cnf); break; #endif default: PFREE (dl_establish_cnf); break; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_dl_establish_ind | +--------------------------------------------------------------------+ PURPOSE : Process the primitive DL_ESTABLISH_IND received from DL. This is only expected for short messages on SAPI 3 during a connection. */ GLOBAL void dat_dl_establish_ind (T_DL_ESTABLISH_IND *dl_establish_ind) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_dl_establish_ind()"); switch (GET_STATE (STATE_DAT)) { case DAT_DEDICATED: /* * if it indicates a mobile terminated connection establishment * for SAPI 3 in the layer 2, change the state in RR for SMS. * Answers from upper layer for SMS can be forwarded then * immediately. */ if (dl_establish_ind->sapi EQ SAPI_3) { /* * set state for SMS if it is on SAPI 3 */ SET_STATE (STATE_SAPI_3, SMS_ESTABLISHED); srv_use_stored_prim (); } break; default: break; } PFREE (dl_establish_ind); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_mph_random_access_cnf | +--------------------------------------------------------------------+ PURPOSE : Layer 1 confirms with the primitive MPH_RANDOM_ACCESS_CNF the sending of a random burst during connection establishment. */ GLOBAL void dat_mph_random_access_cnf (T_MPH_RANDOM_ACCESS_CNF *mph_random_access_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_mph_random_access_cnf()"); EM_CHANNEL_REQUEST_SENT; switch (GET_STATE (STATE_DAT)) { case DAT_IMM_ASS: if (rr_data->ms_data.access_counter < rr_data->ms_data.max_attempt) { /* * if it the last or less then last random burst * copy the frame number of the random burst for later * comparision with the request reference of an immediate * assignment message. */ memcpy (&rr_data->used_frame_no[rr_data->ms_data.access_counter], &mph_random_access_cnf->frame_no, sizeof (T_frame_no)); /* TRACE_EVENT_P5 ("RA %u CNF: %d %d %d 0x%02x", rr_data->ms_data.access_counter, mph_random_access_cnf->frame_no.t1, mph_random_access_cnf->frame_no.t2, mph_random_access_cnf->frame_no.t3, rr_data->used_channel_ref[rr_data->ms_data.access_counter]); */ /* * increment the number of already sent messages */ rr_data->ms_data.access_counter++; if (rr_data->ms_data.access_counter EQ rr_data->ms_data.max_attempt) { /* * T3126 and T3146 (GPRS Packet Access on CCCH) are * the same so use them for both purposes * * if it is the last random burst, start T3126 if the timer is not * running yet (can be started after reception of an immediate * assignment reject message). * The timer controls reception of an immediate assignment message * as response to the random bursts. */ /* Implements Measure#32: Row 196,197 */ (IS_TIMER_ACTIVE(T3126)) ? TRACE_TIMER ( "T3126 re-start") : TRACE_TIMER ( "T3126 start"); if (! IS_TIMER_ACTIVE(T3126)) { TIMERSTART (T3126, T3126_VALUE); } /* * set a flag that all random bursts are send and confirmed. */ rr_data->ms_data.all_conf_received = TRUE; } } break; default: break; } PFREE (mph_random_access_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_dl_release_cnf | +--------------------------------------------------------------------+ PURPOSE : Layer 2 confirms with DL_RELEASE_CNF a disconnection on layer 2 which has been initiated by RR. */ GLOBAL void dat_dl_release_cnf (T_DL_RELEASE_CNF *dl_release_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_dl_release_cnf()"); switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_REL: /* * after reception of a channel release message RR has * started disconnection to come from dedicated to idle * mode. Stop T3110, which controls the disconnection in * layer 2. */ TIMERSTOP (T3110); /* * Send STOP_DEDICATED_REQUEST to L1 and wait for confirmation */ att_stop_dedicated(); break; #ifdef GPRS case DAT_PDCH_ASS_2: dat_rrgrr_resumed_tbf_cnf(); rr_data->gprs_data.tbf_est = TBF_EST_NONE; /* the initial state */ break; #endif case DAT_HANDOVER_4: TRACE_EVENT ("Event: DAT_HANDOVER_4"); /* * the layer 2 resumption on the new channel during handover * has failed and RR switches back to the old channel. */ dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_HANDOVER_5); break; case DAT_CHAN_ASS_1: /* * resumption of layer 2 has failed after channel assignment * go back to the old channel. */ dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_CHAN_ASS_2); break; case DAT_DEDICATED: case DAT_CHAN_ASS: case DAT_CHAN_ASS_2: case DAT_HANDOVER_5: TRACE_EVENT ("Event: DAT_DEDICATED, DAT_CHAN_ASS, DAT_CHAN_ASS_2 or DAT_HANDOVER_5"); if (dl_release_cnf->sapi EQ SAPI_3) { /* * the connection for SAPI 3 is disconnected by the * network. */ SET_STATE (STATE_SAPI_3, SMS_IDLE); dat_rr_release_ind(RRCS_DATA_LINK_FAIL, SAPI_3); /* * clear any stored SAPI 3 message */ srv_clear_stored_prim (RR_DATA_REQ); } else { /* * the reconnection to the old channel has failed * or a lower layer failure had happen. * Indicate the abort to MM and start cell reselection. */ switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_ASS: case DAT_CHAN_ASS_2: TRACE_EVENT("Assignment failed: reconnect failed"); EM_ASS_FAILURE_RECONNECT_FAILED; break; case DAT_HANDOVER_5: TRACE_EVENT("Handover failed: reconnect failed"); EM_HO_FAILURE_RECONNECT_FAILED; break; default: break; } att_code_rr_abort_ind (RRCS_DATA_LINK_FAIL); rr_data->net_lost = TRUE; att_stop_dedicated(); } break; case DAT_IMM_ASS_1: /* * Layer 2 establishment has failed for immediate assignment * Stop dedicated and go back to idle mode. MM will be informed about * release after receiving MPH_STOP_DEDICATED_CNF from L1. */ if (rr_data->ms_data.establish_cause NEQ ESTCS_PAGING) { rr_data->rel_cause = RRCS_DL_EST_FAIL; } att_stop_dedicated(); break; default: break; } PFREE (dl_release_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_dl_release_ind | +--------------------------------------------------------------------+ PURPOSE : Layer 2 indicates disconnection due to layer 2 problems. */ GLOBAL void dat_dl_release_ind (T_DL_RELEASE_IND *dl_release_ind) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_dl_release_ind()"); switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_ASS: case DAT_CHAN_ASS_2: case DAT_DEDICATED: case DAT_HANDOVER: case DAT_HANDOVER_5: TRACE_EVENT ("DL_RELEASE_IND"); if (dl_release_ind->sapi EQ SAPI_3) { /* * indicate release for SAPI 3 (SMS) * to MM and reset RR state back to SMS_IDLE. */ dat_rr_release_ind(RRCS_DATA_LINK_FAIL, SAPI_3); SET_STATE (STATE_SAPI_3, SMS_IDLE); /* * clear any stored SAPI 3 message */ srv_clear_stored_prim (RR_DATA_REQ); } else { /* * Delay 4 frames to allow sending UA response * in RF for FTA testcase 25.2.3 * else the idle mode is configured too early. * vsi_t_sleep (VSI_CALLER FOUR_FRAMES); * * msb: DL delays the release indication itself for completion of the * UA response transmission. */ EM_DL_RELEASE_IND; /* * Inform MM about the release and start cell reselection. */ att_code_rr_abort_ind (RRCS_DATA_LINK_FAIL); rr_data->net_lost = TRUE; att_stop_dedicated(); } break; case DAT_CHAN_ASS_1: /* * resumption of layer 2 has failed after channel assignment * go back to the old channel. */ dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_CHAN_ASS_2); EM_ASS_FAILURE_RECONNECT_FAILED2 break; case DAT_CHAN_REL: /* * after reception of a channel release message RR has * started disconnection to come from dedicated to idle * mode. Stop T3110, which controls the disconnection in * layer 2. */ TIMERSTOP (T3110); /* * Send STOP_DEDICATED_REQUEST to L1 and wait for confirmation */ att_stop_dedicated(); EM_L2_CONNECTION_LOST; break; case DAT_HANDOVER_4: TRACE_EVENT ("DL_RELEASE_IND"); /* * resumption of layer 2 has failed handover * go back to the old channel. */ dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_HANDOVER_5); EM_HO_FAILURE_RECONNECT_FAILED2; break; case DAT_IMM_ASS_1: /* * layer 2 establishment has failed during immediate assignment */ if (dl_release_ind->cs EQ DL_INFO_FIELD_MISMATCH AND rr_data->sc_data.first_attempt) { /* * if the reason is a mismatch in the layer 3 messages in SABM * and the response UA, a second attempt of establishment is started. */ rr_data->sc_data.first_attempt = FALSE; rr_data->repeat_est = TRUE; #ifdef GPRS if (rr_data->ms_data.establish_cause EQ ESTCS_GPRS_PAGING) rr_data->dcch_stop_cause = CONTENTION_RESOLUTION_FAIL; #endif } else { switch (rr_data->ms_data.establish_cause) { #ifdef GPRS case ESTCS_GPRS_PAGING: rr_data->dcch_stop_cause = DL_ESTABLISHMENT_FAIL; break; case ESTCS_PAGING: rr_data->rel_cause = RRCS_INT_NOT_PRESENT; #else case ESTCS_PAGING: #endif break; default: rr_data->rel_cause = RRCS_DL_EST_FAIL; break; } } /* * Stop dedicated and go back to idle mode. */ att_stop_dedicated(); break; #ifdef GPRS case DAT_PDCH_ASS_4: case DAT_CCO_4: if ( GET_STATE (STATE_DAT) EQ DAT_PDCH_ASS_4 OR rr_data->gprs_data.cco_need_reconnect_cnf ) { dat_rrgrr_reconnect_dcch_cnf (RECONN_LOW_FAIL); } att_build_idle_req (SC_INDEX, MODE_CELL_RESELECTION); SET_STATE (STATE_DAT, DAT_IDLE); break; #endif default: break; } PFREE (dl_release_ind); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_mph_dedicated_cnf | +--------------------------------------------------------------------+ PURPOSE : Layer 1 confirms the configuration of a dedicated channel. */ GLOBAL void dat_mph_dedicated_cnf (T_MPH_DEDICATED_CNF *mph_dedicated_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_mph_dedicated_cnf()"); switch (GET_STATE (STATE_DAT)) { case DAT_IMM_ASS_1: /* * A dedicated channel has been configured after * reception of the immediate assignment message. * * clear neighbourcell list and start layer 2 establishment */ 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; /* * from now on we have a channel assigned * even if the contention resolution is not * done yet. If the contention resolution fails * we use the same procedure for selecting a cell * as in dedicated mode */ rr_data->mode_after_dedi = MODE_CELL_SELECTION; /* default mode */ TIMERSTART (T_DEDICATED_MODE, THIRTY_SEC); #ifdef GPRS if(! dat_gprs_start_sabm()) #endif dat_start_sabm (); break; case DAT_CHAN_ASS: if (rr_data->dyn_config.fca) { /* * special testfeature to force a failed layer 2 establishment * during channel assignment. Reset flag and switch back to old * channel. */ rr_data->dyn_config.fca = 0; dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_CHAN_ASS_2); } else { /* * Resume layer 2 connection on the new channel with * an assignment complete message. */ MCAST (assign_com, U_ASSIGN_COMP); PALLOC_MSG ( dl_resume_req, DL_RESUME_REQ, U_ASSIGN_COMP); SET_STATE (STATE_DAT, DAT_CHAN_ASS_1); assign_com->msg_type = U_ASSIGN_COMP; assign_com->rr_cause = RRC_NORMAL_EVENT; /* * set channel and sapi for the new channel description */ dat_code_prr_channel (&dl_resume_req->ch_type, &dl_resume_req->sapi, rr_data->cr_data.chan_desc.chan_type); /* * start layer 2 resumption. */ for_dat_resume_req (dl_resume_req); EM_ASSIGNMENT_COMPLETE; } break; #ifdef GPRS case DAT_PDCH_ASS: /* * The current channel has been stopped at the Physical Layer. */ dat_rrgrr_suspend_dcch_cnf(); SET_STATE (STATE_DAT, DAT_PDCH_ASS_1); SET_STATE (STATE_GPRS, GPRS_PIM_BCCH); /* force MPH_IDLE_REQ with RRGRR_STOP_MON_CCCH_REQ */ rr_data->gprs_data.tbf_est = TBF_EST_PDCH; break; #endif case DAT_HANDOVER: { /* * clearing of neighbourcells is already done * after reception of the handover command. * * following behaviour depends on the result of * handover execution in layer 1. */ switch (mph_dedicated_cnf->dedi_res) { case DEDI_RES_OK: /* * handover is successfull. */ if (rr_data->dyn_config.fca) { /* * special testfeature to simulate * failed handover, reset flag * and start reconnection. */ rr_data->dyn_config.fca = 0; dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_HANDOVER_5); } else { /* * build a handover complete message. */ MCAST (handov_comp, U_HANDOV_COMP); PALLOC_MSG (dl_resume, DL_RESUME_REQ, U_HANDOV_COMP); if (rr_data->ms_data.ho_type.rot EQ TIME_DIFF_YES) { /* * handover command has requested the observed time difference. */ handov_comp->v_mob_time_diff = TRUE; handov_comp->mob_time_diff.diff = rr_data->sc_data.observed_ta; } else { handov_comp->v_mob_time_diff = FALSE; } handov_comp->msg_type = U_HANDOV_COMP; handov_comp->rr_cause = RRC_NORMAL_EVENT; /* * set channel type and sapi for the new channel */ dat_code_prr_channel (&dl_resume->ch_type, &dl_resume->sapi, rr_data->cr_data.chan_desc.chan_type); EM_HANDOVER_COMPLETE; /* * start layer 2 resumption. */ for_dat_resume_req (dl_resume); SET_STATE (STATE_DAT, DAT_HANDOVER_4); } break; case DEDI_RES_TIMEOUT: /* * the timer T3124 during an asynchronous handover * has timed out, start reconnection. */ dat_code_mph_old_chan_req (); SET_STATE (STATE_DAT, DAT_HANDOVER_5); break; case DEDI_RES_CELL_NOT_SYNC : /* * Timing Info for this cell is not present in ALR. * This could be due to : * a) Cell not present in BA list, * b) Synchronization to this cell failed or not attempted. */ case DEDI_RES_TA_OUT_OF_RANGE: { /* * Layer 1 has detected that the timing advance is out of range. * In fact the new channel has not been configured and RR * can start reconnection to the old layer 2 connection immediately. * It sends a handover failure message with the expected cause. */ MCAST (handov_fail, U_HANDOV_FAIL); PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_HANDOV_FAIL); /* * set channel type and sapi for the old channel */ dat_code_prr_channel (&dl_reconnect_req->ch_type, &dl_reconnect_req->sapi, rr_data->sc_data.chan_desc.chan_type); handov_fail->msg_type = U_HANDOV_FAIL; if( mph_dedicated_cnf->dedi_res EQ DEDI_RES_TA_OUT_OF_RANGE) handov_fail->rr_cause = RRC_TIME_ADVANCE; else if ( mph_dedicated_cnf->dedi_res EQ DEDI_RES_CELL_NOT_SYNC) #if defined (REL99) && defined (FF_BHO) handov_fail->rr_cause = RRC_LOWER_LAYER_FAIL; #else handov_fail->rr_cause = RRC_CHAN_UNACCEPT; #endif RR_EM_SET_HANDOVER_FAIL_CAUSE(handov_fail->rr_cause); /* * start reconnection of the layer 2 link on the old channel. */ for_dat_reconnect_req (dl_reconnect_req); SET_STATE (STATE_DAT, DAT_HANDOVER_5); break; } } break; } default: break; } PFREE (mph_dedicated_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_mph_dedicated_fail_cnf | +--------------------------------------------------------------------+ PURPOSE : Layer 1 confirms the re-configuration of the old channel after a failed handover or channel assignment with the primitive MPH_DEDICATED_FAIL_CNF. */ GLOBAL void dat_mph_dedicated_fail_cnf (T_MPH_DEDICATED_FAIL_CNF *mph_dedicated_fail_cnf) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_mph_dedicated_fail_cnf()"); switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_ASS_2: { /* * reconnection is done in layer 2. An assignment failure * message is send to the network. */ MCAST (assign_fail, U_ASSIGN_FAIL); PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_ASSIGN_FAIL); assign_fail->msg_type = U_ASSIGN_FAIL; assign_fail->rr_cause = RRC_PROT_UNSPECIFIED; RR_EM_SET_ASSIGN_FAIL_CAUSE(assign_fail->rr_cause); /* * set channel type and SAPI for layer 2 */ dat_code_prr_channel (&dl_reconnect_req->ch_type, &dl_reconnect_req->sapi, rr_data->sc_data.chan_desc.chan_type); /* * start layer 2 reconnection */ for_dat_reconnect_req (dl_reconnect_req); break; } case DAT_HANDOVER_5: { /* * reconnection is done in layer 2. A handover failure * message is send to the network. */ MCAST (handov_fail, U_HANDOV_FAIL); PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_HANDOV_FAIL); /* * clear neighbourcell list */ 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; handov_fail->msg_type = U_HANDOV_FAIL; handov_fail->rr_cause = RRC_UNSPECIFIED; RR_EM_SET_HANDOVER_FAIL_CAUSE(handov_fail->rr_cause); /* * set channel type and SAPI for layer 2 */ dat_code_prr_channel (&dl_reconnect_req->ch_type, &dl_reconnect_req->sapi, rr_data->sc_data.chan_desc.chan_type); /* * start layer 2 reconnection */ for_dat_reconnect_req (dl_reconnect_req); break; } #ifdef GPRS case DAT_PDCH_ASS_3: { MCAST (u_assign_fail, U_ASSIGN_FAIL); PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_ASSIGN_FAIL); /* * set channel type and SAPI */ dat_code_prr_channel (&dl_reconnect_req->ch_type, &dl_reconnect_req->sapi, rr_data->sc_data.chan_desc.chan_type); u_assign_fail->msg_type = U_ASSIGN_FAIL; u_assign_fail->rr_cause = rr_data->gprs_data.reconn_cause; for_dat_reconnect_req (dl_reconnect_req); SET_STATE (STATE_DAT, DAT_PDCH_ASS_4); break; } case DAT_CCO_3: { MCAST (u_handov_fail, U_HANDOV_FAIL); PALLOC_MSG (dl_reconnect_req, DL_RECONNECT_REQ, U_HANDOV_FAIL); /* * set channel type and SAPI */ dat_code_prr_channel (&dl_reconnect_req->ch_type, &dl_reconnect_req->sapi, rr_data->sc_data.chan_desc.chan_type); u_handov_fail->msg_type = U_HANDOV_FAIL; u_handov_fail->rr_cause = rr_data->gprs_data.reconn_cause; for_dat_reconnect_req (dl_reconnect_req); SET_STATE (STATE_DAT, DAT_CCO_4); break; } #endif default: break; } PFREE (mph_dedicated_fail_cnf); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_rr_abort_req | +--------------------------------------------------------------------+ PURPOSE : MM aborts a connection due to several reasons (SIM remove, timeout, power off etc.). */ GLOBAL void dat_rr_abort_req (T_RR_ABORT_REQ *rr_abort_req) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_rr_abort_req()"); switch (GET_STATE (STATE_DAT)) { case DAT_CHAN_ASS: case DAT_CHAN_ASS_1: case DAT_CHAN_ASS_2: case DAT_DEDICATED: case DAT_HANDOVER: case DAT_HANDOVER_4: case DAT_HANDOVER_5: if (rr_abort_req->abcs EQ ABCS_SIM_REM) { /* * in case of SIM remove the registration data * especially the mobile identities are cleared */ att_clear_registration_data (); } /* * the disconnection of the layer 2 link is started. */ dat_disconnect_link (RRCS_MM_ABORTED); break; case DAT_CHAN_REL: /* * RR has already started the layer 2 link disconnection. * Wait for T3110 timeout or DL disconnection and process * normal cell reselection. */ if (rr_abort_req->abcs EQ ABCS_SIM_REM) { /* * in case of SIM remove the registration data * especially the mobile identities are cleared */ att_clear_registration_data (); } break; case DAT_IDLE: if (rr_abort_req->abcs EQ ABCS_SIM_REM) { /* * in case of SIM remove the registration data * especially the mobile identities are cleared * The idle mode is configured again to set a * faked BS_PA_MFRMS of 9 to slow down layer 1 * and save power. A correct paging group is not * longer needed, because paging is not possible * in limited service. */ att_clear_registration_data (); att_build_idle_req (SC_INDEX, MODE_SYS_INFO_CHANGE); #ifdef REL99 att_config_cbch (); #else att_build_cbch (); #endif } break; case DAT_IMM_ASS: case DAT_IMM_ASS_1: if (rr_abort_req->abcs EQ ABCS_SIM_REM) { /* * in case of SIM remove the registration data * especially the mobile identities are cleared */ att_clear_registration_data (); } /* * stop any timer related to connection establishment */ TIMERSTOP (T3122); TIMERSTOP (T3126); /* * set the release establishment cause. This will be used in * dat_release_connection() function */ rr_data->rel_cause = RRCS_MM_ABORTED; if(GET_STATE (STATE_DAT) EQ DAT_IMM_ASS) { dat_rr_release_ind(rr_data->rel_cause, SAPI_0); att_leave_dat_imm_ass(); } else { /* * go back to idle mode. * inform GRR, and don't wait for CR_RSP */ att_stop_dedicated(); } break; default: if (rr_abort_req->abcs EQ ABCS_SIM_REM) { /* * in case of SIM remove the registration data * especially the mobile identities are cleared */ att_clear_registration_data (); } /* * clear any store establish requests if available * due to a timeout abort of the upper layer. */ if (srv_check_stored_prim (RR_ESTABLISH_REQ)) { /* * release previous establish request */ dat_rr_release_ind(RRCS_MM_ABORTED, SAPI_0); srv_clear_stored_prim (RR_ESTABLISH_REQ); } break; } PFREE (rr_abort_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_rr_data_req | +--------------------------------------------------------------------+ PURPOSE : A layer 3 message of an upper layer shall be send. */ GLOBAL void dat_rr_data_req (T_RR_DATA_REQ *rr_data_req) { GET_INSTANCE_DATA; UBYTE pd; TRACE_FUNCTION ("dat_rr_data_req()"); /* * get the protocol discriminator of the message. */ GET_PD (rr_data_req->sdu, pd); if (pd EQ PD_SMS) { TRACE_EVENT ("SMS Message"); /* * A SMS must be send with SAPI 3. Therefore the * SAPI 3 connection must be established on layer 2. * The STATE_SAPI_3 variable in RR indicates whether * the connection is established or not. If not the * message is stored and the connection will be established. * A SAPI 3 connection is automatically released after * channel assignment, handover or SAPI 0 release. */ switch (GET_STATE (STATE_SAPI_3)) { case SMS_ESTABLISHED: { /* * SAPI 3 connection is available, then send the message * directly. */ PPASS (rr_data_req, dl_data_req, DL_DATA_REQ); /* * set channel type and SAPI for SMS message. */ dat_code_prr_channel_sms (dl_data_req, rr_data->sc_data.chan_desc.chan_type); for_dat_l3_data_req (dl_data_req); break; } case SMS_PENDING: /* * the establishment of SAPI 3 connection is still ongoing. * store the message until connection is ready. */ if (!srv_store_prim ((T_PRIM *)D2P(rr_data_req))) { PFREE (rr_data_req); } break; case SMS_IDLE: /* * the establishment of SAPI 3 connection is not available * store the message until connection is ready. */ if (!srv_store_prim ((T_PRIM *)D2P(rr_data_req))) { PFREE (rr_data_req); } else { /* * Maximum size of the initial message is one frame (= 23 Bytes). */ PALLOC_SDU (dl_establish_req, DL_ESTABLISH_REQ, MAX_L2_FRAME_SIZE * BITS_PER_BYTE); dat_code_prr_channel_sms ((T_DL_DATA_REQ *)dl_establish_req, rr_data->sc_data.chan_desc.chan_type); SET_STATE (STATE_SAPI_3, SMS_PENDING); for_dat_est_req (dl_establish_req); } break; } } else { /* * it is a SAPI 0 message */ PPASS (rr_data_req, dl_data_req, DL_DATA_REQ); /* * set channel type and SAPI according the channel type. */ dat_code_prr_channel (&dl_data_req->ch_type, &dl_data_req->sapi, rr_data->sc_data.chan_desc.chan_type); /* * set N(S) for upper layer message and forward it to Layer 2. */ dat_vsd_bit_set ((T_L3_SDU *)&dl_data_req->sdu, SET_ONLY); for_dat_l3_data_req (dl_data_req); } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_rr_establish_req | +--------------------------------------------------------------------+ PURPOSE : A mobile originated connection is started. */ GLOBAL void dat_rr_establish_req (T_RR_ESTABLISH_REQ *rr_establish_req) { GET_INSTANCE_DATA; TRACE_FUNCTION ("dat_rr_establish_req()"); switch (GET_STATE (STATE_DAT)) { case DAT_NULL: /* * Data transfer process is in null state, that means * the MS has no service */ if (!srv_store_prim ((T_PRIM *)D2P(rr_establish_req))) { /* * storing is not possible due to an overflow of the storage area * then reject the connection attempt. */ dat_rr_release_ind(RRCS_QUEUE_FULL, SAPI_0); PFREE (rr_establish_req); } break; case DAT_IDLE: if (IS_TIMER_ACTIVE(T3122) AND (rr_establish_req->estcs NEQ ESTCS_EMRG_CAL)) { /* * all non-emergency calls are rejected if T3122 is running. * The timer has been started after reception of an immediate * assignment reject message. */ dat_rr_release_ind(RRCS_T3122_RUNNING, SAPI_0); PFREE (rr_establish_req); TRACE_EVENT ("imm ass delayed"); } else { /* * If T3122 is not running the access to the network is checked. */ if (dat_access_allowed (rr_establish_req->estcs)) { if (rr_establish_req->estcs EQ ESTCS_SERV_REQ_BY_MM) { /* * if location updating is started, store fieldstrength * for an optimisation. RR indicates to MM fieldstrength jumps * over 6 dBm in the field, that means better chance to * perform a successfull location updating. */ rr_data->lup_rxlev = rr_data->nc_data[SC_INDEX].rxlev; } /* * store the piggy-backed layer 3 message for later use. */ memcpy (&rr_data->ms_data.l3msg, &rr_establish_req->sdu, sizeof (T_L3_SDU));/*lint !e420 Apparent access beyond array for function*/ /* * Initialize the N(S) for upper layer messages. */ dat_vsd_bit_set (&rr_data->ms_data.l3msg, SET_AND_RESET); /* * Initialize some parameters and start immediate assignment. */ rr_data->sc_data.first_attempt = TRUE; rr_data->repeat_est = FALSE; #ifdef GPRS dat_gprs_set_suspended(); #endif dat_start_immediate_assign (rr_establish_req->estcs); PFREE (rr_establish_req); } else { /* * Access is not allowed and the rejection is signalled to MM. */ dat_rr_release_ind(RRCS_ACCESS_BARRED, SAPI_0); PFREE (rr_establish_req); TRACE_EVENT ("access barred"); } } break; case DAT_IMM_ASS: case DAT_IMM_ASS_1: case DAT_DEDICATED: { /* * collision of MO and MT calls. MT has higher priority than * MO calls. */ dat_rr_release_ind(RRCS_MO_MT_COLL, SAPI_0); PFREE (rr_establish_req); break; } default: PFREE (rr_establish_req); break; } } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_mph_paging_ind | +--------------------------------------------------------------------+ PURPOSE : Layer 1 has detected a paging for the mobile. RR starts the immediate assignment procedure. */ GLOBAL void dat_mph_paging_ind (T_MPH_PAGING_IND *mph_paging_ind) { GET_INSTANCE_DATA; #ifdef GPRS UBYTE ret; #endif TRACE_FUNCTION ("dat_mph_paging_ind()"); EM_PAGING_IND; /* check access control class before processing for paging */ if (dat_access_allowed(ESTCS_PAGING) EQ FALSE) { PFREE (mph_paging_ind); TRACE_EVENT("Access ctrl class not allowed for responding to the page msg"); return; } switch (GET_STATE (STATE_DAT)) { case DAT_NULL: /* * MS is not in idle mode, searching for cell */ if (! IS_TIMER_ACTIVE(T3122) AND GET_STATE (STATE_ATT) NEQ ATT_NULL) { /* * paging is only excepted if T3122 is not running and there isn't * performed a RR_DEACTIVATE_REQ just before */ if (rr_data->pag_rec EQ FALSE) { /* * store paging if no paging is stored until now. */ if (!srv_store_prim ((T_PRIM *)D2P(mph_paging_ind))) { /* * storage is full */ PFREE (mph_paging_ind); } else { /* * marker that paging has been received. */ rr_data->pag_rec = TRUE; } return; } } break; case DAT_IDLE: if (! IS_TIMER_ACTIVE(T3122)) { if (rr_data->first_meas_received EQ FALSE) { /* * we are actually still in cell reselection * because we have not yet received a measurement * report. But we have to be in idle mode to make * measurements in the first place. */ if (srv_check_stored_prim (MPH_PAGING_IND)) { /* * if already a paging is stored, ignore subsequent pagings */ PFREE (mph_paging_ind); } else { /* * store paging until measurement receives */ rr_data->pag_rec = TRUE; if (!srv_store_prim ((T_PRIM *)D2P(mph_paging_ind))) { /* * storage buffer is full */ rr_data->pag_rec = FALSE; PFREE (mph_paging_ind); } } return; } #ifdef GPRS ret = dat_check_packet_paging_ind(mph_paging_ind); if(ret EQ FALSE) { /* * we are suspended and it is not a packet paging */ dat_begin_start_immediate_assign (mph_paging_ind->identity_type, mph_paging_ind->channel_needed); } else if(ret EQ TRUE) { /* * we are not suspended and it is not a packet paging * and GPRS is activate */ dat_ask_paging_ind(mph_paging_ind); } /* ret EQ 2-> packet paging for GPRS, do nothing */ #else /* GPRS */ dat_begin_start_immediate_assign (mph_paging_ind->identity_type, mph_paging_ind->channel_needed); #endif /* GPRS */ } break; #ifdef GPRS case DAT_IMM_ASS: /* only PS pagings are received in this state */ dat_ask_paging_ind_pa_only(mph_paging_ind); break; #endif default: break; } PFREE (mph_paging_ind); } #if defined FF_EOTD /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_rrlc_meas_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive RRLC_MEAS_REQ received from LC. Start the LCS/EOTD postion measurement procedure. */ GLOBAL void dat_rrlc_meas_req (T_RRLC_MEAS_REQ *rrlc_meas_req) { GET_INSTANCE_DATA; T_NC_DATA *sc; int i,n; TRACE_FUNCTION ("dat_rrlc_meas_req()"); switch ( GET_STATE (STATE_DAT) ) { case DAT_HANDOVER : case DAT_HANDOVER_4: case DAT_HANDOVER_5: { 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); PFREE(rrlc_meas_req); return; } default: break; } /* * Check if the requested cell matches the serving cell. */ sc = &rr_data->nc_data[SC_INDEX]; if ( rrlc_meas_req->v_arfcn AND rrlc_meas_req-> arfcn NEQ sc->arfcn AND rrlc_meas_req->v_bsic AND rrlc_meas_req-> bsic NEQ sc->bsic ) { PALLOC (rrlc_error_ind, RRLC_ERROR_IND); rrlc_error_ind->cause = LCS_WRONG_BTS; PSENDX (LC, rrlc_error_ind); PFREE(rrlc_meas_req); return; } /* * The requested cell matches the serving cell or * the requested cell was not specified. */ { PALLOC ( mph_ncell_pos_req, MPH_NCELL_POS_REQ ); rr_data->eotd_req_id = rrlc_meas_req->req_id; n = rrlc_meas_req->v_assist_data ? rrlc_meas_req->c_assist_data : 0; mph_ncell_pos_req->c_ncell_eotd = n; mph_ncell_pos_req->req_id = rrlc_meas_req->req_id; for ( i = 0; i < n; ++i ) mph_ncell_pos_req->ncell_eotd[i] = *(T_ncell_eotd*)&rrlc_meas_req->assist_data[i]; PSENDX ( PL, mph_ncell_pos_req ); } PFREE(rrlc_meas_req); } /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : dat_rrrrlp_data_req | +--------------------------------------------------------------------+ PURPOSE : Process the primitive RRRRLP_DATA_REQ received from LC. Transmit a APDU according 3GPP TS 04.18, section 3.4.21. */ GLOBAL void dat_rrrrlp_data_req (T_RRRRLP_DATA_REQ *rrrrlp_data_req_orig) { GET_INSTANCE_DATA; UBYTE cr = rrrrlp_data_req_orig->cr; T_sdu *sdu = &rrrrlp_data_req_orig->sdu; UBYTE *buf = &sdu->buf[sdu->o_buf/BITS_PER_BYTE]; USHORT len = BYTELEN(sdu->l_buf); USHORT num_seg = len / APDU_FULL_L2_FRAME; /* number of full segments */ USHORT rem_seg = len % APDU_FULL_L2_FRAME; /* size of last segment */ USHORT n_seg; /* total number of segments*/ USHORT i; UBYTE flag; PPASS(rrrrlp_data_req_orig, rrrrlp_data_req, RRRRLP_DATA_REQ); TRACE_FUNCTION ("dat_rrrrlp_data_req()"); /* sdu->o_buf must be a multiple of BITS_PER_BYTE */ TRACE_ASSERT ( sdu->o_buf % BITS_PER_BYTE EQ 0 ); /* compute the total number of segments (n_seg) */ if ( len EQ 0 ) { PFREE(rrrrlp_data_req); return; } n_seg = num_seg + ((rem_seg EQ 0) ? 0 : 1); /* in a loop with DL_DATA_REQ send all APDU segments */ for ( i = 0; i < num_seg; ++i ) { PALLOC_MSG ( dl_data_req, DL_DATA_REQ, B_APPLIC_INFO ); dat_code_prr_channel (&dl_data_req->ch_type, &dl_data_req->sapi, rr_data->sc_data.chan_desc.chan_type ); /* compute the APDU control flags */ if ( n_seg EQ 1 ) { flag = (UBYTE)(FIRST_SEG | LAST_SEG | (cr << 2)); } else { if ( i EQ 0 ) { flag = FIRST_SEG | NOT_LAST_SEG; } else { if ( i EQ num_seg-1 AND rem_seg EQ 0 ) flag = NOT_FIRST_SEG | LAST_SEG | (cr << 2); else flag = NOT_FIRST_SEG | NOT_LAST_SEG; } } /* compile the APDU message and send it to DL */ dl_data_req->sdu.buf[0] = PD_RR_TI_0; dl_data_req->sdu.buf[1] = B_APPLIC_INFO; dl_data_req->sdu.buf[2] = (flag << 4 ) | RRLP_LCS; dl_data_req->sdu.buf[3] = APDU_FULL_L2_FRAME; memcpy ( &dl_data_req->sdu.buf[4], buf, APDU_FULL_L2_FRAME ); buf += APDU_FULL_L2_FRAME; dl_data_req->sdu.l_buf = (4 + APDU_FULL_L2_FRAME) * BITS_PER_BYTE; dl_data_req->sdu.o_buf = 0; PSENDX ( DL, dl_data_req ); } /* send remaining APDU segment if its length > 0 */ if ( rem_seg > 0 ) { PALLOC_MSG ( dl_data_req, DL_DATA_REQ, B_APPLIC_INFO ); dat_code_prr_channel (&dl_data_req->ch_type, &dl_data_req->sapi, rr_data->sc_data.chan_desc.chan_type ); /* compute the APDU control flags */ if ( n_seg EQ 1 ) flag = FIRST_SEG | LAST_SEG | (cr << 2); else flag = NOT_FIRST_SEG | LAST_SEG | (cr << 2); /* compile the APDU message and send it to DL */ dl_data_req->sdu.buf[0] = PD_RR_TI_0; dl_data_req->sdu.buf[1] = B_APPLIC_INFO; dl_data_req->sdu.buf[2] = (flag << 4 ) | RRLP_LCS; dl_data_req->sdu.buf[3] = (UBYTE)rem_seg; memcpy ( &dl_data_req->sdu.buf[4], buf, rem_seg ); dl_data_req->sdu.l_buf = (4 + rem_seg) * BITS_PER_BYTE; dl_data_req->sdu.o_buf = 0; PSENDX ( DL, dl_data_req ); } /* release RRRRLP_DATA_REQ */ PFREE(rrrrlp_data_req); #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 } #endif /* FF_EOTD */ /* +--------------------------------------------------------------------+ | PROJECT : GSM-PS (6147) MODULE : RR_DAT | | STATE : code ROUTINE : att_mph_stop_dedicated_cnf | +--------------------------------------------------------------------+ PURPOSE : Process the primitive MPH_STOP_DEDICATED_CNF received from L1 */ GLOBAL void att_mph_stop_dedicated_cnf (T_MPH_STOP_DEDICATED_CNF * stop_cnf) { GET_INSTANCE_DATA; PFREE(stop_cnf); TRACE_FUNCTION ("att_mph_stop_dedicated_cnf()"); /* * Dedicated mode activity can be stopped in 3 cases * * - normal case :- Dedicated mode actvity has been stopped cleanly, without any errors. * Either a cell selection or a cell reselection (to the same cell) will take * place, depending on the timer T_DEDICATED_MODE. * * - failure :- Dedicated mode actvity has been stopped because of a radio link failure or a * data link failure. In this case cell re-selection must be started immediately. * * - CCO :- This is Applicable after RR has received a network cell change order */ switch(GET_STATE (STATE_ATT)) { case ATT_NULL: case ATT_CS1: case ATT_CS2: break; default: #ifdef GPRS if( rr_data->mode_after_dedi EQ MODE_CELL_CHANGE_ORDER) { PALLOC (mph_bsic_req, MPH_BSIC_REQ); mph_bsic_req->arfcn = rr_data->gprs_data.arfcn; SET_STATE (STATE_ATT, ATT_IDLE); SET_STATE (STATE_CELL_SEL, CS_CCO); rr_data->mode_after_dedi = NOT_PRESENT_8BIT; PSENDX( PL, mph_bsic_req); return; } #endif if(! rr_data->net_lost ) { /* Send Release indication to MM and go back to IDLE state */ dat_release_connection(); } else { #ifdef GPRS att_start_cell_reselection_gprs (BACK_FROM_DEDICATED_RLF); #else att_start_cell_reselection (BACK_FROM_DEDICATED_RLF); #endif } break; } } #endif