FreeCalypso > hg > fc-selenite
diff src/g23m-gsm/rr/rr_datg.c @ 1:d393cd9bb723
src/g23m-*: initial import from Magnetite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Sun, 15 Jul 2018 04:40:46 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/g23m-gsm/rr/rr_datg.c Sun Jul 15 04:40:46 2018 +0000 @@ -0,0 +1,1729 @@ +/* ++----------------------------------------------------------------------------- +| Project : +| Modul : ++----------------------------------------------------------------------------- +| Copyright 2002 Texas Instruments Berlin, AG +| All rights reserved. +| +| This file is confidential and a trade secret of Texas +| Instruments Berlin, AG +| The receipt of or possession of this file does not convey +| any rights to reproduce or disclose its contents or to +| manufacture, use, or sell anything it may describe, in +| whole, or in part, without the specific written consent of +| Texas Instruments Berlin, AG. ++----------------------------------------------------------------------------- +| Purpose : This module holds the functions for handling primitives +| sent from entity GRR to entity RR and vice versa. ++----------------------------------------------------------------------------- +*/ + +#ifndef RR_DATG_C +#define RR_DATG_C + +#ifdef GPRS + +#define ENTITY_RR + +/*==== INCLUDES ===================================================*/ + +#include <string.h> +#include <stddef.h> +#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 "pei.h" +#include "tok.h" +#include "rr_gprs.h" +#include "rr.h" + +static UBYTE get_r_bit (void); +static void handle_non_gprs_param(T_non_gprs* non_gprs); +static void dat_rrgrr_rr_est_ind (void); +static void dat_build_rr_initialisation_request (void); + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_channel_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_CHANNEL_REQ received from GRR. + This primitive indicates to the RR to send a channel request + +*/ + +void dat_rrgrr_channel_req (T_RRGRR_CHANNEL_REQ *chan_req) +{ + GET_INSTANCE_DATA; + USHORT req = (USHORT) (chan_req->req_data + 0x0400); + TRACE_FUNCTION ("gprs_rrgrr_channel_req()"); + + /* + * check availability of GPRS + */ + switch (GET_STATE(STATE_GPRS)) /* rr_data->gprs_data.gprs_avail) */ + { + case GPRS_PIM_BCCH: + case GPRS_PAM_BCCH: + case GPRS_PTM_BCCH: + if (GET_STATE(STATE_DAT) NEQ DAT_NULL) + { + switch (req) + { + case ESTCS_GPRS_1P: + case ESTCS_GPRS_SB: + case ESTCS_PAGING: + /* + * reset values used in the Packet Access + * Procedure + */ + if (IS_TIMER_ACTIVE(T3126)) + { + TIMERSTOP(T3126); + } + memset(rr_data->gprs_data.rr_sdu, NOT_PRESENT_8BIT, + sizeof(rr_data->gprs_data.rr_sdu)); + rr_data->gprs_data.tma_in_progress = FALSE; + rr_data->gprs_data.fn = NOT_PRESENT_32BIT; + rr_data->gprs_data.req_ref_idx = NOT_PRESENT_8BIT; + rr_data->sc_data.first_attempt = TRUE; + rr_data->repeat_est = FALSE; + /* start procedure */ + dat_start_immediate_assign((USHORT)(req EQ + ESTCS_PAGING ? ESTCS_GPRS_PAGING : req)); + SET_STATE(STATE_GPRS, GPRS_PAM_BCCH); + break; + default: + TRACE_EVENT("channel request with wrong value"); + break; + } + } + else + { + TRACE_EVENT ("store channel req"); + if(! srv_store_prim((T_PRIM *)D2P(chan_req))) + { + TRACE_EVENT("prim store full"); + PFREE(chan_req); + } + return; + } + break; + case GPRS_PIM_PBCCH: + case GPRS_PAM_PBCCH: + case GPRS_PTM_PBCCH: + TRACE_EVENT ("chan_req w/ PBCCH!"); + break; + case GPRS_ACTIVATED: + TRACE_EVENT ("no cell selected yet, or cell supports no GPRS"); + break; + case GPRS_SUSPENDED_BCCH: + case GPRS_SUSPENDED_PBCCH: + TRACE_EVENT ("GPRS is suspended!"); + break; + default: + TRACE_EVENT ("GPRS not supported"); + break; + } + PFREE (chan_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_check_gprs_imm_ass | ++-----------------------------------------------------------------------------+ + + PURPOSE : checks an incoming immediate assignment message and forwards + it to GRR if necessary. + +*/ + +GLOBAL BOOL dat_check_gprs_imm_ass (T_MPH_UNITDATA_IND * unitdata, + T_D_IMM_ASSIGN * imm_assign, + UBYTE index) +{ + GET_INSTANCE_DATA; + BOOL ret = FALSE; + int send_indication = 0; + + TRACE_FUNCTION ("dat_check_gprs_imm_ass()"); + + if (GET_STATE(STATE_GPRS) NEQ GPRS_PAM_BCCH) + return FALSE; /* normal circuit switched handling */ + + TRACE_EVENT_P7 ("fn=%u tma=%u ri=%x d_t=%u (tmaip=%u fn=%d ri=%d)", + unitdata->fn, imm_assign->tma, index, imm_assign->d_t, + rr_data->gprs_data.tma_in_progress, rr_data->gprs_data.fn, + rr_data->gprs_data.req_ref_idx); + + if (imm_assign->tma EQ TMA_1) + { + /* Message indicates to be the first message of two in a + * two-message assignment of a downlink TBF. + */ + if (rr_data->gprs_data.tma_in_progress) + { + TRACE_ERROR ("more than one TMA after another!"); + TRACE_EVENT_P4 ("ri=%x?%x(old) fn=%u?%u(old)", + index, rr_data->gprs_data.req_ref_idx, + unitdata->fn, rr_data->gprs_data.fn); + } + + rr_data->gprs_data.tma_in_progress = TRUE; + + /* + * store message, framenumber and burst index + */ + gprs_rrgrr_store_sdu(rr_data->gprs_data.rr_sdu, &unitdata->sdu); + rr_data->gprs_data.fn = unitdata->fn; + rr_data->gprs_data.req_ref_idx = index; + ret = TRUE; /* further treatment by GRR */ + } + else + { + if (rr_data->gprs_data.tma_in_progress) + { /* + * MS awaits the second message of two in a two-message assignment + * of a downlink TBF. + * The message must belong to the same channel request + * and the time difference must be less than two multiframes. + */ + BOOL in_time, same_reference_index; + U32 delta_fn; + + if (rr_data->gprs_data.fn > unitdata->fn) + delta_fn = unitdata->fn + HYPERFRAME - rr_data->gprs_data.fn; + else + delta_fn = unitdata->fn - rr_data->gprs_data.fn; + + in_time = (delta_fn/51) < 2; + same_reference_index = rr_data->gprs_data.req_ref_idx EQ index; + + TRACE_EVENT_P6 ("TMA:delta_fn=%u %s time, %sequal ref idx(%x?%x): %s", + delta_fn, in_time?"in":"out of", same_reference_index?"":"un", + rr_data->gprs_data.req_ref_idx, index, + (in_time AND same_reference_index)?"OK":"not ok"); + + if (in_time AND same_reference_index) + { /* This is the matching second message of a tma. + * -> Send both immediate assignments + */ + send_indication = 2; + ret = TRUE; /* further treatment by GRR */ + } + else + { + TRACE_ERROR ("MS awaits second message of a tma, this is not the right one!"); + + if (!in_time) + { + /* + * If the MS does not received the second IMMEDIATE ASSIGNMENT message + * in a two-message assignment within two multiframe periods following + * the first message, the MS shall discard the IA message received. + */ + rr_data->gprs_data.tma_in_progress = FALSE; + rr_data->gprs_data.fn = NOT_PRESENT_32BIT; + rr_data->gprs_data.req_ref_idx = NOT_PRESENT_8BIT; + } + + if(imm_assign->d_t EQ D_T_TBF) + { + /* + * stop timer and set RR state + * the handling of PDCH is done by GPRS + */ + ret = TRUE; /* further treatment by GPRS */ + } + else + { + /* + * allocation on SDCCH for GPRS + * normal RR establishment + */ + ret = FALSE; + } + } + } + else + { /* + * MS donīt await the second message of two in a two-message assignment + * of a downlink TBF and the message isnīt the first message of a tma. + * + * -> Send one indication to GRR + */ + send_indication = 1; + + if(imm_assign->d_t EQ D_T_TBF) + { + /* + * stop timer and set RR state + * the handling of PDCH is done by GPRS + */ + ret = TRUE; /* further treatment by GRR */ + } + else + /* + * allocation on SDCCH for GPRS + * normal RR establishment + */ + ret = FALSE; + } + } + + if (send_indication) + { + if (send_indication EQ 2) + { + PALLOC_SDU ( rrgrr_ia_ind, RRGRR_IA_IND, MAX_L2_FRAME_SIZE * BITS_PER_BYTE); /* T_RRGRR_IA_IND */ + /* + * indicate first immediate assignment + */ + gprs_rrgrr_fill_from_stored_sdu(&rrgrr_ia_ind->sdu, rr_data->gprs_data.rr_sdu); + rrgrr_ia_ind->fn = 0; /* not valid */ + rrgrr_ia_ind->r_bit = 0; /* not valid */ + PSENDX (GRR, rrgrr_ia_ind); + } + { + PALLOC_SDU ( rrgrr_ia_ind2, RRGRR_IA_IND, MAX_L2_FRAME_SIZE * BITS_PER_BYTE); /* T_RRGRR_IA_IND */ + /* + * indicate second or sole immediate assignment + */ + if (unitdata->sdu.o_buf >= 8) + { + unitdata->sdu.o_buf -= 8; + unitdata->sdu.l_buf += 8; + } + else + { + TRACE_ERROR("dat_check_gprs_imm_ass(), not able to move offset o_buf"); + } + gprs_rrgrr_fill_from_stored_sdu(&rrgrr_ia_ind2->sdu, + &unitdata->sdu.buf[unitdata->sdu.o_buf/8]); + rrgrr_ia_ind2->fn = unitdata->fn; + rrgrr_ia_ind2->r_bit = get_r_bit (); + PSENDX (GRR, rrgrr_ia_ind2); + } + } + + TRACE_EVENT_P1 ("dat_check_gprs_imm_ass() returns %u", ret); + return ret; +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_check_immediate_assignment_ext | ++-----------------------------------------------------------------------------+ + + PURPOSE : checks an incoming immediate assignment extended message + and forwards it to GRR if necessary. + +*/ + +GLOBAL void dat_check_imm_ass_ext (T_MPH_UNITDATA_IND * unitdata, + UBYTE index) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("grps_check_immediate_assignment_ext()"); + + /*switch (rr_data->ms_data.establish_cause) + { + case ESTCS_GPRS_1P: + case ESTCS_GPRS_SB: + case ESTCS_GPRS_PAGING:*/ + switch (GET_STATE(STATE_GPRS)) + { + case GPRS_PAM_BCCH: + /* + * Immediate Assignment Extended received on AGCH during connection + * establishment + */ + { + PALLOC_SDU (rrgrr_iaext_ind, RRGRR_IAEXT_IND, MAX_L2_FRAME_SIZE * BITS_PER_BYTE); + gprs_rrgrr_store_sdu(rr_data->gprs_data.rr_sdu, &unitdata->sdu); + gprs_rrgrr_fill_from_stored_sdu(&rrgrr_iaext_ind->sdu, rr_data->gprs_data.rr_sdu); + + rrgrr_iaext_ind->ia_index = index; + rrgrr_iaext_ind->fn = unitdata->fn; + rrgrr_iaext_ind->r_bit = get_r_bit(); + + PSENDX (GRR, rrgrr_iaext_ind); + } + break; + default: + break; + } +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : att_check_imm_ass_rej | ++-----------------------------------------------------------------------------+ + + PURPOSE : checks an incoming immediate assignment reject message and forwards + it to GRR if necessary. + +*/ + +GLOBAL UBYTE dat_check_imm_ass_rej (UBYTE wait_ind) +{ + GET_INSTANCE_DATA; + UBYTE ret = FALSE; + + TRACE_FUNCTION ("att_check_imm_ass_rej()"); + +/* + switch (rr_data->ms_data.establish_cause) + { + case ESTCS_GPRS_1P: + case ESTCS_GPRS_SB: + case ESTCS_GPRS_PAGING: + */ + switch (GET_STATE(STATE_GPRS)) + { + case GPRS_PAM_BCCH: + /* + * Immediate Assignment Reject received on AGCH during connection + * establishment + */ + { + PALLOC( rrgrr_assignment_rej_ind, RRGRR_ASSIGNMENT_REJ_IND); + + rrgrr_assignment_rej_ind->wait_ind = wait_ind; + rrgrr_assignment_rej_ind->r_bit = get_r_bit (); + + PSENDX (GRR, rrgrr_assignment_rej_ind); + } + ret = TRUE; + break; + /* return TRUE; */ + default: + break; + } + return ret; + /* return FALSE; */ +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_check_imm_assign_pch | ++-----------------------------------------------------------------------------+ + + PURPOSE : checks an incoming immediate assignment message in idle mode on + PCH + +*/ + +GLOBAL UBYTE dat_check_imm_assign_pch (T_MPH_UNITDATA_IND * unitdata, + T_D_IMM_ASSIGN * imm_assign) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("dat_check_imm_assign_pch()"); + TRACE_EVENT("check dl ass"); + if(imm_assign->d_t EQ D_T_TBF AND + imm_assign->dl EQ DL_1) + { + PALLOC_SDU ( rrgrr_ia_ind, RRGRR_IA_DOWNLINK_IND, MAX_L2_FRAME_SIZE * BITS_PER_BYTE); + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_NULL: + case GPRS_ACTIVATED: + /* + * here it would be possible to store it if we are in + * cell reselection + * but i think this does not make sense: + * -> this is not page (ia_dl is only cell wide), + * -> we dont know if its actually for us. + * -> first we have to do a Cell Update. + */ + case GPRS_SUSPENDED_BCCH: + case GPRS_SUSPENDED_PBCCH: + TRACE_EVENT_P1("dl ass in state %d", GET_STATE(STATE_GPRS) ); + PFREE(rrgrr_ia_ind); + return TRUE; + case GPRS_PIM_BCCH: + case GPRS_PAM_BCCH: + /* + * Immediate Assignment received in idle mode and it is a PDCH + */ + TRACE_EVENT("dl ass"); + rr_data->start_cell_reselection = FALSE; + TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection); + gprs_rrgrr_store_sdu(rr_data->gprs_data.rr_sdu, &unitdata->sdu); + gprs_rrgrr_fill_from_stored_sdu(&rrgrr_ia_ind->sdu, rr_data->gprs_data.rr_sdu); + rrgrr_ia_ind->fn = unitdata->fn; + rrgrr_ia_ind->r_bit = NOT_PRESENT_8BIT; + + PSENDX (GRR, rrgrr_ia_ind); + return TRUE; + default: + PFREE(rrgrr_ia_ind); + return FALSE; + } + } + return FALSE; +} + + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_check_packet_paging_ind | ++-----------------------------------------------------------------------------+ + + PURPOSE : checks an incoming paging whether it is for GPRS. + +*/ + +UBYTE dat_check_packet_paging_ind (T_MPH_PAGING_IND * pag_ind) +{ + GET_INSTANCE_DATA; + UBYTE ret=2; + TRACE_FUNCTION ("dat_check_packet_paging_ind ()"); + + if (pag_ind->channel_needed EQ CN_PACKET) + { + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PIM_BCCH: + { + /* + * Inform GRR about packet paging + */ + PALLOC ( rrgrr_packet_paging_ind, RRGRR_PACKET_PAGING_IND ); + switch (pag_ind->identity_type) + { + case ID_IMSI: + rrgrr_packet_paging_ind->pg_type = RRGRR_IMSI; + break; + case ID_PTMSI: + rrgrr_packet_paging_ind->pg_type = RRGRR_PTMSI; + break; + default: + TRACE_EVENT("packet paging with TMSI"); + break; + } + PSENDX (GRR, rrgrr_packet_paging_ind); + } + ret = 2; + break; + case GPRS_NULL: + case GPRS_ACTIVATED: + /*strange cases, ignore it */ + break; + case GPRS_SUSPENDED_BCCH: + case GPRS_SUSPENDED_PBCCH: + /*is is a packet paging but we are suspended so ignore it*/ + ret = 2; + break; + default: + break; + } + } + else + { + /* normal CS paging */ + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_SUSPENDED_BCCH: + case GPRS_SUSPENDED_PBCCH: + case GPRS_NULL: + case GPRS_ACTIVATED: + /* we are already suspended so just react to the paging */ + /* or GPRS is not activated */ + ret = 0; + break; + default: + /* ask GRR */ + ret = 1; + break; + } + } + return ret; +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_start_sabm | ++-----------------------------------------------------------------------------+ + + PURPOSE : starts connection establishment if a packet service is requested. + +*/ + +BOOL dat_gprs_start_sabm(void) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("gprs_start_sabm()"); + + switch (GET_STATE(STATE_GPRS)) + { + /* + * Mobile originated packet connection + */ + case GPRS_PAM_BCCH: + dat_build_rr_initialisation_request (); + return TRUE; + default: + return FALSE; + } +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_build_rr_initialisation_request| ++-----------------------------------------------------------------------------+ + + PURPOSE : starts connection establishment if a mobile originated packet + service is requested and it builds + +*/ + +static void dat_build_rr_initialisation_request (void) +{ + GET_INSTANCE_DATA; + MCAST (rr_init_req, D_RR_INIT_REQ); + PALLOC_MSG (establish_req, DL_ESTABLISH_REQ, D_RR_INIT_REQ); + + TRACE_FUNCTION ("grps_build_rr_initialisation_request()"); + TRACE_EVENT ("POWER CLASS: grps_build_rr_initialisation_request()"); + + dat_code_prr_channel (&establish_req->ch_type, + &establish_req->sapi, + rr_data->sc_data.chan_desc.chan_type); + + /* + * fill message parameter + */ + rr_init_req->msg_type = D_RR_INIT_REQ; + rr_init_req->ciph_key_num.key_seq = rr_data->ms_data.cksn; + memcpy(&rr_init_req->mob_class_2, &rr_data->ms_data.classmark2, + sizeof(rr_init_req->mob_class_2)); + + /* + * set power classes + */ + rr_init_req->mob_class_2.rf_pow_cap = att_get_power (); + + /* + * set all other parameter + */ + rr_init_req->chan_coding.mac_mode = rr_data->gprs_data.mac_req; + rr_init_req->chan_coding.cod_scheme = rr_data->gprs_data.cs_req; + + /* + * store tlli independent from the used binary format + */ + rr_init_req->ded_tlli.l_ded_tlli = 32; + rr_init_req->ded_tlli.o_ded_tlli = 0; + ccd_codeByte (rr_init_req->ded_tlli.b_ded_tlli, 0, 8, (UBYTE)(rr_data->gprs_data.tlli >> 24)); + ccd_codeByte (rr_init_req->ded_tlli.b_ded_tlli, 8, 8, (UBYTE)(rr_data->gprs_data.tlli >> 16)); + ccd_codeByte (rr_init_req->ded_tlli.b_ded_tlli, 16, 8, (UBYTE)(rr_data->gprs_data.tlli >> 8)); + ccd_codeByte (rr_init_req->ded_tlli.b_ded_tlli, 24, 8, (UBYTE)rr_data->gprs_data.tlli); + + rr_init_req->chan_req_desc.or_ty = rr_data->gprs_data.p_chan_req_des.mo_mt; + + if (rr_init_req->chan_req_desc.or_ty) + { + rr_init_req->chan_req_desc.v_crd_prio = 1; + rr_init_req->chan_req_desc.crd_prio = rr_data->gprs_data.p_chan_req_des.prio; + rr_init_req->chan_req_desc.v_rlc_mode = 1; + rr_init_req->chan_req_desc.rlc_mode = rr_data->gprs_data.p_chan_req_des.rlc_mode_req; + rr_init_req->chan_req_desc.v_llc_fr_type = 1; + rr_init_req->chan_req_desc.llc_fr_type = rr_data->gprs_data.p_chan_req_des.llc_type; + rr_init_req->chan_req_desc.v_rbw = 1; + rr_init_req->chan_req_desc.rbw = rr_data->gprs_data.p_chan_req_des.req_bwd; + rr_init_req->chan_req_desc.v_rlc_c_oct = 1; + rr_init_req->chan_req_desc.rlc_c_oct = rr_data->gprs_data.p_chan_req_des.rlc_octets; + } + + rr_init_req->gprs_meas_res.c_val = rr_data->gprs_data.gprs_meas_results.c_value; + rr_init_req->gprs_meas_res.rxqual = rr_data->gprs_data.gprs_meas_results.rxqual; + rr_init_req->gprs_meas_res.sign_var = rr_data->gprs_data.gprs_meas_results.sign_var; + + for_dat_est_req_content (establish_req); +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_stop_dcch_ind | ++-----------------------------------------------------------------------------+ + + PURPOSE : inform GRR about failed layer 2 establishment. + +*/ +void dat_stop_dcch_ind (UBYTE stop_cause) +{ + GET_INSTANCE_DATA; + PALLOC(stop, RRGRR_STOP_DCCH_IND); + TRACE_FUNCTION ("gprs_stop_dcch_ind()"); + stop->stop_cause = stop_cause; + /* we will do a CR anyway */ + SET_STATE(STATE_GPRS, GPRS_ACTIVATED); + PSENDX(GRR, stop); +} + + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_rrgrr_gprs_data_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : The primitive RRGRR_GPRS_DATA_REQ contains various parameters from + GRR. Layer 1 is configured and some data are stored. +*/ + +void dat_rrgrr_gprs_data_req (T_RRGRR_GPRS_DATA_REQ *data_req) +{ + GET_INSTANCE_DATA; + /* + * store parameter + */ + + rr_data->gprs_data.tlli = data_req->tlli; + rr_data->gprs_data.p_chan_req_des = data_req->p_chan_req_des; + rr_data->gprs_data.gprs_meas_results = data_req->gprs_meas_results; + rr_data->gprs_data.mac_req = data_req->mac_req; + rr_data->gprs_data.cs_req = data_req->cs_req; + rr_data->gprs_data.current_rai = data_req->rai; + + if(rr_data->gprs_data.ptmsi NEQ data_req->old_ptmsi OR + rr_data->gprs_data.ptmsi2 NEQ data_req->new_ptmsi) + { + rr_data->gprs_data.ptmsi = data_req->old_ptmsi; + rr_data->gprs_data.ptmsi2 = data_req->new_ptmsi; + att_mph_identity_req (); + } + + PFREE (data_req); +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_data_ind | ++-----------------------------------------------------------------------------+ + + PURPOSE : Send the primitive rrgrr_data_ind to GRR. + This primitive indicates to the GRR that a + CTRL Message on DCCH for RR was received. + IN : frame_number + OUT : rrgrr_data_ind + +*/ + +void dat_rrgrr_data_ind (T_DL_DATA_IND* dl_data_ind) +{ + USHORT soff,doff; + PALLOC_SDU ( rrgrr_data_ind, RRGRR_DATA_IND, dl_data_ind->sdu.l_buf ); + + TRACE_EVENT ("dat_rrgrr_data_ind ()"); + + /* + * compute byte offsets (soff,doff) into message streams, + * assume that o_buf is multiple of 8 + */ + + doff = (USHORT)(rrgrr_data_ind->sdu.o_buf / BITS_PER_BYTE); + soff = (USHORT)( dl_data_ind->sdu.o_buf / BITS_PER_BYTE); + + memcpy ( &rrgrr_data_ind->sdu.buf[doff], + & dl_data_ind->sdu.buf[soff], BYTELEN ( dl_data_ind->sdu.l_buf ) ); + + rrgrr_data_ind->fn = NOT_PRESENT_32BIT; + + PFREE ( dl_data_ind ); + PSENDX (GRR, rrgrr_data_ind); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_rrgrr_data_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_DATA_REQ received from GRR. + This primitive indicates to the RR to send a block on DCCH. + IN : + OUT : + +*/ + +void dat_rrgrr_data_req (T_RRGRR_DATA_REQ *rrgrr_data_req) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("dat_rrgrr_data_req ()"); + + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_DEDI_SDCCH: + { + PPASS (rrgrr_data_req, dl_data_req, DL_DATA_REQ); + + dat_code_prr_channel (&dl_data_req->ch_type, + &dl_data_req->sapi, + rr_data->sc_data.chan_desc.chan_type); + dat_vsd_bit_set ((T_L3_SDU *)&dl_data_req->sdu, SET_ONLY); + for_dat_l3_data_req (dl_data_req); + } + break; + default: + break; + } + + PFREE (rrgrr_data_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rgrr_suspend_dcch_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_SUSPEND_DCCH_REQ received from GRR. + This primitive is used by GRR to order RR to stop the + dedicated channel. It is only a trigger. + IN : RRGRR-SUSPEND-DCCH-REQ + OUT : DL-SUSPEND-REQ and MPH-DEDICATED-REQ + +*/ +void dat_rrgrr_suspend_dcch_req( T_RRGRR_SUSPEND_DCCH_REQ *suspend_dcch_req) +{ + GET_INSTANCE_DATA; + PALLOC (dedicated_req, MPH_DEDICATED_REQ); + + TRACE_EVENT ("dat_rrgrr_suspend_dcch_req ()"); + + for_suspend_layer_2(); + + memset (dedicated_req, 0, sizeof (T_MPH_DEDICATED_REQ)); + dedicated_req->mod = MODE_PDCH_ASSIGN; + PSENDX (PL, dedicated_req); + + SET_STATE (STATE_DAT, DAT_PDCH_ASS); + + PFREE (suspend_dcch_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_suspend_dcch_cnf | ++-----------------------------------------------------------------------------+ + + PURPOSE : Create the primitive RRGRR_SUSPEND_DCCH_CNF and send it to GRR. + As a response GRR will start the establishment of a TBF. + IN : nothing + OUT : RRGRR_SUSPEND_DCCH_CNF + +*/ +void dat_rrgrr_suspend_dcch_cnf( void ) +{ + PALLOC (suspend_dcch_cnf, RRGRR_SUSPEND_DCCH_CNF); + PSENDX (GRR, suspend_dcch_cnf); +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_reconnect_dcch_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR-RECONNECT-DCCH-REQ received from GRR. + This primitive is used by GRR during a PDCH Assignment procedure + and RR Network Controlled Cell Change Order to order RR to + continue with the dedicated channel. + IN : T-RRGRR-RECONNECT-DCCH-REQ + OUT : DL-DATA-REQ(u-assign-fail) or MPH_DEDICATED_FAIL_REQ + +*/ +void dat_rrgrr_reconnect_dcch_req (T_RRGRR_RECONNECT_DCCH_REQ *reconnect_dcch_req) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("dat_rrgrr_reconnect_dcch_req()"); + + if ( rr_data->gprs_data.tbf_est EQ TBF_EST_PDCH OR + rr_data->gprs_data.tbf_est EQ TBF_EST_CCO ) + { + UBYTE next_state; + + if ( rr_data->gprs_data.tbf_est EQ TBF_EST_PDCH ) + next_state = DAT_PDCH_ASS_3; + else + next_state = DAT_CCO_3; + + /* + * The dedicated channel has been suspended at PL and DL. + * However RR could not established the TBF. + */ + + rr_data->gprs_data.tbf_est = TBF_EST_NONE; + dat_code_mph_old_chan_req(); + rr_data->gprs_data.reconn_cause = reconnect_dcch_req->reconn_cause; + rr_data->gprs_data.cco_need_reconnect_cnf = TRUE; + SET_STATE (STATE_DAT, next_state); + } + else /* Any other state assuming D_PDCH_ASS_CMD has been sent to GRR. + GRR cannot evaluate the message. */ + { + MCAST (u_assign_fail, U_ASSIGN_FAIL); + PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_ASSIGN_FAIL); + + /* + * 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); + + u_assign_fail->msg_type = U_ASSIGN_FAIL; + u_assign_fail->rr_cause = reconnect_dcch_req->reconn_cause; + for_dat_data_req (dl_data_req); + + dat_rrgrr_reconnect_dcch_cnf (RECONN_OK); + } + PFREE (reconnect_dcch_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_reconnect_dcch_cnf | ++-----------------------------------------------------------------------------+ + + PURPOSE : Create the primitive RRGRR_RECONNECT_DCCH_CNF and send it to GRR. + This indicates the outcome of the Reconnection procedure to GRR. + IN : nothing + OUT : RRGRR-RECONNECT-DCCH-CNF + +*/ +void dat_rrgrr_reconnect_dcch_cnf( UBYTE reconn_state ) +{ + PALLOC (reconnect_dcch_cnf, RRGRR_RECONNECT_DCCH_CNF); + TRACE_EVENT ("dat_rrgrr_reconnect_dcch_cnf()"); + reconnect_dcch_cnf->reconn_state = reconn_state; + PSENDX (GRR, reconnect_dcch_cnf); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rgrr_resumed_tbf_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR-RESUMED-TBF-REQ received from GRR. + This primitive is used by GRR to order RR to indicate the + successful outcome of a TBF establishment at GRR. + This is applicable during PDCH Assignment and RR Network Contolled + Cell Change Order. + IN : RRGRR-RESUMED-TBF-REQ + OUT : MPH-IDLE-REQ and DL-RELEASE-REQ + +*/ +void dat_rrgrr_resumed_tbf_req( T_RRGRR_RESUMED_TBF_REQ *resumed_tbf_req ) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("dat_rrgrr_resumed_tbf_req ()"); + + if ( rr_data->gprs_data.tbf_est EQ TBF_EST_PDCH OR + rr_data->gprs_data.tbf_est EQ TBF_EST_CCO ) + { + PALLOC (dl_release_req, DL_RELEASE_REQ); + + rr_data->gprs_data.tbf_est = TBF_EST_NONE; + + att_build_idle_req(SC_INDEX, MODE_PACKET_TRANSFER); + + /* + * Note that also during a Cell Change Order the states DAT_PDCH* are used. + */ + + SET_STATE (STATE_GPRS, GPRS_PTM_BCCH); + SET_STATE (STATE_DAT, DAT_PDCH_ASS_2); + + dat_code_prr_channel (&dl_release_req->ch_type, + &dl_release_req->sapi, + rr_data->sc_data.chan_desc.chan_type); + + dl_release_req->mode = DL_NORMAL_RELEASE; + PSENDX (DL, dl_release_req); + } + PFREE (resumed_tbf_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_resumed_tbf_cnf | ++-----------------------------------------------------------------------------+ + + PURPOSE : Create a primitive RGRR_RESUMED_TBF_CNF and send it to GRR. + This indicates the successful outcome of the release of the DCCH + which was in use before the TBF was established. + IN : nothing + OUT : RGRR-RESUMED-TBF-CNF + +*/ +void dat_rrgrr_resumed_tbf_cnf( void ) +{ + GET_INSTANCE_DATA; + PALLOC (rrgrr_resumed_tbf_cnf, RRGRR_RESUMED_TBF_CNF); + + TRACE_EVENT ("dat_rrgrr_resumed_tbf_cnf ()"); + + SET_STATE(STATE_GPRS, GPRS_PTM_BCCH); + SET_STATE(STATE_DAT, DAT_IDLE); + SET_STATE(STATE_ATT, ATT_IDLE); + + PSENDX (GRR, rrgrr_resumed_tbf_cnf); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_change_order | ++-----------------------------------------------------------------------------+ + + PURPOSE : Handle the message RR Network Controlled Cell Change Order. + IN : DL-DATA-IND + OUT : RRGRR-DATA-IND + +*/ +void dat_rrgrr_change_order (T_DL_DATA_IND *dl_data_ind, T_D_CHANGE_ORDER *d_change_order) +{ + GET_INSTANCE_DATA; + for_check_cell_descr (&d_change_order->cell_desc); /* check if the BCCH is ok */ + + if ( rr_data->ms_data.error.cs EQ 0 ) /* '0' indicates successful message decoding */ + { + T_cell_desc *cell_desc; + + for_suspend_layer_2(); + + if ( rr_data->gprs_data.dl_data_ind NEQ NULL ) + { + PFREE ( rr_data->gprs_data.dl_data_ind ); + } + rr_data->gprs_data.dl_data_ind = dl_data_ind; + + dat_att_null(); + cs_set_all(); + + cell_desc = &d_change_order->cell_desc; + rr_data->gprs_data.bsic = (UBYTE)(( cell_desc->ncc << 3 ) + cell_desc->bcc); + rr_data->gprs_data.arfcn = (USHORT)(( cell_desc->bcch_arfcn_hi << 8 ) + + cell_desc->bcch_arfcn_lo); + TIMERSTOP(T_DEDICATED_MODE); + rr_data->mode_after_dedi = MODE_CELL_CHANGE_ORDER; + att_stop_dedicated(); + } + else + { + MCAST (handov_fail, U_HANDOV_FAIL); + PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_HANDOV_FAIL); + + handov_fail->msg_type = U_HANDOV_FAIL; + handov_fail->rr_cause = RRC_PROT_UNSPECIFIED; + dat_code_prr_channel (&dl_data_req->ch_type, + &dl_data_req->sapi, + rr_data->sc_data.chan_desc.chan_type); + for_dat_data_req (dl_data_req); + PFREE ( dl_data_ind ); + } +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_check_packet_access | ++-----------------------------------------------------------------------------+ + + PURPOSE : change state from conn. establishment to dedicated + IN : + OUT : + +*/ + +BOOL dat_check_packet_access(void) +{ + GET_INSTANCE_DATA; + if(GET_STATE(STATE_GPRS) EQ GPRS_PAM_BCCH) + { + SET_STATE(STATE_GPRS, GPRS_DEDI_SDCCH); + return TRUE; + } + else return FALSE; +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_ask_paging_ind | ++-----------------------------------------------------------------------------+ + + PURPOSE : Ask GRR if paging should be processed. Answer will come in + RRGRR_RR_EST_RSP primitive + +*/ + +void dat_ask_paging_ind (T_MPH_PAGING_IND *pag_ind) +{ + GET_INSTANCE_DATA; + TRACE_FUNCTION ("dat_ask_paging_ind ()"); + + rr_data->gprs_data.pag_dat.id_type = pag_ind->identity_type; + rr_data->gprs_data.pag_dat.chan_need = pag_ind->channel_needed; + + rr_data->start_cell_reselection = FALSE; + TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection); + /* ask GRR if paging should be processed */ + dat_rrgrr_rr_est_ind (); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_ask_paging_ind_pa_only | ++-----------------------------------------------------------------------------+ + + PURPOSE : Ask GRR if paging should be processed. Answer will come in + RRGRR_RR_EST_RSP primitive. Only applicable in state GPRS_PA. + +*/ + +void dat_ask_paging_ind_pa_only (T_MPH_PAGING_IND *pag_ind) +{ + GET_INSTANCE_DATA; + if ( GET_STATE(STATE_GPRS) EQ GPRS_PAM_BCCH AND pag_ind->channel_needed NEQ CN_PACKET ) + dat_ask_paging_ind ( pag_ind ); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_rr_est_ind | ++-----------------------------------------------------------------------------+ + + PURPOSE : Send the primitive rrgrr_est_ind to GRR. + This primitive indicates to the GRR that an RR connection + establishment was received from the network via paging. + It is only a trigger. + IN : + OUT : rrgrr_rr_est_ind + +*/ + +static void dat_rrgrr_rr_est_ind (void) +{ + PALLOC ( rrgrr_est_ind, RRGRR_RR_EST_IND ); + TRACE_EVENT ("dat_rrgrr_est_ind ()"); + PSENDX (GRR, rrgrr_est_ind); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_rr_est_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_RR_EST_REQ received from GRR. + This primitive indicates to the RR a RR connection establishment + was received on paging channel (PCCCH or PACCH). RR has to start + a RR connection as if it has received a connection establishment + on CCCH. + IN : + OUT : + +*/ + +void dat_rrgrr_rr_est_req (T_RRGRR_RR_EST_REQ *est_req) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("dat_rrgrr_rr_est_req ()"); + + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PTM_BCCH: + case GPRS_PAM_BCCH: + case GPRS_PTM_PBCCH: + case GPRS_PAM_PBCCH: + case GPRS_PIM_PBCCH: + rr_data->gprs_data.gprs_suspend = est_req->susp_req; + rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_ACK; + + if(est_req->non_gprs.v_non_gprs) + { + handle_non_gprs_param(&est_req->non_gprs); + } + + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PIM_BCCH: + case GPRS_PAM_BCCH: + case GPRS_PTM_BCCH: + SET_STATE(STATE_GPRS, GPRS_SUSPENDED_BCCH); + break; + case GPRS_PIM_PBCCH: + case GPRS_PAM_PBCCH: + case GPRS_PTM_PBCCH: + SET_STATE(STATE_GPRS, GPRS_SUSPENDED_PBCCH); + break; + default: + break; + } + + dat_begin_start_immediate_assign (est_req->ident_type, + est_req->ch_needed); + break; + default: + break; + } + PFREE (est_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : handle_non_gprs_param | ++-----------------------------------------------------------------------------+ + + PURPOSE : Processes RGRR_RR_EST_REQ parameters received from GRR. + IN : Non GPRS parameter structure of the RRGRR_RR_EST_REQ primitive. + OUT : + +*/ + +static void handle_non_gprs_param(T_non_gprs* non_gprs) +{ + GET_INSTANCE_DATA; + rr_data->nc_data[SC_INDEX].control_descr.att = non_gprs->att; + rr_data->nc_data[SC_INDEX].control_descr.bs_ag_blks_res = non_gprs->bs_ag_blks_res; + rr_data->nc_data[SC_INDEX].control_descr.ccch_conf = non_gprs->ccch_conf; + rr_data->nc_data[SC_INDEX].control_descr.bs_pa_mfrms = non_gprs->bs_pa_mfrms; + rr_data->nc_data[SC_INDEX].rach.max_retrans = non_gprs->max_retrans; + rr_data->nc_data[SC_INDEX].rach.tx_integer = non_gprs->tx_integer; + rr_data->nc_data[SC_INDEX].select_para.ms_txpwr_max_cch = non_gprs->gprs_ms_txpwr_max_cch; + rr_data->nc_data[SC_INDEX].select_para.neci = non_gprs->neci; + rr_data->sc_data.cd.cell_options.pow_ctrl = non_gprs->pwrc; + + if(non_gprs->dtx EQ 2) + rr_data->sc_data.cd.dtx = DTX_NOT_USED; + else + rr_data->sc_data.cd.dtx = DTX_USED; + + rr_data->sc_data.cd.dtx_half = rr_data->sc_data.cd.dtx_full = + rr_data->sc_data.cd.dtx; + + rr_data->sc_data.cd.cell_options.rlt = non_gprs->radio_link_timeout; + + if(non_gprs->ec) + rr_data->nc_data[SC_INDEX].rach.ac &= 0x0400; + if(non_gprs->v_T3212) + rr_data->nc_data[SC_INDEX].control_descr.t3212 = non_gprs->T3212; + +#ifdef REL99 + /*Copy Early Classmark Sending Control flag received in PSI2 by GRR*/ + rr_data->nc_data[SC_INDEX].c2_par.ecsc = non_gprs->ecsc; +#endif +} +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_rr_est_rsp | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_RR_EST_RSP received from GRR. + This primitive indicates to the RR whether an establishment of + RR connection is allowed or not. This primitive is an answer + to the RRGRR_RR_EST_IND primitive. + IN : + OUT : + +*/ + +void dat_rrgrr_rr_est_rsp (T_RRGRR_RR_EST_RSP *est_rsp) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("dat_rrgrr_rr_est_rsp ()"); + + rr_data->start_cell_reselection = TRUE; + TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection); + + /* establishment allowed */ + if (est_rsp->rr_est) + { + rr_data->gprs_data.gprs_suspend = est_rsp->susp_req; + rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_ACK; + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PIM_BCCH: + case GPRS_PAM_BCCH: + case GPRS_PTM_BCCH: + SET_STATE(STATE_GPRS, GPRS_SUSPENDED_BCCH); + break; + case GPRS_PIM_PBCCH: + case GPRS_PAM_PBCCH: + case GPRS_PTM_PBCCH: + SET_STATE(STATE_GPRS, GPRS_SUSPENDED_PBCCH); + break; + default: + break; + } + dat_begin_start_immediate_assign (rr_data->gprs_data.pag_dat.id_type, + rr_data->gprs_data.pag_dat.chan_need); + } + + rr_data->gprs_data.pag_dat.id_type = 0; + rr_data->gprs_data.pag_dat.chan_need = 0; + + PFREE (est_rsp); +} + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_gprs_suspend_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Builds GPRS suspension request message. + IN : + OUT : + +*/ + +void dat_gprs_suspend_req (void) +{ + GET_INSTANCE_DATA; + if(rr_data->gprs_data.gprs_suspend) + { + /* + * building of the GPRS Suspension Request message + */ + MCAST (susp_req, U_GPRS_SUSP_REQ); + PALLOC_MSG (dl_data_req, DL_DATA_REQ, U_GPRS_SUSP_REQ); + + /* + * set channel type and SAPI for layer 2 + */ + dat_code_prr_channel (&dl_data_req->ch_type, + &dl_data_req->sapi, + rr_data->sc_data.chan_desc.chan_type); + susp_req->msg_type = U_GPRS_SUSP_REQ; + + /* + * store tlli independent from the used binary format + */ + susp_req->ded_tlli.l_ded_tlli = 32; + susp_req->ded_tlli.o_ded_tlli = 0; + ccd_codeByte (susp_req->ded_tlli.b_ded_tlli, 0, 8, + (UBYTE)(rr_data->gprs_data.tlli >> 24)); + ccd_codeByte (susp_req->ded_tlli.b_ded_tlli, 8, 8, + (UBYTE)(rr_data->gprs_data.tlli >> 16)); + ccd_codeByte (susp_req->ded_tlli.b_ded_tlli, 16, 8, + (UBYTE)(rr_data->gprs_data.tlli >> 8)); + ccd_codeByte (susp_req->ded_tlli.b_ded_tlli, 24, 8, + (UBYTE) rr_data->gprs_data.tlli); + + + switch(rr_data->ms_data.establish_cause) + { + case ESTCS_SERV_REQ_BY_MM: + susp_req->susp_cause = SUSP_C_LU; + break; + case ESTCS_EMRG_CAL: + case ESTCS_CAL_REEST: + case ESTCS_MOB_ORIG_SPCH_CAL_BY_CC: + case ESTCS_MOB_ORIG_DATA_CAL_BY_CC: + case ESTCS_MOB_ORIG_DATA_CAL_BY_CC_HR_SUFF: + case ESTCS_PAGING: + susp_req->susp_cause = SUSP_C_CALL; + break; + case ESTCS_MOB_ORIG_CAL_BY_SS_SMS: + susp_req->susp_cause = SUSP_C_SMS; /* SUSP_C_SS */ + break; + default: + break; + } + + memcpy(susp_req->rout_area_id.mcc,rr_data->gprs_data.current_rai.plmn.mcc, SIZE_MCC); + memcpy(susp_req->rout_area_id.mnc,rr_data->gprs_data.current_rai.plmn.mnc, SIZE_MNC); + if (susp_req->rout_area_id.mnc[2] EQ 0x0f) + susp_req->rout_area_id.c_mnc = 2; + else + susp_req->rout_area_id.c_mnc = SIZE_MNC; + + susp_req->rout_area_id.rac = rr_data->gprs_data.current_rai.rac; + susp_req->rout_area_id.lac = rr_data->gprs_data.current_rai.lac; + + rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_NOT_ACK; + /* + * send to layer 2 + */ + for_dat_data_req (dl_data_req); + } + +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : gprs_rrgrr_stop_task | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_STOP_TASK_REQ received from GRR. + This primitive indicates to the RR that a specific task on RR side + should be stopped. + IN : + OUT : + +*/ + +void gprs_rrgrr_stop_task( T_RRGRR_STOP_TASK_REQ *stop_task) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("gprs_rrgrr_stop_task"); + + switch(stop_task->ctrl_task) + { + case RR_TASK_1: + { + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PAM_BCCH: + rr_data->start_cell_reselection = TRUE; + TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection); + if(stop_task->task.v_stop_ccch NEQ INVALID_MSG) + { + att_build_idle_req(SC_INDEX, MODE_PACKET_TRANSFER); + TIMERSTOP(T3126); + SET_STATE(STATE_GPRS, GPRS_PTM_BCCH); + SET_STATE(STATE_DAT, DAT_IDLE); + SET_STATE(STATE_ATT, ATT_IDLE); + { + PALLOC(stop_cnf, RRGRR_STOP_TASK_CNF); + PSENDX(GRR, stop_cnf); + } + } + break; + case GPRS_PIM_BCCH: + if(stop_task->task.v_stop_ccch NEQ INVALID_MSG) + { + /* + * XXX we still have a problem if the search terminates + * and we want to select to the HPLMN cell just in the moment + * after we have sent the IA_DOWNLINK_IND but before receiving + * the STOP_TASK_REQ. But we should not stop the search + * before, because maybe the IA_DOWNLINK was not actually + * addressing us. + */ + + if (rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI) + { + /*inform MM and stop everything*/ + /* + * send Please Retry to the MMI + */ + rr_data->sc_data.found_entries = 0; + att_code_rr_abort_ind (RRCS_ABORT_CEL_SEL_FAIL); + } + att_build_idle_req(SC_INDEX, MODE_PACKET_TRANSFER); + SET_STATE(STATE_GPRS, GPRS_PTM_BCCH); + SET_STATE(STATE_DAT, DAT_IDLE); + SET_STATE(STATE_ATT, ATT_IDLE); + { + PALLOC(stop_cnf, RRGRR_STOP_TASK_CNF); + PSENDX(GRR, stop_cnf); + } + } + /* + * If a search is active in idle this is set to false + * it is also set to false on sending the IA_DL to GRR + * If the IA_DL is for us we abort the search and enter TBF + * that means that the start_cr flag is always set to true + * If the IA_DL is not for us then the start_cr flag should only be + * reset if no search is ongoing. + */ + if (rr_data->ms_data.req_mm_service NEQ FUNC_NET_SRCH_BY_MMI) + { + rr_data->start_cell_reselection = TRUE; + TRACE_EVENT_P1("start_cell_reselection %d", rr_data->start_cell_reselection); + } + break; + default: + break; + } + } + break; + case LEAVE_PIM_PBCCH: + { + TRACE_EVENT("LEAVE PIM"); + /* stop CCCH reading if running */ + /* SET_STATE(STATE_DAT, DAT_NULL); avoid reacting to crossing prim */ + /* stop CBCH reading if running */ + /* stop active ncell procedures */ + if (rr_data->ms_data.req_mm_service EQ FUNC_NET_SRCH_BY_MMI) + { + /*inform MM and stop everything*/ + /* + * send Please Retry to the MMI + */ + rr_data->sc_data.found_entries = 0; + att_code_rr_abort_ind (RRCS_ABORT_CEL_SEL_FAIL); + } + { + PALLOC(mph_mon_ctrl_req, MPH_MON_CTRL_REQ ); + mph_mon_ctrl_req->action = LEAVING_PIM_PBCCH; + PSENDX (PL, mph_mon_ctrl_req); + } + { + PALLOC(stop_cnf, RRGRR_STOP_TASK_CNF); + PSENDX(GRR, stop_cnf); + } + /* XXX stop PLMN scan ? */ + } + break; + case LEAVE_PAM_PBCCH: + { + PALLOC(mph_mon_ctrl_req, MPH_MON_CTRL_REQ ); + TRACE_EVENT("LEAVE PAM"); + mph_mon_ctrl_req->action = LEAVING_PAM_PBCCH; + PSENDX (PL, mph_mon_ctrl_req); + { + PALLOC(stop_cnf, RRGRR_STOP_TASK_CNF); + PSENDX(GRR, stop_cnf); + } + } + break; + case LEAVE_PTM_PBCCH: + + { + PALLOC(mph_mon_ctrl_req, MPH_MON_CTRL_REQ ); + TRACE_EVENT("LEAVE PTM"); + mph_mon_ctrl_req->action = LEAVING_PTM_PBCCH; + PSENDX (PL, mph_mon_ctrl_req); + + { + PALLOC(stop_cnf, RRGRR_STOP_TASK_CNF); + PSENDX(GRR, stop_cnf); + } + } + break; + default: + break; + + } + PFREE(stop_task); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_rrgrr_activate_req | ++-----------------------------------------------------------------------------+ + + PURPOSE : Process the primitive RRGRR_ACTIVATE_REQ received from GRR. + This primitive activates RR. RR acts as if the MS is only + GSM service mobile. Monitor CCCH and BCCH. + IN : + OUT : + +*/ + +void dat_rrgrr_activate_req (T_RRGRR_ACTIVATE_REQ *act_req) +{ + GET_INSTANCE_DATA; + TRACE_EVENT ("dat_rrgrr_activate_req ()"); + + rr_data->gprs_data.gprs_suspend = act_req->susp_req; + rr_data->gprs_data.rac = act_req->rac; + rr_data->gprs_data.gprs_resump = GPRS_RESUMPTION_ACK; + + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PIM_PBCCH: + case GPRS_PAM_PBCCH: + case GPRS_PTM_PBCCH: + + /* we need the parameters from GRR to make + * a MO call + */ + if(act_req->non_gprs.v_non_gprs) + { + handle_non_gprs_param(&act_req->non_gprs); + } + break; + case GPRS_PIM_BCCH: + /* nothing to do, just wait for MM to start with RR_ESTABLISH_REQ */ + /*SET_STATE(STATE_GPRS, GPRS_SUSPENDED_BCCH); do this on + RR_ESTABLISH_REQ */ + break; + case GPRS_PAM_BCCH: + case GPRS_PTM_BCCH: + /* + * abort procedures we are doing for GPRS + * and go back to idle mode to wait for the + * RR_ESTABLISH_REQ + */ + rr_data->gprs_data.page_mode = PAG_MODE_DEFAULT; +#ifdef REL99 +#else + att_return_to_idle(); +#endif + SET_STATE(STATE_GPRS, GPRS_PIM_BCCH); +#ifdef REL99 + att_return_to_idle(); +#endif + break; + default: + break; + } + + PFREE (act_req); +} + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_set_gprs_resump | ++-----------------------------------------------------------------------------+ + + PURPOSE : Sets stored GPRS resumption value to the RR_RELEASE_IND primitive + to send. + IN : Pointer to RR_RELEASE_IND primitive. + OUT : + +*/ + +void dat_set_gprs_resump (T_RR_RELEASE_IND* rr_release_ind) +{ + GET_INSTANCE_DATA; + rr_release_ind->gprs_resumption = rr_data->gprs_data.gprs_resump; +} + + + +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_gprs_set_suspended | ++-----------------------------------------------------------------------------+ + + PURPOSE : Sets state to GPRS_SUSPENDED_PBCCH or GPRS_SUSPENDED_BCCH + IN : + OUT : + +*/ + + +void dat_gprs_set_suspended(void) +{ + GET_INSTANCE_DATA; + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PIM_PBCCH: + case GPRS_PAM_PBCCH: + case GPRS_PTM_PBCCH: + SET_STATE(STATE_GPRS, GPRS_SUSPENDED_PBCCH); + break; + case GPRS_PIM_BCCH: + case GPRS_PAM_BCCH: + case GPRS_PTM_BCCH: + SET_STATE(STATE_GPRS, GPRS_SUSPENDED_BCCH); + break; + default: + break; + } +} + +#ifdef REL99 +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : dat_gprs_set_suspended | ++-----------------------------------------------------------------------------+ + + PURPOSE : Sets state to GPRS_SUSPENDED_PBCCH or GPRS_SUSPENDED_BCCH + IN : + OUT : + +*/ +BOOL dat_gprs_cell_in_ptm(void) +{ + GET_INSTANCE_DATA; + switch(GET_STATE(STATE_GPRS)) + { + case GPRS_PTM_PBCCH: + case GPRS_PTM_BCCH: + return TRUE; + default: + return FALSE; + } +} +#endif + +/*===========================================================================*/ +/* + * L O C A L S + */ +/*===========================================================================*/ +/* ++-----------------------------------------------------------------------------+ +| PROJECT : GSM-GPRS (??6147) MODULE : RR_GPRS | +| STATE : code ROUTINE : get_r_bit | ++-----------------------------------------------------------------------------+ + + PURPOSE : R-bit for the IA-prims + IN : access counter + OUT : r_bit + +*/ + +static UBYTE get_r_bit (void) +{ + GET_INSTANCE_DATA; + UBYTE r_bit; + + switch (rr_data->ms_data.access_counter) + { + case 0: + r_bit = NOT_PRESENT_8BIT; + break; + case 1: + r_bit = CHAN_REQ_SENT_ONCE; + break; + default: + r_bit = CHAN_REQ_SENT_MORE; + break; + } + return r_bit; +} + +#endif /* GPRS */ +#endif /* RR_DATG_C */