diff src/g23m-gsm/rr/rr_datg.c @ 1:fa8dc04885d8

src/g23m-*: import from Magnetite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:25:50 +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	Fri Oct 16 06:25:50 2020 +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 */