FreeCalypso > hg > fc-magnetite
view src/g23m-gsm/rr/rr_datg.c @ 581:a0a45c5eb3ef
gsmcomp.c: bumping trace partition size to 220 like in gprscomp.c
This change is safe in terms of RAM usage because all of these partition
pools have already been moved from XRAM to IRAM earlier, and our IRAM
usage in VO configs is currently quite low - the one near the limit
is XRAM on C11x.
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Tue, 29 Jan 2019 03:52:49 +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 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 */