diff gsm-fw/g23m-gsm/rr/rr_dats.c @ 673:2f7df7a314f8

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