diff src/cs/layer1/p_cfile/l1p_asyn.c @ 302:0740b5ff15f6

reconstructed L1_GPRS source imported from tcs211-l1-reconst
author Mychaela Falconia <falcon@freecalypso.org>
date Tue, 31 Oct 2017 03:42:35 +0000
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/cs/layer1/p_cfile/l1p_asyn.c	Tue Oct 31 03:42:35 2017 +0000
@@ -0,0 +1,3113 @@
+/************* Revision Controle System Header *************
+ *                  GSM Layer 1 software
+ * L1P_ASYN.C
+ *
+ *        Filename l1p_asyn.c
+ *  Copyright 2003 (C) Texas Instruments
+ *
+ ************* Revision Controle System Header *************/
+
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+  #include "l1_macro.h"
+  #include "l1_confg.h"
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM !=0))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM enabled
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+#define  L1P_ASYN_C
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END         // KEEP IN EXTERNAL MEM otherwise
+#endif
+
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+
+#include "l1_macro.h"
+#include "l1_confg.h"
+
+#if L1_GPRS
+
+#if (CODE_VERSION == SIMULATION)
+  #include <string.h>
+  #include "l1_types.h"
+  #include "sys_types.h"
+  #include "l1_const.h"
+  #if TESTMODE
+    #include "l1tm_defty.h"
+  #endif
+  #if (AUDIO_TASK == 1)
+    #include "l1audio_const.h"
+    #include "l1audio_cust.h"
+    #include "l1audio_defty.h"
+  #endif
+  #if (L1_GTT == 1)
+    #include "l1gtt_const.h"
+    #include "l1gtt_defty.h"
+  #endif
+  #if (L1_MP3 == 1)
+    #include "l1mp3_defty.h"
+  #endif
+  #if (L1_MIDI == 1)
+    #include "l1midi_defty.h"
+  #endif
+  #include "l1_defty.h"
+  #include "cust_os.h"
+  #include "l1_msgty.h"
+  #include "l1_varex.h"
+  #include "l1_signa.h"
+  #include "l1_proto.h"
+  #include "l1_time.h"
+  #include "l1_ctl.h"
+
+  #include "l1p_cons.h"
+  #include "l1p_msgt.h"
+  #include "l1p_deft.h"
+  #include "l1p_vare.h"
+  #include "l1p_tabs.h"
+  #include "l1p_sign.h"
+  #include "l1p_mfta.h"
+  #include "l1p_macr.h"
+
+  #include "macs_def.h"
+  #include "macs_cst.h"
+#else
+  #include <string.h>
+  #include "l1_types.h"
+  #include "sys_types.h"
+  #include "l1_const.h"
+
+  #if TESTMODE
+    #include "l1tm_defty.h"
+  #endif
+  #if (AUDIO_TASK == 1)
+    #include "l1audio_const.h"
+    #include "l1audio_cust.h"
+    #include "l1audio_defty.h"
+  #endif
+  #if (L1_GTT == 1)
+    #include "l1gtt_const.h"
+    #include "l1gtt_defty.h"
+  #endif
+  #if (L1_MP3 == 1)
+    #include "l1mp3_defty.h"
+  #endif
+  #if (L1_MIDI == 1)
+    #include "l1midi_defty.h"
+  #endif
+  #include "l1_defty.h"
+  #include "cust_os.h"
+  #include "l1_msgty.h"
+  #include "l1_varex.h"
+  #include "l1_signa.h"
+  #include "l1_proto.h"
+  #include "l1_time.h"
+  #include "l1_ctl.h"
+
+  #include "l1p_cons.h"
+  #include "l1p_msgt.h"
+  #include "l1p_deft.h"
+  #include "l1p_vare.h"
+  #include "l1p_tabs.h"
+  #include "l1p_sign.h"
+  #include "l1p_mfta.h"
+  #include "l1p_macr.h"
+
+  #include "macs_def.h"
+  #include "macs_cst.h"
+#endif
+
+T_TRANSFER_SET   *l1pa_get_free_transfer_set              (UWORD8  new_tbf);
+void              l1pa_transfer_process                   (xSignalHeaderRec *msg);
+void              l1pa_access_process                     (xSignalHeaderRec *msg);
+void              l1pa_idle_packet_polling_process        (xSignalHeaderRec *msg);
+void              l1pa_idle_paging_process                (xSignalHeaderRec *msg);
+void              l1pa_cr_meas_process                    (xSignalHeaderRec *msg);
+void              l1pa_serving_cell_pbcch_read_process    (xSignalHeaderRec *msg);
+void              l1pa_neighbor_cell_pbcch_read_process   (xSignalHeaderRec *msg);
+int               l1pa_sort                               (const void *a, const void *b);
+void              l1pa_reset_cr_freq_list                 (void);
+void              l1pa_tcr_meas_process                   (xSignalHeaderRec *msg);
+T_CRES_LIST_PARAM *l1pa_get_free_cres_list_set            (void);
+void              l1pa_idle_interference_meas_process     (xSignalHeaderRec *msg);
+void              l1pa_transfer_interference_meas_process (xSignalHeaderRec *msg);
+void              l1pa_idle_smscb_process                 (xSignalHeaderRec *msg);
+
+// External prototype
+void l1pa_send_int_meas_report(UWORD32               SignalCode,
+                               T_L1P_ITMEAS_IND     *last_l1s_msg,
+                               T_L1A_INT_MEAS_PARAM *first_meas_ptr);
+void l1pa_send_confirmation(UWORD32 SignalCode, UWORD8 id);
+void l1pa_send_tbf_release_con(UWORD32 SignalCode, UWORD8 tbf_type);
+
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM > 1))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM == 2
+//#pragma GSM_IDLE2_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+
+/*-------------------------------------------------------*/
+/* l1pa_task()                                           */
+/*-------------------------------------------------------*/
+/*                                                       */
+/* Description:                                          */
+/* ------------                                          */
+/* L1PA (Layer 1 Asynchronous) task function. This       */
+/* function manages the GPRS interface between L3 and L1.*/
+/* It is composed with a set of state machine, each      */
+/* machine handles a particular GSM functionality. When  */
+/* a message is received in L1_C1 message queue, it is   */
+/* submitted to every state machine. The one which are   */
+/* impacted by the message process it. At the end of     */
+/* "l1pa_task()" function, a balance routine is called,  */
+/* it enables L1S tasks consequently to the state machine*/
+/* requests.                                             */
+/*                                                       */
+/*-------------------------------------------------------*/
+void  l1pa_task(xSignalHeaderRec *msg)
+{
+  UWORD8  process;
+
+  // Clear L1PA "enable meas and tasks" variables.
+  //---------------------------------------------
+  for(process=0; process<NBR_L1PA_PROCESSES; process++)
+  {
+    l1pa.l1pa_en_meas[process] = NO_TASK;
+  }
+
+  #if (GSM_IDLE_RAM != 0)
+    if ((msg->SignalCode != L1P_PNP_INFO) && (msg->SignalCode != L1P_PEP_INFO))
+
+    #if (GSM_IDLE_RAM > 1) // GPF modified for GSM_IDLE_RAM -> SW still running in Internal RAM
+          {
+    #endif
+            l1s.gsm_idle_ram_ctl.l1s_full_exec = TRUE;
+  #endif // GSM_IDLE_RAM
+
+  // Serving Cell Packet System Information Reading
+  l1pa_serving_cell_pbcch_read_process(msg);
+
+  // Neighbor Cell Packet System Information Reading
+  l1pa_neighbor_cell_pbcch_read_process(msg);
+
+  #if (GSM_IDLE_RAM <= 1)  // GPF modified for GSM_IDLE_RAM -> SW still running in Internal RAM
+  {
+    // Serving Cell Packet Paging Reading
+    l1pa_idle_paging_process(msg);
+  }
+  #endif
+  // Cell reselection measurement process
+  l1pa_cr_meas_process(msg);
+
+  // Packet access proccess
+  l1pa_access_process(msg);
+
+  // Packet polling process
+  l1pa_idle_packet_polling_process(msg);
+
+  // Packet transfer process.
+  l1pa_transfer_process(msg);
+
+  // Neighbour Cell Measurement in Packet Transfer mode
+  l1pa_tcr_meas_process(msg);
+
+  // Intererence measurements in packet idle mode
+  l1pa_idle_interference_meas_process(msg);
+
+  // Intererence measurements in packet transfer mode
+  l1pa_transfer_interference_meas_process(msg);
+
+  #if (GSM_IDLE_RAM > 1)  // GPF modified for GSM_IDLE_RAM -> SW still running in Internal RAM
+  }else
+  {
+    // Serving Cell Packet Packet Idle Paging Reading
+    l1pa_idle_paging_process(msg);
+  }
+  #endif
+}
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END         // KEEP IN EXTERNAL MEM otherwise
+#endif
+
+/*-------------------------------------------------------*/
+/* l1pa_access_process()                                 */
+/*-------------------------------------------------------*/
+/* Description : This state machine handles the packet   */
+/* access to the network while in PACKET IDLE mode.      */
+/*                                                       */
+/* Starting messages:        MPHP_RA_REQ                 */
+/*                                                       */
+/* Subsequent messages:      MPHP_RA_REQ                 */
+/*                                                       */
+/* Result messages (input):  L1P_PRA_DONE                */
+/*                                                       */
+/* Result messages (output): MPHP_RA_CON                 */
+/*                                                       */
+/* Reset message (input): MPHP_RA_STOP_REQ               */
+/*                                                       */
+/* Reset message (input): MPHP_RA_STOP_CON               */
+/*-------------------------------------------------------*/
+void l1pa_access_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET       = 0,
+    WAIT_INIT   = 1,
+    WAIT_RESULT = 2
+  };
+
+  UWORD8   *state      = &l1pa.state[P_ACC];
+  UWORD32   SignalCode = msg->SignalCode;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_INIT;
+
+        // Reset PRACH process.
+        l1a_l1s_com.l1s_en_task[PRACH]     = TASK_DISABLED;  // Clear PRACH task enable flag.
+        l1pa_l1ps_com.pra_info.prach_alloc = 0;
+      }
+      break;
+
+
+      case WAIT_INIT:
+      {
+        if(SignalCode == MPHP_RA_REQ)
+        // 1st Random access request message.
+        //-----------------------------------
+        {
+
+          // Download Transmit power configuration.
+          // Given value must be used on 1st TX.
+          // TXPWR value supplied by L3 is the max. TX power level the MS may use in the given band
+          l1s.applied_txpwr = ((T_MPHP_RA_REQ *)(msg->SigP))->txpwr;
+
+
+          #if L1_R99
+          // Init PRACH process.
+            // "rand" parameter chosen by protocol in range [1..4] for R99
+            l1pa_l1ps_com.pra_info.rand                 = ((T_MPHP_RA_REQ *)(msg->SigP))->rand;
+          #else
+          // "rand" parameter from msg is not used for the 1st PRACH.
+          l1pa_l1ps_com.pra_info.rand                 = 1; // First PRACH has to be sent immediately
+          #endif
+          l1pa_l1ps_com.pra_info.channel_request_data = ((T_MPHP_RA_REQ *)(msg->SigP))->channel_request_data;
+          l1pa_l1ps_com.pra_info.bs_prach_blks        = ((T_MPHP_RA_REQ *)(msg->SigP))->bs_prach_blks;
+          l1pa_l1ps_com.access_burst_type             = ((T_MPHP_RA_REQ *)(msg->SigP))->access_burst_type;
+
+          // Increment rand parameter by 4 in order to avoid conflict between SYNCHRO and
+          // PRACH tasks when MPHP_START_PCCCH_REQ and MPHP_RA_REQ are
+          // sent at the same time by L3
+          l1pa_l1ps_com.pra_info.rand+=4;
+
+          if ((l1pa_l1ps_com.pra_info.bs_prach_blks == 0) || // no blocks allocated
+              (l1pa_l1ps_com.pra_info.bs_prach_blks > 12))   // invalid number of blocks
+            l1pa_l1ps_com.pra_info.prach_alloc = DYN_PRACH_ALLOC;
+
+          // step in state machine.
+          *state = WAIT_RESULT;
+
+          // Change mode to connection establishment part 1.
+          l1a_l1s_com.mode = CON_EST_MODE1;
+
+          // Activate PRACH task (no semaphore for UL tasks).
+          l1a_l1s_com.l1s_en_task[PRACH] = TASK_ENABLED; // Set PRACH task enable flag.
+
+        }
+
+        // end of process.
+        end_process = 1;
+      }
+      break;
+
+      case WAIT_RESULT:
+      {
+        if(SignalCode == L1P_RA_DONE)
+        // Random access acknowledge message: PRACH sent.
+        //-----------------------------------------------
+        {
+          // Forward result message to L3.
+          l1a_send_result(MPHP_RA_CON, msg, GRRM1_QUEUE);
+
+          // Change mode to connection establishment part 2.
+          l1a_l1s_com.mode = CON_EST_MODE2;
+
+          // end of process.
+          return;
+        }
+
+        else
+        if(SignalCode == MPHP_RA_REQ)
+        // Random access message.
+        //-----------------------
+        {
+          // REM: rand is added the msg content since its current content is the already
+          // spent "slots" from the last PRACH sending.
+          l1pa_l1ps_com.pra_info.rand                += ((T_MPHP_RA_REQ *)(msg->SigP))->rand + 1;
+          l1pa_l1ps_com.pra_info.channel_request_data = ((T_MPHP_RA_REQ *)(msg->SigP))->channel_request_data;
+          l1pa_l1ps_com.pra_info.bs_prach_blks        = ((T_MPHP_RA_REQ *)(msg->SigP))->bs_prach_blks;
+          l1pa_l1ps_com.access_burst_type             = ((T_MPHP_RA_REQ *)(msg->SigP))->access_burst_type;
+
+          if ((l1pa_l1ps_com.pra_info.bs_prach_blks == 0) || // no blocks allocated
+              (l1pa_l1ps_com.pra_info.bs_prach_blks > 12))   // invalid number of blocks
+            l1pa_l1ps_com.pra_info.prach_alloc = DYN_PRACH_ALLOC;
+//          else
+//            l1pa_l1ps_com.pra_info.prach_alloc = FIX_PRACH_ALLOC;
+          else
+            l1pa_l1ps_com.pra_info.prach_alloc = 0; //must be reset for each burst sent
+
+
+          // Activate PRACH task (no semaphore for UL tasks).
+          l1a_l1s_com.l1s_en_task[PRACH] = TASK_ENABLED;   // Set PRACH task enable flag.
+
+          // end of process.
+          return;
+        }
+
+        else
+        if(SignalCode == MPHP_RA_STOP_REQ)
+        // Request to STOP the LINK ACCESS procedure.
+        //-------------------------------------------
+        {
+          UWORD8 i;
+
+          // send confirmation
+          l1a_send_confirmation(MPHP_RA_STOP_CON,GRRM1_QUEUE);
+
+          // Store MAX TXPWR value to be used for first Tx PDCH blocks
+          for(i = 0; i < 8; i++)
+          {
+            l1pa_l1ps_com.transfer.dl_pwr_ctrl.txpwr[i] = l1s.applied_txpwr;
+          }
+
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        if(SignalCode == MPHP_POLLING_RESPONSE_REQ)
+        // Stop packet access when packet polling initiated.
+        //--------------------------------------------------
+        {
+          // Unacknowledged
+
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          end_process = 1;
+        }
+      }
+      break;
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+/*-------------------------------------------------------*/
+/* l1pa_cr_meas_process()                                */
+/*-------------------------------------------------------*/
+/* Description : This state machine handles periodic     */
+/* signal strength monitoring on carriers specified      */
+/* in a frequency list: BA(GPRS), NC_FREQUENCY_LIST,     */
+/* EXT_FREEQUENCY_LIST (respectively: cell reselection   */
+/* Network Control and Extended measurements.            */
+/*                                                       */
+/* Starting messages:        MPHP_CR_MEAS_REQ            */
+/* ------------------                                    */
+/*  L1 starts then the periodic FREQUENCY list receive   */
+/*  level monitoring.                                    */
+/*                                                       */
+/* Subsequent messages:      MPHP_CR_MEAS_REQ            */
+/* --------------------                                  */
+/*  The frequency list is updated only when measures     */
+/*  on all the carriers of the current list are          */
+/*  performed.                                           */
+/*                                                       */
+/* Result messages (input):  L1P_RXLEV_PERIODIC_DONE     */
+/* ------------------------                              */
+/*  This is a message reported to L1A from L1S.          */
+/*  Reporting is done when last carrier of the frequency */
+/*  list is read.                                        */
+/*                                                       */
+/* Result messages (output): MPHP_CR_MEAS_IND            */
+/* -------------------------                             */
+/*  This is the periodic reporting message to L3.        */
+/*                                                       */
+/* Reset messages (input):   MPHP_CR_MEAS_STOP_REQ       */
+/* -----------------------                               */
+/*  Frequency list measurement process is stopped by     */
+/*  this message.                                        */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1pa_cr_meas_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET       = 0,
+    WAIT_INIT   = 1,
+    WAIT_RESULT = 2
+
+  };
+
+  UWORD8   *state      = &l1pa.state[CR_MEAS];
+  UWORD32   SignalCode = msg->SignalCode;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // step in state machine.
+        *state = WAIT_INIT;
+
+        // Reset P_CRMS_MEAS process.
+        l1pa_l1ps_com.l1ps_en_meas &= P_CRMS_MEAS_MASK; // Reset Packet Cell Reselection Measurement enable flag.
+      }
+      break;
+
+      case WAIT_INIT:
+      {
+        if(SignalCode == MPHP_CR_MEAS_REQ)
+        // We receive the Frequency list to be monitored.
+        //----------------------------------------------
+        {
+          UWORD8  i;
+          T_CRES_LIST_PARAM  *free_list;
+
+          // Set parameter synchro semaphore for P_CRMS_MEAS task.
+          l1pa_l1ps_com.meas_param |= P_CRMS_MEAS;
+
+          // Reset the frequency list structure.
+          l1pa_reset_cr_freq_list();
+
+          // Get Ptr to the free Neighbour meas list.
+          // The number of carriers in the list and the list
+          // identification are initialized.
+          free_list = l1pa_get_free_cres_list_set();
+
+          // Set number of carrier in the frequency list.
+          free_list->nb_carrier = ((T_MPHP_CR_MEAS_REQ *)(msg->SigP))->nb_carrier;
+
+          // Store ARFCN list in the Packet Cell Reselection structure.
+          for(i=0;i<free_list->nb_carrier;i++)
+            free_list->freq_list[i] = ((T_MPHP_CR_MEAS_REQ *)(msg->SigP))->radio_freq_no[i];
+
+          // Download Frequency list identifier.
+          free_list->list_id = ((T_MPHP_CR_MEAS_REQ *)(msg->SigP))->list_id;
+
+          // Set "flist" with new set of frequency list parameter
+          l1pa_l1ps_com.cres_freq_list.flist = free_list;
+
+          // Enable Packet Cell Reselection measurement task.
+          l1pa.l1pa_en_meas[CR_MEAS] |= P_CRMS_MEAS;
+
+          // step in state machine.
+          *state = WAIT_RESULT;
+        }
+
+        // End of process.
+        end_process = 1;
+      }
+      break;
+
+      case WAIT_RESULT:
+      {
+        if(SignalCode == L1P_CR_MEAS_DONE)
+        // One set of measurement has been completed.
+        //---------------------------------------------
+        {
+          // Forward result message to L3.
+          l1a_send_result(MPHP_CR_MEAS_IND, msg, GRRM1_QUEUE);
+
+          // End of process.
+          end_process = 1;
+        }
+
+        else
+        if((SignalCode == MPHP_CR_MEAS_STOP_REQ) ||
+           (SignalCode == L1P_TRANSFER_DONE)     ||
+           (SignalCode == L1C_DEDIC_DONE))
+        // Request to STOP this activity.
+        //-------------------------------
+        {
+          // send confirmation message
+          l1a_send_confirmation(MPHP_CR_MEAS_STOP_CON,GRRM1_QUEUE);
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        if (SignalCode == MPHP_CR_MEAS_REQ)
+        {
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          end_process = 1;
+        }
+      }
+      break;
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+#if !((MOVE_IN_INTERNAL_RAM == 1) && (GSM_IDLE_RAM > 1))  // MOVE TO INTERNAL MEM IN CASE GSM_IDLE_RAM == 2
+//#pragma GSM_IDLE2_DUPLICATE_FOR_INTERNAL_RAM_START         // KEEP IN EXTERNAL MEM otherwise
+
+/*-------------------------------------------------------*/
+/* l1pa_idle_paging_process()                            */
+/*-------------------------------------------------------*/
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1pa_idle_paging_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET             = 0,
+    WAIT_INIT         = 1,
+    WAIT_MSG          = 2
+  };
+
+  enum pg_mode
+  {
+    NORM_PG           = 0,
+    EXT_PG            = 1,
+    REORG_PG          = 2
+  };
+
+  UWORD8  *state     = &l1pa.state[PI_SCP];
+  UWORD32 SignalCode = msg->SignalCode;
+  UWORD16 imsimod;
+  UWORD16 split_pg_cycle;
+  UWORD16 kcn;
+  UWORD8  page_mode;
+
+  BOOL end_process = 0;
+
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_INIT;
+
+        // Disable serving cell tasks.
+        l1a_l1s_com.l1s_en_task[PALLC]   = TASK_DISABLED;     // Reset PALLC (reorg) task enable flag.
+        l1a_l1s_com.l1s_en_task[PNP]     = TASK_DISABLED;     // Reset PNP     task enable flag.
+        l1a_l1s_com.l1s_en_task[PEP]     = TASK_DISABLED;     // Reset PEP     task enable flag.
+
+        // No Paging  => no gauging => no Deep sleep
+        l1s.pw_mgr.enough_gaug = FALSE;  // forbid Deep sleep
+
+      }
+      break;
+
+      case WAIT_INIT:
+      {
+        if(SignalCode == MPHP_START_PCCCH_REQ)
+        {
+          // Set semaphores for any PCCCH reading tasks.
+          l1a_l1s_com.task_param[PALLC] = SEMAPHORE_SET;
+          l1a_l1s_com.task_param[PNP]   = SEMAPHORE_SET;
+          l1a_l1s_com.task_param[PEP]   = SEMAPHORE_SET;
+
+          // Request to enter in PACKET PAGING REORGANIZATION or NORMAL mode.
+          //----------------------------------------------------------------
+          // The initial page mode in the Mobile Station shall be set to paging Reorganization
+          // cf 04.08 section 3.3.2.1.1. however current implementation allows to init the Paging
+          // procedure either in Reorganization or in Normal paging mode.
+
+          // Download the PAGING PARAMETERS from the command message.
+          page_mode                           = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->page_mode;
+          imsimod                             = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->imsimod;
+          kcn                                 = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->kcn;
+          split_pg_cycle                      = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->split_pg_cycle;
+          l1pa_l1ps_com.pccch.bs_pag_blks_res = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->bs_pag_blks_res;
+          l1pa_l1ps_com.pccch.bs_pbcch_blks   = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->bs_pbcch_blks;
+          l1pa_l1ps_com.pccch.frequency_list  = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->frequency_list;
+          l1pa_l1ps_com.pccch.packet_chn_desc = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->packet_chn_desc;
+          l1a_l1s_com.Scell_info.pb           = ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->pb << 2; // Pb format 7.1
+
+          // Number of paging blocks "available" on one PCCCH = number of ppch blocks per MF52 * 64
+          // = (12 - BS_PAG_BLKS_RES - BS_PBCCH_BLKS)*64
+          l1pa_l1ps_com.pccch.nb_ppch_per_mf52 = (12 - l1pa_l1ps_com.pccch.bs_pag_blks_res - (l1pa_l1ps_com.pccch.bs_pbcch_blks + 1));
+
+          // Compute M.
+          l1pa_l1ps_com.pccch.pg_blks_avail    =  l1pa_l1ps_com.pccch.nb_ppch_per_mf52 * 64;
+
+          // (IMSI mod 1000) div (KC*N) (Note: N = 1 for PCCCH)
+          l1pa_l1ps_com.pccch.pg_offset        = imsimod / kcn;
+
+          // First Paging Group value: PAGING_GROUP = ((IMSI mod 1000) div ((KC*N)*N)) (for m = 0)
+          l1pa_l1ps_com.pccch.first_pg_grp     = (l1pa_l1ps_com.pccch.pg_offset % l1pa_l1ps_com.pccch.pg_blks_avail);
+
+          // Split Paging computation = min (pg_blks_avail, SPLIT_PG_CYCLE)
+          l1pa_l1ps_com.pccch.split_pg_value = Min(l1pa_l1ps_com.pccch.pg_blks_avail, split_pg_cycle);
+
+          // Paging Period computation
+          l1pa_l1ps_com.pccch.pnp_period = (64*52) / l1pa_l1ps_com.pccch.split_pg_value;
+
+          // Rem: changing the paging parameters changes the place where "Periodic Packet
+          //      Measurement" task must be executed. It implies to set semaphore for P_CRMS task.
+          l1pa_l1ps_com.meas_param |= P_CRMS_MEAS;
+
+          // Layer 1 internal mode is set to IDLE MODE.
+          l1a_l1s_com.mode = I_MODE;
+
+          // In order to keep tn_difference and dl_tn consistent, we need to avoid
+          // the execution of the SYNCHRO task with tn_difference updated and
+          // dl_tn not yet updated (this can occur if we go in the HISR just after
+          // the update of tn_difference). To do this the solution is to use the Semaphore
+          // associated to the SYNCHRO task. SYNCHRO task will be schedule only if its
+          // associated Semaphore is reset.
+          // Note: Due to the specificity of the SYNCHRO task which can be enabled
+          // by L1A state machines as by L1S processes, the semaphore can't followed
+          // the generic rules of the Semaphore shared between L1A and L1S.
+          // We must shift the mobile time setting to the timeslot provided by
+          // ((T_MPHP_START_PCCCH_REQ *)(msg->SigP))->packet_chn_desc.timeslot_no parameter.
+          //   tn_difference -> loaded with the number of timeslot to shift.
+          //   dl_tn         -> loaded with the new timeslot.
+          l1a_l1s_com.task_param[SYNCHRO] = SEMAPHORE_SET;
+          {
+            l1a_l1s_com.tn_difference += l1pa_l1ps_com.pccch.packet_chn_desc.timeslot_no - l1a_l1s_com.dl_tn;
+            l1a_l1s_com.dl_tn          = l1pa_l1ps_com.pccch.packet_chn_desc.timeslot_no;
+
+            // Select GPRS DSP Scheduler.
+            l1a_l1s_com.dsp_scheduler_mode = GPRS_SCHEDULER;
+
+            // Timing must be shifted to a new timeslot, enables SYNCHRO task..
+            l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
+          }
+          l1a_l1s_com.task_param[SYNCHRO] = SEMAPHORE_RESET;
+          // Note: The using of the semaphore associated to the SYNCHRO task can't be done
+          // as it is for the other semaphores. This is due to the specificity of the SYNCHRO
+          // task both touch by L1A and L1S. Here above the semaphore is set prior to touching
+          // the SYNCHRO parameters and reset after. In L1S this semaphore is checked. If it's
+          // seen SET then L1S will not execute SYNCHRO task nor modify its parameters.
+
+          // Step in state machine.
+          *state = WAIT_MSG;
+
+          if(page_mode == REORG_PG)
+          // Paging Reorganization mode...
+          {
+            // Enable Packet Paging Reorganisation tasks.
+            l1a_l1s_com.l1s_en_task[PALLC] = TASK_ENABLED;
+            l1a_l1s_com.l1s_en_task[PNP]   = TASK_ENABLED;
+
+            // End of process.
+            end_process = 1;
+          }
+          else
+          if(page_mode == NORM_PG)
+          // Normal Paging mode...
+          {
+            // Enable Packet Paging tasks in mode "NORMAL".
+            l1a_l1s_com.l1s_en_task[PNP]  = TASK_ENABLED;
+
+            // End of process.
+            end_process = 1;
+          }
+          else
+          // Extended Paging mode...
+          {
+            // Initialize Paging State for PAGING_GROUP computation (L1S part)
+            l1pa_l1ps_com.pccch.epg_computation = PPCH_POS_NOT_COMP;
+
+            // Enable Packet Paging tasks in mode "EXTENDED".
+            l1a_l1s_com.l1s_en_task[PNP]  = TASK_ENABLED;
+            l1a_l1s_com.l1s_en_task[PEP]  = TASK_ENABLED;
+
+            // End of process.
+            end_process = 1;
+          }
+
+        } // end of test on SignalCode == MPHP_START_PCCCH_REQ
+
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          end_process = 1;
+        }
+
+      } // end of case WAIT_INIT
+      break;
+
+      case WAIT_MSG:
+      {
+        if((SignalCode == L1P_PNP_INFO)   ||
+           (SignalCode == L1P_PALLC_INFO) ||
+           (SignalCode == L1P_PEP_INFO))
+        // Paging Task results
+        {
+          // Forward result message to L3.
+          l1a_send_result(MPHP_DATA_IND, msg, GRRM1_QUEUE);
+
+          // End of process.
+          return;
+        }
+
+        else
+        if(SignalCode == MPHP_START_PCCCH_REQ)
+        // New PCCCH configuration is provided.
+        //--------------------------------------------------------
+          {
+          // Step in state machine
+            *state = RESET;
+          }
+
+        else
+        if((SignalCode == MPHP_STOP_PCCCH_REQ) ||
+           (SignalCode == L1P_TRANSFER_DONE) || (SignalCode == L1C_DEDIC_DONE))
+        // Request to STOP any serving cell Packet Paging activity, OR
+        // Packet Transfer has just started.
+        // In both cases, PCCCH reading must be stopped.
+        //--------------------------------------------------------
+        {
+          // Send confirmation message to L3.
+          l1a_send_confirmation(MPHP_STOP_PCCCH_CON,GRRM1_QUEUE);
+
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        if((SignalCode == L1P_SINGLE_BLOCK_CON) ||
+           (SignalCode == MPHP_SINGLE_BLOCK_CON))
+        // If Two Phase Access is ongoing: Packet Resource Request
+        // msg has been sent to the network. PCCCH reading must be
+        // stopped to let PDCH reading going.
+        // REM: we must check both L1P/MPHP messages since an other
+        // process could have renamed L1P into MPHP.
+        //--------------------------------------------------------
+        {
+          if(((T_MPHP_SINGLE_BLOCK_CON *)(msg->SigP))->purpose == TWO_PHASE_ACCESS)
+        {
+          // This process must be reset.
+          *state = RESET;
+        }
+        else
+        {
+            // End of process.
+            return;
+          }
+        }
+
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          return;
+        }
+
+      } // end of case WAIT_MSG
+      break;
+    } // end of switch
+  } // end of while
+} // end of procedure
+
+//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
+#endif
+
+/*-------------------------------------------------------*/
+/* l1pa_idle_packet_polling_process()                    */
+/*-------------------------------------------------------*/
+/* Description :                    .                    */
+/* This state machine handles packet polling after       */
+/* initiation of the packet acces procedure, when a      */
+/* packet queuing notification is sent by the network    */
+/*                                                       */
+/* Starting messages:        MPHP_POLLING_RESPONSE_REQ   */
+/*                                                       */
+/* Subsequent messages:                                  */
+/*                                                       */
+/* Result messages (input):  L1P_PRA_DONE                */
+/*                                                       */
+/* Result messages (output): MPHP_POLLING_IND            */
+/*                                                       */
+/* Reset message (input):                                */
+/*                                                       */
+/* Reset message (input):                                */
+/*-------------------------------------------------------*/
+void l1pa_idle_packet_polling_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET       = 0,
+    WAIT_INIT   = 1,
+    WAIT_RESULT = 2
+  };
+
+  UWORD8   *state      = &l1pa.state[P_POLL];
+  UWORD32   SignalCode = msg->SignalCode;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_INIT;
+
+        // Reset POLL process.
+        l1a_l1s_com.l1s_en_task[POLL] = TASK_DISABLED;  // Clear RAACC task enable flag.
+      }
+      break;
+
+
+      case WAIT_INIT:
+      {
+        if(SignalCode == MPHP_POLLING_RESPONSE_REQ)
+        // Polling response request for access procedure.
+        //-----------------------------------------------
+        {
+          UWORD8 i;
+
+          // Init POLL process.
+          l1pa_l1ps_com.poll_info.pol_resp_type = ((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->pol_resp_type;
+          l1pa_l1ps_com.poll_info.fn            = ((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->fn;
+
+         // TXPWR value supplied by L3 is the max. TX power level the MS may use in the given band
+          l1s.applied_txpwr                     = ((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->txpwr;
+
+          // 1 RLC/MAC block is sent:
+          // This is a special case, only possible if the MS has a valid TA available from a pending
+          // assignment and is pooled for an RLC/MAC block.
+          if (l1pa_l1ps_com.poll_info.pol_resp_type == CS1_TYPE_POLL)
+          {
+            for (i=0; i<24; i++)
+            {
+              // download 24 bytes from message
+              l1pa_l1ps_com.poll_info.chan_req.cs1_data[i] =
+                ((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->channel_request_data[i];
+            }
+            l1pa_l1ps_com.poll_info.timing_advance = ((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->timing_advance;
+
+            // Store MAX TXPWR value to be used for first POLL RESPONSE
+            // if not already done by Packet Access process...
+            for(i = 0; i < 8; i++)
+            {
+              l1pa_l1ps_com.transfer.dl_pwr_ctrl.txpwr[i] = l1s.applied_txpwr;
+            }
+          }
+          // 4 identical PRACH are sent
+          else
+          {
+            // UWORD16 = data[1]<<8 | data[0]
+            l1pa_l1ps_com.poll_info.chan_req.prach_data[0] =
+              ((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->channel_request_data[0];
+            l1pa_l1ps_com.poll_info.chan_req.prach_data[0] |=
+              (((T_MPHP_POLLING_RESPONSE_REQ *)(msg->SigP))->channel_request_data[1] << 8);
+
+            l1pa_l1ps_com.poll_info.timing_advance = 0;
+          }
+
+          // step in state machine.
+          *state = WAIT_RESULT;
+
+          // Change mode to connection establishment part 1.
+          l1a_l1s_com.mode = CON_EST_MODE1;
+
+          // Activate POLL task (no semaphore for UL tasks).
+          // Enable Paging Reorg and Normal paging tasks.
+          l1a_l1s_com.l1s_en_task[POLL] = TASK_ENABLED; // Set PRACH task enable flag.
+        }
+
+        // end of process.
+        end_process = 1;
+      }
+      break;
+
+      case WAIT_RESULT:
+      {
+        if(SignalCode == L1P_POLL_DONE)
+        // Random access acqnowledge message.
+        //-----------------------------------
+        {
+          // Forward result message to L3.
+          l1a_send_result(MPHP_POLLING_IND, msg, GRRM1_QUEUE);
+
+          // Change mode to connection establishment part 2.
+          l1a_l1s_com.mode = CON_EST_MODE2;
+
+          // This state machine has to be reset
+          *state = RESET;
+
+          // end of process.
+          end_process = 1;
+        }
+
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          end_process = 1;
+        }
+      }
+      break;
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+
+/*-------------------------------------------------------*/
+/* l1pa_transfer_process()                               */
+/*-------------------------------------------------------*/
+/* Description:                                          */
+/* ------------                                          */
+/*                                                       */
+/* Starting messages:                                    */
+/* ------------------                                    */
+/*                                                       */
+/* Subsequent messages:                                  */
+/* --------------------                                  */
+/*                                                       */
+/* Result messages (input):                              */
+/* ------------------------                              */
+/*                                                       */
+/* Result messages (output):                             */
+/* -------------------------                             */
+/*                                                       */
+/* Reset messages (input):                               */
+/* -----------------------                               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1pa_transfer_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET       = 0,
+    WAIT_MSG    = 1
+  };
+
+  UWORD8   *state     = &l1pa.state[TRANSFER];
+  UWORD32  SignalCode = msg->SignalCode;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_MSG;
+
+        // Rise transfert parameter semaphore.
+        l1pa_l1ps_com.transfer.semaphore = TRUE;
+      }
+      break;
+
+      case WAIT_MSG:
+      {
+        switch(SignalCode)
+        // switch on input message.
+        //-------------------------
+        {
+          case MPHP_SINGLE_BLOCK_REQ:
+          // Repeat fixed allocation.
+          //-------------------------
+          {
+            T_TRANSFER_SET  *free_set;
+            UWORD8           purpose;
+            UWORD8           i;
+
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            purpose = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->purpose;
+
+            // Get Ptr to the free dedicated parameter set.
+            // All important fields are initialised.
+            free_set = l1pa_get_free_transfer_set(purpose);
+
+            // Fill Transfer mode generic parameters.
+            free_set->assignment_id      = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->assignment_id;
+            free_set->assignment_command = purpose;
+            free_set->allocated_tbf      = purpose;
+            free_set->packet_ta          = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->packet_ta;
+
+            if((purpose == SINGLE_BLOCK_DL)||(purpose == SINGLE_BLOCK_UL))
+            {
+              free_set->packet_ta.ta_index = 255;
+              free_set->packet_ta.ta_tn    = 255;
+            }
+
+            free_set->dl_pwr_ctl         = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->dl_pwr_ctl;
+            if (free_set->dl_pwr_ctl.p0 != 255)
+              free_set->dl_pwr_ctl.p0    <<= 2;  // P0 format 7.1
+            free_set->tsc                = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->tsc;
+            free_set->freq_param         = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->freq_param;
+            free_set->tbf_sti            = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->tbf_sti;
+            free_set->pc_meas_chan       = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->pc_meas_chan;
+
+            // Download access_burst_type
+            l1pa_l1ps_com.transfer.psi_param.access_burst_type    = ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->access_burst_type;
+            // Keep the same Pb factor
+            l1pa_l1ps_com.transfer.psi_param.Scell_pb             = l1a_l1s_com.Scell_info.pb;
+            // Enable PSI param updating in order to update access_burst_type in L1S
+            l1pa_l1ps_com.transfer.psi_param.psi_param_update_cmd = TRUE;
+
+            // Fill single block specific parameters.
+            for(i=0;i<23;i++)
+            {
+              l1pa_l1ps_com.transfer.single_block.data_array[i] =
+                ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->data_array[i];
+            }
+            l1pa_l1ps_com.transfer.single_block.tn =
+              ((T_MPHP_SINGLE_BLOCK_REQ *)(msg->SigP))->timeslot_number;
+
+            l1pa_l1ps_com.transfer.single_block.dl_tn_to_restore = l1a_l1s_com.dl_tn;
+
+            // Fill "synchro_timeslot" which will be the frame synchro slot.
+            free_set->ul_tbf_synchro_timeslot   = l1pa_l1ps_com.transfer.single_block.tn;
+            free_set->transfer_synchro_timeslot = l1pa_l1ps_com.transfer.single_block.tn;
+
+            // Step in state machine.
+            *state = WAIT_MSG;
+
+            // Store signalcode.
+            free_set->SignalCode = MPHP_SINGLE_BLOCK_REQ;
+
+            // Clear transfer parameter semaphore to let L1S use the new parameters.
+            l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_ASSIGNMENT_REQ:
+          // Assignement message.
+          //---------------------
+          {
+            static int count =0;
+
+            T_TRANSFER_SET  *free_set;
+            UWORD8           assignment_command;
+            UWORD8           timeslot_alloc;
+            UWORD8           timeslot;	/* TCS211 reconstruction, =0 in TCS3 */
+
+	// TBF_changes
+
+            #if FF_TBF
+
+              BOOL             pseudo_tbf_two_phase_acc;
+
+              // Special case for two phase access (single or multi allocation):
+              // It is handled as a pseudo UL TBF using a fixed allocation.
+              // Still needs to be flagged to preempt TBF establishment switch in
+              // transfer manager.
+              if (((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->assignment_command == TWO_PHASE_ACCESS)
+              {
+                ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->assignment_command = UL_TBF;
+                pseudo_tbf_two_phase_acc = TRUE;
+              }
+              else
+                pseudo_tbf_two_phase_acc = FALSE;
+            #endif
+            count++ ;
+
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            assignment_command = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->assignment_command;
+
+            // Get Ptr to the free dedicated parameter set.
+            // All important fields are initialised.
+            free_set = l1pa_get_free_transfer_set(assignment_command);
+
+            // Download message containt.
+            free_set->assignment_id      = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->assignment_id;
+            free_set->assignment_command = assignment_command;
+            free_set->multislot_class    = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->multislot_class;
+            free_set->dl_pwr_ctl         = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->dl_pwr_ctl;
+            if (free_set->dl_pwr_ctl.p0 != 255)
+              free_set->dl_pwr_ctl.p0    <<= 2;  // P0 format 7.1
+            free_set->packet_ta          = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->packet_ta;
+            free_set->tsc                = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->tsc;
+            free_set->freq_param         = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->freq_param;
+            free_set->mac_mode           = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->mac_mode;
+            free_set->tbf_sti            = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->tbf_sti;
+            free_set->interf_meas_enable = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->interf_meas_enable;
+            free_set->pc_meas_chan       = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->pc_meas_chan;
+
+// TBF_changes
+
+            #if FF_TBF
+              // Two phase access condition is stored in FSET structure to be
+              // transfered in ASET for transfer mode manager use.
+              free_set->pseudo_tbf_two_phase_acc = pseudo_tbf_two_phase_acc;
+            #endif
+
+            // Download access_burst_type
+            l1pa_l1ps_com.transfer.psi_param.access_burst_type    = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->access_burst_type;
+            // Keep the same Pb factor
+            l1pa_l1ps_com.transfer.psi_param.Scell_pb             = l1a_l1s_com.Scell_info.pb;
+            // Enable PSI param updating in order to update access_burst_type in L1S
+            l1pa_l1ps_com.transfer.psi_param.psi_param_update_cmd = TRUE;
+
+            switch(assignment_command)
+            {
+              case DL_TBF:
+              {
+                free_set->dl_tbf_alloc = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->dl_ressource_alloc;
+
+                if((free_set->allocated_tbf == UL_TBF) ||
+                   (free_set->allocated_tbf == BOTH_TBF))
+                  free_set->allocated_tbf = BOTH_TBF;
+                else
+                  free_set->allocated_tbf = DL_TBF;
+
+                // Look for 1st allocated timeslot.
+                // MSB=TS0...LSB=TS7
+                timeslot_alloc = free_set->dl_tbf_alloc.timeslot_alloc;
+                timeslot       = 0;
+                while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
+                {
+                  timeslot++;
+                }
+
+                // Fill "synchro_timeslot" which will be the frame synchro slot.
+                free_set->dl_tbf_synchro_timeslot   = timeslot;
+                free_set->transfer_synchro_timeslot = timeslot;
+              }
+              break;
+
+              case UL_TBF:
+              {
+                *(free_set->ul_tbf_alloc) = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->ul_ressource_alloc;
+
+                if((free_set->allocated_tbf == DL_TBF) ||
+                   (free_set->allocated_tbf == BOTH_TBF))
+                  free_set->allocated_tbf = BOTH_TBF;
+                else
+                  free_set->allocated_tbf = UL_TBF;
+
+                // Look for 1st allocated timeslot.
+                // MSB=TS0...LSB=TS7
+
+                // Dynamic mode: the uplink PDCH are always monitored
+                // The 1st allocated timeslot is a RX on the lowest numbered
+                // timeslot allocated in uplink
+              #if L1_EDA
+                if((free_set->mac_mode == DYN_ALLOC) || (free_set->mac_mode == EXT_DYN_ALLOC))
+              #else
+                if(free_set->mac_mode == DYN_ALLOC)
+              #endif
+                {
+                  timeslot_alloc = free_set->ul_tbf_alloc->timeslot_alloc;
+
+                  timeslot = 0;
+                  while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
+                  {
+                    timeslot++;
+                  }
+                }
+                else
+
+                // Fixed mode: the 1st allocated timeslot is the downlink control
+                // timeslot allocated by the network, which is a timeslot allocated
+                // in uplink
+                if(free_set->mac_mode == FIX_ALLOC_NO_HALF)
+                {
+                  timeslot = free_set->ul_tbf_alloc->fixed_alloc.ctrl_timeslot;
+                }
+
+                // Fill "synchro_timeslot" which will be the frame synchro slot.
+                free_set->ul_tbf_synchro_timeslot   = timeslot;
+                free_set->transfer_synchro_timeslot = timeslot;
+              }
+              break;
+
+              case BOTH_TBF:
+              {
+                free_set->dl_tbf_alloc    = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->dl_ressource_alloc;
+                *(free_set->ul_tbf_alloc) = ((T_MPHP_ASSIGNMENT_REQ *)(msg->SigP))->ul_ressource_alloc;
+                free_set->allocated_tbf   = BOTH_TBF;
+
+                // Process the downlink TBF first allocated timeslot
+                timeslot_alloc = free_set->dl_tbf_alloc.timeslot_alloc;
+                timeslot       = 0;
+
+                while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
+                {
+                  timeslot++;
+                }
+
+                free_set->dl_tbf_synchro_timeslot   = timeslot;
+
+                // Process the uplink TBF first allocated timeslot
+
+                // Dynamic mode: the uplink PDCH are always monitored
+                // The 1st allocated timeslot is a RX on the lowest numbered
+                // timeslot allocated in uplink
+              #if L1_EDA
+                if((free_set->mac_mode == DYN_ALLOC) || (free_set->mac_mode == EXT_DYN_ALLOC))
+              #else
+                if(free_set->mac_mode == DYN_ALLOC)
+              #endif
+                {
+                  timeslot_alloc = free_set->ul_tbf_alloc->timeslot_alloc;
+
+                  timeslot = 0;
+                  while((timeslot<7) && !(timeslot_alloc & (0x80>>timeslot)))
+                  {
+                    timeslot++;
+                  }
+                }
+                else
+
+                // Fixed mode: the 1st allocated timeslot is the downlink control
+                // timeslot allocated by the network, which is a timeslot allocated
+                // in uplink
+                if(free_set->mac_mode == FIX_ALLOC_NO_HALF)
+                {
+                  timeslot = free_set->ul_tbf_alloc->fixed_alloc.ctrl_timeslot;
+                }
+
+                free_set->ul_tbf_synchro_timeslot   = timeslot;
+
+                // Fill "synchro_timeslot" which will be the frame synchro slot.
+                if (free_set->dl_tbf_synchro_timeslot > free_set->ul_tbf_synchro_timeslot)
+                {
+                  free_set->transfer_synchro_timeslot = free_set->ul_tbf_synchro_timeslot;
+                }
+                else
+                {
+                  free_set->transfer_synchro_timeslot = free_set->dl_tbf_synchro_timeslot;
+                }
+
+              }
+              break;
+            }
+
+            // Cancel any pending release on the assigned TBF
+            if (l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd == TRUE)
+            {
+              // If pending released TBF = assigned TBF or assigned TBF = BOTH
+              if ((assignment_command == l1pa_l1ps_com.transfer.tbf_release_param.released_tbf) ||
+                  (assignment_command == BOTH_TBF))
+              {
+		/*
+		 * FreeCalypso TCS211 reconstruction: in the LoCosto version
+		 * the call to l1pa_send_tbl_release_con() came first,
+		 * but in the TCS211 object it comes after the two
+		 * assignments.
+		 */
+
+                // Cancel the TBF release order
+                l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd = FALSE;
+                l1pa_l1ps_com.transfer.tbf_release_param.released_tbf    = NO_TBF;
+
+		// Send a "TBF Release confirmation" msg to L3  : CQ 46842
+		l1pa_send_tbf_release_con(MPHP_TBF_RELEASE_CON,l1pa_l1ps_com.transfer.tbf_release_param.released_tbf);
+              }
+              // If BOTH TBF release order pending and no BOTH TBF assigned
+              else if (l1pa_l1ps_com.transfer.tbf_release_param.released_tbf == BOTH_TBF)
+              {
+                // Keep the release of the TBF which is not assigned by this message
+                if (assignment_command == DL_TBF)
+                  l1pa_l1ps_com.transfer.tbf_release_param.released_tbf    = UL_TBF;
+                else
+                  l1pa_l1ps_com.transfer.tbf_release_param.released_tbf    = DL_TBF;
+              }
+            }
+
+            // Step in state machine.
+            *state = WAIT_MSG;
+
+            // Store signalcode.
+            free_set->SignalCode = MPHP_ASSIGNMENT_REQ;
+
+            // Clear transfer parameter semaphore to let L1S use the new parameters.
+            l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_TRANSFER_DONE:
+          // Switch to TRANSFER mode has been done. Send a Assignment confirmation
+          // msg to L3.
+          {
+            l1pa_send_confirmation(MPHP_ASSIGNMENT_CON,
+                                   ((T_L1P_TRANSFER_DONE *) msg->SigP)->assignment_id);
+
+            // End of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_TBF_RELEASE_REQ:
+          // TBF Release.
+          //-------------
+          {
+            UWORD8 i;
+
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            // Cumulate with a possible TBF release request received during the same block period
+            if (l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd == TRUE)
+            {
+              if (l1pa_l1ps_com.transfer.tbf_release_param.released_tbf != ((T_MPHP_TBF_RELEASE_REQ *)(msg->SigP))->tbf_type)
+              {
+                l1pa_l1ps_com.transfer.tbf_release_param.released_tbf = BOTH_TBF;
+              }
+            }
+            else
+            {
+              // Enables the TBF release processing in L1S.
+              l1pa_l1ps_com.transfer.tbf_release_param.tbf_release_cmd = TRUE;
+
+              // Download msg info into L1PA_L1PS_COM.
+              l1pa_l1ps_com.transfer.tbf_release_param.released_tbf = ((T_MPHP_TBF_RELEASE_REQ *)(msg->SigP))->tbf_type;
+            }
+
+            // Disable all pending TBFs those type is the same as the released TBF
+            for(i = 0; i < 2; i++)
+            {
+              // Pending assignment
+              if (l1pa_l1ps_com.transfer.fset[i]->SignalCode == MPHP_ASSIGNMENT_REQ)
+              {
+              #if !FF_TBF
+                switch(l1pa_l1ps_com.transfer.tbf_release_param.released_tbf)
+              #else
+                UWORD8 released_tbf;
+
+                // Special case if we got a request to release a two phase access TBF:
+                // It is registered within FSET structure as an uplink TBF. If current
+                // structure is pseudo TBF for two phase access, we process the request
+                // like an uplink release, otherwise we skip it.
+
+                released_tbf = l1pa_l1ps_com.transfer.tbf_release_param.released_tbf;
+
+                if (released_tbf == TWO_PHASE_ACCESS)
+                {
+                  if (l1pa_l1ps_com.transfer.fset[i]->pseudo_tbf_two_phase_acc)
+                    released_tbf = UL_TBF;
+                  else
+                    released_tbf = NO_TBF;
+                }
+
+                switch(released_tbf)
+              #endif // FF_TBF
+                {
+                  case UL_TBF:
+                  {
+                    if (l1pa_l1ps_com.transfer.fset[i]->allocated_tbf == UL_TBF)
+                    {
+                      l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = NO_TBF;
+                      l1pa_l1ps_com.transfer.fset[i]->SignalCode    = NULL;
+                    }
+                    if (l1pa_l1ps_com.transfer.fset[i]->allocated_tbf == BOTH_TBF)
+                    {
+                      l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = DL_TBF;
+                    }
+                  } break;
+
+                  case DL_TBF:
+                  {
+                    if (l1pa_l1ps_com.transfer.fset[i]->allocated_tbf == DL_TBF)
+                    {
+                      l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = NO_TBF;
+                      l1pa_l1ps_com.transfer.fset[i]->SignalCode    = NULL;
+                    }
+                    if (l1pa_l1ps_com.transfer.fset[i]->allocated_tbf == BOTH_TBF)
+                    {
+                      l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = UL_TBF;
+                    }
+                  } break;
+
+                  case BOTH_TBF:
+                  {
+                    l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = NO_TBF;
+                    l1pa_l1ps_com.transfer.fset[i]->SignalCode    = NULL;
+                  } break;
+
+                } // End of switch "tbf_release"
+              } // End if SignalCode = MPHP_ASSIGNMENT_REQ or MPHP_REPEAT_UL_FIXED_ALLOC
+            } // End "for"
+
+            // Clear transfer parameter semaphore to let L1S use the new parameters.
+            l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_TBF_RELEASED:
+          // TBF has been release by L1S. Send a "TBF Release confirmation"
+          // msg to L3
+          {
+            // Send confirmation message to L3.
+            l1pa_send_tbf_release_con(MPHP_TBF_RELEASE_CON,((T_L1P_TBF_RELEASED *)(msg->SigP))->tbf_type);
+
+            // End of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_STOP_SINGLE_BLOCK_REQ:
+          // Stop SINGLE block activity.
+          //----------------------------
+          {
+            UWORD8 i;
+
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            // Disable SINGLE task.
+            l1a_l1s_com.l1s_en_task[SINGLE] = TASK_DISABLED;
+
+            // No more TBF...
+            // Disable PDTCH task.
+            l1a_l1s_com.l1s_en_task[PDTCH] = TASK_DISABLED;
+
+            // Disable PTCCH task.
+            l1a_l1s_com.l1s_en_task[PTCCH] = TASK_DISABLED;
+
+            // Free the active set.
+            l1pa_l1ps_com.transfer.aset->allocated_tbf = NO_TBF;
+
+            // Send confirmation message to L3.
+            l1a_send_confirmation(MPHP_STOP_SINGLE_BLOCK_CON,GRRM1_QUEUE);
+
+            // disable all pending TBF those type is a single block
+            for(i = 0; i < 2; i++)
+            {
+              // check for pending single block req (MPHP_SINGLE_BLOCK_REQ)
+              if (l1pa_l1ps_com.transfer.fset[i]->SignalCode == MPHP_SINGLE_BLOCK_REQ)
+              {
+                // disable the fset corresponding to single blocks
+                l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = NO_TBF;
+                l1pa_l1ps_com.transfer.fset[i]->SignalCode    = NULL;
+              }
+            }
+
+            // This process must be reset.
+            *state = RESET;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_PDCH_RELEASE_REQ:
+          // PDCH Release.
+          //--------------
+          {
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            // Enables the PDCH release processing in L1S.
+            l1pa_l1ps_com.transfer.pdch_release_param.pdch_release_cmd  = TRUE;
+
+            // Download msg info into L1PA_L1PS_COM.
+            l1pa_l1ps_com.transfer.pdch_release_param.timeslot_available = ((T_MPHP_PDCH_RELEASE_REQ *)(msg->SigP))->timeslot_available;
+            l1pa_l1ps_com.transfer.pdch_release_param.assignment_id      = ((T_MPHP_PDCH_RELEASE_REQ *)(msg->SigP))->assignment_id;
+
+            // Clear transfer parameter semaphore to let L1S use the new parameters.
+            l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_PDCH_RELEASED:
+          // PDCHs have been release by L1S. Send a "PDCH Release confirmation"
+          // msg to L3
+          {
+            // Send confirmation message to L3.
+            l1pa_send_confirmation(MPHP_PDCH_RELEASE_CON,
+                                   ((T_L1P_PDCH_RELEASE_CON *) msg->SigP)->assignment_id);
+
+            // End of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_TIMING_ADVANCE_REQ:
+          // TA configuration.
+          //------------------
+          {
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            // Enables the timing advance update in L1S.
+            l1pa_l1ps_com.transfer.ptcch.ta_update_cmd = TRUE;
+
+            // Download message content.
+            l1pa_l1ps_com.transfer.ptcch.packet_ta     = ((T_MPHP_TIMING_ADVANCE_REQ *)(msg->SigP))->packet_ta;
+            l1pa_l1ps_com.transfer.ptcch.assignment_id = ((T_MPHP_TIMING_ADVANCE_REQ *)(msg->SigP))->assignment_id;
+
+            // Clear transfer parameter semaphore to let L1S use the new parameters.
+            l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_TA_CONFIG_DONE:
+          // TA configuration done.
+          //-----------------------
+          {
+            // Send confirmation message to L3.
+            l1pa_send_confirmation(MPHP_TIMING_ADVANCE_CON,
+                                   ((T_MPHP_TIMING_ADVANCE_CON *) msg->SigP)->assignment_id);
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_UPDATE_PSI_PARAM_REQ:
+          // Update PSI Parameters.
+          //----------------------
+          {
+            // Download msg content
+            l1pa_l1ps_com.transfer.psi_param.Scell_pb          = ((T_MPHP_UPDATE_PSI_PARAM_REQ *)(msg->SigP))->pb << 2; // Pb format 7.1
+            l1pa_l1ps_com.transfer.psi_param.access_burst_type = ((T_MPHP_UPDATE_PSI_PARAM_REQ *)(msg->SigP))->access_burst_type;
+
+            l1pa_l1ps_com.transfer.psi_param.psi_param_update_cmd = TRUE;
+
+            // send confirmation message
+            l1a_send_confirmation(MPHP_UPDATE_PSI_PARAM_CON,GRRM1_QUEUE);
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_PACCH_INFO:
+          // Two Phase Access is ongoing: Packet Resource Request
+          // msg has been sent to the network. CCCH reading must be
+          // stopped to let PDCH reading going.
+          //--------------------------------------------------------
+          {
+            // Forward result message to RR.
+            l1a_send_result(MPHP_DATA_IND, msg, GRRM1_QUEUE);
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_SINGLE_BLOCK_CON:
+          // Two Phase Access is ongoing: Packet Resource Request
+          // msg has been sent to the network. CCCH reading must be
+          // stopped to let PDCH reading going.
+          //--------------------------------------------------------
+          {
+            // Forward result message to RR.
+            l1a_send_result(MPHP_SINGLE_BLOCK_CON, msg, GRRM1_QUEUE);
+
+            // This process must be reset.
+            *state = RESET;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_REPEAT_UL_FIXED_ALLOC_REQ:
+          // Repeat uplink fixed mode allocation bitmap
+          //-------------------------------------------
+          {
+            // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+            l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+            // If an UL TBF is running...
+            if ((l1pa_l1ps_com.transfer.aset->allocated_tbf == UL_TBF) ||
+                (l1pa_l1ps_com.transfer.aset->allocated_tbf == BOTH_TBF))
+            {
+              // Download info. from message
+              l1pa_l1ps_com.transfer.repeat_alloc = *((T_MPHP_REPEAT_UL_FIXED_ALLOC_REQ *) msg->SigP);
+            }
+
+            // Send confirmation if this message was a repeat allocation cancelling
+            if (!((T_MPHP_REPEAT_UL_FIXED_ALLOC_REQ *) msg->SigP)->repeat_allocation)
+            {
+              l1a_send_confirmation(MPHP_REPEAT_UL_FIXED_ALLOC_CON,GRRM1_QUEUE);
+            }
+            else
+            {
+              UWORD8 i;
+
+              // Disable all pending UL TBF
+              for(i = 0; i < 2; i++)
+              {
+                // Pending assignment
+                if (l1pa_l1ps_com.transfer.fset[i]->SignalCode == MPHP_ASSIGNMENT_REQ)
+                {
+                  switch(l1pa_l1ps_com.transfer.fset[i]->allocated_tbf)
+                  {
+                    // Remove pending UL TBF
+                    case UL_TBF:
+                    {
+                        l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = NO_TBF;
+                        l1pa_l1ps_com.transfer.fset[i]->SignalCode    = NULL;
+                    }
+                    break;
+
+                    // Change pending BOTH_TBF in pending DL_TBF
+                    case BOTH_TBF:
+                    {
+                        l1pa_l1ps_com.transfer.fset[i]->allocated_tbf = DL_TBF;
+                    }
+                    break;
+
+                  } // End of switch "allocated_tbf"
+                } // End if SignalCode = MPHP_ASSIGNMENT_REQ
+              } // End "for"
+            }
+
+            // Clear transfer parameter semaphore to let L1S use the new parameters.
+            l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_REPEAT_ALLOC_DONE:
+          {
+            // Send confirmation message to L3.
+            l1a_send_confirmation(MPHP_REPEAT_UL_FIXED_ALLOC_CON,GRRM1_QUEUE);
+
+            // end of process.
+            end_process = 1;
+          }
+          break;
+
+          default:
+          // End of process.
+          //----------------
+          {
+            return;
+          }
+        } // end of switch(SignalCode)
+      } // end of case WAIT_CONFIG.
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+/*-------------------------------------------------------*/
+/* l1pa_serving_cell_pbcch_read_process()                */
+/*-------------------------------------------------------*/
+/* Description : This state machine handles Packet       */
+/* serving cell PBCCH reading.                           */
+/*                                                       */
+/* Starting messages:        MPHP_SCELL_PBCCH_REQ        */
+/* ------------------                                    */
+/*                                                       */
+/*  L1 continuously reads the serving cell PBCCH         */
+/*  as requested by the scheduling info (PSI1 repeat     */
+/*  period and relative position.                        */
+/*                                                       */
+/* Result messages (input):  L1C_PBCCHS_INFO             */
+/* ------------------------                              */
+/*  System information data block from L1S.              */
+/*                                                       */
+/* Reset messages (input):   MPHP_SCELL_PBCCH_STOP_REQ   */
+/* -----------------------                               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1pa_serving_cell_pbcch_read_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET              = 0,
+    WAIT_PBCCHS_CONFIG = 1,
+    WAIT_PBCCHS_RESULT = 2,
+    PBCCHS_CONFIG      = 3
+  };
+
+  UWORD8  *state      = &l1pa.state[SCPB];
+  UWORD32  SignalCode = msg->SignalCode;
+
+  #define  PbcchS  l1pa_l1ps_com.pbcchs
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_PBCCHS_CONFIG;
+
+        // Reset PBCCHS process.
+        l1a_l1s_com.l1s_en_task[PBCCHS] = TASK_DISABLED;  // Clear PBCCHS task enable flag.
+      }
+      break;
+
+      case WAIT_PBCCHS_CONFIG:
+      {
+        // Request to read Normal BCCH from serving cell.
+        if(SignalCode == MPHP_SCELL_PBCCH_REQ)
+        {
+          #define MAX_PSI1_PERIOD  16
+
+          UWORD8  i;
+
+          // Set semaphores for Serving Cell PBCCH reading task.
+          l1a_l1s_com.task_param[PBCCHS] = SEMAPHORE_SET;
+
+          // Download message content.
+          //--------------------------
+          PbcchS.nbr_psi                 = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->nbr_psi;
+          PbcchS.bs_pbcch_blks           = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->bs_pbcch_blks;
+          PbcchS.packet_chn_desc         = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->packet_chn_desc;
+          PbcchS.frequency_list          = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->frequency_list;
+          l1a_l1s_com.Scell_info.pb      = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->pb << 2;  // Pb format 7.1
+          PbcchS.psi1_repeat_period      = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->psi1_repeat_period;
+
+          // PBCCH Period is: MF52 * psi1_repeat_period
+          PbcchS.pbcch_period = 52L * PbcchS.psi1_repeat_period;
+
+          if(PbcchS.nbr_psi == 0)
+          // Full PBCCH reading: Emulated throw "relative positions".
+          //---------------------------------------------------------
+          {
+            // Emulate full PBCCH reading throw "relative positions" and a repeat period
+            // of 1 MF52.
+            //   bs_pbcch_blks= 0 -> Read B0
+            //   bs_pbcch_blks= 1 -> Read B0,B6
+            //   bs_pbcch_blks= 2 -> Read B0,B6,B3
+            //   bs_pbcch_blks= 3 -> Read B0,B6,B3,B9
+
+            PbcchS.nbr_psi      = PbcchS.bs_pbcch_blks+1;
+            PbcchS.read_all_psi = TRUE;
+
+            for(i=0;i<PbcchS.nbr_psi;i++)
+            {
+              ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->relative_position_array[i] = i;
+            }
+          }
+
+          else
+          // PBCCH reading: use provided "relative positions".
+          //--------------------------------------------------
+          {
+            PbcchS.read_all_psi = FALSE;
+          }
+
+          // Compute FN offset for each PSI.
+          //--------------------------------
+          for(i=0;i<l1pa_l1ps_com.pbcchs.nbr_psi;i++)
+          {
+            WORD8   nbr_mf52;          // Range 0..MAX_PSI1_PERIOD (can be negative along its estimation)
+            UWORD8  nbr_rest;          // Range 0..3
+            UWORD8  relative_position; // Range 0..4*MAX_PSI1_PERIOD
+            UWORD8  psi_period;        // psi1_repeat_period = 1 if nbr_psi = 0
+
+            relative_position = ((T_MPHP_SCELL_PBCCH_REQ *)(msg->SigP))->relative_position_array[i];
+
+            nbr_mf52 = relative_position / (PbcchS.bs_pbcch_blks+1);
+            nbr_rest = relative_position % (PbcchS.bs_pbcch_blks+1);
+
+            // Block B0 is a special case since CTRL phase occurs during
+            // the MF52 before.
+            if(nbr_rest == 0)
+            {
+              nbr_mf52 -= 1;
+
+              // Set psi_period to 1 when all PSI have to be read (nbr_psi = 0)
+              if(PbcchS.read_all_psi)
+                psi_period = 1;
+              else
+                psi_period = PbcchS.psi1_repeat_period;
+
+              if(nbr_mf52 < 0)
+                nbr_mf52 += psi_period;
+            }
+
+            PbcchS.offset_array[i]            = (nbr_mf52 * 52L) + PBCCH_POSITION[PbcchS.bs_pbcch_blks][nbr_rest];
+            PbcchS.relative_position_array[i] = relative_position;
+          }
+
+          // Step in state machine.
+          *state = PBCCHS_CONFIG;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process.
+          return;
+        }
+      }
+      break;
+
+      case PBCCHS_CONFIG:
+      {
+        WORD8   tn_pbcch;
+
+        // If PBCCH TS is inferior to L1 synchronization TS, the PBCCH reading
+        // control must be done one frame in advance
+        if (PbcchS.packet_chn_desc.timeslot_no < l1a_l1s_com.dl_tn)
+          PbcchS.control_offset = TRUE;
+        else
+          PbcchS.control_offset = FALSE;
+
+        // Set "change_synchro" flag to trigger L1S to change the synchro on fly
+        // within PBCCHS and to restore current synchro when PBCCHS task is completed.
+        if(((PbcchS.packet_chn_desc.timeslot_no - l1a_l1s_com.dl_tn + 8) % 8) >=4)
+        {
+          // L1S will make a intra PBCCHS task synchro to current TS + 4.
+          PbcchS.change_synchro = TRUE;
+          tn_pbcch              = PbcchS.packet_chn_desc.timeslot_no - l1a_l1s_com.dl_tn - 4;
+        }
+        else
+        {
+          // L1S will NOT make the intra PBCCHS task synchro.
+          PbcchS.change_synchro = FALSE;
+          tn_pbcch              = PbcchS.packet_chn_desc.timeslot_no - l1a_l1s_com.dl_tn;
+        }
+
+        if(tn_pbcch < 0)
+          PbcchS.tn_pbcch = tn_pbcch + 8;
+        else
+          PbcchS.tn_pbcch = tn_pbcch;
+
+        // Enable PBCCHS task.
+        l1a_l1s_com.l1s_en_task[PBCCHS] = TASK_ENABLED;
+
+
+        // Step in state machine.
+        *state = WAIT_PBCCHS_RESULT;
+
+        // End of process.
+        end_process = 1;
+      }
+      break;
+
+      case WAIT_PBCCHS_RESULT:
+      {
+        if(SignalCode == L1P_PBCCHS_INFO)
+        // Serving cell BCCH reading result.
+        //----------------------------------
+        {
+          // Forward result message to L3.
+          l1a_send_result(MPHP_DATA_IND, msg, GRRM1_QUEUE);
+
+          // End of process.
+          return;
+        }
+
+        else
+        if(SignalCode == MPHP_SCELL_PBCCH_REQ)
+        // Request to re-configure PBCCH reading.
+        //--------------------------------------
+        {
+          // Step in state machine.
+          *state = WAIT_PBCCHS_CONFIG;
+        }
+
+        else
+        if(SignalCode == MPHP_SCELL_PBCCH_STOP_REQ)
+        // Request to STOP any serving cell pbcch activity.
+        //------------------------------------------------
+        {
+          // Send confirmation message to L3.
+          l1a_send_confirmation(MPHP_SCELL_PBCCH_STOP_CON,GRRM1_QUEUE);
+
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        // End of packet transfer mode: test PDTCH to be sure that TBF downlink and uplink are released
+        if((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all))
+        {
+           // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        if ((SignalCode == L1P_TRANSFER_DONE) || (SignalCode == L1P_TBF_RELEASED) ||           //change of Time Slot
+            (SignalCode  == L1P_REPEAT_ALLOC_DONE) || (SignalCode == L1P_ALLOC_EXHAUST_DONE))
+        {
+          // Clear PBCCHS  task enable flag.
+          l1a_l1s_com.l1s_en_task[PBCCHS] = TASK_DISABLED;
+
+          // Set semaphores for Serving Cell PBCCH reading task.
+          l1a_l1s_com.task_param[PBCCHS] = SEMAPHORE_SET;
+
+          // l1a_l1s_com.dl_tn was changed. Check if a change synchro is needed
+          *state = PBCCHS_CONFIG; // Step in state machine.
+        }
+
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          return;
+        }
+      }
+      break;
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+
+/*-------------------------------------------------------*/
+/* l1pa_neighbor_cell_pbcch_read_process()                */
+/*-------------------------------------------------------*/
+/* Description : This state machine handles Packet       */
+/* neighbor cell PBCCH reading.                           */
+/*                                                       */
+/* Starting messages:        MPHP_NCELL_PBCCH_REQ        */
+/* ------------------                                    */
+/*                                                       */
+/*  L1 continuously reads the neighbor cell PBCCH        */
+/*  as requested by the scheduling info (PSI1 repeat     */
+/*  period and relative position.                        */
+/*                                                       */
+/* Result messages (input):  L1C_PBCCHN_INFO             */
+/* ------------------------                              */
+/*  System information data block from L1S.              */
+/*                                                       */
+/* Reset messages (input):   MPHP_NCELL_PBCCH_STOP_REQ   */
+/* -----------------------                               */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1pa_neighbor_cell_pbcch_read_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET              = 0,
+    WAIT_PBCCHN_CONFIG = 1,
+    WAIT_PBCCHN_RESULT = 2,
+    PBCCHN_CONFIG      = 3
+  };
+
+  UWORD8  *state      = &l1pa.state[NCPB];
+  UWORD32  SignalCode = msg->SignalCode;
+
+  #define  PbcchN  l1pa_l1ps_com.pbcchn
+
+  static  WORD32  fn_offset_mem;
+  static  WORD32  time_alignmt_mem;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_PBCCHN_CONFIG;
+
+        // Reset PBCCHS process.
+        l1a_l1s_com.l1s_en_task[PBCCHN_IDLE] = TASK_DISABLED;  // Clear PBCCHN task enable flag used in IDLE mode
+        l1a_l1s_com.l1s_en_task[PBCCHN_TRAN] = TASK_DISABLED;  // Clear PBCCHN task enable flag used in Transfer Packet mode
+      }
+      break;
+
+      case WAIT_PBCCHN_CONFIG:
+      {
+        // Request to read Normal PBCCH from neighbor cell.
+        if(SignalCode == MPHP_NCELL_PBCCH_REQ)
+        {
+          #define MAX_PSI1_PERIOD  16
+
+          // Set semaphores for Neighbor Cell PBCCH reading task.
+          l1a_l1s_com.task_param[PBCCHN_IDLE] = SEMAPHORE_SET;
+          l1a_l1s_com.task_param[PBCCHN_TRAN] = SEMAPHORE_SET;
+
+          // Download message content.
+          //--------------------------
+          PbcchN.bcch_carrier       = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->bcch_carrier;
+          PbcchN.bs_pbcch_blks      = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->bs_pbcch_blks;
+          PbcchN.packet_chn_desc    = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->packet_chn_desc;
+          PbcchN.frequency_list     = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->frequency_list;
+          PbcchN.psi1_repeat_period = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->psi1_repeat_period;
+          PbcchN.relative_position  = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->relative_position;
+          fn_offset_mem             = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->fn_offset;
+          time_alignmt_mem          = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->time_alignment;
+          PbcchN.pb                 = ((T_MPHP_NCELL_PBCCH_REQ *)(msg->SigP))->pb  << 2; // Pb format 7.1
+
+          // PBCCH Period is: MF52 * psi1_repeat_period
+          PbcchN.pbcch_period = 52L * PbcchN.psi1_repeat_period;
+
+          // Compute FN offset.
+          //------------------
+          {
+            WORD8   nbr_mf52;          // Range 0..MAX_PSI1_PERIOD (can be negative along its estimation)
+            UWORD8  nbr_rest;          // Range 0..3
+            UWORD8  relative_position; // Range 0..4*MAX_PSI1_PERIOD
+
+            relative_position = PbcchN.relative_position;
+
+            // number of PBCCH blocs
+            nbr_mf52 = relative_position / (PbcchN.bs_pbcch_blks+1);
+            nbr_rest = relative_position % (PbcchN.bs_pbcch_blks+1);
+
+            // Block B0 is a special case since CTRL phase occurs during the MF52 before.
+            if(nbr_rest == 0)
+            {
+              nbr_mf52 -= 1;
+
+              if(nbr_mf52 < 0)
+                nbr_mf52 += PbcchN.psi1_repeat_period;
+            }
+
+            PbcchN.offset = (nbr_mf52 * 52L) + PBCCH_POSITION[PbcchN.bs_pbcch_blks][nbr_rest];
+
+            // In case of idle mode
+            if (l1a_l1s_com.mode != PACKET_TRANSFER_MODE)
+            {
+              PbcchN.offset -= 2 ;  // because of the 2 frames for the measurement windows
+              // note: PbcchN.offset can not be negative (PbcchN.offset > 12).
+            }
+          }
+          // Step in state machine.
+          *state = PBCCHN_CONFIG;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process.
+          return;
+        }
+      }
+      break;
+
+      case PBCCHN_CONFIG:
+      {
+         //==================================================================================
+         // choose a relative base time in the neighbor cell in order to simplify the L1S scheduling.
+         //==================================================================================
+         PbcchN.fn_offset    = fn_offset_mem;
+         PbcchN.time_alignmt = time_alignmt_mem;
+
+         //the new relative base time is set in order to have the Neighbor burst in position 0.
+         //update with the burts position of the neighor cell     : PbcchN.packet_chn_desc.timeslot_no
+         //update according to the current serving cell synchro   : l1a_l1s_com.dl_tn
+         PbcchN.time_alignmt += (PbcchN.packet_chn_desc.timeslot_no - l1a_l1s_com.dl_tn ) * TN_WIDTH;
+
+         // PbcchN.time_alignmt is in [-7TS..+16TS[.
+         // more than 1 frame between the serving cell and the neighbor burst
+         if ( PbcchN.time_alignmt >= 8*TN_WIDTH)
+         {
+           PbcchN.time_alignmt -= 8*TN_WIDTH;
+           PbcchN.fn_offset --;
+         }
+         else
+         if ( PbcchN.time_alignmt < 0)
+         {
+           PbcchN.time_alignmt += 8*TN_WIDTH;
+           PbcchN.fn_offset ++;
+         }
+
+         // Set "change_synchro" flag to trigger L1S to change the synchro on fly
+         // within PBCCHN and to restore current synchro when PBCCHN task is completed.
+         if (PbcchN.time_alignmt >= 4 * TN_WIDTH)
+         {
+           PbcchN.time_alignmt -= 4 * TN_WIDTH;
+           PbcchN.change_synchro = TRUE;
+         }
+         else
+           PbcchN.change_synchro = FALSE;
+
+         // In case of packet transfer mode
+         if (l1a_l1s_com.mode == PACKET_TRANSFER_MODE)
+         {
+           // Enable Packet Transfer PBCCHN task
+           l1a_l1s_com.l1s_en_task[PBCCHN_TRAN] = TASK_ENABLED;
+
+         }
+         // in case of Idle mode
+         else
+         {
+           // Enable IDLE PBCCHN task
+           l1a_l1s_com.l1s_en_task[PBCCHN_IDLE] = TASK_ENABLED;
+         }
+
+         // Step in state machine.
+         *state = WAIT_PBCCHN_RESULT;
+
+         // End of process.
+         end_process = 1;
+      }
+      break;
+
+      case WAIT_PBCCHN_RESULT:
+      {
+        if(SignalCode == L1P_PBCCHN_INFO)
+        // Serving cell BCCH reading result.
+        //----------------------------------
+        {
+          // Forward result message to L3.
+         l1a_send_result(MPHP_NCELL_PBCCH_IND, msg, GRRM1_QUEUE);
+
+          // This process must be reset.
+          *state = RESET;
+        }
+
+        else
+        if(SignalCode == MPHP_NCELL_PBCCH_REQ)
+        // Request to re-configure PBCCH reading.
+        //--------------------------------------
+        {
+          // Step in state machine.
+          *state = WAIT_PBCCHN_CONFIG;
+        }
+
+        else
+        if(SignalCode == MPHP_NCELL_PBCCH_STOP_REQ)
+        // Request to STOP any serving cell pbcch activity.
+        //------------------------------------------------
+        {
+          // Send confirmation message to L3.
+          l1a_send_confirmation(MPHP_NCELL_PBCCH_STOP_CON,GRRM1_QUEUE);
+
+          // This process must be reset.
+          *state = RESET;
+        }
+        else
+        // End of packet transfer mode: test PDTCH to be sure that TBF downlink and uplink are released
+        if((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all))
+        {
+           // This process must be reset.
+          *state = RESET;
+        }
+        else
+        if ((SignalCode == L1P_TRANSFER_DONE) || (SignalCode == L1P_TBF_RELEASED) ||          //change of Time Slot
+            (SignalCode  == L1P_REPEAT_ALLOC_DONE) || (SignalCode == L1P_ALLOC_EXHAUST_DONE))
+        {
+          // We consider only the case: packet Transfer => packet Transfer,the serving TS may be changed
+          // For other cases such as Idle -> Transfer... decision not yet taken.
+
+          // update the PBCCHN parameters
+          // Clear PBCCHN_TRAN task disable flag.
+          l1a_l1s_com.l1s_en_task[PBCCHN_TRAN] = TASK_DISABLED;
+
+          // Set semaphores for Neighbor Cell PBCCH reading task.
+          l1a_l1s_com.task_param[PBCCHN_TRAN] = SEMAPHORE_SET;
+
+          // update the PBCCHN parameters
+          *state = PBCCHN_CONFIG;// Step in state machine.
+        }
+        else
+        // No action in this machine for other messages.
+        //----------------------------------------------
+        {
+          // End of process.
+          return;
+        }
+      }
+      break;
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+
+
+/*-------------------------------------------------------*/
+/* l1pa_tcr_meas_process()                               */
+/*-------------------------------------------------------*/
+/* Description : This state machine handles Neigbor cell */
+/* measurement process in Packet Transfer mode.          */
+/* Measurement are made on a specified frequency list.   */
+/* The process is started automatically by L1 (on receipt*/
+/* of a L1P_TRANSFER_DONE message from L1S) and doesn't  */
+/* need to receive any message from L3.                  */
+/* In order to update the frequency list, a              */
+/* MHPC_TCR_MEAS_REQ msg will be sent from L3 to L1      */
+/*                                                       */
+/* Starting messages:        L1P_TRANSFER_DONE           */
+/* ------------------                                    */
+/*  L1 starts then measures on carriers specified in the */
+/*  frequency list. Measures are performed on every      */
+/*  frames with the occurence of 1 measure per frame     */
+/*                                                       */
+/* Subsequent messages:      MPHP_TCR_MEAS_REQ           */
+/* --------------------                                  */
+/*  The update is not done asap but postponed until the  */
+/*  end of the reporting period. Frequency list is       */
+/*  updated with the new list.                           */
+/*                                                       */
+/* Result messages (input):  L1P_TRANSFER_MEAS_DONE      */
+/* ------------------------                              */
+/*  This is the periodic reporting message sent by L1S.  */
+/*  The reporting is done every "reporting period".      */
+/*  The beguining of the reporting period is arbitrary   */
+/*  and starts when the Neigh Meas task is enabled.      */
+/*                                                       */
+/* Result messages (output): MPHP_TCR_MEAS_IND           */
+/* -------------------------                             */
+/*  This is the periodic reporting message to L3.        */
+/*                                                       */
+/* Reset messages (input):   MPHP_TCR_MEAS_STOP_REQ      */
+/* -----------------------                               */
+/*  Frequency list neigbor cell measurement process in   */
+/*  Packet Transfer mode is stopped by this message.     */
+/*                                                       */
+/*-------------------------------------------------------*/
+void l1pa_tcr_meas_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET       = 0,
+    WAIT_INIT   = 1,
+    WAIT_RESULT = 3
+
+  };
+
+  UWORD8            *state      = &l1pa.state[TCR_MEAS];
+  UWORD32           SignalCode  = msg->SignalCode;
+  UWORD8            i;
+  UWORD8            list_size;
+  T_CRES_LIST_PARAM *free_list;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // step in state machine.
+        *state = WAIT_INIT;
+
+        // Reset TCR_MEAS process.
+        l1pa_l1ps_com.l1ps_en_meas &= P_TCRMS_MEAS_MASK; // Disable Neighbour Measurement task.
+      }
+      break;
+
+      case WAIT_INIT:
+      {
+        if(SignalCode == L1P_TRANSFER_DONE)
+        // We enter in Packet Transfer mode.
+        //---------------------------------
+        {
+#if 0	/* FreeCalypso: the following code is not present in TCS211 */
+        #if (CODE_VERSION != SIMULATION)
+          //no meas when entering in Transfer if no BA list initialized
+          //stay in this state and wait for a MPHP_TCR_MEAS_REQ from L3
+          if((l1pa_l1ps_com.cres_freq_list.alist->nb_carrier == 0) &&
+             (l1pa_l1ps_com.tcr_freq_list.new_list_present == FALSE) && (l1a_l1s_com.ba_list.nbr_carrier == 0))
+            return;
+        #endif
+#endif
+          // Set parameter synchro semaphore for P_TCRMS_MEAS task.
+          l1pa_l1ps_com.meas_param |= P_TCRMS_MEAS;
+
+          // Reset Neighbour Cell measurement parameters.
+          l1pa_l1ps_com.tcr_freq_list.tcr_next_to_ctrl        = 0;
+          l1pa_l1ps_com.tcr_freq_list.tcr_next_to_read        = 0;
+          l1pa_l1ps_com.tcr_freq_list.last_stored_tcr_to_read = 0;
+          l1pa_l1ps_com.tcr_freq_list.first_pass_flag  = TRUE;
+
+          // Initialize counter used to report measurements
+          l1pa_l1ps_com.tcr_freq_list.cres_meas_report = 0;
+
+
+          // If no Packet Idle phase has been done and no BA(GPRS) list has been
+          // downloaded, init BA(GPRS) list with BA list used in CS Idle mode.
+          if((l1pa_l1ps_com.cres_freq_list.alist->nb_carrier == 0) &&
+             (l1pa_l1ps_com.tcr_freq_list.new_list_present == FALSE))
+          {
+            // Get Ptr to the free Neighbour meas list.
+            // The number of carriers in the list and the list
+            // identification are initialized.
+            free_list = l1pa_get_free_cres_list_set();
+
+            // Download new list within T_CRES_LIST_PARAM structure.
+            free_list->nb_carrier = l1a_l1s_com.ba_list.nbr_carrier;
+
+            for(i = 0; i < free_list->nb_carrier; i++)
+            {
+              free_list->freq_list[i] = l1a_l1s_com.ba_list.A[i].radio_freq;
+            }
+
+            free_list->list_id = l1a_l1s_com.ba_list.ba_id;
+
+            // Set "flist" with Circuit Swithed BA frequency list parameters
+            l1pa_l1ps_com.cres_freq_list.alist = free_list;
+          }
+
+          // Reset flags.
+          l1pa_l1ps_com.tcr_freq_list.ms_ctrl      = 0;
+          l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d    = 0;
+          l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd   = 0;
+
+          // Reset measures made on beacon frequency.
+          l1pa_l1ps_com.tcr_freq_list.beacon_meas  = 0;
+
+          // Enable Packet Transfer Neighbour Measurement task.
+          l1pa.l1pa_en_meas[TCR_MEAS] |= P_TCRMS_MEAS;
+
+          // step in state machine.
+          *state = WAIT_RESULT;
+        }
+        else
+        if(SignalCode == MPHC_RXLEV_PERIODIC_REQ)
+        // We receive the BA list to be monitored in Idle mode
+        //----------------------------------------------------
+        {
+          // When enter in Transfer the Idle list must be used
+          // =>reset the packet Transfert list in order to use the Idle list
+          l1pa_l1ps_com.cres_freq_list.alist->nb_carrier = 0;
+          l1pa_l1ps_com.tcr_freq_list.new_list_present = FALSE;
+        }
+#if 0	/* FreeCalypso: the following code is not present in TCS211 */
+        else
+        if(SignalCode == MPHP_TCR_MEAS_REQ)
+        // Restart Packet Transfer measurement in TBF after
+        // MPHP_TCR_MEAS_STOP_REQ
+        // ### Check reason why was missing (s921_bis note)...
+        //----------------------------------------------------
+        {
+
+          // Set parameter synchro semaphore for P_TCRMS_MEAS task.
+          l1pa_l1ps_com.meas_param |= P_TCRMS_MEAS;
+
+          free_list = l1pa_get_free_cres_list_set();
+
+
+          // Download new list within T_CRES_LIST_PARAM structure.
+          free_list->nb_carrier = ((T_MPHP_TCR_MEAS_REQ *)(msg->SigP))->nb_carrier;
+
+          for(i = 0; i < free_list->nb_carrier; i++)
+          {
+            free_list->freq_list[i] = ((T_MPHP_TCR_MEAS_REQ *)(msg->SigP))->radio_freq_no[i];
+          }
+
+          free_list->list_id    = ((T_MPHP_TCR_MEAS_REQ *)(msg->SigP))->list_id;
+
+          // Set "flist" with Circuit Swithed BA frequency list parameters
+          l1pa_l1ps_com.cres_freq_list.alist = free_list;
+
+          // Reset Neighbour Cell measurement parameters.
+          l1pa_l1ps_com.tcr_freq_list.tcr_next_to_ctrl        = 0;
+          l1pa_l1ps_com.tcr_freq_list.tcr_next_to_read        = 0;
+          l1pa_l1ps_com.tcr_freq_list.last_stored_tcr_to_read = 0;
+          l1pa_l1ps_com.tcr_freq_list.first_pass_flag  = TRUE;
+
+          // Initialize counter used to report measurements
+          l1pa_l1ps_com.tcr_freq_list.cres_meas_report = 0;
+
+          // Reset flags.
+          l1pa_l1ps_com.tcr_freq_list.ms_ctrl      = 0;
+          l1pa_l1ps_com.tcr_freq_list.ms_ctrl_d    = 0;
+          l1pa_l1ps_com.tcr_freq_list.ms_ctrl_dd   = 0;
+
+          // Reset measures made on beacon frequency.
+          l1pa_l1ps_com.tcr_freq_list.beacon_meas  = 0;
+
+          // Enable Packet Transfer Neighbour Measurement task.
+          l1pa.l1pa_en_meas[TCR_MEAS] |= P_TCRMS_MEAS;
+
+          // step in state machine.
+          *state = WAIT_RESULT;
+        }
+#endif
+
+        // End of process.
+        end_process = 1;
+      }
+      break;
+
+      case WAIT_RESULT:
+      {
+        switch(SignalCode)
+        {
+          case L1P_TCR_MEAS_DONE:
+          // One reporting period has been completed. A set of measures is forward to L3.
+          //-----------------------------------------------------------------------------
+          {
+            // Forward result message to L3.
+            l1a_send_result(MPHP_TCR_MEAS_IND, msg, GRRM1_QUEUE);
+
+            // End of process.
+            end_process = 1;
+          }
+          break;
+
+          case MPHP_TCR_MEAS_REQ:
+          // Update of the parameters are postponed until end of the reporting period.
+          // Parameters are saved in a double buffer.
+          {
+            // Reset present flag to avoid to mix 2 updates in case of
+            // an update already pending within "l1pa_l1ps_com.cres_freq_list.flist".
+            l1pa_l1ps_com.tcr_freq_list.new_list_present = FALSE;
+
+            // Get Ptr to the free Neighbour meas list.
+            // The number of carriers in the list and the list
+            // identification are initialized.
+            free_list = l1pa_get_free_cres_list_set();
+
+
+            // Download new list within T_CRES_LIST_PARAM structure.
+            list_size             = ((T_MPHP_TCR_MEAS_REQ *)(msg->SigP))->nb_carrier;
+            free_list->nb_carrier = list_size;
+
+            for(i = 0; i < list_size; i++)
+            {
+              free_list->freq_list[i] = ((T_MPHP_TCR_MEAS_REQ *)(msg->SigP))->radio_freq_no[i];
+            }
+
+            free_list->list_id    = ((T_MPHP_TCR_MEAS_REQ *)(msg->SigP))->list_id;
+
+            // Set "flist" with new set of frequency list parameter
+            l1pa_l1ps_com.cres_freq_list.flist = free_list;
+
+            // Set present flag only when the list has been downloaded.
+            l1pa_l1ps_com.tcr_freq_list.new_list_present = TRUE;
+
+            // End of process.
+            end_process = 1;
+          }
+          break;
+
+          case L1P_TBF_RELEASED:
+          {
+            // Test if all TBF have been released
+            // Then stop Neighbour Measurement process
+            if(((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)
+            {
+              // This process must be reset.
+              *state = RESET;
+            }
+            else
+            {
+              return;
+            }
+          }
+          break;
+
+          case MPHP_TCR_MEAS_STOP_REQ:
+          // Note: A TBF stop do not imply a stop of the Neighbour Measurement process.
+          // L3 has to send a MPHP_TCR_MEAS_STOP message to stop the measurement process.
+          {
+            // send confirmation message
+            l1a_send_confirmation(MPHP_TCR_MEAS_STOP_CON,GRRM1_QUEUE);
+
+            // This process must be reset.
+            *state = RESET;
+          }
+          break;
+
+          default:
+          // No action in this machine for other messages.
+          // Note: No action is performed on receipt of a L1P_TRANSFER_DONE
+          // message. However a SYNCHRO task is programmed, which implies
+          // a reset of measures related to the Serving Cell (cf. L1S).
+          //--------------------------------------------------------------
+          {
+            return;
+          }
+        } // end of switch(SignalCode)
+      }
+      break;
+    } // end of "switch".
+  } // end of "while"
+} // end of procedure.
+
+/*-------------------------------------------------------*/
+/* l1pa_idle_interference_meas_process()                 */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/*                                                       */
+/* Starting messages:        MPHP_INT_MEAS_REQ           */
+/*                                                       */
+/* This message requests signal strength measurements    */
+/* on several channels of a specific carrier.            */
+/* Measurements must be done on one search frame and one */
+/* PTCCH frame.                                          */
+/*                                                       */
+/* Result messages (input):  L1PS_ITMEAS_IND             */
+/*                                                       */
+/* This message is reported to L1A when signal strength  */
+/* has been measured on one idle frame (PTCCH or search) */
+/*                                                       */
+/* Result messages (output): MPHP_INT_MEAS_IND           */
+/*                                                       */
+/* This message is reported to L3 when measurements have */
+/* been done on two contiguous idle frames               */
+/*                                                       */
+/* Reset message (input):    MPHP_INT_MEAS_STOP_REQ      */
+/*                                                       */
+/* Interference measurement processing is stopped by     */
+/* this message                                          */
+/*-------------------------------------------------------*/
+void l1pa_idle_interference_meas_process(xSignalHeaderRec *msg)
+{
+  enum states
+  {
+    RESET             = 0,
+    WAIT_INIT         = 1,
+    WAIT_1ST_RESULT   = 2,
+    WAIT_2ND_RESULT   = 3
+  };
+
+  static   T_L1A_INT_MEAS_PARAM int_meas_param;
+  UWORD8   *state      = &l1pa.state[PI_INT_MEAS];
+  UWORD32  SignalCode  = msg->SignalCode;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_INIT;
+
+        // Reset ITMEAS process.
+        l1a_l1s_com.l1s_en_task[ITMEAS]    = TASK_DISABLED;  // Clear ITMEAS task enable flag.
+      }
+      break;
+
+      case WAIT_INIT:
+      {
+        // Interference measurement request
+        //---------------------------------
+        if (SignalCode == MPHP_INT_MEAS_REQ)
+        {
+          UWORD8 bitmap,i;
+
+          // Set semaphore
+          l1a_l1s_com.task_param[ITMEAS] = SEMAPHORE_SET;
+
+          // Download message content
+          l1pa_l1ps_com.itmeas.packet_intm_freq_param  = ((T_MPHP_INT_MEAS_REQ *)(msg->SigP))->packet_intm_freq_param;
+          l1pa_l1ps_com.itmeas.multislot_class         = ((T_MPHP_INT_MEAS_REQ *)(msg->SigP))->multislot_class;
+          int_meas_param.id                           = ((T_MPHP_INT_MEAS_REQ *)(msg->SigP))->carrier_id;
+
+          // Processing of the 2 possible measurement bitmaps
+          //-------------------------------------------------
+
+          // 1- Without Rx on the frame before
+
+          l1pa_l1ps_com.itmeas.idle_tn_no_rx = ((T_MPHP_INT_MEAS_REQ *)(msg->SigP))->tn;
+
+          // Trb respect after measurements
+          // We consider that the timeslot on which the Layer 1 is synchronized is
+          // always allocated on the frame after the idle frame.
+          // For the Trb multi-slot class parameter respect, we must clear the bits at
+          // the right of the interference measurement bitmap
+          l1pa_l1ps_com.itmeas.idle_tn_no_rx &= (UWORD8)
+                           ~(   0xFF
+                             >> (  8 + l1a_l1s_com.dl_tn
+                                 - MS_CLASS[l1pa_l1ps_com.itmeas.multislot_class].trb));
+
+          // 2- With a Rx programmed on the frame before
+          // Note: This Rx is always on the dl_tn
+
+          l1pa_l1ps_com.itmeas.idle_tn_rx = l1pa_l1ps_com.itmeas.idle_tn_no_rx;
+
+          // Trb respect before measurements
+          // The timeslot on which the Layer 1 is synchronized is allocated on the frame
+          // before the idle frame.
+          // For the Trb multi-slot class parameter respect, we must clear the bits at
+          // the left of the interference measurement bitmap
+          bitmap = 0x80;
+
+          i = 8 - l1a_l1s_com.dl_tn - MS_CLASS[l1pa_l1ps_com.itmeas.multislot_class].trb;
+          if (i > 8)
+            bitmap >>= (-i);
+          else
+            bitmap <<= i;
+
+          for (i = 1; i<= MS_CLASS[l1pa_l1ps_com.itmeas.multislot_class].trb; i++)
+          {
+            l1pa_l1ps_com.itmeas.idle_tn_rx &= (UWORD8) ~bitmap;
+            bitmap <<= 1;
+          }
+
+          // Initialize parameters
+          l1pa_l1ps_com.itmeas.position        = ANY_IDLE_FRAME;  // First measurement on any idle frame
+
+          // Enable synchronous task
+          l1a_l1s_com.l1s_en_task[ITMEAS]      = TASK_ENABLED;
+
+          // Step in state machine
+          *state = WAIT_1ST_RESULT;
+
+          // End of process
+          end_process = 1;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process.
+          end_process = 1;
+        }
+      }
+      break;
+
+      case WAIT_1ST_RESULT:
+      {
+        // Reporting of 1st measurement session
+        //-------------------------------------
+        if (SignalCode == L1P_ITMEAS_IND)
+        {
+          UWORD8  i;
+
+          // Set semaphore
+          l1a_l1s_com.task_param[ITMEAS] = SEMAPHORE_SET;
+
+          // Save interference measurements
+          for(i=0; i<8; i++)
+            int_meas_param.rxlev[i]  = ((T_L1P_ITMEAS_IND *)(msg->SigP))->rxlev[i];
+
+          // Save bitmap
+          int_meas_param.meas_bitmap = ((T_L1P_ITMEAS_IND *)(msg->SigP))->meas_bitmap;
+
+           // Save reported fn
+          int_meas_param.fn          = ((T_L1P_ITMEAS_IND *)(msg->SigP))->fn;
+
+          // Position = complement of reported position
+          if (((T_L1P_ITMEAS_IND *)(msg->SigP))->position == PTCCH_FRAME)
+            l1pa_l1ps_com.itmeas.position = SEARCH_FRAME;
+          else
+            l1pa_l1ps_com.itmeas.position = PTCCH_FRAME;
+
+            // Enable ITMEAS
+            l1a_l1s_com.l1s_en_task[ITMEAS] = TASK_ENABLED;
+
+          // Step in state machine
+          *state = WAIT_2ND_RESULT;
+
+          // End of process
+          return;
+        }
+
+          else
+        if (SignalCode == MPHP_INT_MEAS_STOP_REQ)
+          {
+          // Send confirmation
+          l1a_send_confirmation(MPHP_INT_MEAS_STOP_CON,GRRM1_QUEUE);
+
+          // Reset process
+          *state = RESET;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process
+          return;
+        }
+      }
+      break;
+
+      case WAIT_2ND_RESULT:
+      {
+        // Reporting subsequent measurement session
+        //-----------------------------------------
+        if (SignalCode == L1P_ITMEAS_IND)
+        {
+          // At least one measurement session has already been reported
+          //-----------------------------------------------------------
+          UWORD32 reported_fn;
+
+          // Check fn
+          // The two measurement sessions must be done in two contiguous idle frames
+
+          // Modulo
+          if (((T_L1P_ITMEAS_IND *)(msg->SigP))->fn < int_meas_param.fn)
+          {
+            reported_fn = ((T_L1P_ITMEAS_IND *)(msg->SigP))->fn + MAX_FN;
+          }
+          else
+          {
+            reported_fn = ((T_L1P_ITMEAS_IND *)(msg->SigP))->fn;
+          }
+
+          // The two last measurement sessions are enough close
+          if ((reported_fn - int_meas_param.fn) == 13)
+          {
+            // Build and send result msg to L3.
+            l1pa_send_int_meas_report(MPHP_INT_MEAS_IND,
+                                      ((T_L1P_ITMEAS_IND *)(msg->SigP)),
+                                      &int_meas_param);
+
+            // Only one measurement session per request
+            *state = RESET;
+          }
+
+          // The two last measurement sessions aren't enough close
+          else
+          {
+            // 1st measurement result is no more valid, second result
+            // must replace it: this is achieved by WAIT_1ST_RESULT state!!!
+
+            // Step in state machine
+            *state = WAIT_1ST_RESULT;
+          }
+        }
+
+        else
+        if (SignalCode == MPHP_INT_MEAS_STOP_REQ)
+        {
+          // Send confirmation
+          l1a_send_confirmation(MPHP_INT_MEAS_STOP_CON,GRRM1_QUEUE);
+
+          // Reset process
+          *state = RESET;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process
+          return;
+        }
+      }
+      break;
+
+    } // End of "switch"
+  } // End of "while"
+} // End of "procedure"
+
+/*-------------------------------------------------------*/
+/* l1pa_transfer_interference_meas_process()             */
+/*-------------------------------------------------------*/
+/* Description :                                         */
+/*                                                       */
+/* Starting messages:        L1P_TRANFSER_DONE           */
+/*                                                       */
+/* Interference measurement processing starts each time  */
+/* a new starting time occurs if the interference        */
+/* measurements are enabled                              */
+/* Measurements must be done on one search frame and one */
+/* PTCCH frame.                                          */
+/*                                                       */
+/* Result messages (input):  L1PS_ITMEAS_IND             */
+/*                                                       */
+/* This message is reported to L1A when signal strength  */
+/* has been measured on one idle frame (PTCCH or search) */
+/*                                                       */
+/* Result messages (output): MPHP_TINT_MEAS_IND          */
+/*                                                       */
+/* This message is reported to L3 when measurements have */
+/* been done on two idle frames as close as possible     */
+/*                                                       */
+/* Reset message (input):    L1P_TBF_RELEASED            */
+/*                                                       */
+/* Interference measurement processing is stopped when   */
+/* all TBF are released                                  */
+/*-------------------------------------------------------*/
+void l1pa_transfer_interference_meas_process(xSignalHeaderRec *msg)
+{
+  /* Bitmaps used for the processing of full_allocation */
+  /*----------------------------------------------------*/
+  const UWORD8 FULL_ALLOCATION[9]=
+{
+    0x00,
+    0x80,
+    0xc0,
+    0xe0,
+    0xf0,
+    0xf8,
+    0xfc,
+    0xfe,
+    0xff
+  };
+
+  enum states
+  {
+    RESET             = 0,
+    WAIT_INIT         = 1,
+    CONFIG            = 2,
+    WAIT_1ST_RESULT   = 3,
+    WAIT_2ND_RESULT   = 4
+  };
+
+  static   T_L1A_INT_MEAS_PARAM int_meas_param;
+  UWORD8   *state      = &l1pa.state[PT_INT_MEAS];
+  UWORD32  SignalCode  = msg->SignalCode;
+
+  BOOL end_process = 0;
+  while(!end_process)
+  {
+    switch(*state)
+    {
+      case RESET:
+      {
+        // Step in state machine.
+        *state = WAIT_INIT;
+
+        // Reset ITMEAS process.
+        l1a_l1s_com.l1s_en_task[ITMEAS]    = TASK_DISABLED;  // Clear ITMEAS task enable flag.
+      }
+      break;
+
+      case WAIT_INIT:
+      {
+        // New channel assignment
+        //-----------------------
+        if ((SignalCode == L1P_TRANSFER_DONE) || (SignalCode == L1P_REPEAT_ALLOC_DONE) ||
+            (SignalCode == L1P_ALLOC_EXHAUST_DONE))
+        {
+          *state = CONFIG;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process.
+          return;
+        }
+      }
+      break;
+
+      case CONFIG:
+      {
+        // Rise transfert parameter semaphore to prevent L1S to use partial configuration.
+        l1pa_l1ps_com.transfer.semaphore = TRUE;
+
+        // If the interference measurements are disabled
+        if (l1pa_l1ps_com.transfer.aset->interf_meas_enable == FALSE)
+        {
+          *state = WAIT_INIT;
+        }
+        else
+        {
+          // Set semaphore
+          l1a_l1s_com.task_param[ITMEAS]   = SEMAPHORE_SET;
+
+          // Initialize parameters
+          l1pa_l1ps_com.itmeas.position    = ANY_IDLE_FRAME;  // First measurement on any idle frame
+
+          // Save assignment ID for the interference measurements reporting message
+          int_meas_param.id = l1pa_l1ps_com.transfer.aset->assignment_id;
+
+          // Processing of the measurement bitmap
+          l1pa_l1ps_com.itmeas.meas_bitmap = (UWORD8)
+               FULL_ALLOCATION[MS_CLASS[l1pa_l1ps_com.transfer.aset->multislot_class].rx] >>
+               l1a_l1s_com.dl_tn;
+
+          // Enable synchronous task
+          l1a_l1s_com.l1s_en_task[ITMEAS]  = TASK_ENABLED;
+
+          // Step in state machine
+          *state = WAIT_1ST_RESULT;
+        }
+
+        // Clear transfer parameter semaphore to let L1S use the new parameters.
+        l1pa_l1ps_com.transfer.semaphore = FALSE;
+
+        // End of process.
+        end_process = 1;
+      }
+      break;
+
+      case WAIT_1ST_RESULT:
+      {
+        // Reporting of 1st measurement session
+        //-------------------------------------
+        if (SignalCode == L1P_ITMEAS_IND)
+        {
+          UWORD8  i;
+
+          // Set semaphore
+          l1a_l1s_com.task_param[ITMEAS] = SEMAPHORE_SET;
+
+          // Save interference measurements
+          for(i=0; i<8; i++)
+            int_meas_param.rxlev[i]  = ((T_L1P_ITMEAS_IND *)(msg->SigP))->rxlev[i];
+
+          // Save bitmap
+          int_meas_param.meas_bitmap = ((T_L1P_ITMEAS_IND *)(msg->SigP))->meas_bitmap;
+
+            // Save reported fn
+          int_meas_param.fn          = ((T_L1P_ITMEAS_IND *)(msg->SigP))->fn;
+
+          // Position = complement of reported position
+          if (((T_L1P_ITMEAS_IND *)(msg->SigP))->position == PTCCH_FRAME)
+            l1pa_l1ps_com.itmeas.position = SEARCH_FRAME;
+          else
+            l1pa_l1ps_com.itmeas.position = PTCCH_FRAME;
+
+            // Enable ITMEAS
+            l1a_l1s_com.l1s_en_task[ITMEAS] = TASK_ENABLED;
+
+          // Step in state machine
+          *state = WAIT_2ND_RESULT;
+
+            // End of process
+            return;
+        }
+
+        else
+        if (SignalCode == L1P_TRANSFER_DONE)
+        // The starting time of a new TBF occurs
+        {
+          // Reset process
+          *state = RESET;
+        }
+
+        else
+        if (SignalCode == L1P_TBF_RELEASED)
+        // A TBF has been released
+        {
+          // No remaining TBF
+          if(((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)
+          {
+            // Reset process
+            *state = RESET;
+          }
+          else
+          {
+            // Enable a new measurement session
+            *state = CONFIG;
+          }
+        }
+
+        else
+        if (SignalCode == L1P_PDCH_RELEASED)
+        // PDCH have been released
+        {
+          // Enable a new measurement session
+          *state = CONFIG;
+        }
+
+        // No action in this machine for other messages.
+          else
+          {
+          // End of process
+          return;
+        }
+      }
+      break;
+
+      case WAIT_2ND_RESULT:
+      {
+        // Reporting subsequent measurement session
+        //-----------------------------------------
+        if (SignalCode == L1P_ITMEAS_IND)
+        {
+          // At least one measurement session has already been reported
+          //-----------------------------------------------------------
+          UWORD32 reported_fn;
+
+          // Check fn
+          // The two measurement sessions must be done in two contiguous idle frames
+
+          // Modulo
+          if (((T_L1P_ITMEAS_IND *)(msg->SigP))->fn < int_meas_param.fn)
+          {
+            reported_fn = ((T_L1P_ITMEAS_IND *)(msg->SigP))->fn + MAX_FN;
+          }
+          else
+          {
+            reported_fn = ((T_L1P_ITMEAS_IND *)(msg->SigP))->fn;
+          }
+
+            // The two last measurement sessions are enough close
+          if ((reported_fn - int_meas_param.fn) <= 104)
+          {
+            // Build and send result msg to L3.
+            l1pa_send_int_meas_report(MPHP_TINT_MEAS_IND,
+                                      ((T_L1P_ITMEAS_IND *)(msg->SigP)),
+                                      &int_meas_param);
+
+              // Enable a new measurement session
+              *state = CONFIG;
+          }
+
+          // The two last measurement sessions aren't enough close
+          else
+          {
+            // 1st measurement result is no more valid, second result
+            // must replace it: this is achieved by WAIT_1ST_RESULT state!!!
+
+            // Step in state machine
+            *state = WAIT_1ST_RESULT;
+          }
+        }
+
+        else
+
+        // New channel assignment
+        //-----------------------
+        if ((SignalCode == L1P_TRANSFER_DONE) || (SignalCode == L1P_REPEAT_ALLOC_DONE) ||
+            (SignalCode == L1P_ALLOC_EXHAUST_DONE))
+        {
+          // Reset process
+          *state = RESET;
+        }
+
+        else
+        if (SignalCode == L1P_TBF_RELEASED)
+        // A TBF has been released
+        {
+          // No remaining TBF
+          if(((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)
+          {
+            // Reset process
+            *state = RESET;
+          }
+          else
+          {
+            // Enable a new measurement session
+            *state = CONFIG;
+          }
+        }
+
+        else
+        if (SignalCode == L1P_PDCH_RELEASED)
+        // PDCH have been released
+        {
+          // Enable a new measurement session
+          *state = CONFIG;
+        }
+
+        // No action in this machine for other messages.
+        else
+        {
+          // End of process
+          return;
+        }
+      }
+      break;
+
+    } // End of "switch"
+  } // End of "while"
+} // End of "procedure"
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
+#endif
+//#pragma DUPLICATE_FOR_INTERNAL_RAM_END