view chipsetsw/layer1/cfile/l1_async.c @ 77:4bdffcf1467a

l1_dyn_dwl_async.c: perfect match to original TCS211 object
author Mychaela Falconia <falcon@ivan.Harhan.ORG>
date Tue, 29 Mar 2016 06:21:36 +0000
parents 196a39d210aa
children
line wrap: on
line source

/************* Revision Controle System Header *************
 *                  GSM Layer 1 software
 * L1_ASYNC.C
 *
 *        Filename l1_async.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 L1_ASYNC_C

//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END           // KEEP IN EXTERNAL MEM otherwise
#endif

//#pragma DUPLICATE_FOR_INTERNAL_RAM_START
#if (CODE_VERSION == SIMULATION)
  #include <string.h>
  #include "l1_types.h"
  #include "sys_types.h"
  #include "l1_const.h"
  #include "l1_signa.h"
  #include "cust_os.h"
  #if TESTMODE
    #include "l1tm_defty.h"
    #include "l1tm_signa.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_proto.h"
    #include "l1midi_defty.h"
  #endif
//ADDED FOR AAC
  #if (L1_AAC == 1)
    #include "l1aac_defty.h"
  #endif
  #if (L1_DYN_DSP_DWNLD == 1)
    #include "l1_dyn_dwl_signa.h"
  #endif

  #include "l1_defty.h"
  #include "l1_msgty.h"
  #include "l1_varex.h"
  #include "l1_proto.h"
  #include "l1_mftab.h"

  #if L1_GPRS
    #include "l1p_mfta.h"
    #include "l1p_msgt.h"
    #include "l1p_cons.h"
    #include "l1p_deft.h"
    #include "l1p_vare.h"
    #include "l1p_sign.h"
  #endif

  #include "l1_tabs.h"

  #if (VCXO_ALGO == 1)
    #include "l1_ctl.h"
  #endif

  #if L2_L3_SIMUL
    #include "hw_debug.h"
  #endif
#else
  #include <string.h>
  #include "l1_types.h"
  #include "sys_types.h"
  #include "l1_const.h"
  #include "l1_time.h"
  #include "l1_signa.h"
  #include "cust_os.h"
  #if TESTMODE
    #include "l1tm_defty.h"
    #include "l1tm_signa.h"
  #endif
  #if (AUDIO_TASK == 1)
    #include "l1audio_const.h"
    #include "l1audio_cust.h"
    #include "l1audio_defty.h"
    #include "l1audio_signa.h"
  #endif
  #if (L1_GTT == 1)
    #include "l1gtt_const.h"
    #include "l1gtt_defty.h"
  #endif
  #if (L1_MP3 == 1)
    #include "l1mp3_defty.h"
    #include "l1mp3_signa.h"
  #endif
  #if (L1_MIDI == 1)
    #include "l1midi_proto.h"
    #include "l1midi_defty.h"
  #endif
//ADDED FOR AAC
  #if (L1_AAC == 1)
    #include "l1aac_defty.h"
    #include "l1aac_signa.h"
  #endif
  #if (L1_DYN_DSP_DWNLD == 1)
    #include <stdio.h>
    #include "l1_dyn_dwl_signa.h"
  #endif

  #include "l1_defty.h"
  #include "l1_msgty.h"
  #include "l1_varex.h"
  #include "l1_proto.h"
  #include "l1_mftab.h"

  #if L1_GPRS
    #include "l1p_mfta.h"
    #include "l1p_msgt.h"
    #include "l1p_cons.h"
    #include "l1p_deft.h"
    #include "l1p_vare.h"
    #include "l1p_sign.h"
  #endif

  #include "l1_tabs.h"

  #if L1_RECOVERY
    #if ((CHIPSET == 12) || (CHIPSET == 15))
        #include "sys_inth.h"
    #else
        #include "iq.h"
        #include "inth.h"
        #include "mem.h"
    #endif

  #endif

  #if (VCXO_ALGO == 1)
    #include "l1_ctl.h"
  #endif

  #if L2_L3_SIMUL
    #include "hw_debug.h"
  #endif

  #if (OP_L1_STANDALONE == 1)
    #include "dynamic_clock.h"
  #endif
#endif

// External function prototypes
extern void l1ctl_gauging  (UWORD32 nb_32khz, UWORD32 nb_hf);
extern void l1_tpu_init_light(void);
extern void tm_receive(UWORD8 *inbuf, UWORD16 size);

#if L1_RECOVERY
  extern void l1_initialize_for_recovery(void);
  #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
    extern void l1_trace_recovery(void);
  #endif
#endif

#if (L1_GTT == 1)
  extern void l1a_mmi_gtt_process               (xSignalHeaderRec *msg);
#endif

#if(L1_DYN_DSP_DWNLD == 1)
  extern void l1a_dyn_dsp_dwnld_process(xSignalHeaderRec *msg);
#endif

#if (AUDIO_TASK == 1)
  /**************************************/
  /* External audio prototypes          */
  /**************************************/
  #if (OP_RIV_AUDIO == 1)
    #if (L1_AUDIO_DRIVER == 1)
      // driver task
      extern void l1a_audio_driver_process        (xSignalHeaderRec *msg);
    #endif
  #endif
  #if (KEYBEEP)
    // Keybeep task process
    extern void l1a_mmi_keybeep_process         (xSignalHeaderRec *msg);
  #endif
  #if (TONE)
    // Keybeep task process
    extern void l1a_mmi_tone_process            (xSignalHeaderRec *msg);
  #endif
  #if (L1_CPORT == 1)
    // Cport task process
    extern void l1a_mmi_cport_process           (xSignalHeaderRec *msg);
  #endif
  #if (MELODY_E1)
    // Melody 0 task process
    extern void l1a_mmi_melody0_process         (xSignalHeaderRec *msg);
    // Melody 1 task process
    extern void l1a_mmi_melody1_process         (xSignalHeaderRec *msg);
  #endif
  #if (VOICE_MEMO)
    // Voice memo playing process
    extern void l1a_mmi_vm_playing_process      (xSignalHeaderRec *msg);
    // Voice memo recording process
    extern void l1a_mmi_vm_recording_process    (xSignalHeaderRec *msg);
  #endif
  #if (L1_PCM_EXTRACTION)
    /* PCM download process */
    void l1a_mmi_pcm_download_process           (xSignalHeaderRec *msg);
    /* PCM upload process */
    void l1a_mmi_pcm_upload_process             (xSignalHeaderRec *msg);
  #endif
  #if (L1_VOICE_MEMO_AMR)
    // Voice memo amr playing process
    extern void l1a_mmi_vm_amr_playing_process  (xSignalHeaderRec *msg);
    // Voice memo amr recording process
    extern void l1a_mmi_vm_amr_recording_process(xSignalHeaderRec *msg);
  #endif
  #if (SPEECH_RECO)
    // Speech recognition enrollment process
    extern void l1a_mmi_sr_enroll_process       (xSignalHeaderRec *msg);
    // Speech recognition update process
    extern void l1a_mmi_sr_update_process       (xSignalHeaderRec *msg);
    // Speech recognition reco process
    extern void l1a_mmi_sr_reco_process         (xSignalHeaderRec *msg);
    // Speech recognition update-check process
    extern void l1a_mmi_sr_update_check_process (xSignalHeaderRec *msg);
  #endif
  #if (AEC)
    // AEC process
    extern void l1a_mmi_aec_process             (xSignalHeaderRec *msg);
  #endif
  #if (FIR)
    // FIR process
    extern void l1a_mmi_fir_process             (xSignalHeaderRec *msg);
  #endif
  #if (AUDIO_MODE)
    // AUDIO MODE process
    extern void l1a_mmi_audio_mode_process      (xSignalHeaderRec *msg);
  #endif
  #if (MELODY_E2)
    extern void l1a_mmi_melody0_e2_process      (xSignalHeaderRec *msg);
    extern void l1a_mmi_melody1_e2_process      (xSignalHeaderRec *msg);
  #endif
  #if (L1_MP3 == 1)
    extern void l1a_mmi_mp3_process             (xSignalHeaderRec *msg);
  #endif
//ADDED FOR AAC
  #if (L1_AAC == 1)
    extern void l1a_mmi_aac_process             (xSignalHeaderRec *msg);
  #endif
  #if (L1_EXTERNAL_AUDIO_VOICE_ONOFF == 1 || L1_EXT_MCU_AUDIO_VOICE_ONOFF == 1)
    extern void l1a_mmi_audio_onoff_process       (xSignalHeaderRec *msg);
  #endif
  #if (L1_EXT_AUDIO_MGT == 1)
    // External audio_mgt task process
    extern void l1a_mmi_ext_audio_mgt_process   (xSignalHeaderRec *msg);
  #endif
  #if (L1_ANR == 1 || L1_ANR == 2)
    extern void l1a_mmi_anr_process             (xSignalHeaderRec *msg);
  #endif
  #if (L1_IIR == 1 || L1_IIR == 2)
    extern void l1a_mmi_iir_process             (xSignalHeaderRec *msg);
  #endif
  #if (L1_WCM == 1)
    extern void l1a_mmi_wcm_process             (xSignalHeaderRec *msg);
  #endif
  #if (L1_AGC_UL == 1)
    extern void l1a_mmi_agc_ul_process          (xSignalHeaderRec *msg);
  #endif
  #if (L1_AGC_DL == 1)
    extern void l1a_mmi_agc_dl_process          (xSignalHeaderRec *msg);
  #endif
#if (L1_DRC == 1)
    extern void l1a_mmi_drc_process             (xSignalHeaderRec *msg);
  #endif
  #if (L1_LIMITER == 1)
    extern void l1a_mmi_limiter_process         (xSignalHeaderRec *msg);
  #endif
  #if (L1_ES == 1)
    extern void l1a_mmi_es_process              (xSignalHeaderRec *msg);
  #endif
  #if (L1_VOCODER_IF_CHANGE == 1)
    extern void l1a_mmi_vocoder_cfg_process    (xSignalHeaderRec *msg);

  #endif //VOCODER_IF_CHANGE == 1

  #if(L1_BT_AUDIO ==1)
    extern void l1a_mmi_bt_process(xSignalHeaderRec *msg); 
  #endif  

    extern void l1a_mmi_outen_cfg_process      (xSignalHeaderRec *msg);
#endif

#if(L1_CHECK_COMPATIBLE == 1)
    extern void l1a_checkmsg_compatibility    (xSignalHeaderRec *msg);
#endif

#if TESTMODE
  void l1a_tmode(xSignalHeaderRec *msg);
  #if (OP_L1_STANDALONE == 0)
    typedef void (*TM_CALLBACK_FUNC)(UWORD8*, UWORD16);
    extern int etm_register(char name[], int mid, int task_id,
                            UWORD16 addr_id, TM_CALLBACK_FUNC callback);
  #endif
#endif


#if L1_GPRS
  void  l1pa_task(xSignalHeaderRec *msg);
#endif

#if (TRACE_TYPE == 1) ||(TRACE_TYPE == 4) || (TRACE_TYPE == 7) || (TESTMODE)
  #include "l1_trace.h"

  extern T_RVT_USER_ID tm_trace_user_id;
  extern void l1_trace_configuration(T_RVT_BUFFER trace_msg, UINT16 trace_msg_size);
#endif

//#pragma DUPLICATE_FOR_INTERNAL_RAM_END

#if (TRACE_TYPE == 1) ||(TRACE_TYPE == 4) || (TRACE_TYPE == 7) || (TESTMODE)
  T_RVT_USER_ID tm_trace_user_id;
#endif


#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

/*-------------------------------------------------------*/
/* l1a_task()                                            */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* L1A (Layer 1 Asynchronous) task function. This        */
/* function manages the 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     */
/* "l1a_task()" function, a balance routine is called,   */
/* it enables L1S tasks consequently to the state machine*/
/* requests.                                             */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_task(UWORD32 argc, void *argv)
{
  xSignalHeaderRec *msg;

  #if (TRACE_TYPE == 7)
    rvt_register_id("L1", &trace_info.l1_trace_user_id, (RVT_CALLBACK_FUNC)NULL);
  #endif

  #if ((TESTMODE) && (CODE_VERSION != SIMULATION))
    // Testmode register for UART TX only in standalone L1
    #if (OP_L1_STANDALONE == 0)
      // Register the tm_receive func. as the TM3 packet receptor in the ETM database
      etm_register("TML1", 0x0, 0, 0, tm_receive); // 0x00 = use of TM3 Signalling PC<->MS
    #else
      rvt_register_id("TM", &tm_trace_user_id, tm_receive);
    #endif // End of OP_L1_STANDALONE
  #endif // End of TESTMODE && (CODE_VERSION != SIMULATION)

  #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
    // Enable auto-test HW in order to trace versions
    trace_info.init_trace    = 1;
    l1a_l1s_com.l1s_en_task[HWTEST] = TASK_ENABLED;
    l1a_l1s_com.l1a_activity_flag = TRUE;
  #endif

  while(1)
  /*************************************************************/
  /* LOOP on L1A message queue...                              */
  /*************************************************************/
  {
    UWORD8  process;

    /***********************************************/
    /*  Wait for a new message from RRM1 or L1S    */
    /***********************************************/
    msg = os_receive_sig(L1C1_QUEUE);
    DEBUGMSG(status,NU_RCVE_QUEUE_ERR)

    // Reset "l1_msg_forwarded" flag for this new incoming msg.
    // ========================================================
    l1a.l1_msg_forwarded = FALSE;

    #if (TRACE_TYPE==1) || (TRACE_TYPE==4) || (TRACE_TYPE==7)
        l1_trace_message(msg);
    #endif

#if(L1_CHECK_COMPATIBLE == 1)
       l1a_checkmsg_compatibility(msg);
#endif

    #if (DRP_FW_EXT == 1)
    if(!l1s.boot_result)
    {
    #endif /* DRP_FW_EXT*/
#if (GSM_IDLE_RAM <= 1)
    #if TESTMODE
      // if NOT in TestMode, go through normal mode processes
      if (l1_config.TestMode == 0)
      {
    #endif

        #if(L1_DYN_DSP_DWNLD==1)
          // Dynamic download L1A state machine
          l1a_dyn_dsp_dwnld_process(msg);
        #endif

        #if L1_GPRS
          // Pass the new msg to packet L1A.
          l1pa_task(msg);
        #endif

    #if TESTMODE
      }
    #endif
#endif

        #if (GSM_IDLE_RAM != 0)
            #if L1_GPRS
              if ((msg->SignalCode != L1C_NP_INFO) &&
                  (msg->SignalCode != L1C_EP_INFO) &&
                  (msg->SignalCode != L1C_RXLEV_PERIODIC_DONE) &&
                  (msg->SignalCode != L1P_PNP_INFO) &&
                  (msg->SignalCode != L1P_PEP_INFO) &&
                  (l1a_l1s_com.mode == I_MODE))
            #else
              if ((msg->SignalCode != L1C_NP_INFO) &&
                  (msg->SignalCode != L1C_EP_INFO) &&
                  (msg->SignalCode != L1C_RXLEV_PERIODIC_DONE) &&
                  (l1a_l1s_com.mode == I_MODE))
            #endif

          #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

    // Clear L1A "enable meas and tasks" variables.
    //---------------------------------------------
    for(process=0; process<NBR_L1A_PROCESSES; process++)
    {
      l1a.l1a_en_meas[process] = NO_TASK;
    }

    // Go through all processes...
    /******************************/

#if TESTMODE
  // if NOT in TestMode, go through normal mode processes
  if (l1_config.TestMode == 0)
  {
#endif

    // Hardware test:
    //---------------
    l1a_test_process(msg);

    #if (OP_L1_STANDALONE == 1)
       // Dynamic configuration : clock management for test
       l1a_test_config_process(msg);
    #endif

    #if (TRACE_TYPE==3)
      // Statistics or Test process:
      //---------------------------
      l1a_stats_process(msg);
    #endif

    // ADC conversion:
    //----------------
    l1a_mmi_adc_req(msg);

    // Frequency Band configuration: GSM900, E-GSM900, DCS1800, DUAL, DUALEXT, PCS 1900
    //----------------------------------------------------------------------------------
    l1a_freq_band_configuration(msg);

    // Network synchronization process:
    //---------------------------------

    // Synchronization with a Neighbour cell for Cell Selection.
    l1a_initial_network_sync_process(msg);

    // lost Network
    l1a_network_lost(msg);

    // Cell Selection/Idle processes:
    //-------------------------------

    // Full list receive level monitoring.
    l1a_full_list_meas_process(msg);

    // 6 strongest Neighbor cells synchro. monitoring.
    l1a_idle_6strongest_monitoring_process(msg);

    // 6 strongest Neighbor cells BCCH reading.
    l1a_neighbour_cell_bcch_reading_process(msg);

    // Serving Cell BCCH reading.
    l1a_idle_serving_cell_bcch_reading_process(msg);
#if (GSM_IDLE_RAM <= 1)
    // Serving Cell PAGING reading.
    l1a_idle_serving_cell_paging_process(msg);
#endif
    // Short Message Servive Cell Broadcast reading.
    l1a_idle_smscb_process(msg);
#if (GSM_IDLE_RAM <= 1)
    // BA list (periodic) power monitoring.
    l1a_idle_ba_list_meas_process(msg);
#endif

    // Cell Reselection processes:
    //----------------------------

    // Synchronization and requested BCCH reading.
    // --> camp on new serving cell.
    l1a_cres_process(msg);


    // Connection Establishment processes (also called "Link Access"):
    //----------------------------------------------------------------

    // Link Access process.
    l1a_access_process(msg);


    // Dedicated mode processes:
    //--------------------------

    // Dedicated mode process.
    l1a_dedicated_process(msg);

    // 6 strongest Neighbor cells synchro. monitoring and BCCH reading.
    l1a_dedic6_process(msg);

    // BA list (periodic) power monitoring.
    l1a_dedic_ba_list_meas_process(msg);

    #if (L1_GTT == 1)
      // GTT process handling.
      l1a_mmi_gtt_process(msg);
    #endif

    #if (AUDIO_TASK == 1)
      #if (OP_RIV_AUDIO == 1)
        #if (L1_AUDIO_DRIVER == 1)
          l1a_audio_driver_process(msg);
        #endif
      #endif
      #if (KEYBEEP)
        // Keybeep task process
        l1a_mmi_keybeep_process(msg);
      #endif
      #if (TONE)
        // Tone task process
        l1a_mmi_tone_process(msg);
      #endif
      #if (L1_CPORT == 1)
        // Cport task process
        l1a_mmi_cport_process(msg);
      #endif
      #if (MELODY_E1)
        // Melody 0 task process
        l1a_mmi_melody0_process(msg);
        // Melody 1 task process
        l1a_mmi_melody1_process(msg);
      #endif
      #if (VOICE_MEMO)
        // Voice memo playing process
        l1a_mmi_vm_playing_process(msg);
        // Voice memo recording process
        l1a_mmi_vm_recording_process(msg);
      #endif
      #if  (L1_PCM_EXTRACTION)
        /* PCM download process */
        l1a_mmi_pcm_download_process(msg);
        /* PCM upload process */
        l1a_mmi_pcm_upload_process(msg);
      #endif
      #if (L1_VOICE_MEMO_AMR)
        // Voice memo amr playing process
        l1a_mmi_vm_amr_playing_process(msg);
        // Voice memo amr recording process
        l1a_mmi_vm_amr_recording_process(msg);
      #endif
      #if (SPEECH_RECO)
        // Speech recognition enrollment process
        l1a_mmi_sr_enroll_process(msg);
        // Speech recognition update process
        l1a_mmi_sr_update_process(msg);
        // Speech recognition reco process
        l1a_mmi_sr_reco_process(msg);
        // Speech recognition update-check process
        l1a_mmi_sr_update_check_process(msg);
      #endif
      #if (AEC)
        // AEC process
        l1a_mmi_aec_process(msg);
      #endif
      #if (FIR)
        // FIR process
        l1a_mmi_fir_process(msg);
      #endif
      #if (AUDIO_MODE)
        // AUDIO MODE process
        l1a_mmi_audio_mode_process(msg);
      #endif
      #if (MELODY_E2)
        // MELODY E2 process
        l1a_mmi_melody0_e2_process(msg);
        l1a_mmi_melody1_e2_process(msg);
      #endif
      #if (L1_MP3==1)
        // MP3 process
        l1a_mmi_mp3_process(msg);
      #endif
      #if (L1_MIDI==1)
        // MIDI process
        l1a_mmi_midi_process(msg);
      #endif
//ADDED FOR AAC
      #if (L1_AAC==1)
        // AAC process
        l1a_mmi_aac_process(msg);
      #endif
      #if (L1_EXTERNAL_AUDIO_VOICE_ONOFF == 1 || L1_EXT_MCU_AUDIO_VOICE_ONOFF == 1)
        l1a_mmi_audio_onoff_process(msg);
      #endif
      #if (L1_EXT_AUDIO_MGT == 1)
        // External audio_mgt task process
        l1a_mmi_ext_audio_mgt_process(msg);
      #endif
      #if (L1_ANR == 1 || L1_ANR == 2)
        l1a_mmi_anr_process(msg);
      #endif
      #if (L1_IIR == 1 || L1_IIR == 2)
        l1a_mmi_iir_process(msg);
      #endif
      #if (L1_AGC_UL == 1)
        l1a_mmi_agc_ul_process(msg);
      #endif
      #if (L1_AGC_DL == 1)
        l1a_mmi_agc_dl_process(msg);
      #endif
      #if (L1_WCM == 1)
        l1a_mmi_wcm_process(msg);
      #endif
      #if (L1_DRC == 1)
        l1a_mmi_drc_process(msg);
      #endif
      #if (L1_LIMITER == 1)
        l1a_mmi_limiter_process(msg);
      #endif
      #if (L1_ES == 1)
        l1a_mmi_es_process(msg);
      #endif
      #if (L1_VOCODER_IF_CHANGE == 1)
        l1a_mmi_vocoder_cfg_process(msg);
      #endif // L1_VOCODER_IF_CHANGE == 1
      #if(L1_BT_AUDIO ==1)
        l1a_mmi_bt_process(msg); 
      #endif // L1_VOCODER_IF_CHANGE == 1
       /*
	* FreeCalypso Frankenstein: the following call to
	* l1a_mmi_outen_cfg_process() was totally unconditional
	* in the LoCosto source we got, but no such function
	* exists in TCS211.  To be investigated further when
	* we reach the audio stuff.
	*/
      #if 0
        l1a_mmi_outen_cfg_process(msg);
      #endif
    #endif //AUDIO TASK

    // Only processes supported by GSM IDLE in Internal RAM
    #if (GSM_IDLE_RAM > 1)
       #if L1_GPRS
          if ((msg->SignalCode >> 8) == P_GPRS)
            l1pa_task(msg);
       #endif

       // Serving Cell PAGING reading.
       l1a_idle_serving_cell_paging_process(msg);

       // BA list (periodic) power monitoring.
       l1a_idle_ba_list_meas_process(msg);
    #endif // GSM_IDLE_RAM > 1

#if TESTMODE
  } // end if not in TestMode

    //TestMode State Machine
    l1a_tmode(msg);
#endif // TESTMODE

    // Make a balance for L1A "tasks and meas tasks".
    //===============================================
    l1a_balance_l1a_tasks();

    l1a_l1s_com.l1a_activity_flag = TRUE;
#if (DRP_FW_EXT == 1)
  } /* end if DRP boot success boot_result == 0 */
#endif

    // Deallocate memory for the received message if msg not forwarded to L3.
    // ----------------------------------------------------------------------
    if(l1a.l1_msg_forwarded == FALSE)
    {
      os_free_sig(msg);
      DEBUGMSG(status,NU_DEALLOC_ERR)
    }
  } // end while().
} // end of procedure.

//-----------------------------------------------------------------------------------------------

/*-------------------------------------------------------*/
/* l1a_balance_l1a_tasks()                               */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* This function enables the L1S tasks consequently to   */
/* the L1A state machine requests.                       */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_balance_l1a_tasks()
{
  UWORD8   process;
  UWORD32  l1a_en_meas    = 0;
#if L1_GPRS
  UWORD32  l1pa_en_meas   = 0;
#endif
  UWORD32  l1a_dl_en_task = 0;

  for(process=0; process<NBR_L1A_PROCESSES; process++)
  {
    // Balance for measurement tasks.
    l1a_en_meas    |= l1a.l1a_en_meas[process];
  }

  #if L1_GPRS
    for(process=0; process<NBR_L1PA_PROCESSES; process++)
    {
      // Balance for measurement tasks.
      l1pa_en_meas    |= l1pa.l1pa_en_meas[process];
    }

    // Balance for Packet measurement tasks.
    l1pa_l1ps_com.l1ps_en_meas |= l1pa_en_meas;
    #if (TRACE_TYPE==5) && FLOWCHART
      trace_flowchart_l1tsk(l1pa_en_meas, l1pa.l1pa_en_meas);
    #endif

  #endif

  // Balance for measurement tasks.
  l1a_l1s_com.l1s_en_meas |= l1a_en_meas;
  #if (TRACE_TYPE==5) && FLOWCHART
    trace_flowchart_l1tsk(l1a_en_meas, l1a.l1a_en_meas);
  #endif

} // end of procedure.

//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
#endif
//-----------------------------------------------------------------------------------------------

#if (TRACE_TYPE==3)
/*-------------------------------------------------------*/
/* l1a_stats_process()                                   */
/*-------------------------------------------------------*/
/* Description : This function handles statistics        */
/* or test mode setting.                                 */
/*                                                       */
/* Starting messages:        L1_STATS_REQ.               */
/*                           L1_PLAY_REQ.                */
/*                                                       */
/* Result messages (input):  none                        */
/* Result messages (output): none                        */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_stats_process(xSignalHeaderRec *msg)
{
  UWORD32  SignalCode = msg->SignalCode;

  if(SignalCode == L1_STATS_REQ)
  {
    // store type of burst to spy...
    l1_stats.type = ((T_L1_STATS_REQ *)(msg->SigP))->type;
    // initialize variables and buffer for statistics...
    initialize_stats();
  }
}
#endif

/*-------------------------------------------------------*/
/* l1a_test_process()                                    */
/*-------------------------------------------------------*/
/* Description : This function tests hardware and DSP.   */
/*                                                       */
/* Starting messages:        TST_TEST_HW_REQ             */
/*                                                       */
/* Result messages (input):  TST_TEST_HW_CON             */
/* Result messages (output): none                        */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_test_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1,
    WAIT_RESULT = 2
  };

  UWORD8   *state      = &l1a.state[HW_TEST];
  UWORD32   SignalCode = msg->SignalCode;

  BOOL end_process = 0;


  #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
    if (trace_info.init_trace == 1)
    {
      *state = WAIT_RESULT;

      if(SignalCode == TST_TEST_HW_REQ)
      {
        trace_info.init_trace = 0;
      }
    }
  #endif

   while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset tasks used in the process.
        l1a_l1s_com.l1s_en_task[HWTEST] = TASK_DISABLED;  // Clear  task enable flag.

      }
      break;

      case WAIT_INIT:
      {
        // Use incoming message
        //---------------------
        if(SignalCode == TST_TEST_HW_REQ)
        {
          *state = WAIT_RESULT;

          // set tasks used in the process.
          l1a_l1s_com.l1s_en_task[HWTEST] = TASK_ENABLED;  // Set task enable flag.
        }
        // End of process.
        end_process = 1;

      }
      break;

      case WAIT_RESULT:
      {

        // Use incoming message
        //---------------------
        if(SignalCode == L1_TEST_HW_INFO)
        {
          #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
            if (trace_info.init_trace == 0)
          #endif
              // Forward result message to L3.
              l1a_send_result(TST_TEST_HW_CON, msg, RRM1_QUEUE);
          #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
            else
              trace_info.init_trace = 0;
          #endif

          *state = RESET;
        }
        else
        {
           end_process = 1;
        }
      }
      break;
    }
  }
}

#if (OP_L1_STANDALONE == 1)
/*-------------------------------------------------------*/
/* l1a_test_config_process()                             */
/*-------------------------------------------------------*/
/* Description : This function allows modify the original*/
/*               initialization of hardware parameters   */
/*               like for example clock configuration.   */
/*                                                       */
/* Starting messages:        TST_HW_CONFIG_REQ           */
/*                           TST_SW_CONFIG_REQ           */
/*                                                       */
/* Result messages (input):  none                        */
/* Result messages (output): none                        */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_test_config_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1
  };

  UWORD8   *state      = &l1a.state[HSW_CONF];
  UWORD32   SignalCode = msg->SignalCode;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // step in state machine.
        *state = WAIT_INIT;

        // Reset tasks used in the process.
        //l1a_l1s_com.l1s_en_task[HSWCONF] = TASK_DISABLED;  // Clear  task enable flag.
      }
      break;

      case WAIT_INIT:
      {
        if(SignalCode == TST_HW_CONFIG_REQ)
        /*
         * Depending on the arguments of the message,
         * actions are different (clock config, ABB config, ...).
         * The first argument is for clock configuration.
         */
        {
          #if  (CHIPSET == 4) || (CHIPSET == 7) || (CHIPSET == 8) || (CHIPSET == 10) || \
               (CHIPSET == 11) || (CHIPSET == 12) || (CHIPSET == 15)
          /* Only SAMSON/CALYPSO families are considered for dynamic clock configuration.*/
          UWORD8        d_clock_cfg;    // Num of selected clock configuration.

          /*
           * Read num of selected clock configuration as first arg of message
           */
          d_clock_cfg = ((T_TST_HW_CONFIG_REQ *)(msg->SigP))->num_of_clock_cfg;

          /*
           * Check if dynamic clock configuration requested.
           * If FFh, no dynamic clock configuration is requested.
           */
        #if (CODE_VERSION != SIMULATION)
          if (d_clock_cfg != C_CLOCK_NO_CFG)
          {
            /* If wrong index, keep the current clock configuration unchanged */
            f_dynamic_clock_cfg(d_clock_cfg);
          }
        #endif
          /* Only SAMSON/CALYPSO families are considered for dynamic clock configuration.*/
          #endif   // CHIPSET = 4 or 7 or 8 or 10 or 11 or 12

          // set tasks used in the process.
          //l1a_l1s_com.l1s_en_task[HSWCONF] = TASK_ENABLED;  // Set task enable flag.

          // step in state machine.
          *state = RESET;
        }

        if(SignalCode == TST_SW_CONFIG_REQ)
        /*
         * Depending on the arguments of the message,
         * actions are different.
         */
        {
        #if IDS
          l1_config.ids_enable = ((T_TST_SW_CONFIG_REQ *)(msg->SigP))->ids_enable;
        #endif

          l1_config.facch_test.enable = ((T_TST_SW_CONFIG_REQ *)(msg->SigP))->facch_test.enable;
          l1_config.facch_test.period = ((T_TST_SW_CONFIG_REQ *)(msg->SigP))->facch_test.period;

          if ((l1_config.facch_test.enable) &&
              (l1_config.facch_test.period == 0))
          {
            l1_config.facch_test.period = 1;
          }

          // set tasks used in the process.
          //l1a_l1s_com.l1s_en_task[HSW_CONF] = TASK_ENABLED;  // Set task enable flag.

          // step in state machine.
          *state = RESET;
        }
        // End of process.
        end_process = 1;
      }
      break;
    } // end of "switch".
  } // end of "while"
} // end of procedure.
#endif // OP_L1_STANDALONE


/*-------------------------------------------------------*/
/* l1a_mmi_adc_req ()                                    */
/*-------------------------------------------------------*/
/* Description : This function is in charge of requesting*/
/*               L1 to trigger an ADC conversion sequence*/
/*                                                       */
/* Starting messages:        MMI_ADC_REQ                 */
/*                                                       */
/* Result messages (input):  none                        */
/* Result messages (output): none                        */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_mmi_adc_req(xSignalHeaderRec *msg)
{
  UWORD32  SignalCode = msg->SignalCode;
  UWORD8   *state      = &l1a.state[I_ADC];

  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1
  };

  BOOL end_process = 0;

  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        l1a_l1s_com.adc_cpt  = 0;
        l1a_l1s_com.adc_mode = ADC_DISABLED;

        // Disable ADC tasks used in CS_MODE0
        l1a_l1s_com.l1s_en_task[ADC_CSMODE0] = TASK_DISABLED;  // Reset ADC task enable flag.

        // Step in state machine.
        *state = WAIT_INIT;
      }
      break;

      case WAIT_INIT:
      {
        // Use incoming message
        //---------------------
        if(SignalCode == MMI_ADC_REQ)
        {
          UWORD8 tx_flag;

          tx_flag                        = ((T_MMI_ADC_REQ *)(msg->SigP))-> tx_flag;
          l1a_l1s_com.adc_traffic_period = ((T_MMI_ADC_REQ *)(msg->SigP))-> traffic_period;
          l1a_l1s_com.adc_idle_period    = ((T_MMI_ADC_REQ *)(msg->SigP))-> idle_period;

          // -------------------------------
          // Activation for Idle and CS_MODE
          // -------------------------------

          l1a_l1s_com.adc_mode = ADC_DISABLED;
          l1a_l1s_com.adc_cpt  = 0;

          if (l1a_l1s_com.adc_idle_period == 0)
          { // performed only one time
            l1a_l1s_com.adc_mode |= ADC_NEXT_NORM_PAGING
                                 |  ADC_NEXT_MEAS_SESSION
                                 |  ADC_NEXT_CS_MODE0 ;
          }
          else
          { // performed on each periode
            l1a_l1s_com.adc_mode |= ADC_EACH_NORM_PAGING
                                 |  ADC_EACH_MEAS_SESSION
                                 |  ADC_EACH_CS_MODE0 ;
          }

          // ----------------------------------------------------------
          // Activation for Dedicated and Connection Establishment mode
          // ----------------------------------------------------------
          if (tx_flag == 1) // ADC is performed inside a TX burst
          {
            l1a_l1s_com.adc_mode |= ADC_EACH_RACH; // traffic_period is meaningless for RACH / PRACH

            if (l1a_l1s_com.adc_traffic_period == 0)
            {  // performed only one time
              l1a_l1s_com.adc_mode |= ADC_NEXT_TRAFFIC_UL;
            }
            else
            {  // performed on each periode
              l1a_l1s_com.adc_mode |= ADC_EACH_TRAFFIC_UL;
            }
          }
          else // ADC is performed outside a TX burst
          {
            if (l1a_l1s_com.adc_traffic_period == 0)
            { // performed only one time
              l1a_l1s_com.adc_mode |= ADC_NEXT_TRAFFIC_DL;
            }
            else
            { // performed on each periode
              l1a_l1s_com.adc_mode |= ADC_EACH_TRAFFIC_DL;
            }

            if (l1a_l1s_com.adc_idle_period == 0)
            { // performed only one time
              l1a_l1s_com.adc_mode |= ADC_NEXT_NORM_PAGING_REORG;
            }
            else
            { // performed on each periode
              l1a_l1s_com.adc_mode |= ADC_EACH_NORM_PAGING_REORG;
            }
          }
          l1a_l1s_com.l1s_en_task[ADC_CSMODE0] = TASK_ENABLED;  // enable ADC task for CS_MODE0
        }
        else
        if(SignalCode == MMI_STOP_ADC_REQ)
        {
          // send confirmation message
          l1a_send_confirmation(MMI_STOP_ADC_CON,RRM1_QUEUE);

          // Disable ADC tasks used in CS_MODE0
          // It is mandatory to disable the task here because in CS_MODE0 there is no new messages
          // to validate the RESET state in the state machine.
          l1a_l1s_com.l1s_en_task[ADC_CSMODE0] = TASK_DISABLED;  // Reset ADC task enable flag.

          // This process must be reset.
          *state = RESET;
        }

        // End of process.
        end_process = 1;
      }
      break;
    }
  }
}


/*-------------------------------------------------------*/
/* l1a_network_lost()                                    */
/*-------------------------------------------------------*/
/* Description : This function allows the MS to enter in */
/*               deep sleep while it is performig cell   */
/*               selection full power measurement        */
/*                                                       */
/* Starting messages:        MPHC_NETWORK_LOST_IND       */
/*                                                       */
/* Result messages (input):  none                        */
/* Result messages (output): none                        */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_network_lost(xSignalHeaderRec *msg)
{
  UWORD32  SignalCode = msg->SignalCode;

  if(SignalCode == MPHC_NETWORK_LOST_IND)
  {
    // set new mode in order to allow the deep sleep
    l1a_l1s_com.mode = CS_MODE0;

    // reset the gauging algorithm in order to re-compute
    // the 32khz/13Mhz when re-enter in IDLE mode.
    l1ctl_gauging (0,0);
  }
}

#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

/*-------------------------------------------------------*/
/* l1a_idle_ba_list_meas_process()                       */
/*-------------------------------------------------------*/
/* Description : This state machine handles neigbor cell */
/* measurement process in IDLE mode with BA list.        */
/*                                                       */
/* Starting messages:        MPHC_RXLEV_PERIODIC_REQ     */
/* ------------------                                    */
/*  L1 starts then the periodic BA list receive level    */
/*  monitoring.                                          */
/*                                                       */
/* Subsequent messages:      MPHC_RXLEV_PERIODIC_REQ     */
/* --------------------                                  */
/*  L1 changes the BA list and starts the periodic BA    */
/*  list receive level monitoring with this new list.    */
/*                                                       */
/* Result messages (input):  L1C_RXLEV_PERIODIC_DONE     */
/* ------------------------                              */
/*  This is the periodic reporting message from L1s.     */
/*                                                       */
/* Result messages (output): MPHC_RXLEV_PERIODIC_IND     */
/* -------------------------                             */
/*  This is the periodic reporting message to L3.        */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_RXLEV_PERIODIC_REQ*/
/* -----------------------                               */
/*  BA list neigbor cell measurement process in IDLE     */
/*  is stopped by this message.                          */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_idle_ba_list_meas_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1,
    WAIT_RESULT = 3
  };

  UWORD8   *state      = &l1a.state[I_NMEAS];
  UWORD32   SignalCode = msg->SignalCode;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // step in state machine.
        *state = WAIT_INIT;

        // Reset I_NMEAS process.
        l1a_l1s_com.l1s_en_meas &= I_BAMS_MEAS_MASK; // Reset I_BAMS Measurement enable flag.
      }
      break;

      case WAIT_INIT:
      {
        if(SignalCode == MPHC_RXLEV_PERIODIC_REQ)
        // We receive the BA list to be monitored.
        //----------------------------------------
        {
          UWORD8        ba_id;
          UWORD8        nbchans;
          TC_CHAN_LIST  *listptr;
          UWORD8        next_radio_freq_measured;
          UWORD8        i;

          nbchans =     ((T_MPHC_RXLEV_PERIODIC_REQ *)(msg->SigP))->num_of_chans;
          listptr =   &(((T_MPHC_RXLEV_PERIODIC_REQ *)(msg->SigP))->chan_list);
          ba_id   =     ((T_MPHC_RXLEV_PERIODIC_REQ *)(msg->SigP))->ba_id;
          next_radio_freq_measured
                  = ((T_MPHC_RXLEV_PERIODIC_REQ *)(msg->SigP))->next_radio_freq_measured;
          // Set parameter synchro semaphore for I_BAMS task.
          l1a_l1s_com.meas_param |= I_BAMS_MEAS;

          // Reset the BA list structure.
          l1a_reset_ba_list();

          // Store ARFCN list in the BA structure.
          for(i=0;i<nbchans;i++)
            l1a_l1s_com.ba_list.A[i].radio_freq = listptr->A[i];

          // Set number of carrier in the BA list.
          l1a_l1s_com.ba_list.nbr_carrier = nbchans;

          // Set BA identifier.
          l1a_l1s_com.ba_list.ba_id = ba_id;

          // Carrier for next power measurement control.
          l1a_l1s_com.ba_list.next_to_ctrl = next_radio_freq_measured;
          // Carrier for next power measurement result.
          l1a_l1s_com.ba_list.next_to_read = next_radio_freq_measured;
          // Set first BA index measured in current session.
          l1a_l1s_com.ba_list.first_index =  next_radio_freq_measured;

          // Enable BA list measurement task.
          l1a.l1a_en_meas[I_NMEAS] |= I_BAMS_MEAS;

          // step in state machine.
          *state = WAIT_RESULT;
        }

        // End of process.
        end_process = 1;
      }
      break;

      case WAIT_RESULT:
      {
        if(SignalCode == L1C_RXLEV_PERIODIC_DONE)
        // One bunch of measurement has been completed.
        //---------------------------------------------
        {
          // Forward result message to L3.
          l1a_send_result(MPHC_RXLEV_PERIODIC_IND, msg, RRM1_QUEUE);

          // End of process.
          return;
        }

        else
        #if (L1_GPRS)
          if((SignalCode == MPHC_STOP_RXLEV_PERIODIC_REQ) ||
              (SignalCode == L1P_TRANSFER_DONE)           ||
              (SignalCode == L1C_DEDIC_DONE))
        #else
          if((SignalCode == MPHC_STOP_RXLEV_PERIODIC_REQ) ||
              (SignalCode == L1C_DEDIC_DONE))
        #endif
        // Request to STOP this activity.
        //-------------------------------
        {
          // send confirmation message
          l1a_send_confirmation(MPHC_STOP_RXLEV_PERIODIC_CON,RRM1_QUEUE);
          // This process must be reset.
          *state = RESET;
        }

        else
        if (SignalCode == MPHC_RXLEV_PERIODIC_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.

//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END         // KEEP IN EXTERNAL MEM otherwise
#endif

/*-------------------------------------------------------*/
/* l1a_full_list_meas_process()                          */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* This function is a state machine which handles the    */
/* Cell Selection Full List Power Measurement L1/L3      */
/* interface and it handles the neigbour cell            */
/* measurement process in IDLE mode with FULL list.      */
/* When a message MPHC_RXLEV_REQ is received             */
/* the L1S task FSMS_MEAS is enabled. When this task     */
/* is completed a reporting message L1C_VALID_MEAS_INFO */
/* is received and forwarded to L3.                      */
/*                                                       */
/* Starting messages:        MPHC_RXLEV_REQ.             */
/*                                                       */
/* Result messages (input):  L1C_VALID_MEAS_INFO        */
/*                                                       */
/* Result messages (output): MPHC_RXLEV_IND              */
/*                                                       */
/* Reset messages (input):   none                        */
/*                                                       */
/* Stop message (input):     MPHC_STOP_RXLEV_REQ         */
/*                                                       */
/* Stop message (output):    MPHC_STOP_RXLEV_CON         */
/*                                                       */
/* Rem:                                                  */
/* ----                                                  */
/* L3 is in charge of the number of pass to follow the   */
/* GSM recommendation.                                   */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_full_list_meas_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1,
    WAIT_RESULT = 2
  };

  UWORD8   *state      = &l1a.state[FULL_MEAS];
  UWORD32   SignalCode = msg->SignalCode;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset FULL_MEAS process.
        l1a_l1s_com.l1s_en_meas &= FSMS_MEAS_MASK; // Clear Cell Selection Measurement enable flag.
      }
      break;

      case WAIT_INIT:
      {
        if(SignalCode == MPHC_RXLEV_REQ)
        // Request to enter the Cell Selection measurements.
        //--------------------------------------------------
        {
          UWORD16 i;

          #if L1_RECOVERY
            // check whether we need to recover L1
            if (l1a_l1s_com.recovery_flag == TRUE)
            {
              // recovery only allowed during cell selection to avoid side effects
              // Transition rules: MPHC_RXLEV_REQ may also be sent in idle mode or packet idle mode
              // check whether idle mode task NP inactive
              #if L1_GPRS
              if ((l1a_l1s_com.l1s_en_task[NP]  == TASK_DISABLED) &&
                  (l1a_l1s_com.l1s_en_task[PNP] == TASK_DISABLED))
              #else
              if (l1a_l1s_com.l1s_en_task[NP] == TASK_DISABLED)
              #endif
              {
                #if (CHIPSET == 12) || (CHIPSET == 15)
                  F_INTH_DISABLE_ONE_IT(C_INTH_FRAME_IT); // disable IT TDMA
                #else
                  INTH_DISABLEONEIT(IQ_FRAME); // disable IT TDMA
                #endif

                #if (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
                {
                  l1_trace_recovery();
                }
                #endif

                l1_initialize_for_recovery();

                // Set SYNCHRO task enable flag in order to call the function l1d_reset_hw
                l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;

                #if (CHIPSET == 12) || (CHIPSET == 15)
                  F_INTH_ENABLE_ONE_IT(C_INTH_FRAME_IT); // enable IT TDMA
                #else
                  INTH_ENABLEONEIT(IQ_FRAME); // enable IT TDMA
                #endif
              }
            }
          #endif

          // download info from message
          l1a_l1s_com.full_list_ptr=(T_MPHC_RXLEV_REQ *)(msg->SigP);
          if (l1a_l1s_com.full_list_ptr->power_array_size==0) return; //empty list -> return

          // Set "parameter synchro semaphores"
          l1a_l1s_com.meas_param |= FSMS_MEAS;

          // Reset the full list structure.
          l1a_reset_full_list();

          // Reset the Input Level (IL) memory table.
          if ((l1a_l1s_com.mode == CS_MODE) || (l1a_l1s_com.mode == CS_MODE0))

          {
#if (L1_FF_MULTIBAND == 0)
            for(i=0; i<=l1_config.std.nbmax_carrier; i++)
#else
            for(i=0; i<= NBMAX_CARRIER; i++)
#endif
            {
              l1a_l1s_com.last_input_level[i].input_level = l1_config.params.il_min;
              l1a_l1s_com.last_input_level[i].lna_off     = 0;
            }
          }

          // Enable Cell Selection Full list measurement task.
          l1a.l1a_en_meas[FULL_MEAS] |= FSMS_MEAS;

          // Step in state machine.
          *state = WAIT_RESULT;
        }

        // End of process.
        end_process = 1;
      }
      break;

      case WAIT_RESULT:
      {
        if(SignalCode == L1C_VALID_MEAS_INFO)
        // One valid measurement pass has been completed over the full list of carriers.
        //------------------------------------------------------------------------------
        {
          //--------------------------------------------------------
          // WE COULD PUT HERE THE CODE TO TRANSLATE IL -> RXLEV !!!
          //--------------------------------------------------------

          // Forward result message to L3.
          l1a_send_result(MPHC_RXLEV_IND, msg, RRM1_QUEUE);

          // Reset the machine.
          *state = RESET;
        }

        else if (SignalCode == MPHC_STOP_RXLEV_REQ)
        {
          // Forward result message to L3.
          l1a_send_confirmation(MPHC_STOP_RXLEV_CON,RRM1_QUEUE);
          // Reset the machine.
          *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.

/*-------------------------------------------------------*/
/* l1a_cres_process()                                    */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* This function is a state machine which handles Cell   */
/* Reselection.                                          */
/*                                                       */
/* Starting messages:        MPHC_NEW_SCELL_REQ          */
/* ------------------                                    */
/*  L1 camps on the given ARFCN.                         */
/*                                                       */
/* Result messages (output): MPHC_NEW_SCELL_CON          */
/* -------------------------                             */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_cres_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET              = 0,
    WAIT_INIT          = 1
  };

  UWORD8  *state      = &l1a.state[CR_B];
  UWORD32  SignalCode = msg->SignalCode;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;
      }
      break;

      case WAIT_INIT:
      {
        if(SignalCode == MPHC_NEW_SCELL_REQ)
        // Request to enter the Cell Reselection BCCH reading.
        //----------------------------------------------------
        // L1 must keep reading the system informations flagged
        // in the bitmap.
        {
          // Reset the Neighbor Cell information structure.
          l1a_reset_cell_info(&(l1a_l1s_com.Scell_info));

          // Reset serving cell E-OTD store on Cell Change
          #if ((L1_EOTD == 1) && (L1_EOTD_QBIT_ACC == 1))
            l1a_l1s_com.nsync.serv_fn_offset = 0;
            l1a_l1s_com.nsync.serv_time_alignmt = 0;
          #endif

          // Download ARFCN, timing information and bitmap from the command message.
          l1a_l1s_com.Scell_info.radio_freq   = ((T_MPHC_NEW_SCELL_REQ *)(msg->SigP))->radio_freq;
          l1a_l1s_com.Scell_info.bsic         = ((T_MPHC_NEW_SCELL_REQ *)(msg->SigP))->bsic;
          l1a_l1s_com.Scell_info.time_alignmt = ((T_MPHC_NEW_SCELL_REQ *)(msg->SigP))->time_alignmt;
          l1a_l1s_com.Scell_info.fn_offset    = ((T_MPHC_NEW_SCELL_REQ *)(msg->SigP))->fn_offset;

#if (L1_FF_MULTIBAND == 1)
          {
            UWORD8 physical_band_id; 
            physical_band_id = 
                l1_multiband_radio_freq_convert_into_physical_band_id(l1a_l1s_com.Scell_info.radio_freq );
            L1_MULTIBAND_TRACE_PARAMS(MULTIBAND_PHYSICAL_BAND_TRACE_ID,multiband_rf[physical_band_id].gsm_band_identifier);
          }
#endif /*#if (L1_FF_MULTIBAND == 1)*/
          

          // Layer 1 internal mode is set to CS MODE.
          l1a_l1s_com.mode = CS_MODE;

          // Set flag for toa init.
          #if (TOA_ALGO != 0)
            l1a_l1s_com.toa_reset = TRUE;
          #endif

          // 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.
          // 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 += 0 - l1a_l1s_com.dl_tn;
            l1a_l1s_com.dl_tn         = 0; // Camping on timeslot 0.

            #if L1_GPRS
              // Select GSM DSP Scheduler.
              l1a_l1s_com.dsp_scheduler_mode = GSM_SCHEDULER;
            #endif

            // Timing must be shifted to a new timeslot, enables SYNCHRO task..
            l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;   // Set SYNCHRO task enable flag.
          }
          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 = RESET;

          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_NEW_SCELL_CON,RRM1_QUEUE);

          // 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.


/*-------------------------------------------------------*/
/* l1a_neighbour_cell_bcch_reading_process()        */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* This function is a state machine which handles the    */
/* BCCH reading from up to 6 neighbour cells             */
/*                                                       */
/* Starting messages:         MPHC_NCELL_BCCH_REQ        */
/* ------------------                                    */
/*                                                       */
/* Result messages (input):   L1C_BCCHN_INFO             */
/* ------------------------                              */
/*                                                       */
/* Result messages (output):  MPHC_NCELL_BCCH_IND        */
/* -------------------------                             */
/*                                                       */
/* Reset messages (input):    MPHC_STOP_NCELL_BCCH_REQ   */
/* -----------------------   (MPHC_STOP_NCELL_BCCH_CON)  */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_neighbour_cell_bcch_reading_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET              = 0,
    WAIT_INIT          = 1,
    BCCHN_CONFIG       = 2,
    WAIT_BCCHN_RESULT  = 3
  };

  UWORD8  *state      = &l1a.state[I_BCCHN];
  UWORD32  SignalCode = msg->SignalCode;
  UWORD32  time_alignmt;
  UWORD32  fn_offset;
  UWORD8   task;

  // use only in packet transfer mode
  // in this mode only one neighbor is allowed to be decoded
  // so these variables memorize this neighbor parameters.
  static UWORD32  time_alignmt_mem;
  static UWORD32  fn_offset_mem;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset CS_MEAS process.
        l1a_l1s_com.l1s_en_task[BCCHN] = TASK_DISABLED;          // Clear BCCHN  task enable flag.
        l1a_l1s_com.l1s_en_task[BCCHN_TOP] = TASK_DISABLED;      // Clear BCCHN_TOP task enable flag.
        #if (L1_GPRS)
          l1a_l1s_com.l1s_en_task[BCCHN_TRAN] = TASK_DISABLED;   // Clear BCCHN_TRAN  task enable flag.
        #endif
      }
      break;

      case WAIT_INIT:
      {
        if(SignalCode == MPHC_NCELL_BCCH_REQ)
        // Request to read BCCH from one neighbour cell.
        //----------------------------------------------
        {
          // there are 3 priorities with BCCH neighbor task
          // => TOP PRIORITY: this request has priority over serving cell activity
          //                  and any other neighbor cells activity (used for GPRS).
          //                  In IDLE circuit this priority enable the task BCCHN_TOP
          //                  In Packet Transfer this priority enable the task BCCHN_TRAN
          // => HIGH_PRIORITY:this request has priority over the neighbor cell BCCH reading
          //                  with priority set to NORMAL_PRIORITY.
          // => NORMAL_PRIORITY:this request has no special priority.
          // Note: HIGH_PRIORITY and NORMAL_PRIORITY enable the task BCCHN.

          #if (L1_GPRS)
            if(l1a_l1s_com.mode == PACKET_TRANSFER_MODE)
              task = BCCHN_TRAN;
            else
              if(((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->gprs_priority == TOP_PRIORITY)
                task = BCCHN_TOP;
              else
                task = BCCHN;
          #else
            task = BCCHN;
          #endif

          // Set semaphores for neighbor BCCH task.
          l1a_l1s_com.task_param[task] = SEMAPHORE_SET;

          // Step in state machine.
          *state = BCCHN_CONFIG;
        }

        // No action in this machine for other messages.
        else
        {
          // End of process.
          return;
        }
      }
      break;


      case BCCHN_CONFIG:
      {
        // Request to read BCCH from one neighbour cell.
        //----------------------------------------------

        UWORD8   neigh_number = 0;
        UWORD8   neigh_id;

        // there are 3 priorities with BCCH neighbor task
        // => TOP PRIORITY: this request has priority over serving cell activity
        //                  and any other neighbor cells activity (used for GPRS).
        //                  In IDLE circuit this priority enable the task BCCHN_TOP
        //                  In Packet Transfer this priority enable the task BCCHN_TRAN
        // => HIGH_PRIORITY:this request has priority over the neighbor cell BCCH reading
        //                  with priority set to NORMAL_PRIORITY.
        // => NORMAL_PRIORITY:this request has no special priority.
        // Note: HIGH_PRIORITY and NORMAL_PRIORITY enable the task BCCHN.

        #if (L1_GPRS)
          if(l1a_l1s_com.mode == PACKET_TRANSFER_MODE)
            task = BCCHN_TRAN;
          else
            if(((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->gprs_priority == TOP_PRIORITY)
              task = BCCHN_TOP;
            else
              task = BCCHN;
        #else
            task = BCCHN;
        #endif


        #if (L1_GPRS)
          //in case of packet transfer mode
          //only one neighbor is allowed to be decoded => clear the BCCHN list.
          if(l1a_l1s_com.mode == PACKET_TRANSFER_MODE)
          {
            for (neigh_id=0;neigh_id<6;neigh_id++)
              l1a_l1s_com.bcchn.list[neigh_id].status = NSYNC_FREE;
            l1a_l1s_com.bcchn.current_list_size = 0;
          }
        #endif

        // Abort if there is no room for a new neighbour BCCH reading request.
        if(l1a_l1s_com.bcchn.current_list_size >= 6)
        {
          *state = WAIT_BCCHN_RESULT;
          return;
        }

        // Look for first free location within L1 structure.
        while((neigh_number < 6) && (l1a_l1s_com.bcchn.list[neigh_number].status != NSYNC_FREE))
          neigh_number++;


        // Download neighbour info from request message.
        //----------------------------------------------

        // Download ARFCN, timing information and bitmap from the command message.
        time_alignmt_mem   = ((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->time_alignmt;
        fn_offset_mem      = ((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->fn_offset;

        // Sub the serving cell timeslot number to the Neigh./Serving timing
        // difference to format it for L1S use.
        time_alignmt =time_alignmt_mem;
        fn_offset    =fn_offset_mem;
        l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);

        l1a_l1s_com.bcchn.list[neigh_number].radio_freq    = ((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->radio_freq;
        l1a_l1s_com.bcchn.list[neigh_number].fn_offset     = fn_offset;
        l1a_l1s_com.bcchn.list[neigh_number].time_alignmt  = time_alignmt;
        l1a_l1s_com.bcchn.list[neigh_number].tsc           = ((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->tsc;
        l1a_l1s_com.bcchn.list[neigh_number].bcch_blks_req = ((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->bcch_blks_req;


        #if L1_GPRS
          // in packet transfer only one priority is allowed : TOP_PRIORITY
          if(l1a_l1s_com.mode != PACKET_TRANSFER_MODE)
            l1a_l1s_com.bcchn.list[neigh_number].gprs_priority = ((T_MPHC_NCELL_BCCH_REQ *)(msg->SigP))->gprs_priority;
          else
            l1a_l1s_com.bcchn.list[neigh_number].gprs_priority = TOP_PRIORITY;
        #else
          l1a_l1s_com.bcchn.list[neigh_number].gprs_priority = NORMAL_PRIORITY;
        #endif

        // Enable L1S activity on this new neighbour task BCCH.
        l1a_l1s_com.bcchn.list[neigh_number].status  = NSYNC_PENDING;

        l1a_l1s_com.bcchn.current_list_size         += 1;

        l1a_l1s_com.l1s_en_task[task] = TASK_ENABLED;

        // Step in state machine.
        *state = WAIT_BCCHN_RESULT;

        // End of process.
        end_process = 1;

      }
      break; // case BCCHN_CONFIG


      case WAIT_BCCHN_RESULT:
      {
        if(SignalCode == L1C_BCCHN_INFO)
        // Neighbor cell BCCH reading result.
        //-----------------------------------
        {
          UWORD8  neigh_id         = ((T_L1C_BCCHN_INFO *)(msg->SigP))->neigh_id;
          UWORD16 neigh_radio_freq = ((T_L1C_BCCHN_INFO *)(msg->SigP))->radio_freq;

          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_BCCH_REQ message has been received
          // in the same frame than this L1s message)
          // BUG_973: an issue occurs when this 3 messages arrives in this order and
          //          in the same frame MPHC_STOP_NCELL_BCCH_REQ(A) + MPHC_NCELL_BCCH_REQ(B) + this L1s message(A)
          //          In this case the carrier B wasn't handled because the L1s message deletes the carrier B in the list
          if (neigh_radio_freq != l1a_l1s_com.bcchn.list[neigh_id].radio_freq)
          {
             // REM: the message is not sent to L3

             return; // Stay in current state.
          }

          // Disable neigh BCCH reading when any of the TC have been read.
          l1a_l1s_com.bcchn.list[neigh_id].status = NSYNC_FREE;
          l1a_l1s_com.bcchn.current_list_size    -= 1;

          // Forward result message to L3.
          l1a_send_result(MPHC_NCELL_BCCH_IND, msg, RRM1_QUEUE);

          // Is it the end of the complete process ?
          if(l1a_l1s_com.bcchn.current_list_size == 0)
          {
            // This process must be reset.
            *state = RESET;
          }

          else
          {
            // End of process.
            return;
          }
        }

        else
        if(SignalCode == MPHC_NCELL_BCCH_REQ)
        // Request to read BCCH from one neighbour cell.
        //-----------------------------------
        {
          // Step in state machine.
          *state = BCCHN_CONFIG;
        }

        else
        if(SignalCode == MPHC_STOP_NCELL_BCCH_REQ)
        // Request to STOP neighbour cell activity for certain carriers.
        //--------------------------------------------------------------
        {
          UWORD8  i,j;
          UWORD8  array_size;

          // Disable neighbor BCCH task.
          l1a_l1s_com.l1s_en_task[BCCHN] = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[BCCHN_TOP] = TASK_DISABLED;
          #if (L1_GPRS)
            l1a_l1s_com.l1s_en_task[BCCHN_TRAN] = TASK_DISABLED;
          #endif

          array_size = ((T_MPHC_STOP_NCELL_BCCH_REQ *)(msg->SigP))->radio_freq_array_size;

          if(array_size != 6)
          {
            // Stop some of the Neighb. synchro.
            for(i=0;i<array_size;i++)
            {
              UWORD16  radio_freq = ((T_MPHC_STOP_NCELL_BCCH_REQ *)(msg->SigP))->radio_freq_array[i];

              // Search for same value within L1 structure.
              j=0;
              while(!((radio_freq == l1a_l1s_com.bcchn.list[j].radio_freq) &&
                      (l1a_l1s_com.bcchn.list[j].status != NSYNC_FREE)) &&
                    (j < 6))
              {
                	j++;
              }

              // If found, reset L1 structure for this carrier.
              if(j<6)
              {
                l1a_l1s_com.bcchn.list[j].status = NSYNC_FREE;
                l1a_l1s_com.bcchn.current_list_size --;
              }
            }
          }
          else
          {
            // Stop all the Neighb. BCCH reading.
            l1a_l1s_com.bcchn.current_list_size = 0;

            for(i=0;i<6;i++)
              l1a_l1s_com.bcchn.list[i].status = NSYNC_FREE;
          }

          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_STOP_NCELL_BCCH_CON,RRM1_QUEUE);

          // All neigh synchro have been removed.
          if(l1a_l1s_com.bcchn.current_list_size == 0)
          {
            // This process must be reset.
            *state = RESET;
          }
          else
          {
            // NOTE: in packet transfer mode only one BCCHN is allowed to be decoded
            //       so it is impossible to be here after the STOP message in this mode
            //       The tasks that may be restart are: BCCHN_TOP and/or BCCHN

            // Check if it remains some BCCHN_TOP or BCCHN tasks to restart
            for(i=0;i<6;i++)
            {
              if (l1a_l1s_com.bcchn.list[i].status != NSYNC_FREE)
              {
                if (l1a_l1s_com.bcchn.list[i].gprs_priority == TOP_PRIORITY)
                {
                  // it remains one BCCHN_TOP task to restart
                  l1a_l1s_com.task_param[BCCHN_TOP]  = SEMAPHORE_SET;
                  l1a_l1s_com.l1s_en_task[BCCHN_TOP] = TASK_ENABLED;
                }
                else
                {
                  // it remains one BCCHN task to restart
                  l1a_l1s_com.task_param[BCCHN]  = SEMAPHORE_SET;
                  l1a_l1s_com.l1s_en_task[BCCHN] = TASK_ENABLED;
                }
              }
            }

            // Stay in current state.
            return;
          }
        }

        #if (L1_GPRS)
          else
          // End of packet transfer mode if TBF downlink and uplink have been released
          if((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all))
          {
            l1a_l1s_com.bcchn.list[0].status = NSYNC_FREE;
            l1a_l1s_com.bcchn.current_list_size = 0;

             // 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 BCCHN parameters

             // Clear BCCHN_TRAN  task enable flag.
             l1a_l1s_com.l1s_en_task[BCCHN_TRAN] = TASK_DISABLED;

             // Set semaphores for neighbor BCCH task.
             l1a_l1s_com.task_param[BCCHN_TRAN] = SEMAPHORE_SET;

             // Sub the serving cell timeslot number to the Neigh./Serving timing
             // difference to format it for L1S use.
             time_alignmt = time_alignmt_mem;
             fn_offset    = fn_offset_mem;

             l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);

             l1a_l1s_com.bcchn.list[0].fn_offset     = fn_offset;
             l1a_l1s_com.bcchn.list[0].time_alignmt  = time_alignmt;

             l1a_l1s_com.l1s_en_task[BCCHN_TRAN] = TASK_ENABLED;

             // Stay in current state.
             return;
          }
        #endif

        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.

/*-------------------------------------------------------*/
/* l1a_idle_6strongest_monitoring_process()              */
/*-------------------------------------------------------*/
/*                                                       */
/* Description:                                          */
/* ------------                                          */
/* This function is a state machine which handles the    */
/* synchronization with up to 6 neighbor cells           */
/*                                                       */
/* Starting messages:        MPHC_NCELL_SYNC_REQ         */
/* ------------------        MPHC_NCELL_LIST_SYNC_REQ    */
/*  L1 makes an attempt to read the FB/SB or to confirm  */
/*  SB.                                                  */
/*                                                       */
/*                                                       */
/* Result messages (input):  L1C_FB_INFO                 */
/* ------------------------  L1C_SB_INFO                 */
/*                           L1C_SBCONF_INFO             */
/*  Result messages from L1S. FB detection, SB detection,*/
/*  SB confirmation.                                     */
/*                                                       */
/* Result messages (output): MPHC_NCELL_SYNC_IND         */
/* -------------------------                             */
/*  SB indication.                                       */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_NCELL_SYNC_REQ    */
/* -----------------------  (MPHC_STOP_NCELL_SYNC_CON)   */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_idle_6strongest_monitoring_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET              = 0,
    WAIT_INIT          = 1,
    NSYNC_CONFIG       = 2,
    WAIT_NSYNC_RESULT  = 3
#if (L1_12NEIGH == 1)
    ,NSYNC_LIST_CONFIG = 4
    ,WAIT_SSYNC_RESULT = 5
#endif
  };

          UWORD8  *state      = &l1a.state[I_6MP];
          UWORD32  SignalCode = msg->SignalCode;


#if (L1_12NEIGH == 1)
  static  UWORD8   list_size;
#endif

#if (L1_EOTD ==1)
  static  UWORD8   last_cell;
#endif

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset of process is embbeded in other state to
        // avoid conflicts between processes using the same
        // L1S tasks.
      }
      break;

      case WAIT_INIT:
      {
        #if (L1_12NEIGH ==1)
          if(SignalCode == MPHC_NCELL_LIST_SYNC_REQ)
          {
            // Check request validity for this process:
            //   ->  This machine works only for IDLE MODE.
            //   ->  Search must be correct.

            if(l1a_l1s_com.mode != I_MODE)
              return;
            #if (L1_EOTD ==1)
              // For EOTD, nsync must be FREE...
            if ( (((T_MPHC_NCELL_LIST_SYNC_REQ *)(msg->SigP))->eotd == TRUE)
                 && (l1a_l1s_com.nsync.current_list_size != 0) )
              // End of process.
              return;
            #endif

            l1a_l1s_com.nsync.first_in_list=0;

            // Set semaphores for all neighbor relative task.
            l1a_l1s_com.task_param[NSYNC]  = SEMAPHORE_SET;
            l1a_l1s_com.task_param[FBNEW]  = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SB2]    = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SBCONF] = SEMAPHORE_SET;

            // Step in state machine.
            *state = NSYNC_LIST_CONFIG;

          }
          else
        #endif

        if(SignalCode == MPHC_NCELL_SYNC_REQ)
        // Request to READ the FB/SB or SB from the given carrier.
        //--------------------------------------------------------
        {
          // Check request validity for this process:
          //   ->  This machine works only for IDLE MODE.
          //   ->  Search must be correct.

            if(l1a_l1s_com.mode != I_MODE)
              return;

          l1a_l1s_com.nsync.first_in_list=0;

          // Set semaphores for all neighbor relative task.
          l1a_l1s_com.task_param[NSYNC]  = SEMAPHORE_SET;
          l1a_l1s_com.task_param[FBNEW]  = SEMAPHORE_SET;
          l1a_l1s_com.task_param[SB2]    = SEMAPHORE_SET;
          l1a_l1s_com.task_param[SBCONF] = SEMAPHORE_SET;

          // Step in state machine.
          *state = NSYNC_CONFIG;
        }

        // No action in this machine for other messages.
        else
        {
          // End of process.
          return;
        }
      }
      break;


      case NSYNC_CONFIG:
      {
        // Request to read FB/SB or SB from one neighbour cell.
        //-----------------------------------------------------
        UWORD8  neigh_number = l1a_l1s_com.nsync.first_in_list;

        // Abort if there is no room for a new neighbour synchro request.
        #if (L1_12NEIGH ==1)
          if (l1a_l1s_com.nsync.current_list_size >= NBR_NEIGHBOURS)
        #else
          if (l1a_l1s_com.nsync.current_list_size >= 6)
        #endif
        {
          *state = WAIT_NSYNC_RESULT;
          return;
        }

        // Look for first free location within L1 structure.
        #if (L1_12NEIGH ==1)
          while((neigh_number<NBR_NEIGHBOURS) && (l1a_l1s_com.nsync.list[neigh_number].status != NSYNC_FREE))
          {
            neigh_number++;
            if ( neigh_number == NBR_NEIGHBOURS ) neigh_number=0;
          }
        #else
          while((neigh_number<6) && (l1a_l1s_com.nsync.list[neigh_number].status != NSYNC_FREE))
          {
            neigh_number++;
            if ( neigh_number == 6 ) neigh_number=0;
          }
        #endif

        // Download neighbour info from request message.
        //----------------------------------------------

        l1a_l1s_com.nsync.list[neigh_number].radio_freq      = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq;
        l1a_l1s_com.nsync.list[neigh_number].timing_validity = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->timing_validity;

      #if ((REL99 == 1) && (FF_RTD ==1)) // RTD feature
        // In this case that timing information is provided related to Real Time Difference RTD of the cell.
        // We force the timing_validity to no timing information because there is no special mechanism to take into
        // account RTD information in idle mode. So it is preferable to do a complete FB search than
        // using inaccurate timing in a bad way.
        if(l1a_l1s_com.nsync.list[neigh_number].timing_validity == 3)
          l1a_l1s_com.nsync.list[neigh_number].timing_validity = 0 ;
      #endif

        if(l1a_l1s_com.nsync.list[neigh_number].timing_validity != 0)
        {
          UWORD32  time_alignmt;
          UWORD32  fn_offset;

          // Download ARFCN, timing information and bitmap from the command message.
          time_alignmt   = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->time_alignmt;
          fn_offset      = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->fn_offset;

          // Sub the serving cell timeslot number to the Neigh./Serving timing
          // difference to format it for L1S use.
          l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
          l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

          l1a_l1s_com.nsync.list[neigh_number].fn_offset    = fn_offset;
          l1a_l1s_com.nsync.list[neigh_number].time_alignmt = time_alignmt;
        }
        else
        {
          l1a_l1s_com.nsync.list[neigh_number].fn_offset    = 0;
          l1a_l1s_com.nsync.list[neigh_number].time_alignmt = 0;
        }
        // Enable L1S activity on this new neighbour task BCCH.
        l1a_l1s_com.nsync.list[neigh_number].status  = NSYNC_PENDING;
        l1a_l1s_com.nsync.current_list_size         += 1;
        l1a_l1s_com.l1s_en_task[NSYNC]               = TASK_ENABLED;

        // Step in state machine.
        *state = WAIT_NSYNC_RESULT;

        // End of process.
        end_process = 1;
      }
      break; // case NSYNC_CONFIG

      #if (L1_12NEIGH == 1)
        case NSYNC_LIST_CONFIG:
        {
          // Request to read FB/SB or SB from 1 to 12 neighbour cells.
          //----------------------------------------------------------
          UWORD8  neigh_number = l1a_l1s_com.nsync.first_in_list;
          UWORD8  nbr_free = (UWORD8) (NBR_NEIGHBOURS) - l1a_l1s_com.nsync.current_list_size;
          T_MPHC_NCELL_LIST_SYNC_REQ *pt = ((T_MPHC_NCELL_LIST_SYNC_REQ *)(msg->SigP));
          UWORD8 i;

          //Read list size
          list_size= ((T_MPHC_NCELL_LIST_SYNC_REQ *)(msg->SigP))->list_size;

          // Abort if there is no room for a new neighbour synchro request.
          if ( (l1a_l1s_com.nsync.current_list_size >= NBR_NEIGHBOURS) ||
               (nbr_free < list_size) )
          {
            *state = WAIT_NSYNC_RESULT;
            return;
          }

          #if (L1_EOTD==1)
          // Abort if list Not empty and request for an EOTD session....
          if ( (l1a_l1s_com.nsync.current_list_size != 0) &&
               ( pt->eotd == TRUE) )
          {
            *state = WAIT_NSYNC_RESULT;
            return;
          }
          // store Eotd flag
            l1a_l1s_com.nsync.eotd_meas_session = pt->eotd;
          #endif

          // Download neighbour info from request message.
          //----------------------------------------------
          for (i=0; i<list_size; i++,neigh_number++)
          {
            if ( neigh_number == NBR_NEIGHBOURS ) neigh_number=0; //cyclic buffer
            // Look for first free location within L1 structure.
            while((neigh_number<NBR_NEIGHBOURS) && (l1a_l1s_com.nsync.list[neigh_number].status != NSYNC_FREE))
            {
               neigh_number++;
               if ( neigh_number == NBR_NEIGHBOURS ) neigh_number=0;
            }

            l1a_l1s_com.nsync.list[neigh_number].radio_freq      = pt->ncell_list[i].radio_freq;
            l1a_l1s_com.nsync.list[neigh_number].timing_validity = pt->ncell_list[i].timing_validity;
          #if ((REL99 == 1) && (FF_RTD == 1)) // RTD feature
            // In this case that timing information is provided related to Real Time Difference RTD of the cell.
            // We force the timing_validity to no timing information because there is no special mechanism to take into
            // account RTD information in idle mode. So it is preferable to do a complete FB search than
            // using inaccurate timing in a bad way.
            if(l1a_l1s_com.nsync.list[neigh_number].timing_validity == 3)
              l1a_l1s_com.nsync.list[neigh_number].timing_validity = 0 ;
          #endif

            if(l1a_l1s_com.nsync.list[neigh_number].timing_validity != 0)
            {
              UWORD32  time_alignmt;
              UWORD32  fn_offset;

              // Download ARFCN, timing information and bitmap from the command message.
              time_alignmt   = pt->ncell_list[i].time_alignmt;
              fn_offset      = pt->ncell_list[i].fn_offset;

              // Sub the serving cell timeslot number to the Neigh./Serving timing
              // difference to format it for L1S use.
              l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
              l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

              l1a_l1s_com.nsync.list[neigh_number].fn_offset    = fn_offset;
              l1a_l1s_com.nsync.list[neigh_number].time_alignmt = time_alignmt;
            }
            else
            {
              l1a_l1s_com.nsync.list[neigh_number].fn_offset    = 0;
              l1a_l1s_com.nsync.list[neigh_number].time_alignmt = 0;
            }

            // Increment list size
            l1a_l1s_com.nsync.current_list_size += 1;

            // Enable L1S activity on all new neighbour tasks if NOT eotd.
#if (L1_EOTD==1)
            if (pt->eotd == FALSE)
#endif
              l1a_l1s_com.nsync.list[neigh_number].status  = NSYNC_PENDING;

          } // end for

          // If NOT Eotd start new neighbours.
#if (L1_EOTD == 1)
          if (pt->eotd == FALSE)
          {
#endif
            l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;
            // Step in state machine.
            *state = WAIT_NSYNC_RESULT;
#if (L1_EOTD == 1)
          }

            else
            {
              UWORD32  time_alignmt =0;
              UWORD32  fn_offset = 0;

              // Set eotd mode
              l1a_l1s_com.nsync.eotd_meas_session = TRUE;

              // In Eotd : Serving cell is not part of the list
              //-----------------------------------------------
              // But it must be the 1st monitored
              // Sub the serving cell timeslot number to the Neigh./Serving timing
              // difference to format it for L1S use.
              #if (L1_EOTD_QBIT_ACC==1)
                time_alignmt = l1a_l1s_com.nsync.serv_time_alignmt;
                fn_offset = l1a_l1s_com.nsync.serv_fn_offset;
              #endif

              l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
              l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

              // Load Serving cell in last position [NBR_NEIGHBOURS]
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].radio_freq   = l1a_l1s_com.Scell_info.radio_freq;
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].fn_offset    = fn_offset;
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].time_alignmt = time_alignmt;
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].timing_validity = 2;

              // Set list size
              l1a_l1s_com.nsync.current_list_size = 1;

              // start Eotd
              last_cell = FALSE;

              // Enable Serving cell monitoring
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status  = NSYNC_PENDING;
              l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

              // Step in state machine.
              *state = WAIT_SSYNC_RESULT;
            }
          #endif // L1_EOTD == 1

          // End of process.
          end_process = 1;
        }
        break; // case NSYNC_LIST_CONFIG

      #endif //(L1_12NEIGH == 1)

#if ((L1_EOTD == 1)&&L1_12NEIGH)
      case WAIT_SSYNC_RESULT:
      {
        if(SignalCode == L1C_SBCONF_INFO)
        // Synchro Burst confirmation attempt result.
        //-------------------------------------------
        {
          UWORD8  neigh_id        = ((T_L1C_SBCONF_INFO *)(msg->SigP))->neigh_id;
          BOOL    sb_found        = ((T_L1C_SBCONF_INFO *)(msg->SigP))->sb_flag;
          UWORD16 neigh_radio_freq= ((T_L1C_SBCONF_INFO *)(msg->SigP))->radio_freq;


          // Check if this neighbor is NOT serving cell
          if ( (neigh_radio_freq != l1a_l1s_com.Scell_info.radio_freq) || (neigh_id !=12))
          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          // Set mode IDLE for EOTD
          ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 0;

          if(sb_found == TRUE)
          // SB detection is a success.
          {
            UWORD32  *fn_offset_ptr    = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_offset);
            UWORD32  *time_alignmt_ptr = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->time_alignmt);
            UWORD32  fn_sb_neigh = ((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_sb_neigh;
            WORD16   d_eotd_first= ((T_L1C_SBCONF_INFO *)(msg->SigP))->d_eotd_first;
            UWORD32  toa         = ((T_L1C_SBCONF_INFO *)(msg->SigP))->toa;
            WORD32   ta_sb_neigh  = l1a_l1s_com.nsync.list[neigh_id].time_alignmt;
            UWORD32  delta_fn;
            WORD32   delta_qbit;


            // Correct "fn_offset" and "time_alignmt" to report the true
            // Serving/Neighbor time difference.
            //  1) Shift 20 bit since result is from a SB detection.
            //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
            l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
            l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);

            // compute the true Serving/Neighbor time difference.
            //  1) update time_alignmt with (23bit - d_eotd_first) delta
            //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
            ta_sb_neigh  += (d_eotd_first - (23))*4 +
                            (l1a_l1s_com.dl_tn * 625);

            if (last_cell == FALSE)
            {
              l1a_l1s_com.nsync.fn_sb_serv = fn_sb_neigh;
              l1a_l1s_com.nsync.ta_sb_serv = ta_sb_neigh;

              ((T_MPHC_NCELL_SYNC_IND*)(msg->SigP))->timetag = 0;
            }
            else
            // End of EOTD meas. Consider Serving Cell as a neighbour cell
            // for timetag computation...
            {
              UWORD32 timetag;
              delta_fn = (fn_sb_neigh - l1a_l1s_com.nsync.fn_sb_serv + MAX_FN)%MAX_FN;
              delta_qbit = ta_sb_neigh - l1a_l1s_com.nsync.ta_sb_serv;

              timetag = (delta_fn*5000) + (WORD32)(delta_qbit);
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->timetag = timetag;

              #if (L1_EOTD_QBIT_ACC ==1)
                // Attempt QB tracking of the serving cell (independent of the TOA algorithm)
                // This is only performed on the second SYNC IND as we do not want to move the serving cell
                // timing during the E-OTD session.
                l1a_compensate_sync_ind((T_MPHC_NCELL_SYNC_IND *)(msg->SigP));
                l1a_l1s_com.nsync.serv_fn_offset    = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset;
                l1a_l1s_com.nsync.serv_time_alignmt = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt;
              #endif

//              #if (CODE_VERSION == SIMULATION)
//                 #if  (TRACE_TYPE==5)
                    ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_fn   = delta_fn;
                    ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_qbit = delta_qbit;
//                 #endif
//              #endif


            }

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
          }
          else
          // SB detection failled.
          {
            #if (L1_EOTD_QBIT_ACC==1)
              l1a_l1s_com.nsync.serv_time_alignmt = 0;
              l1a_l1s_com.nsync.serv_fn_offset = 0;
            #endif

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
//            // Send reporting message with a faillure indication.
//            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);
          }

          // Disable the serving sync. reading.
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status = NSYNC_FREE;
          l1a_l1s_com.nsync.current_list_size   = 0;

          if (last_cell == TRUE)
          {
            // reset list size
            list_size = 0;

            // stop eotd session.
            l1a_l1s_com.nsync.eotd_meas_session = FALSE;

            // reset process.
            l1a_l1s_com.l1s_en_task[NSYNC]  = TASK_DISABLED;
            l1a_l1s_com.l1s_en_task[FBNEW]  = TASK_DISABLED;
            l1a_l1s_com.l1s_en_task[SB2]    = TASK_DISABLED;
            l1a_l1s_com.l1s_en_task[SBCONF] = TASK_DISABLED;

              // This process must be reset.
            *state = RESET;
          }
          else
          {
            UWORD8  i;

            // Curious case where there are no previously synchronised neighbours,
            // but an EOTD session is requested. Apparently, this is legal.
            // Here, we synchronise to the serving cell a second time with the
            // eotd_meas_session flag set so that no AFC or TOA updates are performed.
            #if (L1_EOTD_QBIT_ACC == 1)
              if(list_size == 0)
              {
                // L1 SW : Create a temporary copy of the serving time_alignmt and fn_offset
                //         as we don't want to do the timeslot maths on the reference version
                //         in case the synchronisation fails and we can't write the new values
                //         back to the store...

                UWORD32 time_alignmt = l1a_l1s_com.nsync.serv_time_alignmt;
                UWORD32 fn_offset = l1a_l1s_com.nsync.serv_fn_offset;

                // In Eotd : Serving cell is not part of the list
                //-----------------------------------------------
                // But it must be the 1st and last monitored
                // Sub the serving cell timeslot number to the Neigh./Serving timing
                // difference to format it for L1S use.

                l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
                l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

                // Load Serving cell in last position [NBR_NEIGHBOURS]
                l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].radio_freq   = l1a_l1s_com.Scell_info.radio_freq;
                l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].fn_offset    = fn_offset;
                l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].time_alignmt = time_alignmt;
                l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].timing_validity = 2;

                // Set list size
                l1a_l1s_com.nsync.current_list_size = 1;

                // start Eotd
                last_cell = TRUE;

                // Enable Serving cell monitoring
                l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status  = NSYNC_PENDING;
                l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

                // No step in state machine in this case.
                *state = WAIT_SSYNC_RESULT;
                return;
              }
              else
              {
            #endif // (L1_EOTD_QBIT_ACC == 1)

            // enable all neighbour monitoring
            l1a_l1s_com.nsync.current_list_size = list_size;

            for (i=0; i<list_size; i++)
              l1a_l1s_com.nsync.list[i].status  = NSYNC_PENDING;
            l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

            // step in state machine
            *state = WAIT_NSYNC_RESULT;
            return;

          #if (L1_EOTD_QBIT_ACC == 1)
            }
          #endif
          }
        }

        else
        if(SignalCode == MPHC_STOP_NCELL_SYNC_REQ)
        // Request to STOP neighbour cell activity for all carriers.
        //--------------------------------------------------------------
        {
          UWORD8  array_size;

          array_size = ((T_MPHC_STOP_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq_array_size;

          // TOP accepted only for ALL cells
          if ( (array_size != l1a_l1s_com.nsync.current_list_size) &&
               (array_size != NBR_NEIGHBOURS))
              // Stay in current state.
              return;

          // Stop Eotd session.
          l1a_l1s_com.nsync.eotd_meas_session = FALSE;

          // Disable neighbor sync. tasks.
          l1a_l1s_com.l1s_en_task[NSYNC]  = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[FBNEW]  = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[SB2]    = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[SBCONF] = TASK_DISABLED;

          // Stop Serv. sync reading.
          l1a_l1s_com.nsync.current_list_size = 0;
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status = NSYNC_FREE;

          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_STOP_NCELL_SYNC_CON,RRM1_QUEUE);

          // All neigh synchro have been removed.
          // This process must be reset.
          *state = RESET;
        }
        // No action in this machine for other messages.
        else
        {
          // End of process.
          return;
        }
      }
      break;
#endif

      case WAIT_NSYNC_RESULT:
      {
        if(SignalCode == L1C_FB_INFO)
        // Frequency Burst acquisition attempt result.
        //--------------------------------------------
        {
          BOOL    fb_found;
          UWORD8  neigh_id         = ((T_L1C_FB_INFO *)(msg->SigP))->neigh_id;
          UWORD16 neigh_radio_freq = ((T_L1C_FB_INFO *)(msg->SigP))->radio_freq;

          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_SYNC_REQ message has been received
          // in the same frame than this L1s message)
          // BUG_973: an issue occurs when this 3 messages arrives in this order and
          //          in the same frame MPHC_STOP_NCELL_SYNC_REQ(A) + MPHC_NCELL_SYNC_REQ(B) + this L1s message(A)
          //          In this case the carrier B wasn't handled because the L1s message deletes the carrier B in the list
          if (neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)
          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          // Get result from the message.
          fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

          if(fb_found == TRUE)
          // FB attempt is a success.
          {
            // Enable NSYNC task for SB detection (SB2).
          #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
			            l1a_l1s_com.nsync.list[neigh_id].timing_validity = SB_ACQUISITION_PHASE;
			          #else
			            l1a_l1s_com.nsync.list[neigh_id].timing_validity = 3;
			#endif
            // Enable neighbour sync 0.
            l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_PENDING;

            // End of process.
            return;
          }

          else
          // FB attempt failed.
          //-------------------
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);
          }

          // Disable a neigh sync. reading.
          l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_FREE;
          l1a_l1s_com.nsync.current_list_size    -= 1;

          // Is it the end of the complete process ?
          if(l1a_l1s_com.nsync.current_list_size == 0)
          {
            // Reset process.
            l1a_l1s_com.l1s_en_task[NSYNC]  = TASK_DISABLED;
            l1a_l1s_com.l1s_en_task[FBNEW]  = TASK_DISABLED;
            l1a_l1s_com.l1s_en_task[SB2]    = TASK_DISABLED;
            l1a_l1s_com.l1s_en_task[SBCONF] = TASK_DISABLED;

            // This process must be reset.
            *state = RESET;
          }

          // End of process.
          else
          {
              // Check if first in list was removed from the list. Go to next first in list
              while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
              {
                l1a_l1s_com.nsync.first_in_list++;
                #if (L1_12NEIGH==1)
                  if (l1a_l1s_com.nsync.first_in_list == NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
                #else
                  if (l1a_l1s_com.nsync.first_in_list == 6) l1a_l1s_com.nsync.first_in_list = 0;
                #endif
              }
            return;
          }
        }

        else
        if(SignalCode == L1C_SB_INFO)
        // Synchro Burst acquisition attempt result.
        //------------------------------------------
        {
          typedef struct
          {
            BOOL    sb_found_flag;
            UWORD8  bsic;
            UWORD32 fn_offset;
            UWORD32 time_alignmt;
          }
          T_L1A_NSYNC;

          #if (L1_12NEIGH ==1)
             static T_L1A_NSYNC  static_nsync[NBR_NEIGHBOURS];
          #else
             static T_L1A_NSYNC  static_nsync[6];
          #endif
             BOOL         sb_found    = ((T_L1C_SB_INFO *)(msg->SigP))->sb_flag;
             UWORD8       attempt     = ((T_L1C_SB_INFO *)(msg->SigP))->attempt;
             UWORD8       neigh_id    = ((T_L1C_SB_INFO *)(msg->SigP))->neigh_id;
             UWORD16 neigh_radio_freq = ((T_L1C_SB_INFO *)(msg->SigP))->radio_freq;
             T_L1A_NSYNC *static_nsync_ptr = &(static_nsync[neigh_id]);


          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_SYNC_REQ message has been received
          // in the same frame than this L1s message)
          // BUG_973: an issue occurs when this 3 messages arrives in this order and
          //          in the same frame MPHC_STOP_NCELL_SYNC_REQ(A) + MPHC_NCELL_SYNC_REQ(B) + this L1s message(A)
          //          In this case the carrier B wasn't handled because the L1s message deletes the carrier B in the list
          if (neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)

          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          // Reset static structure SB detection flag.
          if(attempt == 1) static_nsync[neigh_id].sb_found_flag = FALSE;

          if(sb_found == TRUE)
          // SB detection is a success...
          //-----------------------------
          {
            // Save Results.
            static_nsync_ptr->sb_found_flag = TRUE;
            static_nsync_ptr->bsic          = ((T_L1C_SB_INFO *)(msg->SigP))->bsic;
            static_nsync_ptr->fn_offset     = ((T_L1C_SB_INFO *)(msg->SigP))->fn_offset;
            static_nsync_ptr->time_alignmt  = ((T_L1C_SB_INFO *)(msg->SigP))->time_alignmt;
          }

          // Report message to L3 is generated after the 2 attempts.
          if(attempt == 2)
          {
            // Disable a neigh sync. reading.
            l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_FREE;
            l1a_l1s_com.nsync.current_list_size    -= 1;

            if(static_nsync_ptr->sb_found_flag == FALSE)
            {
              // Send reporting message with a faillure indication.
              l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);
            }

            else
            {
              UWORD32  *fn_offset_ptr    = &(((T_L1C_SB_INFO *)(msg->SigP))->fn_offset);
              UWORD32  *time_alignmt_ptr = &(((T_L1C_SB_INFO *)(msg->SigP))->time_alignmt);

              // Download neighbour info in result message.
              ((T_L1C_SB_INFO *)(msg->SigP))->sb_flag      = static_nsync_ptr->sb_found_flag;
              ((T_L1C_SB_INFO *)(msg->SigP))->fn_offset    = static_nsync_ptr->fn_offset;
              ((T_L1C_SB_INFO *)(msg->SigP))->time_alignmt = static_nsync_ptr->time_alignmt;
              ((T_L1C_SB_INFO *)(msg->SigP))->bsic         = static_nsync_ptr->bsic;

              // Correct "fn_offset" and "time_alignmt" to report the true
              // Serving/Neighbor time difference.
              //  1) Shift 20 bit since result is from a SB detection.
              //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
              l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
              l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);

              // Forward the result msg to L3.
              l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
            }

            // Is it the end of the complete process ?
            if(l1a_l1s_com.nsync.current_list_size == 0)
            {
              // Reset process.
              l1a_l1s_com.l1s_en_task[NSYNC]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[FBNEW]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SB2]    = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SBCONF] = TASK_DISABLED;

              // This process must be reset.
              *state = RESET;
            }

            // End of process.
            else
            {
              // Check if first in list was removed from the list. Go to next first in list
              while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
              {
                l1a_l1s_com.nsync.first_in_list++;
                #if (L1_12NEIGH==1)
                  if (l1a_l1s_com.nsync.first_in_list == NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
                #else
                  if (l1a_l1s_com.nsync.first_in_list == 6) l1a_l1s_com.nsync.first_in_list = 0;
                #endif
              }
              return;
            }
          }

          // End of process.
          else
          {
            return;
          }
        }

        else
        if(SignalCode == L1C_SBCONF_INFO)
        // Synchro Burst confirmation attempt result.
        //-------------------------------------------
        {
          UWORD8  neigh_id        = ((T_L1C_SBCONF_INFO *)(msg->SigP))->neigh_id;
          BOOL    sb_found        = ((T_L1C_SBCONF_INFO *)(msg->SigP))->sb_flag;
          UWORD16 neigh_radio_freq= ((T_L1C_SBCONF_INFO *)(msg->SigP))->radio_freq;


          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_SYNC_REQ message has been received
          // in the same frame than this L1s message)
          // BUG_973: an issue occurs when this 3 messages arrives in this order and
          //          in the same frame MPHC_STOP_NCELL_SYNC_REQ(A) + MPHC_NCELL_SYNC_REQ(B) + this L1s message(A)
          //          In this case the carrier B wasn't handled because the L1s message deletes the carrier B in the list
          if (neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)
          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          if(sb_found == TRUE)
          // SB detection is a success.
          {

              UWORD32  *fn_offset_ptr    = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_offset);
              UWORD32  *time_alignmt_ptr = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->time_alignmt);

              // Correct "fn_offset" and "time_alignmt" to report the true
              // Serving/Neighbor time difference.
              //  1) Shift 20 bit since result is from a SB detection.
              //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
              l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
              l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);


            #if (L1_EOTD==1)
              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {

                UWORD32  fn_sb_neigh = ((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_sb_neigh;
                WORD16   d_eotd_first= ((T_L1C_SBCONF_INFO *)(msg->SigP))->d_eotd_first;
                UWORD32  toa         = ((T_L1C_SBCONF_INFO *)(msg->SigP))->toa;
                WORD32   ta_sb_neigh  = l1a_l1s_com.nsync.list[neigh_id].time_alignmt;
                UWORD32  delta_fn;
                WORD32   delta_qbit;
                UWORD32  timetag;

                // compute the true Serving/Neighbor time difference.
                //  1) update time_alignmt with (23bit - d_eotd_first) delta
                //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
                ta_sb_neigh  += (d_eotd_first - (23))*4 +
                                (l1a_l1s_com.dl_tn * 625);


                delta_fn = (fn_sb_neigh - l1a_l1s_com.nsync.fn_sb_serv + MAX_FN)%MAX_FN;
                delta_qbit = ta_sb_neigh - l1a_l1s_com.nsync.ta_sb_serv;

                // Set timetag
                timetag = (delta_fn*5000) + (WORD32)(delta_qbit);
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->timetag = timetag;

                // Set mode
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 0;

//                #if (CODE_VERSION == SIMULATION)
//                  #if (TRACE_TYPE == 5)
                    ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_fn   = delta_fn;
                    ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->delta_qbit = delta_qbit;
//                  #endif
//                #endif
             }

            #endif

            #if ((L1_EOTD == 1) && (L1_EOTD_QBIT_ACC == 1))
              // Attempt to compensate each N-Cell SYNC IND for QB tracking.
              l1a_compensate_sync_ind((T_MPHC_NCELL_SYNC_IND *)(msg->SigP));
            #endif

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
          }

          else
          // SB detection failled.
          {
           #if (L1_EOTD ==1)
            // Set mode
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
             {
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 0;
               // Forward the result msg to L3.
               l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
             }
             else
           #endif
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);
          }

          // Disable a neigh sync. reading.
          l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_FREE;
          l1a_l1s_com.nsync.current_list_size    -= 1;

          // Is it the end of the complete process ?
          if(l1a_l1s_com.nsync.current_list_size == 0)
          {
           #if ((L1_EOTD ==1)&& L1_12NEIGH)
            // Is it EOTD ?
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
            {
               UWORD32  time_alignmt=0;
               UWORD32  fn_offset=0;

              // Init list to serving cell
              // Download ARFCN, timing information and bitmap from the command message.
              // Sub the serving cell timeslot number to the Neigh./Serving timing
              // difference to format it for L1S use.
              #if (L1_EOTD_QBIT_ACC==1)
                time_alignmt = l1a_l1s_com.nsync.serv_time_alignmt;
                fn_offset = l1a_l1s_com.nsync.serv_fn_offset;
              #endif

              l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
              l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

              // Store Serving cell infos in location [NBR_NEIGHBOURS]
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].radio_freq   = l1a_l1s_com.Scell_info.radio_freq;
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].fn_offset    = fn_offset;
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].time_alignmt = time_alignmt;
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].timing_validity = 2;

              // Set list size && last cell flag.
              l1a_l1s_com.nsync.current_list_size = 1;
              last_cell = TRUE;

              // Enable Serving cell monitoring
              l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status  = NSYNC_PENDING;
              l1a_l1s_com.l1s_en_task[NSYNC]    = TASK_ENABLED;

              *state = WAIT_SSYNC_RESULT;
              return;
            }
            else
            #endif
            {
              // Reset process.
              l1a_l1s_com.l1s_en_task[NSYNC]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[FBNEW]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SB2]    = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SBCONF] = TASK_DISABLED;

              // This process must be reset.
              *state = RESET;
            }
          }

          // End of process.
          else
          {
            // Check if first in list was removed from the list. Go to next first in list
            while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
            {
              l1a_l1s_com.nsync.first_in_list++;
              #if (L1_12NEIGH==1)
                if (l1a_l1s_com.nsync.first_in_list == NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
              #else
                if (l1a_l1s_com.nsync.first_in_list == 6) l1a_l1s_com.nsync.first_in_list = 0;
              #endif
            }
            return;
          }
        }
        #if (L1_12NEIGH ==1)
          else
          if(SignalCode == MPHC_NCELL_LIST_SYNC_REQ)
          // Request to READ the FB/SB or SB of 1 to 12 carriers.
          //--------------------------------------------------------
          {
          #if (L1_EOTD ==1)
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              // Stay in current state.
              return;
            else
          #endif
              // Step in state machine.
              *state = NSYNC_LIST_CONFIG;
          }
        #endif
        else
        if(SignalCode == MPHC_NCELL_SYNC_REQ)
        // Request to READ the FB/SB or SB from the given carrier.
        //--------------------------------------------------------
        {
          #if (L1_EOTD ==1)
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              // Stay in current state.
              return;
            else
          #endif

          // Step in state machine.
          *state = NSYNC_CONFIG;
        }

        else
        if(SignalCode == MPHC_STOP_NCELL_SYNC_REQ)
        // Request to STOP neighbour cell activity for certain carriers.
        //--------------------------------------------------------------
        {
          UWORD8  i,j;
          UWORD8  array_size;

          array_size = ((T_MPHC_STOP_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq_array_size;

          #if (L1_EOTD ==1)
            // Only stop for ALL neighbours in list are accepted.
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
            {
              if ( (array_size != l1a_l1s_com.nsync.current_list_size) &&
                   (array_size != NBR_NEIGHBOURS))
                // Stay in current state.
                return;
            }
            // Stop Eotd session.
            l1a_l1s_com.nsync.eotd_meas_session = FALSE;
          #endif

          // Disable neighbor sync. tasks.
          l1a_l1s_com.l1s_en_task[NSYNC]  = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[FBNEW]  = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[SB2]    = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[SBCONF] = TASK_DISABLED;

          #if (L1_12NEIGH ==1)
            if(array_size != NBR_NEIGHBOURS)
          #else
            if(array_size != 6)
          #endif
          {
            // Stop some of the Neighb. synchro.
            for(i=0;i<array_size;i++)
            {
              UWORD16  radio_freq = ((T_MPHC_STOP_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq_array[i];

              // Search for same value within L1 structure.
              j=0;
              while(!((radio_freq == l1a_l1s_com.nsync.list[j].radio_freq) &&
                      (l1a_l1s_com.nsync.list[j].status != NSYNC_FREE)) &&
              #if (L1_12NEIGH ==1)
                      (j < NBR_NEIGHBOURS))
              #else
                      (j < 6))
              #endif
              {
                j++;
              }

              // If found, reset L1 structure for this carrier.
              #if (L1_12NEIGH ==1)
                if(j<NBR_NEIGHBOURS)
              #else
                if(j<6)
              #endif
              {
                l1a_l1s_com.nsync.list[j].status = NSYNC_FREE;
                l1a_l1s_com.nsync.current_list_size --;
              }
            }
          }
          else
          {
            // Stop all the Neighb. BCCH reading.
            l1a_l1s_com.nsync.current_list_size = 0;

            #if (L1_12NEIGH ==1)
              for(i=0;i<NBR_NEIGHBOURS;i++)
            #else
              for(i=0;i<6;i++)
            #endif
              l1a_l1s_com.nsync.list[i].status = NSYNC_FREE;
          }

          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_STOP_NCELL_SYNC_CON,RRM1_QUEUE);

          // All neigh synchro have been removed.
          if(l1a_l1s_com.nsync.current_list_size == 0)
          {
            // Tasks already disabled.

            // This process must be reset.
            *state = RESET;
          }
          else
          {
            // Check if first in list was removed from the list. Go to next first in list
            while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
            {
              l1a_l1s_com.nsync.first_in_list++;
              #if (L1_12NEIGH==1)
                if (l1a_l1s_com.nsync.first_in_list == NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
              #else
                if (l1a_l1s_com.nsync.first_in_list == 6) l1a_l1s_com.nsync.first_in_list = 0;
              #endif
            }

            // Set semaphores for all neighbor relative task before re-enebling NSYNC task.
            l1a_l1s_com.task_param[NSYNC]  = SEMAPHORE_SET;
            l1a_l1s_com.task_param[FBNEW]  = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SB2]    = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SBCONF] = SEMAPHORE_SET;

            // Enable neighbour sync task.
            l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

            // Stay in current state.
            return;
          }
        }
        // No action in this machine for other messages.
        else
        {
          // End of process.
          end_process = 1;
        }
      }
      break;
    } // end of "switch".
  } // end of "while"
} // end of procedure.

/*-------------------------------------------------------*/
/* l1a_idle_serving_cell_bcch_reading_process()          */
/*-------------------------------------------------------*/
/* Description : This state machine handles serving cell */
/* BCCH reading.                                         */
/*                                                       */
/* Starting messages:        MPHC_SCELL_NBCCH_REQ        */
/* ------------------        MPHC_SCELL_EBCCH_REQ        */
/*                                                       */
/*  L1 continuously reads the serving cell BCCH and/or   */
/*  Extended BCCH as requested by the scheduling info.   */
/*                                                       */
/* Result messages (input):  L1C_BCCHS_INFO              */
/* ------------------------                              */
/*  System information data block from L1S.              */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_SCELL_BCCH_REQ    */
/* -----------------------  (MPHC_STOP_SCELL_BCCH_CON)   */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_idle_serving_cell_bcch_reading_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET              = 0,
    WAIT_INIT          = 1,
    NBCCHS_CONFIG      = 2,
    EBCCHS_CONFIG      = 3,
    WAIT_BCCHS_RESULT  = 4
  };

  UWORD8  *state      = &l1a.state[I_SCB];
  UWORD32  SignalCode = msg->SignalCode;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset CS_MEAS process.
        l1a_l1s_com.l1s_en_task[NBCCHS] = TASK_DISABLED;  // Clear NBCCHS task enable flag.
        l1a_l1s_com.l1s_en_task[EBCCHS] = TASK_DISABLED;  // Clear EBCCHS task enable flag.
      }
      break;

      case WAIT_INIT:
      {
        // Request to read Normal BCCH from serving cell.
        if(SignalCode == MPHC_SCELL_NBCCH_REQ)
        {
          // Step in state machine.
          *state = NBCCHS_CONFIG;
        }

        // Request to read Extended BCCH from serving cell.
        else
        if(SignalCode == MPHC_SCELL_EBCCH_REQ)
        {
          // Step in state machine.
          *state = EBCCHS_CONFIG;
        }

        // No action in this machine for other messages.
        else
        {
          // End of process.
          return;
        }
      }
      break;

      case NBCCHS_CONFIG:
      {
        UWORD8 i;

        // Set semaphores for Normal Serving BCCH reading task.
        l1a_l1s_com.task_param[NBCCHS] = SEMAPHORE_SET;

        // Download message content.
        //--------------------------
        l1a_l1s_com.nbcchs.schedule_array_size = ((T_MPHC_SCELL_NBCCH_REQ *)(msg->SigP))->schedule_array_size;

        for(i=0;i<l1a_l1s_com.nbcchs.schedule_array_size;i++)
        {
          l1a_l1s_com.nbcchs.schedule_array[i].modulus =
            ((T_MPHC_SCELL_NBCCH_REQ *)(msg->SigP))->schedule_array[i].modulus;
          l1a_l1s_com.nbcchs.schedule_array[i].relative_position =
            ((T_MPHC_SCELL_NBCCH_REQ *)(msg->SigP))->schedule_array[i].relative_position;
        }

        // Enable NBCCHS task.
        l1a_l1s_com.l1s_en_task[NBCCHS] = TASK_ENABLED;

        // Step in state machine.
        *state = WAIT_BCCHS_RESULT;

        // End of process.
        end_process = 1;
      }
      break;

      case EBCCHS_CONFIG:
      {
        UWORD8 i;

        // Set semaphores for Normal Serving BCCH reading task.
        l1a_l1s_com.task_param[EBCCHS] = SEMAPHORE_SET;

        // Download message content.
        //--------------------------
        l1a_l1s_com.ebcchs.schedule_array_size = ((T_MPHC_SCELL_EBCCH_REQ *)(msg->SigP))->schedule_array_size;

        for(i=0;i<l1a_l1s_com.ebcchs.schedule_array_size;i++)
        {
          l1a_l1s_com.ebcchs.schedule_array[i].modulus =
            ((T_MPHC_SCELL_EBCCH_REQ *)(msg->SigP))->schedule_array[i].modulus;
          l1a_l1s_com.ebcchs.schedule_array[i].relative_position =
            ((T_MPHC_SCELL_EBCCH_REQ *)(msg->SigP))->schedule_array[i].relative_position;
        }

        // Enable EBCCHS task.
        l1a_l1s_com.l1s_en_task[EBCCHS] = TASK_ENABLED;

        // Step in state machine.
        *state = WAIT_BCCHS_RESULT;

        // End of process.
        end_process = 1;
      }
      break;

      case WAIT_BCCHS_RESULT:
      {
        if(SignalCode == L1C_BCCHS_INFO)
        // Serving cell BCCH reading result.
        //----------------------------------
        {
          // Forward result message to L3.
          l1a_send_result(MPHC_DATA_IND, msg, RRM1_QUEUE);

          // End of process.
          return;
        }

        else
        if(SignalCode == MPHC_SCELL_NBCCH_REQ)
        // Request to re-configure Normal BCCH reading.
        //---------------------------------------------
        {
          // Step in state machine.
          *state = NBCCHS_CONFIG;
        }

        else
        if(SignalCode == MPHC_SCELL_EBCCH_REQ)
        // Request to re-configure Normal BCCH reading.
        //---------------------------------------------
        {
          // Step in state machine.
          *state = EBCCHS_CONFIG;
        }

        else
        if((SignalCode == MPHC_STOP_SCELL_BCCH_REQ) || (SignalCode == L1C_DEDIC_DONE))
        // Request to STOP any serving cell bcch activity.
        //------------------------------------------------
        {
          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_STOP_SCELL_BCCH_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        #if L1_GPRS
          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. BCCH 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
          // 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) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->Transfer_update == FALSE))
          // Transition IDLE -> Packet Transfer
          // Request to STOP serving cell BCCH activity.
          //--------------------------------------------
          {
            // Send confirmation message to L3.
            l1a_send_confirmation(MPHC_STOP_SCELL_BCCH_CON,RRM1_QUEUE);

            // This process must be reset.
            *state = RESET;
          }
          else
          if((SignalCode == L1P_TRANSFER_DONE) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->Transfer_update == TRUE))
          // Transition Packet Transfer -> Packet Transfer
          {
             // Remark: the synchro is handled by the task CTRL.
             // stay in the same state

             // End of process.
             return;
          }
        #endif

        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

/*-------------------------------------------------------*/
/* l1a_idle_serving_cell_paging_process()                */
/*-------------------------------------------------------*/
/* Description : This state machine handles paging       */
/*                                                       */
/* Starting messages:        MPHC_START_CCCH_REQ         */
/* ------------------                                    */
/*                                                       */
/*  L1 continuously reads the serving cell BCCH and/or   */
/*  Extended BCCH as requested by the scheduling info.   */
/*                                                       */
/* Result messages (input):  L1C_ALLC_INFO               */
/* ------------------------  L1C_NP_INFO                 */
/*                           L1C_EP_INFO                 */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_CCCH_REQ          */
/* -----------------------  (MPHC_STOP_CCCH_CON)         */
/*                                                       */
/*-------------------------------------------------------*/

/*
 * FreeCalypso Frankenstein: the source we got with LoCosto contains
 * some logic, apparently designed to increase opportunities for
 * deep sleep, marked with "Nina added" comments.  This addition by
 * Nina showed up on our radar because it makes use of a new member
 * in the l1s structure which is not present in the TCS211 version
 * of this data structure, which we are not allowed to change while
 * deblobbing L1 one module at a time.  I am going to turn Nina's
 * addition into a conditional compilation option. -- Mychaela
 */

#define	NINA_ADDED	0

#if NINA_ADDED
INT8 last_page_mode = 2; //REORG;
#endif

void l1a_idle_serving_cell_paging_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET             = 0,
    WAIT_INIT         = 1,
    WAIT_MSG          = 2
  };

  enum pg_modes
  {
    NORMAL            = 0,
    EXTENDED          = 1,
    REORG             = 2
  };

         UWORD8  *state      = &l1a.state[I_SCP];
         UWORD32  SignalCode = msg->SignalCode;
  static UWORD8   page_mode  = REORG;

  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[NP]   = TASK_DISABLED;  // Reset NP   task enable flag.
        l1a_l1s_com.l1s_en_task[EP]   = TASK_DISABLED;  // Reset EP   task enable flag.
        l1a_l1s_com.l1s_en_task[ALLC] = TASK_DISABLED;  // Reset ALLC (reorg) task enable flag.

        // No Paging  => no gauging => no Deep sleep
        //Nina modify to save power, not forbid deep sleep, only force gauging in next paging
#if NINA_ADDED
        if(l1s.force_gauging_next_paging_due_to_CCHR == 0) // Force gauging next paging
#endif
        l1s.pw_mgr.enough_gaug = FALSE;  // forbid Deep sleep

      }
      break;

      case WAIT_INIT:
      {
        if (SignalCode == MPHC_START_CCCH_REQ)
        {
          // download page mode from message (msg)
          page_mode = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_mode;
#if NINA_ADDED
if(((last_page_mode == NORMAL) && (page_mode == EXTENDED)) ||
	((last_page_mode == EXTENDED) && (page_mode == NORMAL)))
{
l1s.force_gauging_next_paging_due_to_CCHR = 1;
}
			last_page_mode = page_mode;
#endif

          if(page_mode == REORG)
          // Request to enter the PAGING REORGANIZATION paging mode.
          //--------------------------------------------------------
          // L1 must start the Serving cell paging monitoring in PAGING REORGANIZATION
          // paging mode. L1 starts reading the FULL BCCH and CCCH informations.
          {
            // Set semaphores for all serving cell tasks.
            l1a_l1s_com.task_param[ALLC] = SEMAPHORE_SET;   // Set ALLC task semaphore.
            l1a_l1s_com.task_param[NP]   = SEMAPHORE_SET;   // Set NP   task semaphore.

            // Set parameter synchro semaphore for I_BAMS task.
            // Rem: changing the paging parameters changes the place where I_BAMS
            //      task must be executed.
            l1a_l1s_com.meas_param |= I_BAMS_MEAS;

            // Download the PAGING PARAMETERS from the command message.
            l1a_l1s_com.bcch_combined    = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bcch_combined;
            l1a_l1s_com.bs_pa_mfrms      = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bs_pa_mfrms;
            l1a_l1s_com.bs_ag_blks_res   = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bs_ag_blks_res;
            l1a_l1s_com.ccch_group       = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->ccch_group;
            l1a_l1s_com.page_group       = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_group;
            l1a_l1s_com.page_block_index = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_block_index;

            /*----------------------------------------------------*/
            /* Download Idle parameters and Info in the Serving   */
            /* structure.                                         */
            /*----------------------------------------------------*/
            /* Rem: Get Idle Information from ROM table. Get nbr  */
            /* of paging blocks in a MF51 from ROM table.         */
            /*   "nb_pch_per_mf51" = N div BS_PA_MFRMS.           */
            /*   "idle_task_info"  = info about PCH, EXT_PCH and  */
            /*                       other task to settle in IM.  */
            /*----------------------------------------------------*/
            if(l1a_l1s_com.bcch_combined == TRUE)
            {
              l1a_l1s_com.idle_task_info  =
                IDLE_INFO_COMB[(l1a_l1s_com.bs_ag_blks_res * (MAX_PG_BLOC_INDEX_COMB+1)) +
                               (l1a_l1s_com.page_block_index)];
              l1a_l1s_com.nb_pch_per_mf51 =
                NBPCH_IN_MF51_COMB[l1a_l1s_com.bs_ag_blks_res];
            }
            else
            {
              l1a_l1s_com.idle_task_info  =
                IDLE_INFO_NCOMB[(l1a_l1s_com.bs_ag_blks_res * (MAX_PG_BLOC_INDEX_NCOMB+1)) +
                                (l1a_l1s_com.page_block_index)];
              l1a_l1s_com.nb_pch_per_mf51 =
                NBPCH_IN_MF51_NCOMB[l1a_l1s_com.bs_ag_blks_res];
            }

            // 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
            // the "ccch_group" 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 += (2 * l1a_l1s_com.ccch_group) - l1a_l1s_com.dl_tn;
              l1a_l1s_com.dl_tn         = 2 * l1a_l1s_com.ccch_group;  // Save new TN id.

              #if L1_GPRS
                // Select GSM DSP Scheduler.
                l1a_l1s_com.dsp_scheduler_mode = GSM_SCHEDULER;
              #endif

              // Timing must be shifted to a new timeslot, enables SYNCHRO task..
              l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;   // Set SYNCHRO task enable flag.
            }

            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.

            // In paging reorganization, Full BCCH reading must be setup.
            l1a_l1s_com.Scell_info.si_bit_map = ALL_SI;

            // Step in state machine.
            *state = WAIT_MSG;

            // Enable Paging Reorganisation tasks.
            l1a_l1s_com.l1s_en_task[NP]   = TASK_ENABLED;      // Set NP task enable flag.
            l1a_l1s_com.l1s_en_task[ALLC] = TASK_ENABLED;      // Set ALLC (for paging reorg) task enable flag.

            // End of process.
            return;
          }

          else
          if(page_mode == NORMAL)
          {
            // Request to enter the NORMAL PAGING paging mode.
            //------------------------------------------------
            // L1 must start the Serving cell paging monitoring in NORMAL PAGING
            // paging mode. L1 starts reading only its own paging subchannel.

            #if (TRACE_TYPE==3)
              if (l1_stats.type == FER_CCCH || l1_stats.type == FER_CCCH_TN246)
                l1_stats.wait_time = 0;
            #endif

            // Disable the paging reorganization tasks.
            l1a_l1s_com.l1s_en_task[NP]   = TASK_DISABLED;  // Reset NP   task enable flag.
            l1a_l1s_com.l1s_en_task[ALLC] = TASK_DISABLED;  // Reset ALLC (reorg) task enable flag.

            // Set parameter synchro semaphore for I_BAMS task.
            // Rem: changing the paging parameters changes the place where I_BAMS
            //      task must be executed.
            l1a_l1s_com.meas_param |= I_BAMS_MEAS;

            // Set semaphores for the normal paging reading task.
            l1a_l1s_com.task_param[NP] = SEMAPHORE_SET;     // Set NP   task semaphore.

            // Download the PAGING PARAMETERS from the command message.
            l1a_l1s_com.bcch_combined    = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bcch_combined;
            l1a_l1s_com.bs_pa_mfrms      = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bs_pa_mfrms;
            l1a_l1s_com.bs_ag_blks_res   = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bs_ag_blks_res;
            l1a_l1s_com.ccch_group       = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->ccch_group;
            l1a_l1s_com.page_group       = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_group;
            l1a_l1s_com.page_block_index = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_block_index;

            /*----------------------------------------------------*/
            /* Download Idle parameters and Info in the Serving   */
            /* structure.                                         */
            /*----------------------------------------------------*/
            /* Rem: Get Idle Information from ROM table. Get nbr  */
            /* of paging blocks in a MF51 from ROM table.         */
            /*   "nb_pch_per_mf51" = N div BS_PA_MFRMS.           */
            /*   "idle_task_info"  = info about PCH, EXT_PCH and  */
            /*                       other task to settle in IM.  */
            /*----------------------------------------------------*/
            if(l1a_l1s_com.bcch_combined == TRUE)
            {
              l1a_l1s_com.idle_task_info  =
                IDLE_INFO_COMB[(l1a_l1s_com.bs_ag_blks_res * (MAX_PG_BLOC_INDEX_COMB+1)) +
                               (l1a_l1s_com.page_block_index)];
              l1a_l1s_com.nb_pch_per_mf51 =
                NBPCH_IN_MF51_COMB[l1a_l1s_com.bs_ag_blks_res];
            }
            else
            {
              l1a_l1s_com.idle_task_info  =
                IDLE_INFO_NCOMB[(l1a_l1s_com.bs_ag_blks_res * (MAX_PG_BLOC_INDEX_NCOMB+1)) +
                                (l1a_l1s_com.page_block_index)];
              l1a_l1s_com.nb_pch_per_mf51 =
                NBPCH_IN_MF51_NCOMB[l1a_l1s_com.bs_ag_blks_res];
            }


          #if L1_GPRS
            //In case of network mode of operation II or III, CCCH reading is possible
            //in packet idle mode and in packet transfer mode.
            //But the SYNCHRO task is not used anymore as opposite to CS mode for CCCH readings
            if (!((l1a_l1s_com.l1s_en_task[PNP]    == TASK_ENABLED) ||
                  (l1a_l1s_com.l1s_en_task[PEP]    == TASK_ENABLED) ||
                  (l1a_l1s_com.l1s_en_task[PALLC]  == TASK_ENABLED) ||
                  (l1a_l1s_com.l1s_en_task[PDTCH]  == TASK_ENABLED) ||
                  (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))

          #endif
            {

              // 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 stay on the same serving cell but change the RX timeslot
              // (CCCH_GROUP or timeslot), then the "timeslot difference" between new
              // and old configuration is given in "tn_difference".
              //   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 += (2 * l1a_l1s_com.ccch_group) - l1a_l1s_com.dl_tn;
                l1a_l1s_com.dl_tn          = 2 * l1a_l1s_com.ccch_group;  // Save new TN id.

                #if L1_GPRS
                  // Select GSM DSP Scheduler.
                   l1a_l1s_com.dsp_scheduler_mode = GSM_SCHEDULER;

                 // Timing must be shifted to a new timeslot, enables SYNCHRO task..
                  l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;   // Set SYNCHRO task enable flag.
                #else
                  if(l1a_l1s_com.tn_difference != 0)
                  // Timing must be shifted to a new timeslot, enables SYNCHRO task..
                  {
                    l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;  // Set SYNCHRO task enable flag.
                  }
                #endif
              }
              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;

            // Enable normal paging mode.
            l1a_l1s_com.l1s_en_task[NP] = TASK_ENABLED;     // Set NP task enable flag.

            // End of process.
            return;
          }
          else
          {
            // No action for other page mode
            return;
          }
        }//if (SignalCode == MPHC_START_CCCH_REQ)
        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          end_process = 1;
        }
      }
      break;

      case WAIT_MSG:
      {
        if(SignalCode == MPHC_START_CCCH_REQ)
        {
          // download paging mode from msg
          page_mode = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_mode;
#if NINA_ADDED

			if(((last_page_mode == NORMAL) && (page_mode == EXTENDED)) ||
				((last_page_mode == EXTENDED) && (page_mode == NORMAL)))
			{
			l1s.force_gauging_next_paging_due_to_CCHR = 1;
			}
			last_page_mode = page_mode;
#endif
          if ((page_mode == NORMAL) || (page_mode == REORG))
          {
            // Step in state machine.
            *state = RESET;
          }
          else if (page_mode == EXTENDED)
          {
            // Request to enter the EXTENDED PAGING paging mode.
            //------------------------------------------------

            #if (TRACE_TYPE==3)
              if (l1_stats.type == FER_CCCH || l1_stats.type == FER_CCCH_TN246)
                l1_stats.wait_time = 0;
            #endif

            // Disable the paging reorganization tasks.
            l1a_l1s_com.l1s_en_task[NP]   = TASK_DISABLED;  // Reset NP   task enable flag.
            l1a_l1s_com.l1s_en_task[ALLC] = TASK_DISABLED;  // Reset ALLC (reorg) task enable flag.

            // Set parameter synchro semaphore for I_BAMS task.
            // Rem: changing the paging parameters changes the place where I_BAMS
            //      task must be executed.
            l1a_l1s_com.meas_param |= I_BAMS_MEAS;

            // Set semaphores for the normal/extended paging reading task.
            l1a_l1s_com.task_param[NP] = SEMAPHORE_SET;     // Set NP   task semaphore.
            l1a_l1s_com.task_param[EP] = SEMAPHORE_SET;     // Set EP   task semaphore.

            // Download the PAGING PARAMETERS from the command message.
            l1a_l1s_com.bcch_combined    = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bcch_combined;
            l1a_l1s_com.bs_pa_mfrms      = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bs_pa_mfrms;
            l1a_l1s_com.bs_ag_blks_res   = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->bs_ag_blks_res;
            l1a_l1s_com.ccch_group       = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->ccch_group;
            l1a_l1s_com.page_group       = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_group;
            l1a_l1s_com.page_block_index = ((T_MPHC_START_CCCH_REQ *)(msg->SigP))->page_block_index;

            /*----------------------------------------------------*/
            /* Download Idle parameters and Info in the Serving   */
            /* structure.                                         */
            /*----------------------------------------------------*/
            /* Rem: Get Idle Information from ROM table. Get nbr  */
            /* of paging blocks in a MF51 from ROM table.         */
            /*   "nb_pch_per_mf51" = N div BS_PA_MFRMS.           */
            /*   "idle_task_info"  = info about PCH, EXT_PCH and  */
            /*                       other task to settle in IM.  */
            /*----------------------------------------------------*/
            if(l1a_l1s_com.bcch_combined == TRUE)
            {
              l1a_l1s_com.idle_task_info  =
                IDLE_INFO_COMB[(l1a_l1s_com.bs_ag_blks_res * (MAX_PG_BLOC_INDEX_COMB+1)) +
                               (l1a_l1s_com.page_block_index)];
              l1a_l1s_com.nb_pch_per_mf51 =
                NBPCH_IN_MF51_COMB[l1a_l1s_com.bs_ag_blks_res];
            }
            else
            {
              l1a_l1s_com.idle_task_info  =
                IDLE_INFO_NCOMB[(l1a_l1s_com.bs_ag_blks_res * (MAX_PG_BLOC_INDEX_NCOMB+1)) +
                                (l1a_l1s_com.page_block_index)];
              l1a_l1s_com.nb_pch_per_mf51 =
                NBPCH_IN_MF51_NCOMB[l1a_l1s_com.bs_ag_blks_res];
            }


            #if L1_GPRS
              //In case of network mode of operation II or III, CCCH reading is possible
              //in packet idle mode and in packet transfer mode.
              //But the SYNCHRO task is not used anymore as opposite to CS mode for CCCH readings
              if (!((l1a_l1s_com.l1s_en_task[PNP]    == TASK_ENABLED) ||
                    (l1a_l1s_com.l1s_en_task[PEP]    == TASK_ENABLED) ||
                    (l1a_l1s_com.l1s_en_task[PALLC]  == TASK_ENABLED) ||
                    (l1a_l1s_com.l1s_en_task[PDTCH]  == TASK_ENABLED) ||
                    (l1a_l1s_com.l1s_en_task[SINGLE] == TASK_ENABLED)))
            #endif
            {
            // 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 stay on the same serving cell but change the RX timeslot
            // (CCCH_GROUP or timeslot), then the "timeslot difference" between new
            // and old configuration is given in "tn_difference".
            //   tn_difference -> loaded with the number of timeslot to shift.
            //   dl_tn         -> loaded with the new timeslot.

            // Layer 1 internal mode is set to IDLE MODE.

              l1a_l1s_com.mode = I_MODE;

              l1a_l1s_com.task_param[SYNCHRO] = SEMAPHORE_SET;
              {
                l1a_l1s_com.tn_difference += (2 * l1a_l1s_com.ccch_group) - l1a_l1s_com.dl_tn;
                l1a_l1s_com.dl_tn          =  2 * l1a_l1s_com.ccch_group;  // Save new TN id.

                #if L1_GPRS
                  // Select GSM DSP Scheduler.
                  l1a_l1s_com.dsp_scheduler_mode = GSM_SCHEDULER;

                  // Timing must be shifted to a new timeslot, enables SYNCHRO task..
                  l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;   // Set SYNCHRO task enable flag.
                #else
                  if(l1a_l1s_com.tn_difference != 0)
                  // Timing must be shifted to a new timeslot, enables SYNCHRO task..
                  {
                    l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;   // Set SYNCHRO task enable flag.
                  }
                #endif
              }
              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.
            }

            // Enable normal/extended paging mode.
            l1a_l1s_com.l1s_en_task[NP] = TASK_ENABLED;  // Set NP task enable flag.
            l1a_l1s_com.l1s_en_task[EP] = TASK_ENABLED;  // Set EP task enable flag also.

            // Paging parameters change => perform the gauging on the next paging
        //Nina modify to save power, not forbid deep sleep, only force gauging in next paging
#if NINA_ADDED
if(l1s.force_gauging_next_paging_due_to_CCHR == 0)
#endif
l1s.pw_mgr.enough_gaug = FALSE;  // forbid Deep sleep until next gauging
//End Nina modify


            // end of process
            return;
          }//end if (page_mode == EXTENDED)
        }// end if(SignalCode == MPHC_START_CCCH_REQ)

        else
        if((SignalCode == L1C_ALLC_INFO) ||
           (SignalCode == L1C_NP_INFO)   ||
           (SignalCode == L1C_EP_INFO))
        // Paging reorganization tasks results.
        //-------------------------------------
        {
          // Forward result message to L3.
          l1a_send_result(MPHC_DATA_IND, msg, RRM1_QUEUE);

          // End of process.
          return;
        }

        else
        if((SignalCode == MPHC_STOP_CCCH_REQ) || (SignalCode == L1C_DEDIC_DONE))
        // Request to STOP any serving cell paging activity.
        //--------------------------------------------------
        {
          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_STOP_CCCH_CON,RRM1_QUEUE);
          // This process must be reset.
          *state = RESET;
        }

        #if L1_GPRS
          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. CCCH 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
          // End of packet transfer mode
          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) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->Transfer_update == FALSE))
          // Transition IDLE -> Packet Transfer
          // Request to STOP serving cell CCCH activity.
          //--------------------------------------------
          {
            // Send confirmation message to L3.
            l1a_send_confirmation(MPHC_STOP_CCCH_CON,RRM1_QUEUE);
            // This process must be reset.
            *state = RESET;
          }
          else
          if((SignalCode == L1P_TRANSFER_DONE) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->Transfer_update == TRUE))
          // Transition Packet Transfer -> Packet Transfer
          {
              // Remark: the synchro is handled by the task CTRL.
              // stay in the same state

            // End of process.
             return;
          }
        #endif

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          end_process = 1;
        }
      }// end case WAIT_MSG
      break;
    } // end of "switch".
  } // end of "while"
} // end of procedure.

//#pragma GSM_IDLE_DUPLICATE_FOR_INTERNAL_RAM_END
#endif


/*-------------------------------------------------------*/
/* l1a_initial_network_sync_process()                    */
/*-------------------------------------------------------*/
/* Description : This state machine handles the 1st      */
/* synchronization with the network.                     */
/*                                                       */
/* Starting messages:        MPHC_NETWORK_SYNC_REQ       */
/*                                                       */
/* Result messages (input):  L1C_FB_INFO                 */
/*                           L1C_SB_INFO                 */
/*                                                       */
/* Result messages (output): MPHC_NETWORK_SYNC_IND       */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_NETWORK_SYNC_REQ  */
/*                          (MPHC_STOP_NETWORK_SYNC_CON) */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_initial_network_sync_process(xSignalHeaderRec *msg)
{

  enum states
  {
    RESET               =  0,  // Reset state.
    WAIT_INIT           =  1,  // Initial state.

    SET_FS_FB1_MODE0    =  2,  // First Synchro, Setting of 1st FB mode 0.
    WAIT_FS_FB1_MODE0   =  3,  // First Synchro, 1st FB mode 0 state.

    SET_FS_FB2_MODE0    =  10,  // First Synchro, Setting of 2nd FB mode 0.
    WAIT_FS_FB2_MODE0   =  11,  // First Synchro, 2nd FB mode 0 state.
    SET_FS_FB_MODE1     =  12,  // First Synchro, Setting of FB mode 1.
    WAIT_FS_FB_MODE1    =  13,  // First Synchro, FB mode 1 state.
    WAIT_FS_SB          =  14,  // First Synchro, SB state.

    SET_FB_MODE1        =  15,  // Setting of FB mode 1.
    WAIT_FB_MODE1       =  16,  // FB mode 1 (freq. in tracking) state.
    WAIT_SB             =  17,  // SB state.
    WAIT_BCCHS          =  18   // BCCHS state.
  };


  #if (VCXO_ALGO == 1)
    #define FS_FB1_MODE0_CENTER   1
    #define FS_FB1_MODE0_MAX      2
    #define FS_FB1_MODE0_MIN      3

    static  UWORD32  state_vcxo;
  #endif

  UWORD8  *state      = &l1a.state[CS_NORM];
  UWORD32  SignalCode = msg->SignalCode;

  static WORD16   static_attempt_counter_0;
  static WORD16   static_attempt_counter_1;


  static UWORD8   static_sb_found_flag;
  static UWORD8   static_bsic;
  static UWORD32  static_fn_offset;
  static UWORD32  static_time_alignmt;
  static UWORD8   static_timing_validity;

  // to keep track of the old AFC value
  static WORD16 old_afc;

  while(1)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset tasks used in the process.
        l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;

        // Disable neighbour sync 0.
        l1a_l1s_com.nsync.list[0].status = NSYNC_FREE;
      }
      break;

      case WAIT_INIT:
      {
        if(SignalCode == MPHC_NETWORK_SYNC_REQ)
        // Request to READ the FULL BCCH on the given carrier.
        //----------------------------------------------------
        // L1 must first synchronize with the given carrier and then start
        // reading the FULL BCCH.
        {
          UWORD8  search_mode = ((T_MPHC_NETWORK_SYNC_REQ *)(msg->SigP))->search_mode;
           #if L1_FF_WA_OMAPS00099442
            // reset TPU offset to current value + half a TDMA to avoid having the Fb burst at the begining of the FBNEW TPU window
            // This can be done safely in L1A at this point
            //l1s.tpu_offset = (l1s.tpu_offset + TPU_CLOCK_RANGE >> 1 ) % TPU_CLOCK_RANGE;
            //l1dmacro_synchro(IMM, l1s.tpu_offset);
          #endif

          // Set task semaphores.
          l1a_l1s_com.task_param[NSYNC] = SEMAPHORE_SET;
          l1a_l1s_com.task_param[FBNEW] = SEMAPHORE_SET;
          l1a_l1s_com.task_param[SB2]   = SEMAPHORE_SET;

          l1a_l1s_com.nsync.current_list_size = 0;

          // Downlink stuff timeslot is 0 (default in CS)
          l1a_l1s_com.dl_tn = 0;

          // Download neighbour info from request message.
          //----------------------------------------------

          l1a_l1s_com.nsync.list[0].radio_freq      = ((T_MPHC_NETWORK_SYNC_REQ *)(msg->SigP))->radio_freq;
          
#if (L1_FF_MULTIBAND== 1)
          {
            UWORD8 physical_band_id;
            physical_band_id = l1_multiband_radio_freq_convert_into_physical_band_id(l1a_l1s_com.nsync.list[0].radio_freq);
            L1_MULTIBAND_TRACE_PARAMS(MULTIBAND_PHYSICAL_BAND_TRACE_ID,multiband_rf[physical_band_id].gsm_band_identifier);
          }
#endif /*#if (L1_FF_MULTIBAND == 1)*/
          
          l1a_l1s_com.nsync.list[0].timing_validity = ((T_MPHC_NETWORK_SYNC_REQ *)(msg->SigP))->timing_validity;
        #if ((REL99 == 1) && (FF_RTD == 1)) // RTD feature
          // In this case that timing information is provided related to Real Time Difference RTD of the cell.
          // We force the timing_validity to no timing information because there is no special mechanism to take into
          // account RTD information in idle mode. So it is preferable to do a complete FB search than
          // using inaccurate timing in a bad way.

          if(l1a_l1s_com.nsync.list[0].timing_validity == 3)  // force complete search
            l1a_l1s_com.nsync.list[0].timing_validity = 0 ;

        #endif

          static_timing_validity = l1a_l1s_com.nsync.list[0].timing_validity;

          if(l1a_l1s_com.nsync.list[0].timing_validity != 0)
          {
            UWORD32  time_alignmt;
            UWORD32  fn_offset;

            // Download ARFCN, timing information and bitmap from the command message.
            time_alignmt   = ((T_MPHC_NETWORK_SYNC_REQ *)(msg->SigP))->time_alignmt;
            fn_offset      = ((T_MPHC_NETWORK_SYNC_REQ *)(msg->SigP))->fn_offset;

            // Sub the serving cell timeslot number to the Neigh./Serving timing
            // difference to format it for L1S use.
            l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
            l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

            l1a_l1s_com.nsync.list[0].fn_offset    = fn_offset;
            l1a_l1s_com.nsync.list[0].time_alignmt = time_alignmt;
          }
          else
          {
            l1a_l1s_com.nsync.list[0].fn_offset    = 0;
            l1a_l1s_com.nsync.list[0].time_alignmt = 0;
          }

          // Reset attempt counters
          static_attempt_counter_0 = 0;
          #if (TRACE_TYPE==3)
            if (l1_stats.type == FER_FCH_MODE1)
              search_mode = 1;
            else
              search_mode = 0;
          #endif

          // Set functional mode.
          l1a_l1s_com.mode = CS_MODE;
          #if L1_FF_WA_OMAPS00099442
            l1a_l1s_com.change_tpu_offset_flag = TRUE;
          #endif

          #if L1_GPRS
            // Select GSM DSP Scheduler.
            l1a_l1s_com.dsp_scheduler_mode = GSM_SCHEDULER;

            // Timing must be shifted to a new timeslot, enables SYNCHRO task..
            l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;   // Set SYNCHRO task enable flag.
          #else
            // Enable SYNCHRO task to cleanup the MFTAB.
            l1a_l1s_com.l1s_en_task[SYNCHRO] = TASK_ENABLED;
          #endif

          if(search_mode == 0)
          // Run "FIRST SYNCHRO" algorithme.
          //--------------------------------
          {
            // Step in state machine.
            #if (VCXO_ALGO == 1)
              if ((l1_config.params.afc_algo == ALGO_AFC_LQG_PREDICTOR) ||
                  (l1_config.params.afc_algo == ALGO_AFC_KALMAN_PREDICTOR))
                  state_vcxo = FS_FB1_MODE0_CENTER;
            #endif
                *state = SET_FS_FB1_MODE0;

          }

          else
          // Run "Frequency in Tracking" algorithme.
          //----------------------------------------
          {
            // Step in state machine.
            *state = SET_FB_MODE1;
          }
        }

        // No action in this machine for other messages.
        //----------------------------------------------
        else
        {
          // End of process.
          return;
        }
      }
      break;

      case SET_FS_FB1_MODE0:
        {

        if(static_attempt_counter_0 >= 4)
        // Max number of FB1/Mode0 attempt is reached... Stop process.
        {
          #if (VCXO_ALGO == 1)
            if ((l1_config.params.afc_algo == ALGO_AFC_LQG_PREDICTOR) ||
                (l1_config.params.afc_algo == ALGO_AFC_KALMAN_PREDICTOR))
            {
              if (state_vcxo == FS_FB1_MODE0_CENTER)
              {
                // update vcxo state, reset attempts FB1_MODE0
                state_vcxo = FS_FB1_MODE0_MAX;
                static_attempt_counter_0 = 0;
                break;
              }
              else if (state_vcxo == FS_FB1_MODE0_MAX)
              {
                // update vcxo state, reset attempts FB1_MODE0
                state_vcxo = FS_FB1_MODE0_MIN;
                static_attempt_counter_0 = 0;
                break;
              }
            }
          #endif
          // Send reporting message with a faillure indication.
          l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);

          // Reset state machine.
          *state = RESET;
        }

        else
        // Make a new attempt FB1/mode0.
        {
          // Step in state machine.
          *state = WAIT_FS_FB1_MODE0;
          // Enable neighbour sync 0.
          l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

          // Wideband search for FB detection.
          l1a_l1s_com.fb_mode = FB_MODE_0;

          // Initialize AFC control function.
          #if AFC_ALGO
            #if TESTMODE
              if (l1_config.afc_enable)
            #endif
              {
                #if (VCXO_ALGO == 1)
                  if ((l1_config.params.afc_algo == ALGO_AFC_LQG_PREDICTOR) ||
                      (l1_config.params.afc_algo == ALGO_AFC_KALMAN_PREDICTOR))
                  {
                    if (state_vcxo == FS_FB1_MODE0_CENTER)
                      l1s.afc = l1ctl_afc(AFC_INIT_CENTER, &l1s.afc_frame_count, l1_config.params.eeprom_afc, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode);
                    else
                    if (state_vcxo == FS_FB1_MODE0_MAX)
                      l1s.afc = l1ctl_afc(AFC_INIT_MAX, &l1s.afc_frame_count, l1_config.params.eeprom_afc, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode);
                    else
                    if (state_vcxo == FS_FB1_MODE0_MIN)
                      l1s.afc = l1ctl_afc(AFC_INIT_MIN, &l1s.afc_frame_count, l1_config.params.eeprom_afc, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode);
                  }
                  else
                   l1s.afc = l1ctl_afc(AFC_INIT, &l1s.afc_frame_count, l1_config.params.eeprom_afc, 0, l1a_l1s_com.nsync.list[0].radio_freq,l1a_l1s_com.mode);
                #else
                  l1s.afc = l1ctl_afc(AFC_INIT, &l1s.afc_frame_count, l1_config.params.eeprom_afc, 0, l1a_l1s_com.nsync.list[0].radio_freq);
                #endif
              }
          #endif

          // Restart synch process as initialized by L3->L1 msg
          l1a_l1s_com.nsync.list[0].timing_validity = static_timing_validity;

          // Enable NSYNC task for FB detection mode 0.
          l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

          // End of process.
          return;
        }
      }
      break;

      case WAIT_FS_FB1_MODE0:
      {
        if(SignalCode == L1C_FB_INFO)
        // Frequency Burst acquisition result.
        //------------------------------------
        {
          UWORD8  fb_found;

          // Increment "static_attempt_counter_0".
          static_attempt_counter_0++;

          // Get result from message parameters.
          fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

          // Loop on FB reception when making statistics.
          #if (TRACE_TYPE==3)
            if (l1_stats.type == FER_FCH_MODE0 || l1_stats.type == FER_FCH_MODE1)
            {
               // Enable FB_new.
               l1a_l1s_com.l1s_en_task[FBNEW] = TASK_ENABLED;  // Set FB_new task enable flag.

               // End of process.
               return;
            }
          #endif

          if(fb_found == TRUE)
          // FB attempt is a success.
          //-------------------------
          {
            // Stop the search in this current interval
            #if (VCXO_ALGO == 1)
              static_attempt_counter_0 = 4;
            #endif
            // Reset "static_attempt_counter_1".
            static_attempt_counter_1 = 0;

            // We consider the result of this successfull FB search attempt
            // as a good a-priori information for next attempt.
            // "fn_offset" is reversed to satisfy its definition,
            //    fn_offset = Fn_neigh - Fn_serving.

            l1a_l1s_com.nsync.list[0].timing_validity = 1;
            l1a_l1s_com.nsync.list[0].fn_offset       = 51 - l1a_l1s_com.nsync.list[0].fn_offset;

            // Step in state machine.
            *state = SET_FS_FB2_MODE0;
          }

          else
          // FB attempt failled.
          //--------------------
          {
            // Step in state machine.
            *state = SET_FS_FB1_MODE0;
          }
        }

        else
        if(SignalCode == MPHC_STOP_NETWORK_SYNC_REQ)
        // Request to STOP reading the FULL BCCH.
        //---------------------------------------
        {
          l1a_send_confirmation(MPHC_STOP_NETWORK_SYNC_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      case SET_FS_FB2_MODE0:
      {
        if (static_attempt_counter_1 >= 4)
        // Max number of attempt is reached... go back to 1st FB mode 0.
        // otherwise stop the search and report message with failure indication
        #if (VCXO_ALGO == 1)
        {
          if (state_vcxo == FS_FB1_MODE0_MIN)
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);
            // Reset state machine.
            *state = RESET;
          }
          else
          {
            // Step in state machine.
            *state = SET_FS_FB1_MODE0;
          }
        }
        #else  // VCXO_ALGO
        {
          // Send reporting message with a faillure indication.
          l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);
          // Reset state machine.
          *state = RESET;
        }
        #endif // VCXO_ALGO
        else
        // Make a new attempt FB2/mode0.
        {
          // Step in state machine.
          *state = WAIT_FS_FB2_MODE0;

          // Enable neighbour sync 0.
          l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

          // End of process.
          return;
        }

      }
      break;

      case WAIT_FS_FB2_MODE0:
      {
        // Use incoming message.
        //----------------------
        if(SignalCode == L1C_FB_INFO)
        {
          UWORD8  fb_found;

          // Increment "static_attempt_counter_1".
          static_attempt_counter_1++;

          // Get result from message parameters.
          fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

          if(fb_found == TRUE)
          // FB attempt is a success.
          //-------------------------
          {
            // Reset "static_attempt_counter_1".
            static_attempt_counter_1 = 0;

            // We consider the result of this successfull FB search attempt
            // as a good a-priori information for next attempt.
            // "fn_offset" is reversed to satisfy its definition,
            //    fn_offset = Fn_neigh - Fn_serving.

            l1a_l1s_com.nsync.list[0].timing_validity = 1;
            l1a_l1s_com.nsync.list[0].fn_offset       = 51 - l1a_l1s_com.nsync.list[0].fn_offset;

            // Step in state machine.
            *state = SET_FS_FB_MODE1;
          }

          else
          // FB attempt failed.
          //-------------------
          {
            // Step in state machine.
            *state = SET_FS_FB2_MODE0;
          }
        }

        else
        if(SignalCode == MPHC_STOP_NETWORK_SYNC_REQ)
        // Request to STOP reading the FULL BCCH.
        //---------------------------------------
        {
          l1a_send_confirmation(MPHC_STOP_NETWORK_SYNC_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;


      case SET_FS_FB_MODE1:
      {
        if(static_attempt_counter_1 >= 4)
        // Max number of attempt is reached... go back to 1st FB mode 0.
        // otherwise stop the search and report message with failure indication
        #if (VCXO_ALGO == 1)
        {
          if (state_vcxo == FS_FB1_MODE0_MIN)
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);
            // Reset state machine.
            *state = RESET;
          }
          else
          {
            // Step in state machine.
            *state = SET_FS_FB1_MODE0;
          }
        }
        #else  // VCXO_ALGO
        {
          // Send reporting message with a faillure indication.
          l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);
          // Reset state machine.
          *state = RESET;
        }
        #endif // VCXO_ALGO

        else
        // Make a new attempt FB/Mode1.
        {
          // Step in state machine.
          *state = WAIT_FS_FB_MODE1;

          // Set FB detection mode.
          l1a_l1s_com.fb_mode = FB_MODE_1;

          // Enable neighbour sync 0.
          l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

          // End of process.
          return;
        }
      }
      break;


      case WAIT_FS_FB_MODE1:
      {
        // Use incoming message.
        //----------------------
        if(SignalCode == L1C_FB_INFO)
        {
          UWORD8  fb_found;

          // Increment "static_attempt_counter_1".
          static_attempt_counter_1++;

          // get result from message parameters.
          fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

          if(fb_found == TRUE)
          // FB attempt is a success.
          //-------------------------
          {
            // Reset "static_attempt_counter_1".
            static_attempt_counter_1 = 0;

            // Reset "static_sb_found_flag".
            static_sb_found_flag = FALSE;

            // Step in state machine.
            *state = WAIT_FS_SB;

            // WE SHOULD UPDATE THE APRIORI TIMING.

            // Enable NSYNC task for SB detection (SB2).
          #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
            l1a_l1s_com.nsync.list[0].timing_validity = SB_ACQUISITION_PHASE;
          #else
            l1a_l1s_com.nsync.list[0].timing_validity = 3;
          #endif
            // Enable neighbour sync 0.
            l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

            // End of process.
            return;
          }

          else
          // FB attempt failed.
          //-------------------
          {
            // Step in state machine.
            *state = SET_FS_FB_MODE1;
          }
        }

        else
        if(SignalCode == MPHC_STOP_NETWORK_SYNC_REQ)
        // Request to STOP reading the FULL BCCH.
        //---------------------------------------
        {
          l1a_send_confirmation(MPHC_STOP_NETWORK_SYNC_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      case WAIT_FS_SB:
      {
        // Use incoming message.
        //----------------------
        if(SignalCode == L1C_SB_INFO)
        {
          UWORD8  sb_found = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->sb_flag;
          UWORD8  bsic     = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->bsic;

          // Increment "static_attempt_counter_1".
          static_attempt_counter_1++;

          if(sb_found == TRUE)
          // SB detection is a success...
          //-----------------------------
          {
            // Save Results.
            static_sb_found_flag = TRUE;
            static_bsic          = bsic;
            static_fn_offset     = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset;
            static_time_alignmt  = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt;
          }

          if(static_attempt_counter_1 >= 8)
          {
            #if (TRACE_TYPE==3)
              // Loop on FB mode 1 detection when making SB statistics.
              if (l1_stats.type == FER_SCH)
              {
                // Reset SB2 task enable flag.
                l1a_l1s_com.l1s_en_task[SB2] = TASK_DISABLED;
                // Reset "static_attempt_counter_1".
                static_attempt_counter_1 = 0;
                // go back to FB mode 1 detection...
                *state = SET_FS_FB_MODE1;
                break;
              }
            #endif


            // Disable NSYNC task.
            l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;

            if(static_sb_found_flag == TRUE)
            // SB detection is a success.
            //----------------------------
            {
              // Save results.
              l1a_l1s_com.nsync.list[0].fn_offset    = static_fn_offset;
              l1a_l1s_com.nsync.list[0].time_alignmt = static_time_alignmt;

              // Correct "ntdma" and "time_alignment" to shift 20 bit to the
              // futur for Normal Burst reading tasks.
              l1a_add_time_for_nb(&l1a_l1s_com.nsync.list[0].time_alignmt,
                                  &l1a_l1s_com.nsync.list[0].fn_offset);

              // 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.
              // 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 = 0; // No timeslot shift to be performed.
              l1a_l1s_com.dl_tn         = 0; // Camping on timeslot 0.
              }
              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.

              // Clear "time_alignmt, fn_offset" in the result message since we are
              // going to camp on that cell.
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset    = l1a_l1s_com.nsync.list[0].fn_offset;
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt = l1a_l1s_com.nsync.list[0].time_alignmt;
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->sb_flag      = static_sb_found_flag;
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->bsic         = static_bsic;

              // Forward result message to L3.
              l1a_send_result(MPHC_NETWORK_SYNC_IND, msg, RRM1_QUEUE);
              // keep in memory the last good AFC value
              old_afc = l1s.afc;

              // Set flag for toa init.
              #if (TOA_ALGO != 0)
                l1a_l1s_com.toa_reset = TRUE;
              #endif

              // End of this process.
              *state = RESET;
            }

            else
            // SB detection failed.
            //---------------------
            {
                // Send reporting message with a faillure indication.
                l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);

                // Reset state machine.
                *state = RESET;
            }
          }

          else
          // Make a new attempt SB.
          {
            // Enable neighbour sync 0.
            l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

            // End of process.
            return;
          }
        }

        else
        if(SignalCode == MPHC_STOP_NETWORK_SYNC_REQ)
        // Request to STOP reading the FULL BCCH.
        //---------------------------------------
        {
          l1a_send_confirmation(MPHC_STOP_NETWORK_SYNC_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      // In case of narrowband search

      case SET_FB_MODE1:
      {
        if (static_attempt_counter_0 >= 4)
        // Max number of FB/Mode1 attempt is reached... Stop process.
        {
          // Send reporting message with a faillure indication.
          l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);

          // Reset state machine.
          *state = RESET;
        }

        else
        // Make a new attempt FB/Mode1.
        {
          // Step in state machine.
          *state = WAIT_FB_MODE1;

          // Set FB detection mode.
          l1a_l1s_com.fb_mode = FB_MODE_1;

          // Enable neighbour sync 0.
          l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

          // Restart synch process as initialized by L3->L1 msg
          l1a_l1s_com.nsync.list[0].timing_validity = static_timing_validity;

          // Enable NSYNC for FB detection mode 1.
          l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

          // End of process.
          return;
        }
      }
      break;

      case WAIT_FB_MODE1:
      {
        // Use incoming message.
        //----------------------
        if(SignalCode == L1C_FB_INFO)
        {
          UWORD8  fb_found;

          // Increment "static_attempt_counter_0".
          static_attempt_counter_0++;

          // get result from message parameters.
          fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

          // Loop on FB reception when making statistics.
          #if (TRACE_TYPE==3)
            if (l1_stats.type == FER_FCH_MODE0 || l1_stats.type == FER_FCH_MODE1 )
            {
               // Enable FB_new.
               l1a_l1s_com.l1s_en_task[FBNEW] = TASK_ENABLED;  // Set FB_new task enable flag.

               // End of process.
               return;
            }
          #endif

          if(fb_found == TRUE)
          // FB attempt is a success.
          //-------------------------
          {
            // Reset "static_attempt_counter_1".
            static_attempt_counter_1 = 0;

            // Reset "static_sb_found_flag".
            static_sb_found_flag = FALSE;

            // Enable NSYNC task for SB detection (SB2).
          #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
            l1a_l1s_com.nsync.list[0].timing_validity = SB_ACQUISITION_PHASE;
          #else
            l1a_l1s_com.nsync.list[0].timing_validity = 3;
          #endif
            // Enable neighbour sync 0.
            l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

            // Step in state machine.
            *state = WAIT_SB;

            // End of process.
            return;
          }

          else
          // FB attempt failed.
          //-------------------
          {
            // Step in state machine.
            *state = SET_FB_MODE1;
          }
        }

        else
        if(SignalCode == MPHC_STOP_NETWORK_SYNC_REQ)
        // Request to STOP reading the FULL BCCH.
        //---------------------------------------
        {
          l1a_send_confirmation(MPHC_STOP_NETWORK_SYNC_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      case WAIT_SB:
      {
        // Use incoming message.
        //----------------------
        if(SignalCode == L1C_SB_INFO)
        {
          UWORD8  sb_found = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->sb_flag;
          UWORD8  bsic     = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->bsic;

          // Increment "static_attempt_counter_1".
          static_attempt_counter_1++;

          if(sb_found == TRUE)
          // SB detection is a success, check plmn...
          //-----------------------------------------
          {
            // Save Results.
            static_sb_found_flag = TRUE;
            static_bsic          = bsic;
            static_fn_offset     = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset;
            static_time_alignmt  = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt;
          }

          if (static_attempt_counter_1 >= 8)
          {
            // Reset NSYNC task enable flag.
            l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;

            if(static_sb_found_flag == TRUE)
            // SB detection is a success.
            //----------------------------
            {
              // Save results.
              l1a_l1s_com.nsync.list[0].fn_offset    = static_fn_offset;
              l1a_l1s_com.nsync.list[0].time_alignmt = static_time_alignmt;

              // Correct "ntdma" and "time_alignment" to shift 20 bit to the
              // futur for Normal Burst reading tasks.
              l1a_add_time_for_nb(&l1a_l1s_com.nsync.list[0].time_alignmt,
                                  &l1a_l1s_com.nsync.list[0].fn_offset);


              // 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.
              // 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 = 0; // No timeslot shift to be performed.
              l1a_l1s_com.dl_tn         = 0; // Camping on timeslot 0.
              }
              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.


              // Clear "time_alignmt, fn_offset" in the result message since we are
              // going to camp on that cell.
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset    = l1a_l1s_com.nsync.list[0].fn_offset;
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt = l1a_l1s_com.nsync.list[0].time_alignmt;

              // Recreate the last sucessful attempt.
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->sb_flag = static_sb_found_flag;
              ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->bsic    = static_bsic;

              // Forward result message to L3.
              l1a_send_result(MPHC_NETWORK_SYNC_IND, msg, RRM1_QUEUE);
              // Keep in memory the AFC value driving to a good synchro
              old_afc = l1s.afc;

              // Initialize toa.
              #if (TOA_ALGO != 0)
                l1a_l1s_com.toa_reset = TRUE;
              #endif

              // step in state machine.
              *state = RESET;
            }

            else
            // SB detection failed.
            //---------------------
            {
                // Send reporting message with a faillure indication.
                // Set the flag spurious_fb_detected to TRUE to reuse in the
                // AFC algo the old variables
                l1s.spurious_fb_detected = TRUE;
                // reuse the old AFC value
                l1s.afc = old_afc;
                l1a_report_failling_ncell_sync(MPHC_NETWORK_SYNC_IND, 0);

                // Reset state machine.
                *state = RESET;
            }
          }

          else
          // Make a new attempt SB.
          {
            // Enable neighbour sync 0.
            l1a_l1s_com.nsync.list[0].status = NSYNC_PENDING;

            // End of process.
            return;
          }
        }

        else
        if(SignalCode == MPHC_STOP_NETWORK_SYNC_REQ)
        // Request to STOP reading the FULL BCCH.
        //---------------------------------------
        {
          l1a_send_confirmation(MPHC_STOP_NETWORK_SYNC_CON,RRM1_QUEUE);

          // This process must be reset.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

    } // end of "switch".
  } // end of "while"
} // end of procedure.


/*-------------------------------------------------------*/
/* l1a_idle_smscb_process()                              */
/*-------------------------------------------------------*/
/* Description : This state machine handles the SMSCB    */
/* (Short Message Service Cell Broadcast).               */
/*                                                       */
/* Starting messages:        MPHC_CONFIG_CBCH_REQ        */
/*                                                       */
/* Subsequent messages:      MPHC_CBCH_SCHEDULE_REQ      */
/*                           MPHC_CBCH_INFO_REQ          */
/*                           MPHC_CBCH_UPDATE_REQ        */
/*                                                       */
/* Result messages (input):  L1C_CB_INFO                 */
/*                                                       */
/* Result messages (output): MPHC_DATA_IND               */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_CBCH_REQ          */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_idle_smscb_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET           = 0,
    WAIT_CONFIG     = 1,
    WAIT_FOR_CHANGE = 2,
    SET_SCHEDULE    = 3,
    WAIT_RESULT     = 4
  };

  UWORD8                *state      = &l1a.state[I_SMSCB];
  UWORD32                SignalCode = msg->SignalCode;

  UWORD32                first_block_0;
  UWORD32                first_block_1;
  BOOL                   extended_cbch;
  T_CBCH_HEAD_SCHEDULE  *cbch_schedule_ptr;
  UWORD8                 schedule_length;

  BOOL end_process = 0;

  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_CONFIG;

        // Reset SMSCB process.
        l1a_l1s_com.l1s_en_task[SMSCB] = TASK_DISABLED;  // Clear RAACC task enable flag.
      }
      break;

      case WAIT_CONFIG:
      {
        if(SignalCode == MPHC_CONFIG_CBCH_REQ)
        // CBCH configuration message.
        //----------------------------------------------------
        // L1 must download the CBCH description from the command
        // message.
        {
          WORD8 tn_smscb;

          #define SMSCB_NCOMB_START_TIME   6  // SMSCB (case not combined, SDCCH/8).
          #define SMSCB_COMB_START_TIME   30  // SMSCB (case combined, SDCCH/4).

          // Set "parameter synchro semaphores"
          l1a_l1s_com.task_param[SMSCB] = SEMAPHORE_SET;   // Set "parameter synchro semaphore for SMSCB task.

          // Download new CBCH parameters.
          l1a_l1s_com.cbch_desc      = ((T_MPHC_CONFIG_CBCH_REQ *)(msg->SigP))->cbch_desc;
          l1a_l1s_com.cbch_freq_list = ((T_MPHC_CONFIG_CBCH_REQ *)(msg->SigP))->cbch_freq_list;

          if(l1a_l1s_com.cbch_desc.channel_type == SDCCH_8)
          // case SDCCH/8...
          // Rem: Serving tasks on timeslot 0 is a special case,
          //      start frame is 1 later than other cases.
          {
            if(l1a_l1s_com.cbch_desc.timeslot_no < l1a_l1s_com.dl_tn)
            {
              l1a_l1s_com.cbch_start_in_mf51 = SMSCB_NCOMB_START_TIME;
              l1a_l1s_com.pre_scheduled_cbch = TRUE;
            }
            else
            {
              l1a_l1s_com.cbch_start_in_mf51 = SMSCB_NCOMB_START_TIME + 1;
              l1a_l1s_com.pre_scheduled_cbch = FALSE;
            }
          }
          else
          // case SDCCH/4...
          {
            if(l1a_l1s_com.cbch_desc.timeslot_no < l1a_l1s_com.dl_tn)
            {
              l1a_l1s_com.cbch_start_in_mf51 = SMSCB_COMB_START_TIME;
              l1a_l1s_com.pre_scheduled_cbch = TRUE;
            }
            else
            {
              l1a_l1s_com.cbch_start_in_mf51 = SMSCB_COMB_START_TIME + 1;
              l1a_l1s_com.pre_scheduled_cbch = FALSE;
            }
          }

          // Set "change_synchro" flag to trigger L1S to change the synchro on fly
          // within SMSCB task and to restore current synchro when SMSCB task is completed.
          if(((l1a_l1s_com.cbch_desc.timeslot_no - l1a_l1s_com.dl_tn + 8) % 8) >=4)
          {
            // L1S will make a intra SMSCB task synchro to current TS + 4.
            l1a_l1s_com.change_synchro_cbch  = TRUE;
            tn_smscb                         = l1a_l1s_com.cbch_desc.timeslot_no - l1a_l1s_com.dl_tn - 4;
          }
          else
          {
            // L1S will NOT make the intra SMSCB task synchro.
            l1a_l1s_com.change_synchro_cbch = FALSE;
            tn_smscb                        = l1a_l1s_com.cbch_desc.timeslot_no - l1a_l1s_com.dl_tn;
          }

          if(tn_smscb < 0)
            l1a_l1s_com.tn_smscb = tn_smscb + 8;
          else
            l1a_l1s_com.tn_smscb = tn_smscb;

          // Disable TB1/2/3/5/6/7 reading.
          l1a_l1s_com.cbch_info_req.cbch_num = 0;
          l1a_l1s_com.cbch_info_req.next     = 0;

          // Reset the CBCH/TB0/TB4 activity.
          l1a_l1s_com.norm_cbch_schedule.cbch_state = CBCH_INACTIVE;
          l1a_l1s_com.ext_cbch_schedule.cbch_state  = CBCH_INACTIVE;

          // Step in state machine.
          *state = WAIT_FOR_CHANGE;
        }

        // end of process.
        end_process = 1;
      }
      break;

      case WAIT_FOR_CHANGE:
      {
        if(SignalCode == MPHC_CBCH_SCHEDULE_REQ)
        // CBCH scheduling message.
        //----------------------------------------------------
        {
          // Stop SMSCB task.
          l1a_l1s_com.l1s_en_task[SMSCB] = TASK_DISABLED;  // Clear SMSCB task enable flag.

          // Set "parameter synchro semaphore for SMSCB task.
          l1a_l1s_com.task_param[SMSCB] = SEMAPHORE_SET;

          extended_cbch   = ((T_MPHC_CBCH_SCHEDULE_REQ *)(msg->SigP))->extended_cbch;
          schedule_length = ((T_MPHC_CBCH_SCHEDULE_REQ *)(msg->SigP))->schedule_length;

          // Choose schedule table according to the considered CBCH (normal or extended).
          if(extended_cbch) cbch_schedule_ptr = &l1a_l1s_com.ext_cbch_schedule;
          else              cbch_schedule_ptr = &l1a_l1s_com.norm_cbch_schedule;

          // Correction of BUG2176: CBCH_HEAD_STRUCTURE has to be updated with schedule_length
          // value, potentially used in SET_SCHEDULE state after receipt of an CBCH_UPDATE_REQ
          cbch_schedule_ptr->schedule_length = schedule_length;


          if(schedule_length == 0)
          {
            // Continuous CBCH header reading.
            //--------------------------------

            // No scheduling info provided, L1 must start reading continously TB0 on
            // normal CBCH or TB4 on extended CBCH.
            cbch_schedule_ptr->cbch_state = CBCH_CONTINUOUS_READING;

            // Continuous reading must start immediately.
            cbch_schedule_ptr->start_continuous_fn = -1;

            // Activate SMSCB task.
            l1a_l1s_com.l1s_en_task[SMSCB] = TASK_ENABLED;   // Set SMSCB task enable flag.

            // Step in state machine.
            *state = WAIT_RESULT;

            // End of process.
            return;
          }

          else
          {
            UWORD32 starting_fn;

            // Scheduled CBCH header reading.
            //--------------------------------

            cbch_schedule_ptr->cbch_state      = CBCH_SCHEDULED;

            first_block_0   = ((T_MPHC_CBCH_SCHEDULE_REQ *)(msg->SigP))->first_block_0;
            first_block_1   = ((T_MPHC_CBCH_SCHEDULE_REQ *)(msg->SigP))->first_block_1;

            // Compute "schedule period" starting frame number.
            // Note: the reception of MPHC_CBCH_SCHEDULE_REQ schedule message always
            //       refers to a scheduling period starting at the next "8*MF51" boundary.
            //       There is no real time issue there since we have plenty TDMA frame
            //       between the reception of the scheduling message from CBCH and the
            //       starting of the considered scheduling period.

            starting_fn = l1s.actual_time.fn - (l1s.actual_time.fn%(8*51)) + 8*51;
            if(starting_fn >= MAX_FN) starting_fn -= MAX_FN;

            cbch_schedule_ptr->starting_fn = starting_fn;

            // Step in state machine.
            *state = SET_SCHEDULE;
          }
        }

        else
        if(SignalCode == MPHC_CBCH_INFO_REQ)
        // CBCH info request message.
        //----------------------------------------------------
        {
          UWORD32  starting_fn;
          UWORD8   i,j;
          UWORD8   tb_bitmap;

          // This request message is a consequence of a CBCH/TB0 or CBCH/TB4 reading.

          // Stop SMSCB task.
          l1a_l1s_com.l1s_en_task[SMSCB] = TASK_DISABLED;

          // Set "parameter synchro semaphore for SMSCB task.
          l1a_l1s_com.task_param[SMSCB] = SEMAPHORE_SET;

          // Store TB bitmap from message.
          tb_bitmap = ((T_MPHC_CBCH_INFO_REQ *)(msg->SigP))->tb_bitmap;

          // Compute next TB1 multiframe 51 starting frame number.
          starting_fn = l1s.actual_time.fn - (l1s.actual_time.fn%(8*51)) + 51;

          if(starting_fn >= MAX_FN) starting_fn -= MAX_FN;

          // Compute schedule table according to the provided bitmap.
          j=0;
          for(i=0; i<3; i++) // TB 1\2\3
          {
            if(tb_bitmap & (1L<<i))
            {
              l1a_l1s_com.cbch_info_req.start_fn[j] = (starting_fn +
                                                       (UWORD32)i*51L +
                                                       l1a_l1s_com.cbch_start_in_mf51) % MAX_FN;
              j++;
            }
          } // End "for"

          for(i=3; i<6; i++) // TB 4\5\6
          {
            if(tb_bitmap & (1L<<i))
            {
              l1a_l1s_com.cbch_info_req.start_fn[j] = (starting_fn +
                                                       (UWORD32)i*51L +
                                                       l1a_l1s_com.cbch_start_in_mf51 +
                                                       51L) % MAX_FN;
              j++;
            }
          } // End "for"

          // Store number of CBCH info to read.
          l1a_l1s_com.cbch_info_req.cbch_num = j;
          l1a_l1s_com.cbch_info_req.next     = 0;

          // Activate SMSCB task.
          l1a_l1s_com.l1s_en_task[SMSCB] = TASK_ENABLED;   // Set SMSCB task enable flag.

          // Step in state machine.
          *state = WAIT_RESULT;

          // End of process.
          return;
        }

        else
        if(SignalCode == MPHC_CBCH_UPDATE_REQ)
        // CBCH scheduling message.
        //----------------------------------------------------
        {
          // Stop SMSCB task.
          l1a_l1s_com.l1s_en_task[SMSCB] = TASK_DISABLED;  // Clear SMSCB task enable flag.

          // Set "parameter synchro semaphore for SMSCB task.
          l1a_l1s_com.task_param[SMSCB] = SEMAPHORE_SET;

          extended_cbch   = ((T_MPHC_CBCH_UPDATE_REQ *)(msg->SigP))->extended_cbch;

          // Choose schedule table according to the considered CBCH (normal or extended).
          if(extended_cbch) cbch_schedule_ptr = &l1a_l1s_com.ext_cbch_schedule;
          else              cbch_schedule_ptr = &l1a_l1s_com.norm_cbch_schedule;

          // Scheduled CBCH header reading.
          //--------------------------------

          cbch_schedule_ptr->cbch_state = CBCH_SCHEDULED;

          first_block_0   = ((T_MPHC_CBCH_UPDATE_REQ *)(msg->SigP))->first_block_0;
          first_block_1   = ((T_MPHC_CBCH_UPDATE_REQ *)(msg->SigP))->first_block_1;

          // DO NOT CHANGE "cbch_schedule_ptr->starting_fn" content.

          // Step in state machine.
          *state = SET_SCHEDULE;
        }

        else
        if(SignalCode == MPHC_STOP_CBCH_REQ)
        // Request to STOP reading the CBCH.
        //----------------------------------
        {
          BOOL normal_cbch   = ((T_MPHC_STOP_CBCH_REQ *)(msg->SigP))->normal_cbch;
          BOOL extended_cbch = ((T_MPHC_STOP_CBCH_REQ *)(msg->SigP))->extended_cbch;

          // Stop SMSCB task.
          l1a_l1s_com.l1s_en_task[SMSCB] = TASK_DISABLED;

          // Set "parameter synchro semaphore for SMSCB task.
          l1a_l1s_com.task_param[SMSCB] = SEMAPHORE_SET;

          if(normal_cbch)   l1a_l1s_com.norm_cbch_schedule.cbch_state = CBCH_INACTIVE;
          if(extended_cbch) l1a_l1s_com.ext_cbch_schedule.cbch_state  = CBCH_INACTIVE;

          if((l1a_l1s_com.norm_cbch_schedule.cbch_state == CBCH_INACTIVE) &&
             (l1a_l1s_com.ext_cbch_schedule.cbch_state  == CBCH_INACTIVE))
          // This process must be reset.
          {
             // send confirmation
            l1a_send_confirmation(MPHC_STOP_CBCH_CON,RRM1_QUEUE);

           // Step in state machine.
            *state = RESET;
          }
          else
          {
            // Activate SMSCB task.
            l1a_l1s_com.l1s_en_task[SMSCB] = TASK_ENABLED;

            // Step in state machine.
            *state = WAIT_RESULT;

            // End of process.
            return;
          }
        }
#if 0	/* match TCS211 */
        else
        if(SignalCode == L1C_DEDIC_DONE)
        {
            // Stop SMSCB task.
            l1a_l1s_com.l1s_en_task[SMSCB] = TASK_DISABLED;

           // Set "parameter synchro semaphore for SMSCB task.
           l1a_l1s_com.task_param[SMSCB] = SEMAPHORE_SET;

 	    l1a_l1s_com.norm_cbch_schedule.cbch_state = CBCH_INACTIVE;
	    l1a_l1s_com.ext_cbch_schedule.cbch_state  = CBCH_INACTIVE;

	    // Step in state machine.
           *state = RESET;        
        }
#endif

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      case SET_SCHEDULE:
      {
        UWORD8  i,j;
        UWORD8  mf51_offset;

        // Choose schedule table according to the considered CBCH (normal or extended).
        if(extended_cbch) mf51_offset = 4*51;  // Offset to read TB4.
        else              mf51_offset = 0;     // No offset to read TB0.

        // Compute schedule table according to the provided bitmap.
        j=0;
        for(i=0; i<48; i++)
        {
          if(i<32)
          {
            if(first_block_0 & (1L<<i))
            {
              cbch_schedule_ptr->first_block[j] = (cbch_schedule_ptr->starting_fn +
                                                   (UWORD32)i*8L*51L +
                                                   l1a_l1s_com.cbch_start_in_mf51 +
                                                   mf51_offset) % MAX_FN;
              j++;
            }
          }
          else
          {
            if(first_block_1 & (1L<<(i-32)))
            {
              cbch_schedule_ptr->first_block[j] = (cbch_schedule_ptr->starting_fn +
                                                   (UWORD32)i*8L*51L +
                                                   l1a_l1s_com.cbch_start_in_mf51 +
                                                   mf51_offset) % MAX_FN;
              j++;
            }
          }
        } // End "for"

        // Compute FN for starting continuous CBCH/TB0 reading.
        // Rem: this FN is given by the starting FN of the schedule period starting
        // immediately after the schedule period considered in the message.
        cbch_schedule_ptr->start_continuous_fn = ( cbch_schedule_ptr->starting_fn +
                                                   (UWORD32)cbch_schedule_ptr->schedule_length*8L*51L +
                                                   l1a_l1s_com.cbch_start_in_mf51 +
                                                   mf51_offset ) % MAX_FN;

        // Store number of scheduled CBCH according to the considered CBCH (normal or extended).
        // Store "schedule period" starting frame number.
        cbch_schedule_ptr->cbch_num          = j;
        cbch_schedule_ptr->next              = NULL;//o omaps 00090550

        // Activate SMSCB task.
        l1a_l1s_com.l1s_en_task[SMSCB] = TASK_ENABLED;   // Set SMSCB task enable flag.

        // Step in state machine.
        *state = WAIT_RESULT;

        // End of process.
        return;
      }


      case WAIT_RESULT:
      {
        if(SignalCode == L1C_CB_INFO)
        // CBCH result message.
        //---------------------
        {
          // Forward result message to L3.
          l1a_send_result(MPHC_DATA_IND, msg, RRM1_QUEUE);

          // End of process.
          return;
        }

        else
        if((SignalCode == MPHC_CBCH_SCHEDULE_REQ) ||
           (SignalCode == MPHC_CBCH_UPDATE_REQ)   ||
           (SignalCode == MPHC_CBCH_INFO_REQ))
        // Request to reconsider the ongoing CBCH activity.
        //-----------------------------------------------------------
        {
          // Step in state machine.
          *state = WAIT_FOR_CHANGE;
        }

        else
        //if((SignalCode == MPHC_STOP_CBCH_REQ)||(SignalCode == L1C_DEDIC_DONE))
        if(SignalCode == MPHC_STOP_CBCH_REQ)
        // Request to (may be partially) STOP reading the CBCH.
        //-----------------------------------------------------
        {
          // This process must be reset.
          *state = WAIT_FOR_CHANGE;
        }

        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.


/*-------------------------------------------------------*/
/* l1a_access_process()                                  */
/*-------------------------------------------------------*/
/* Description : This state machine handles the access   */
/* to the network while in IDLE mode.                    */
/*                                                       */
/* Starting messages:        MPHC_RA_REQ                 */
/*                                                       */
/* Subsequent messages:      MPHC_RA_REQ                 */
/*                                                       */
/* Result messages (input):  L1C_RA_DONE                 */
/*                                                       */
/* Result messages (output): MPHC_RA_CON                 */
/*                                                       */
/* Reset message (input): MPHC_STOP_RA_REQ               */
/*                                                       */
/* Reset message (input): MPHC_STOP_RA_CON               */
/*-------------------------------------------------------*/
void l1a_access_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1,
    WAIT_RESULT = 2
  };

  UWORD8   *state      = &l1a.state[ACCESS];
  UWORD32   SignalCode = msg->SignalCode;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset RAACC process.
        l1a_l1s_com.l1s_en_task[RAACC] = TASK_DISABLED;  // Clear RAACC task enable flag.
      }
      break;


      case WAIT_INIT:
      {
        if(SignalCode == MPHC_RA_REQ)
        // 1st Random access request message.
        //-----------------------------------
        {
          UWORD8  supplied_txpwr;

          // Download Transmit power configuration.
          supplied_txpwr         = ((T_MPHC_RA_REQ *)(msg->SigP))->txpwr;

#if (L1_FF_MULTIBAND == 0)

          //Config.
          if ((l1_config.std.id == DUAL) ||
              (l1_config.std.id == DUALEXT) ||
              (l1_config.std.id == DUAL_US))
          {
            l1a_l1s_com.powerclass_band1 = ((T_MPHC_RA_REQ *)(msg->SigP))->powerclass_band1;
            l1a_l1s_com.powerclass_band2 = ((T_MPHC_RA_REQ *)(msg->SigP))->powerclass_band2;
          }
          else
          {
            l1a_l1s_com.powerclass_band1 = ((T_MPHC_RA_REQ *)(msg->SigP))->powerclass_band1;
          }
#endif

          // Check max transmit power (min txpwr) according to powerclass
          // and clip to MIN_TXPWR_LEVEL.
          supplied_txpwr = l1a_clip_txpwr(supplied_txpwr,l1a_l1s_com.Scell_info.radio_freq);

          // Given value must be used on 1st TX.
          l1s.applied_txpwr = supplied_txpwr;

          // Init RAACC process.
          l1a_l1s_com.ra_info.rand            = ((T_MPHC_RA_REQ *)(msg->SigP))->rand;
          l1a_l1s_com.ra_info.channel_request = ((T_MPHC_RA_REQ *)(msg->SigP))->channel_request;


          // Increment "rand" value in order to avoid to abort RACH by SYNCHRO task
          // when MPHC_START_CCCH_REQ and MPHC_RA_REQ are sent in same TDMA.
          l1a_l1s_com.ra_info.rand+=4;

          // step in state machine.
          *state = WAIT_RESULT;

          // Change mode to connection establishment part 1.
          l1a_l1s_com.mode = CON_EST_MODE1;

          // Activate RAACC task (no semaphore for UL tasks).
          // Enable Paging Reorg and Normal paging tasks.
          l1a_l1s_com.l1s_en_task[RAACC] = TASK_ENABLED; // Set RAACC task enable flag.
        }

        // end of process.
        end_process = 1;
      }
      break;

      case WAIT_RESULT:
      {
        if(SignalCode == L1C_RA_DONE)
        // Random access acqnowledge message.
        //-----------------------------------
        {
          // Forward result message to L3.
          l1a_send_result(MPHC_RA_CON, msg, RRM1_QUEUE);

          // Change mode to connection establishment part 2.
          l1a_l1s_com.mode = CON_EST_MODE2;

          // end of process.
          return;
        }


        else
        if(SignalCode == MPHC_RA_REQ)
        // Random access message.
        //-----------------------
        {
          // REM: rand is added the msg content since its current content is the already
          // spent "slots" from the last RACH sending.
          l1a_l1s_com.ra_info.rand            += ((T_MPHC_RA_REQ *)(msg->SigP))->rand;
          l1a_l1s_com.ra_info.channel_request  = ((T_MPHC_RA_REQ *)(msg->SigP))->channel_request;

          // Activate RAACC task (no semaphore for UL tasks).
          l1a_l1s_com.l1s_en_task[RAACC] = TASK_ENABLED;   // Set RAACC task enable flag.

          // end of process.
          return;
        }

        else
        if(SignalCode == MPHC_STOP_RA_REQ)
        // Request to STOP the LINK ACCESS procedure.
        //-------------------------------------------
        {
          #if L1_GPRS
            UWORD8 i;

            // 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;
            }
          #endif

          // send confirmation
          l1a_send_confirmation(MPHC_STOP_RA_CON,RRM1_QUEUE);


          // 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.

//-----------------------------------------------------------------------------------------------

/*-------------------------------------------------------*/
/* l1a_dedicated_process()                               */
/*-------------------------------------------------------*/
/* Description : This state machine handles the dedicated*/
/* mode setup (L1A side).                                */
/*                                                       */
/* Starting messages:        MPHC_IMMED_ASSIGN_REQ       */
/*                                                       */
/* Subsequent messages:      MPHC_CHANNEL_ASSIGN_REQ     */
/*                           MPHC_SYNC_HO_REQ            */
/*                           MPHC_PRE_SYNC_HO_REQ        */
/*                           MPHC_PSEUDO_SYNC_HO_REQ     */
/*                           MPHC_ASYNC_HO_REQ           */
/*                           MPHC_ASYNC_HO_COMPLETE      */
/*                           MPHC_HANDOVER_FAIL_REQ      */
/*                           MPHC_CHANGE_FREQUENCY       */
/*                           OML1_CLOSE_TCH_LOOP_REQ     */
/*                           OML1_OPEN_TCH_LOOP_REQ      */
/*                           OML1_START_DAI_TEST_REQ     */
/*                           OML1_STOP_DAI_TEST_REQ      */
/*                                                       */
/* Result messages (input):  L1C_DEDIC_DONE              */
/*                           L1C_SACCH_INFO              */
/*                                                       */
/* Result messages (output): MPHC_CHANNEL_ASSIGN_CON     */
/*                           MPHC_SYNC_HO_CON            */
/*                           MPHC_PRE_SYNC_HO_CON        */
/*                           MPHC_PSEUDO_SYNC_HO_CON     */
/*                           MPHC_ASYNC_HO_CON           */
/*                           MPHC_TA_FAIL_IND            */
/*                           MPHC_DATA_IND               */
/*                           OML1_CLOSE_TCH_LOOP_CON     */
/*                           OML1_OPEN_TCH_LOOP_CON      */
/*                           OML1_START_DAI_TEST_CON     */
/*                           OML1_STOP_DAI_TEST_CON      */
/*                                                       */
/* Reset messages (input):   MPHC_CHANNEL_RELEASE        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_dedicated_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET          = 0,
    WAIT_INIT      = 1,
    WAIT_DYN_DWNLD = 2,
    WAIT_MSG       = 3
  };

          T_DEDIC_SET  *free_set;
          UWORD8       *state      = &l1a.state[DEDICATED];
          UWORD32       SignalCode = msg->SignalCode;

  static  UWORD32       static_ho_fail_time_alignmt;
  static  UWORD32       static_ho_fail_fn_offset;
  static  T_DEDIC_SET  *static_ho_fail_aset;

#if ((L1_EOTD==1) && (L1_EOTD_QBIT_ACC == 1))
  static UWORD32        static_serv_fn_offset    = 0;
  static UWORD32        static_serv_time_alignmt = 0;
#endif

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset L1S dedicated mode manager trigger.
        l1a_l1s_com.dedic_set.SignalCode = NULL;
      }
      break;

      case WAIT_INIT:
      {
        switch(SignalCode)
        // switch on input message.
        //-------------------------------
        {
          case MPHC_IMMED_ASSIGN_REQ:
          // Immediate assignement message.
          //-------------------------------
          {
            UWORD8  maio_bef_sti;
#if (L1_FF_MULTIBAND == 1)
            UWORD16 operative_radio_freq;
#endif
            

            // Get Ptr to the free dedicated parameter set.
            // All important fields are initialised.
            free_set = l1a_get_free_dedic_set();

            // Save given dedicated channel parameters from MPHC_IMMED_ASSIGN_REQ msg.
            //========================================================================
            // Rem1: Mode is forced to Signalling Only.

            free_set->chan1.mode = SIG_ONLY_MODE;

            free_set->chan1.desc           = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->channel_desc;
            free_set->ma.freq_list         = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->frequency_list;
            free_set->ma.freq_list_bef_sti = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->frequency_list_bef_sti;
            maio_bef_sti                   = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->maio_bef_sti;
            free_set->new_timing_advance   = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->timing_advance;
            free_set->dtx_allowed          = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->dtx_allowed;
            l1a_l1s_com.dedic_set.pwrc     = ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->pwrc;

            //----------------------------------------------
            //Rem: bcch_allocation, ba_id are not used!!!!!!
            //----------------------------------------------

            // New Timing Advance value must be applied on 1st frame of dedic. channel.
            free_set->timing_advance = free_set->new_timing_advance;

            // TXPWR command was given in Idle, save it in dedicated mode structure.
            free_set->new_target_txpwr = l1s.applied_txpwr;

            // Serving Cell stays the same.
            free_set->cell_desc                  = l1a_l1s_com.Scell_info;
            
#if (L1_FF_MULTIBAND == 0)
            
            free_set->cell_desc.traffic_meas_beacon
                                                 = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset];
            free_set->cell_desc.traffic_meas     = l1a_l1s_com.last_input_level[l1a_l1s_com.Scell_info.radio_freq - l1_config.std.radio_freq_index_offset];

#else // L1_FF_MULTIBAND = 1 below

            operative_radio_freq = 
                l1_multiband_radio_freq_convert_into_operative_radio_freq(l1a_l1s_com.Scell_info.radio_freq);
            free_set->cell_desc.traffic_meas_beacon = l1a_l1s_com.last_input_level[operative_radio_freq];
            free_set->cell_desc.traffic_meas     = l1a_l1s_com.last_input_level[operative_radio_freq];

#endif // #if (L1_FF_MULTIBAND == 0) else


            // Decode the "starting time field", since staying on the same serving
            // the same STI fn is saved in both "neig_sti_fn" and "serv_sti_fn".
            free_set->neig_sti_fn = l1a_decode_starting_time(((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->starting_time);
            free_set->serv_sti_fn = free_set->neig_sti_fn;

            // Check/Fill "before starting time" fields.
            l1a_fill_bef_sti_param(free_set, ((T_MPHC_IMMED_ASSIGN_REQ *)(msg->SigP))->starting_time.start_time_present);

            // Use provided "before starting time MAIO" if hopping channel.
            if(free_set->chan1.desc_bef_sti.chan_sel.h)
              free_set->chan1.desc_bef_sti.chan_sel.rf_channel.hopping_rf.maio = maio_bef_sti;

            // 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.
            // Save the "timeslot difference" between new and old configuration
            // in "tn_difference".
            //   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 += free_set->chan1.desc.timeslot_no - l1a_l1s_com.dl_tn;
              l1a_l1s_com.dl_tn         = free_set->chan1.desc.timeslot_no;  // Save new TN id.
            }
            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.


            // Set "fset" pointer to the new parameter set.
            l1a_l1s_com.dedic_set.fset = free_set;

            /*
             * FreeCalypso: the following logic related to dynamic DSP
             * patching has been reconstructed from our only available
             * binary object version.
             */
          #if (L1_DYN_DSP_DWNLD == 1)
            if (l1a.dyn_dwnld.semaphore_vect[DEDI_STATE_MACHINE]==GREEN)
          #endif
            {
              // Give new msg code to L1S.
              l1a_l1s_com.dedic_set.SignalCode = MPHC_IMMED_ASSIGN_REQ;

              #if (TRACE_TYPE==5) && FLOWCHART
                trace_flowchart_dedic(l1a_l1s_com.dedic_set.SignalCode);
              #endif

              // Set confirmation message name.
              l1a.confirm_SignalCode = MPHC_IMMED_ASSIGN_CON;

              // step in state machine.
              *state = WAIT_MSG;
            }
          #if (L1_DYN_DSP_DWNLD == 1)
            else
            {
              *state = WAIT_DYN_DWNLD;
              #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4) || (TRACE_TYPE == 5))
                if((trace_info.current_config->l1_dyn_trace) & (1<<L1_DYN_TRACE_DYN_DWNLD))
                {
                  char str[30];
                  sprintf(str,"DEDI SM blocked by DYN DWNLD\r\n");
                  #if(CODE_VERSION == SIMULATION)
                     trace_fct_simu_dyn_dwnld(str);
                  #else
                     rvt_send_trace_cpy((T_RVT_BUFFER)str,trace_info.l1_trace_user_id,strlen(str),RVT_ASCII_FORMAT);
                  #endif
                }
              #endif    // (TRACE_TYPE == 1) || (TRACE_TYPE == 4)
            }
          #endif
          }
          break;

          case MPHC_CHANNEL_ASSIGN_REQ:
          // Channel assignement message.
          //-----------------------------
          {
            UWORD8  supplied_txpwr;
            UWORD16 tch_radio_freq;

#if ((REL99 == 1) && (FF_BHO == 1))
              //restore long_rem_handover_type from previous handover activites
              l1a_l1s_com.dedic_set.long_rem_handover_type = 0; //reset handover to normal
#endif // #if ((REL99 == 1) && (FF_BHO == 1))

#if(L1_CHECK_COMPATIBLE == 1)
           l1a.stop_req = FALSE;
#endif

            // Get Ptr to the free dedicated parameter set.
            free_set = l1a_get_free_dedic_set();

            // Save given dedicated channel parameters from MPHC_CHANNEL_ASSIGN_REQ msg.
            //=============================================================--==========

            free_set->chan1.desc           = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->channel_desc_1;
            free_set->chan1.desc_bef_sti   = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->channel_desc_1_bef_sti;
            free_set->chan1.mode           = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->channel_mode_1;

            free_set->chan2.desc           = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->channel_desc_2;
            free_set->chan2.desc_bef_sti   = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->channel_desc_2_bef_sti;
            free_set->chan2.mode           = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->channel_mode_2;

            free_set->ma.freq_list         = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->frequency_list;
            free_set->ma.freq_list_bef_sti = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->frequency_list_bef_sti;

            free_set->dtx_allowed          = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->dtx_allowed;

            supplied_txpwr                 = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->txpwr;

            #if (AMR == 1)
              // download AMR ver 1.0 information
              free_set->amr_configuration    = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->amr_configuration;
              free_set->cmip                 = C_AMR_CMIP_DEFAULT;
            #endif

            #if (TRACE_TYPE==3)
             l1_stats.chan_mode = free_set->chan1.mode;
            #endif

            // Determine which band we are transmitting on
            if(free_set->chan1.desc.chan_sel.h == TRUE)           // we are hopping therefore
              tch_radio_freq = free_set->ma.freq_list.rf_chan_no.A[0]; // take band from first element in maio list
            else                                                  // else take band from fixed radio_freq
              tch_radio_freq = free_set->chan1.desc.chan_sel.rf_channel.single_rf.radio_freq;

            // Check max transmit power (min txpwr) according to powerclass
            // and clip to MIN_TXPWR_LEVEL using new TCH radio_freq info.
            supplied_txpwr = l1a_clip_txpwr(supplied_txpwr,tch_radio_freq);

            free_set->new_target_txpwr = supplied_txpwr;

            if(((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->cipher_mode != 0)
              free_set->a5mode = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->a5_algorithm + 1;
            else
              free_set->a5mode = 0;

            // Grab the cipher key
            free_set->ciph_key = ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->cipher_key;

            // Serving Cell stays the same.
            free_set->cell_desc = l1a_l1s_com.Scell_info;

            // Decode the "starting time field", since staying on the same serving
            // the same STI fn is saved in both "neig_sti_fn" and "serv_sti_fn".
            free_set->neig_sti_fn = l1a_decode_starting_time(((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->starting_time);
            free_set->serv_sti_fn = free_set->neig_sti_fn;

            // Check/Fill "before starting time" fields.
            l1a_fill_bef_sti_param(free_set, ((T_MPHC_CHANNEL_ASSIGN_REQ *)(msg->SigP))->starting_time.start_time_present);


            // 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.
            // Save the "timeslot difference" between new and old configuration
            // in "tn_difference".
            //   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 += free_set->chan1.desc.timeslot_no - l1a_l1s_com.dl_tn;
              l1a_l1s_com.dl_tn         = free_set->chan1.desc.timeslot_no;  // Save new TN id.
            }
            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.



            // Carry over the previous "tch_loop" settings for HW bit error testing */
            free_set->chan1.tch_loop = l1a_l1s_com.dedic_set.aset->chan1.tch_loop;
            free_set->chan2.tch_loop = l1a_l1s_com.dedic_set.aset->chan2.tch_loop;

            // Set "fset" pointer to the new parameter set.
            l1a_l1s_com.dedic_set.fset = free_set;

            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = MPHC_CHANNEL_ASSIGN_REQ;

            #if (TRACE_TYPE==5) && FLOWCHART
              trace_flowchart_dedic(l1a_l1s_com.dedic_set.SignalCode);
            #endif

            // Set confirmation message name.
            l1a.confirm_SignalCode = MPHC_CHANNEL_ASSIGN_CON;

            // step in state machine.
            *state = WAIT_MSG;
          }
          break;

          case MPHC_SYNC_HO_REQ:
          case MPHC_PRE_SYNC_HO_REQ:
          case MPHC_PSEUDO_SYNC_HO_REQ:
          case MPHC_ASYNC_HO_REQ:
          // Handover messages.
          //-------------------
          {
            WORD32   new_ta = 0;
            BOOL     nci    = 0;

            UWORD16  radio_freq;
            UWORD16  tch_radio_freq;
            UWORD32  ncc;
            UWORD32  bcc;
            UWORD32  time_alignmt = 0;
            UWORD32  fn_offset = 0;
            UWORD8   supplied_txpwr;
#if (L1_FF_MULTIBAND == 1)
            UWORD16  operative_radio_freq;
#endif
            

#if ((REL99 == 1) && (FF_BHO == 1))
              // Get the handover type: regular or blind
              switch(SignalCode)
              {
                case MPHC_SYNC_HO_REQ:
                {
                  l1a_l1s_com.dedic_set.handover_type = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_type;

                }
                break;

                case MPHC_PRE_SYNC_HO_REQ:
                {
                  l1a_l1s_com.dedic_set.handover_type = ((T_MPHC_PRE_SYNC_HO_REQ *)(msg->SigP))->handover_type;

                }
                break;

                case MPHC_ASYNC_HO_REQ:
                {
                  l1a_l1s_com.dedic_set.handover_type = ((T_MPHC_ASYNC_HO_REQ *)(msg->SigP))->handover_type;

                }
                break;

                case MPHC_PSEUDO_SYNC_HO_REQ:
                {
                  l1a_l1s_com.dedic_set.handover_type = ((T_MPHC_PSEUDO_SYNC_HO_REQ *)(msg->SigP))->handover_type;

                }
                break;
              }

              // BCCH frequency of target cell
              l1a_l1s_com.dedic_set.bcch_carrier_of_nbr_cell = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.cell_description.bcch_carrier;

              //Store handover type in another variable to be used in L1S till handover finished is issued.
              l1a_l1s_com.dedic_set.long_rem_handover_type   = l1a_l1s_com.dedic_set.handover_type;
#endif // #if ((REL99 == 1) && (FF_BHO == 1))

            // Get Ptr to the free dedicated parameter set.
            free_set = l1a_get_free_dedic_set();

            /*--------------------------------------------------------------*/
            /* Save msg content in the free "DEDICATED PARAM. STRUCT."      */
            /* Rem: since the HANDOVER PARAMETER structure is on the top of */
            /* each handover message, we can access it using any "cast".    */
            /* Here we chose the "(T_MPHC_SYNC_HO_REQ *)".                  */
            /*--------------------------------------------------------------*/

            // Download timing information from the command message.
          #if ((REL99 == 1) && (FF_BHO == 1))
            if (l1a_l1s_com.dedic_set.handover_type == NORMAL_HANDOVER)
          #endif
          {

            time_alignmt = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->time_alignmt;
            fn_offset    = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->fn_offset;
          }
            // Save time difference between new serving and previous one
            // in case of HANDOVER FAIL.
            static_ho_fail_time_alignmt = (5000 - time_alignmt) % 5000;
            static_ho_fail_fn_offset    = (1 + MAX_FN - fn_offset) % MAX_FN;

            #if ((L1_EOTD==1) && (L1_EOTD_QBIT_ACC ==1))
              // Save time_alignmt and fn_offset for Serving Cell E-OTD
              // in case of handover failure...

              static_serv_fn_offset = l1a_l1s_com.nsync.serv_fn_offset;
              static_serv_time_alignmt = l1a_l1s_com.nsync.serv_time_alignmt;

              l1a_l1s_com.nsync.serv_fn_offset = 0;
              l1a_l1s_com.nsync.serv_time_alignmt = 0;
            #endif


            if(time_alignmt == 0)
            // The 2 base stations are seen qbit synchronized...
            // -> Prevent frame diff. side effect.
            {
              static_ho_fail_fn_offset = (static_ho_fail_fn_offset + MAX_FN - 1) % MAX_FN;
            }

            // Save Acitve dedicated mode parameter set
            // in case of HANDOVER FAIL.
            static_ho_fail_aset = l1a_l1s_com.dedic_set.aset;

            // Setup new serving cell information.
            radio_freq = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.cell_description.bcch_carrier;
            ncc   = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.cell_description.ncc;
            bcc   = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.cell_description.bcc;

            free_set->cell_desc.radio_freq            = radio_freq;
            free_set->cell_desc.bsic             = (bcc) | (ncc << 3);
            free_set->cell_desc.time_alignmt     = time_alignmt;
            free_set->cell_desc.fn_offset        = fn_offset;
            free_set->cell_desc.meas.acc         = 0;
            free_set->cell_desc.meas.nbr_meas    = 0;

#if 0	/* FreeCalypso TCS211 reconstruction */
#if (L1_FF_MULTIBAND == 0) // TBD 
            free_set->cell_desc.traffic_meas_beacon = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset];
            free_set->cell_desc.traffic_meas        = l1a_l1s_com.last_input_level[radio_freq - l1_config.std.radio_freq_index_offset];

#else // L1_FF_MULTIBAND = 1 below 

            operative_radio_freq = 
              l1_multiband_radio_freq_convert_into_operative_radio_freq(radio_freq);
            free_set->cell_desc.traffic_meas_beacon = l1a_l1s_com.last_input_level[operative_radio_freq];
            free_set->cell_desc.traffic_meas        = l1a_l1s_com.last_input_level[operative_radio_freq];
            
#endif // #if (L1_FF_MULTIBAND == 1) else                    
#endif

            // Download the message content.
            free_set->chan1.desc           = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.channel_desc_1;
            free_set->chan1.desc_bef_sti   = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.channel_desc_1_bef_sti;
            free_set->chan1.mode           = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.channel_mode_1;

            free_set->chan2.desc           = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.channel_desc_2;
            free_set->chan2.desc_bef_sti   = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.channel_desc_2_bef_sti;
            free_set->chan2.mode           = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.channel_mode_2;

            free_set->ma.freq_list         = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.frequency_list;
            free_set->ma.freq_list_bef_sti = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.frequency_list_bef_sti;

            supplied_txpwr                 = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.txpwr;
            #if (AMR == 1)
              // download AMR ver 1.0 information
              switch(SignalCode)
              {
                case MPHC_SYNC_HO_REQ:
                {
                  free_set->amr_configuration  = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->amr_configuration;
                }
                break;

                case MPHC_PRE_SYNC_HO_REQ:
                {
                  free_set->amr_configuration  = ((T_MPHC_PRE_SYNC_HO_REQ *)(msg->SigP))->amr_configuration;
                }
                break;

                case MPHC_ASYNC_HO_REQ:
                {
                  free_set->amr_configuration  = ((T_MPHC_ASYNC_HO_REQ *)(msg->SigP))->amr_configuration;
                }
                break;
              }
            free_set->cmip                     = C_AMR_CMIP_DEFAULT;
            #endif

            // Determine which band we are transmitting on
            if(free_set->chan1.desc.chan_sel.h == TRUE)           // we are hopping therefore
              tch_radio_freq = free_set->ma.freq_list.rf_chan_no.A[0]; // take band from first element in maio list
            else                                                  // else take band from fixed radio_freq
              tch_radio_freq = free_set->chan1.desc.chan_sel.rf_channel.single_rf.radio_freq;

            // Check max transmit power (min txpwr) according to powerclass
            // and clip to MIN_TXPWR_LEVEL using new TCH radio_freq info.
            supplied_txpwr = l1a_clip_txpwr(supplied_txpwr,tch_radio_freq);

            free_set->new_target_txpwr     = supplied_txpwr;
            free_set->ho_acc               = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.ho_acc;

            // Copy in cipher key Kc.
            free_set->ciph_key = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->cipher_key;

            if(((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.cipher_mode != 0)
              free_set->a5mode = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.a5_algorithm + 1;
            else
              free_set->a5mode = 0;

            // Decode the "starting time field". Since changing the serving cell
            // a different STI fn is saved in "neig_sti_fn" and "serv_sti_fn".
            free_set->neig_sti_fn = l1a_decode_starting_time(((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.starting_time);
            if(free_set->neig_sti_fn != -1)
              free_set->serv_sti_fn = (free_set->neig_sti_fn - free_set->cell_desc.fn_offset + MAX_FN) % MAX_FN;

            // Check/Fill "before starting time" fields.
            l1a_fill_bef_sti_param(free_set, ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.starting_time.start_time_present);

            // TIMING ADVANCED COMPUTATION...(GSM05.10)
            //--------------------------------
            switch(SignalCode)
            {
              case MPHC_SYNC_HO_REQ:
              case MPHC_PSEUDO_SYNC_HO_REQ:
              {
                WORD32 t1_hbit;
                WORD32 otd_hbit;

                if(SignalCode == MPHC_SYNC_HO_REQ)
                // Synchronous Handover
                {
                  l1a.confirm_SignalCode = MPHC_SYNC_HO_CON; // Set confirmation message name.

                  //rtd_hbit_mod256 = 0;
                  nci = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->nci;
                }

                // Compute Timing Advance TA.
                //---------------------------
                // t1 = t0 + OTD - RTD (GSM05.10, $A1.3)
                // OTD: Observed Time Difference. ( OTD = time(BTS0) - time(BTS1) )
                // RTD: Report Time Difference.
                // t0:  one way line of sight propagation MS-BTS0 (old BTS) ( t0 = TA(BTS0) / 2 ).
                // t1:  one way line of sight propagation MS-BTS1 (new BTS) ( t1 = TA(BTS1) / 2 ).

                /*** Convert QBO to Half bits (HBO)                                          ***/
                otd_hbit = (((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->time_alignmt / 2);

                // If OTD is too high, it should be seen as a Negative value.
                if(otd_hbit > 1250)
                {
                    /*** Cell is advanced in timing from serving, hence TDMA arrives earlier
                         => Smaller Timing Advance and OTD is -ve                            ***/
                    otd_hbit -= 2500 ;
                }
                else
                {
                    /*** Cell is retarted in timing from serving, hence TDMA arrives later
                         => Larger Timing Advance and OTD is +ve                             ***/
                }

                t1_hbit = (WORD32) (otd_hbit + (WORD32) l1a_l1s_com.dedic_set.aset->new_timing_advance);

                if(t1_hbit < 0)
                   t1_hbit = 0;

                new_ta = t1_hbit;
              }
              break;

              case MPHC_PRE_SYNC_HO_REQ:
              // Pre-Synchronous Handover...
              {
                l1a.confirm_SignalCode = MPHC_PRE_SYNC_HO_CON; // Set confirmation message name.

                if(((T_MPHC_PRE_SYNC_HO_REQ *)(msg->SigP))->timing_advance_valid)
                  new_ta = ((T_MPHC_PRE_SYNC_HO_REQ *)(msg->SigP))->timing_advance;
                else
                  new_ta = 1;
              }
              break;

              case MPHC_ASYNC_HO_REQ:
              // Asynchronous Handover...
              {
                l1a.confirm_SignalCode = MPHC_ASYNC_HO_CON; // Set confirmation message name.
              }
              break;
            } // End switch...

            // Ensure TA is never set to > 63.
            if(new_ta > 63)
            {
               if(nci == 1)
               // Out of range TA must trigger a HO failure procedure.
               // GSM04.08, $3.4.4.4 and $10.5.2.39.
               {
                  // Send confirmation message to L3.
                  l1a_send_confirmation(MPHC_TA_FAIL_IND,RRM1_QUEUE);

                  // step in state machine.
                  *state = WAIT_MSG;

                  // Stop current L1A process.
                  return;
               }
               else
               // Max TA is 63.
               {
                  new_ta = 63;
               }
            }

            // Save computed TA in the new set.
            // This new TA shall be applied on 1st frame of new channel.
            free_set->new_timing_advance = (UWORD8)new_ta;
            free_set->timing_advance     = free_set->new_timing_advance;

#if ((REL99 == 1) && (FF_BHO == 1))
            free_set->nci                = nci;
            free_set->report_time_diff   = ((T_MPHC_SYNC_HO_REQ *)(msg->SigP))->handover_command.report_time_diff;

            if(SignalCode == MPHC_PSEUDO_SYNC_HO_REQ)
              free_set->real_time_difference = ((T_MPHC_PSEUDO_SYNC_HO_REQ *)(msg->SigP))->real_time_difference;
#endif
            // 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.
            // Save the "timeslot difference" between new and old configuration
            // in "tn_difference".
            //   tn_difference -> loaded with the number of timeslot to shift.
            //   dl_tn         -> loaded with the new timeslot.

#if ((REL99 == 1) && (FF_BHO == 1))
            if(l1a_l1s_com.dedic_set.handover_type == NORMAL_HANDOVER)
            {
#endif
            l1a_l1s_com.task_param[SYNCHRO] = SEMAPHORE_SET;
            {
              l1a_l1s_com.tn_difference += free_set->chan1.desc.timeslot_no - l1a_l1s_com.dl_tn;
              l1a_l1s_com.dl_tn         = free_set->chan1.desc.timeslot_no;  // Save new TN id.
            }
            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.
#if ((REL99 == 1) && (FF_BHO == 1))
            }
#endif //#if ((REL99 == 1) && (FF_BHO == 1))


            // Set "fset" pointer to the new parameter set.
            l1a_l1s_com.dedic_set.fset = free_set;

#if ((REL99 == 1) && (FF_BHO == 1))
            // check whether handover is Normal or Blind. If it is normal handover,
            // follow the normal path. Otherwise go to blind handover state.
            if(l1a_l1s_com.dedic_set.handover_type == NORMAL_HANDOVER)
            {
#endif // #if ((REL99 == 1) && (FF_BHO == 1))
            // Give new msg code to L1S.
            // Rem: only 2 cases handled by L1S, SYNC and ASYNC.
            if(SignalCode == MPHC_ASYNC_HO_REQ)
              l1a_l1s_com.dedic_set.SignalCode = MPHC_ASYNC_HO_REQ;
            else
              l1a_l1s_com.dedic_set.SignalCode = MPHC_SYNC_HO_REQ;


#if ((REL99 == 1) && (FF_BHO == 1))
              }
              else // Handover type is blind.
              {
                // step in state machine.
                free_set->HO_SignalCode = SignalCode;

                // Give new msg code to L1S. (below process is done by l1a_dedicated_process())
                l1a_l1s_com.dedic_set.SignalCode = MPHC_STOP_DEDICATED_REQ;

              }
#endif // #if ((REL99 == 1) && (FF_BHO == 1))
            #if (TRACE_TYPE==5) && FLOWCHART
              trace_flowchart_dedic(l1a_l1s_com.dedic_set.SignalCode);
            #endif

            // step in state machine.
            *state = WAIT_MSG;
          }
          break;

          case MPHC_HANDOVER_FAIL_REQ:
          // Handover failled, we must go back to the previous channel.
          //-----------------------------------------------------------
          {
            // Give back the previous configuration in the "fset" ptr.
            l1a_l1s_com.dedic_set.fset = static_ho_fail_aset;

            // Set confirmation message name.
            l1a.confirm_SignalCode = MPHC_HANDOVER_FAIL_CON;

            #if (TRACE_TYPE==5) && FLOWCHART
              trace_flowchart_dedic(SignalCode);
            #endif

            #if ((L1_EOTD==1) && (L1_EOTD_QBIT_ACC ==1))
              // Restore E-OTD serving cell time_alignmt and fn_offset
              // from the cached versions...

              l1a_l1s_com.nsync.serv_fn_offset = static_serv_fn_offset;
              l1a_l1s_com.nsync.serv_time_alignmt = static_serv_time_alignmt;
            #endif

            // Sub the serving cell timeslot number to the Neigh./Serving timing
            // difference to format it for L1S use.
            l1a_sub_timeslot(&static_ho_fail_time_alignmt,
                             &static_ho_fail_fn_offset,
                             l1a_l1s_com.dl_tn);

            // Setup new serving cell information.
            l1a_l1s_com.dedic_set.fset->cell_desc.time_alignmt = static_ho_fail_time_alignmt;
            l1a_l1s_com.dedic_set.fset->cell_desc.fn_offset    = static_ho_fail_fn_offset;

            // 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.
            // Since switching to a neigh cell, the known time_alignmt is about TN=0.
            // Set "tn_difference" with the new timeslot.
            //   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 += l1a_l1s_com.dedic_set.fset->chan1.desc.timeslot_no;
            l1a_l1s_com.dl_tn         = l1a_l1s_com.dedic_set.fset->chan1.desc.timeslot_no;  // Save new TN id.
            }
            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.

            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = SignalCode;

            // step in state machine.
            *state = WAIT_MSG;
          }
          break;

          case MPHC_STOP_DEDICATED_REQ:
          // Release dedicated mode message.
          //--------------------------------
          {
            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = SignalCode;

            #if (TRACE_TYPE==5) && FLOWCHART
              trace_flowchart_dedic(l1a_l1s_com.dedic_set.SignalCode);
            #endif

            // step in state machine.
            *state = WAIT_MSG;
          }
          break;

          case MPHC_CHANGE_FREQUENCY:
          // Frequency redefinition msg.
          //----------------------------
          {
            UWORD8          subchannel;

            // Get Ptr to the free dedicated parameter set.
            free_set = l1a_get_free_dedic_set();

            // Download Active set in the new set.
            *free_set = *l1a_l1s_com.dedic_set.aset;

            // Get subchannel for the target channel.
            subchannel = ((T_MPHC_CHANGE_FREQUENCY *)(msg->SigP))->channel_desc.subchannel;

            // Copy current parameters to BEF STI.
            free_set->chan1.desc_bef_sti   = free_set->chan1.desc;
            free_set->chan2.desc_bef_sti   = free_set->chan2.desc;
            free_set->ma.freq_list_bef_sti = free_set->ma.freq_list;

            // Download new param in AFTER STI.
            free_set->ma.freq_list = ((T_MPHC_CHANGE_FREQUENCY *)(msg->SigP))->frequency_list;
            if(subchannel == free_set->chan1.desc.subchannel)
              // Target channel is CHAN1.
              free_set->chan1.desc = ((T_MPHC_CHANGE_FREQUENCY *)(msg->SigP))->channel_desc;
            else
              // Target channel is CHAN2.
              free_set->chan2.desc = ((T_MPHC_CHANGE_FREQUENCY *)(msg->SigP))->channel_desc;

            // Compute starting time.
            free_set->neig_sti_fn = l1a_decode_starting_time(((T_MPHC_CHANGE_FREQUENCY *)(msg->SigP))->starting_time);
            free_set->serv_sti_fn = free_set->neig_sti_fn;

            // Set FREQUENCY REDEFINITION flag to trigger a confirmation when STI is reached.
            free_set->freq_redef_flag = TRUE;

            // Set "fset" pointer to the new parameter set.
            l1a_l1s_com.dedic_set.fset = free_set ;

            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = SignalCode;

            // step in state machine.
            *state = WAIT_MSG;
          }
          break;
        } // end of "switch(SignalCode)".

        // end of process.
        end_process = 1;
      }
      break;

      /*
       * FreeCalypso: the following logic related to dynamic DSP
       * patching has been reconstructed from our only available
       * binary object version.
       */
    #if (L1_DYN_DSP_DWNLD == 1)
      case WAIT_DYN_DWNLD:
      {
        if((SignalCode==API_L1_DYN_DWNLD_FINISHED) && (l1a.dyn_dwnld.semaphore_vect[DEDI_STATE_MACHINE] == GREEN))
        {
          /* replicate the code that would have executed originally */

          // Give new msg code to L1S.
          l1a_l1s_com.dedic_set.SignalCode = MPHC_IMMED_ASSIGN_REQ;

          #if (TRACE_TYPE==5) && FLOWCHART
            trace_flowchart_dedic(l1a_l1s_com.dedic_set.SignalCode);
          #endif

          // Set confirmation message name.
          l1a.confirm_SignalCode = MPHC_IMMED_ASSIGN_CON;

          #if ((TRACE_TYPE == 1) || (TRACE_TYPE == 4) || (TRACE_TYPE == 5))
            if((trace_info.current_config->l1_dyn_trace) & (1<<L1_DYN_TRACE_DYN_DWNLD))
            {
              char str[30];
              sprintf(str,"DEDI SM un-blocked\r\n");
              #if(CODE_VERSION == SIMULATION)
                 trace_fct_simu_dyn_dwnld(str);
              #else
                 rvt_send_trace_cpy((T_RVT_BUFFER)str,trace_info.l1_trace_user_id,strlen(str),RVT_ASCII_FORMAT);
              #endif
            }
          #endif    // (TRACE_TYPE == 1) || (TRACE_TYPE == 4)

          // step in state machine.
          *state = WAIT_MSG;
        }
        // End process
        end_process = 1;
      }
      break;
    #endif

      case WAIT_MSG:
      {
        switch(SignalCode)
        // switch on input message.
        //-------------------------------
        {
          case L1C_DEDIC_DONE:
          // Dedicated channel activated.
          //-----------------------------
          {
            // Send confirmation message to L3.
            l1a_send_confirmation(l1a.confirm_SignalCode,RRM1_QUEUE);

            // End of process.
            end_process = 1;
          }
          break;

          case L1C_REDEF_DONE:
          // Dedicated channel activated.
          //-----------------------------
          {
            // Send confirmation message to L3.
            l1a_send_confirmation(MPHC_CHANGE_FREQUENCY_CON,RRM1_QUEUE);

            // End of process.
            end_process = 1;
          }
          break;

          case L1C_HANDOVER_FINISHED:
          // HANDOVER finished.
          //-------------------
          {
            #if ((REL99 == 1) && (FF_BHO == 1))
              // Forwarding the BHO params to L2/L3.
              ((T_MPHC_HANDOVER_FINISHED *)(msg->SigP))->fn_offset = l1a_l1s_com.dedic_set.fn_offset;//static_nsync_bho.fn_offset;
              ((T_MPHC_HANDOVER_FINISHED *)(msg->SigP))->time_alignment = l1a_l1s_com.dedic_set.time_alignment;//static_nsync_bho.time_alignmt;
            #endif
            // Forward result message to L3.
            l1a_send_result(MPHC_HANDOVER_FINISHED, msg, RRM1_QUEUE);

            // End of process.

            end_process = 1;
          }
          break;

          case MPHC_CHANNEL_MODE_MODIFY_REQ:
          // New parameters are given concerning channel mode.
          //--------------------------------------------------
          {
            l1a_l1s_com.dedic_set.mode_modif.subchannel =
              ((T_MPHC_CHANNEL_MODE_MODIFY_REQ *)(msg->SigP))->subchannel;
            l1a_l1s_com.dedic_set.mode_modif.channel_mode =
              ((T_MPHC_CHANNEL_MODE_MODIFY_REQ *)(msg->SigP))->channel_mode;

            #if (AMR == 1)
              // download AMR ver 1.0 information
              l1a_l1s_com.dedic_set.mode_modif.amr_configuration =
                  ((T_MPHC_CHANNEL_MODE_MODIFY_REQ *)(msg->SigP))->amr_configuration;
              l1a_l1s_com.dedic_set.aset->cmip = C_AMR_CMIP_DEFAULT;
            #endif

            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = SignalCode;

            // Send confirmation message to L3.
            l1a_send_confirmation(MPHC_CHANNEL_MODE_MODIFY_CON,RRM1_QUEUE);

            // End of process.
            end_process = 1;
          }
          break;

          case OML1_CLOSE_TCH_LOOP_REQ:
          // Close TCH loop.
          //----------------
          // Rem: frame_erasure field is supposed to contain "Y" and "Z" bit from
          //      CLOSE_TCH_LOOP_CMD (GSM11.10 $36.2.4.1). Wait for confirmation
          //      from CAPDEBIS. WARNING!!!!!!!!!1
          //         frame_erasure  |  Loop  |  tch_loop
          //         ---------------|--------|-----------
          //                        |  none  |     0
          //              0         |   A    |     1
          //              1         |   B    |     2
          //              2         |   C    |     3
          //              3         |   D    |     4
          //              4         |   E    |     5
          //              5         |   F    |     6
          //              6         |   I    |     7

          {
            if(l1a_l1s_com.mode == DEDIC_MODE)
            // Command message is valid only when dedic. mode is running.
            {
              UWORD8 subchannel = ((T_OML1_CLOSE_TCH_LOOP_REQ *)(msg->SigP))->sub_channel;
              UWORD8 tch_loop   = ((T_OML1_CLOSE_TCH_LOOP_REQ *)(msg->SigP))->frame_erasure + 1;

              if(subchannel == l1a_l1s_com.dedic_set.aset->chan1.desc.subchannel)
              // Loop must be closed on CHAN1, this is done "on fly".
              {
                l1a_l1s_com.dedic_set.aset->chan1.tch_loop = tch_loop;
              }
              else
              // Loop must be closed on CHAN2, this is done "on fly".
              {
                l1a_l1s_com.dedic_set.aset->chan2.tch_loop = tch_loop;
              }

              // Send confirmation message to L3.
              l1a_send_confirmation(OML1_CLOSE_TCH_LOOP_CON,RRM1_QUEUE);
            }

            // End of process.
            end_process = 1;
          }
          break;

          case OML1_OPEN_TCH_LOOP_REQ:
          // Open TCH loop.
          //---------------
          {
            // Any loop is opened, this is done "on fly".
            l1a_l1s_com.dedic_set.aset->chan1.tch_loop = 0;
            l1a_l1s_com.dedic_set.aset->chan2.tch_loop = 0;

            // Send confirmation message to L3.
            l1a_send_confirmation(OML1_OPEN_TCH_LOOP_CON,RRM1_QUEUE);

            // End of process.
            end_process = 1;
          }
          break;

          case OML1_START_DAI_TEST_REQ:
          // Start DAI test.
          //----------------
          //         tested_device  | dai_mode  |    test
          //         ---------------|-----------|--------------------
          //              0         |     0     |  no test
          //              1         |     2     |  speech decoder
          //              2         |     1     |  speech encoder
          //              3         |     0     |  no test
          //              4         |     3     |  Acouustic devices
          {
            const UWORD8 dai_transcode[] = {0, 2, 1, 0, 3};
            const UWORD8 dai_vbctl3[] = {0, 1, 2, 0, 3};
            UWORD32   vbctl3;

            UWORD8 dai_mode = dai_transcode[((T_OML1_START_DAI_TEST_REQ *)(msg->SigP))->tested_device];

            // DAI mode is set "on fly".
            l1a_l1s_com.dedic_set.aset->dai_mode = dai_mode;

            // program vbctl3
            //      bit 12 |  bit 11
            //      ----------------
            //         1   |    1   Acouustic devices
            //         1   |    0   speech encoder
            //         0   |    1   speech decoder
            //         0   |    0   no test

            #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3) || (ANLG_FAM == 11))
              vbctl3 = ( (l1s_dsp_com.dsp_ndb_ptr ->d_dai_onoff & 0xE7FF) |
                       (dai_vbctl3[((T_OML1_START_DAI_TEST_REQ *)(msg->SigP))->tested_device] << 11) );
              l1s_dsp_com.dsp_ndb_ptr ->d_dai_onoff = vbctl3 | TRUE;
            #endif


            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = SignalCode;

            // Send confirmation message to L3.
            #if (OP_RIV_AUDIO == 1)
              l1a_audio_send_confirmation(OML1_START_DAI_TEST_CON);
            #else
              l1a_send_confirmation(OML1_START_DAI_TEST_CON,RRM1_QUEUE);
            #endif

            // End of process.
            end_process = 1;
          }
          break;

          case OML1_STOP_DAI_TEST_REQ:
          {
            UWORD32  vbctl3;

            // DAI test is stopped "on fly".
            l1a_l1s_com.dedic_set.aset->dai_mode = 0;

             #if ((ANLG_FAM == 1) || (ANLG_FAM == 2) || (ANLG_FAM == 3))
              // program vbctl3
              vbctl3 = (l1s_dsp_com.dsp_ndb_ptr ->d_dai_onoff & 0xE7FF);
              l1s_dsp_com.dsp_ndb_ptr ->d_dai_onoff = vbctl3 | TRUE;
            #endif

            // Give new msg code to L1S.
            l1a_l1s_com.dedic_set.SignalCode = SignalCode;

            // Send confirmation message to L3.
            #if (OP_RIV_AUDIO == 1)
              l1a_audio_send_confirmation(OML1_STOP_DAI_TEST_CON);
            #else
              l1a_send_confirmation(OML1_STOP_DAI_TEST_CON,RRM1_QUEUE);
            #endif

            // End of process.
            end_process = 1;
          }
          break;

          case MPHC_SET_CIPHERING_REQ:

          // Ciphering must be started or stopped.
          //--------------------------------------
          {
            if (l1a_l1s_com.dedic_set.handover_fail_mode)
            // The current state is the dedicated mode during an handover fail
            // the request must be ignored.
            // And a confirmation is returned to the L3.
            {
              // Send confirmation message to L3.
              l1a_send_confirmation(MPHC_SET_CIPHERING_CON,RRM1_QUEUE);
            }
            else
            {
              // GSM 4.08 $10.5.2.9 says (we suppose that "a5_algorithm" is
              // loaded with "algorithm identifier" and "cipher_mode" with
              // "SC").
              //  a5_algorithm from msg  |    A5 algo   | a5_algorithm in dedic set
              //  -----------------------|--------------|--------------------------
              //                         |              |          0 (no ciphering)
              //              0          |      A5/1    |          1
              //              1          |      A5/2    |          2
              //              2          |      A5/3    |          3
              //              3          |      A5/4    |          4
              //              4          |      A5/5    |          5
              //              5          |      A5/6    |          6
              //              6          |      A5/7    |          7

              UWORD8 cipher_mode  = ((T_MPHC_SET_CIPHERING_REQ *)(msg->SigP))->cipher_mode;

              l1a_l1s_com.dedic_set.aset->ciph_key = ((T_MPHC_SET_CIPHERING_REQ *)(msg->SigP))->new_ciph_param;

              if(cipher_mode != 0) // Save A5 algo.
                l1a_l1s_com.dedic_set.aset->a5mode = ((T_MPHC_SET_CIPHERING_REQ *)(msg->SigP))->a5_algorithm + 1;
              else // No cipering.
                l1a_l1s_com.dedic_set.aset->a5mode = 0;

              // Give new msg code to L1S.
              l1a_l1s_com.dedic_set.SignalCode = SignalCode;

              // Send confirmation message to L3.
              l1a_send_confirmation(MPHC_SET_CIPHERING_CON,RRM1_QUEUE);
            }

            end_process = 1;
          }
          break;

          case L1C_SACCH_INFO:
          // SACCH result messages.
          //-----------------------
          {
            // Forward result message to L3.
            l1a_send_result(PH_DATA_IND, msg, DLL1_QUEUE);

            // end of process.
            end_process = 1;
          }
          break;

          case L1C_STOP_DEDICATED_DONE:
          // Dedicated channel released
          //-----------------------------
          {
          #if ((REL99 == 1) && (FF_BHO == 1))
            // This event is disregarded in case of blind handover
            // (target cell synchro started)
            if(l1a_l1s_com.dedic_set.handover_type != BLIND_HANDOVER)
          #endif
            {
            // Send confirmation message to L3.
            l1a_send_confirmation(MPHC_STOP_DEDICATED_CON,RRM1_QUEUE);

            // Step in state machine.
            *state = RESET;
	      }

            // end of process.
            end_process = 1;
          }
          break;

          case MPHC_STOP_DEDICATED_REQ:
          case MPHC_CHANNEL_ASSIGN_REQ:
          case MPHC_SYNC_HO_REQ:
          case MPHC_PRE_SYNC_HO_REQ:
          case MPHC_PSEUDO_SYNC_HO_REQ:
          case MPHC_ASYNC_HO_REQ:
          case MPHC_HANDOVER_FAIL_REQ:
          case MPHC_CHANGE_FREQUENCY:
          // Reset messages.
          //----------------
          {
            // Step in state machine.
            *state = RESET;
          }
          break;
#if ((REL99 == 1) && (FF_BHO == 1))
          case L1C_FBSB_INFO:
          {
            T_DEDIC_SET  *free_set = l1a_l1s_com.dedic_set.fset;

            BOOL fb_found = ((T_L1C_FBSB_INFO*)(msg->SigP))->fb_flag;
            BOOL sb_found = ((T_L1C_FBSB_INFO*)(msg->SigP))->sb_flag;
            UWORD8 bsic   = ((T_L1C_FBSB_INFO*)(msg->SigP))->bsic;

            UWORD32  fn_offset = ((T_L1C_FBSB_INFO*)(msg->SigP))->fn_offset;
            UWORD32  time_alignmt = ((T_L1C_FBSB_INFO*)(msg->SigP))->time_alignmt;

            if ((fb_found == FALSE) ||
                (sb_found == FALSE) ||
                (bsic != free_set->cell_desc.bsic))
            // ------------------------
            // FB + SB detection failed
            // ------------------------
            {

              // Send reporting message with a faillure indication.
              xSignalHeaderRec *msg_new;

              msg_new = os_alloc_sig(sizeof(T_MPHC_HANDOVER_FINISHED));
              DEBUGMSG(status,NU_ALLOC_ERR)

              msg_new->SignalCode = MPHC_HANDOVER_FINISHED;

              if (fb_found == FALSE)
              {
                // FB attempt failed.
                ((T_MPHC_HANDOVER_FINISHED *)(msg_new->SigP))->cause = HO_FB_FAIL;
              }
              else // (fb_found == FALSE)
              {
                // SB attempt failed.
                // or BSIC is not matching.
                ((T_MPHC_HANDOVER_FINISHED *)(msg_new->SigP))->cause = HO_SB_FAIL;
              } // (fb_found == FALSE)

              l1a_send_result(MPHC_HANDOVER_FINISHED, msg_new, RRM1_QUEUE);

              // Reset handover to normal
              l1a_l1s_com.dedic_set.handover_type = 0;

              // End of process.
              end_process=1;//return;
            }
            else //((fb_found == FALSE) || (sb_found == FALSE) || (bsic != free_set->cell_desc.bsic))
            // -------------------------
            // FB + SB detection success
            // -------------------------
            {

              //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
              l1a_add_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);

              // update time_alignmt and fn_offset of new cell
              free_set->cell_desc.fn_offset = fn_offset;
              free_set->cell_desc.time_alignmt = time_alignmt;
              if(free_set->neig_sti_fn != -1)
                free_set->serv_sti_fn = (free_set->neig_sti_fn - free_set->cell_desc.fn_offset + MAX_FN) % MAX_FN;


              // This is to send across fn_offset and time_alignmt of new cell to L2/L3.
              l1a_l1s_com.dedic_set.fn_offset = fn_offset;
              l1a_l1s_com.dedic_set.time_alignment = time_alignmt;

              // reset handover to normal
              l1a_l1s_com.dedic_set.handover_type = 0;

              SignalCode = free_set->HO_SignalCode;

              // Save time difference between new serving and previous one
              // in case of HANDOVER FAIL.
              static_ho_fail_time_alignmt = (5000 - time_alignmt) % 5000;
              static_ho_fail_fn_offset = (1 + MAX_FN - fn_offset) % MAX_FN;

              if (time_alignmt == 0)
              // The 2 base stations are seen qbit synchronized...
              // -> Prevent frame diff. side effect.
              {
                static_ho_fail_fn_offset = (static_ho_fail_fn_offset + MAX_FN - 1) % MAX_FN;
              }

              // TIMING ADVANCED COMPUTATION...(GSM05.10)
              //-----------------------------------------
              switch(SignalCode)
              {
                case MPHC_SYNC_HO_REQ:
                case MPHC_PSEUDO_SYNC_HO_REQ:
                {
                  WORD32 t1_hbit;
                  WORD32 otd_hbit;
                  WORD32   new_ta = 0;
                  BOOL     nci    = 0;

                  if(SignalCode == MPHC_SYNC_HO_REQ)
                  // Synchronous Handover
                  {
                    nci = free_set->nci;
                  }

                  // Compute Timing Advance TA.
                  //---------------------------
                  // t1 = t0 + OTD - RTD (GSM05.10, $A1.3)
                  // OTD: Observed Time Difference. ( OTD = time(BTS0) - time(BTS1) )
                  // RTD: Report Time Difference.
                  // t0:  one way line of sight propagation MS-BTS0 (old BTS) ( t0 = TA(BTS0) / 2 ).
                  // t1:  one way line of sight propagation MS-BTS1 (new BTS) ( t1 = TA(BTS1) / 2 ).

                  // Convert QBO to Half bits (HBO)
                  otd_hbit = (time_alignmt / 2);

                  // If OTD is too high, it should be seen as a Negative value.
                  if(otd_hbit > 1250)
                  {
                    // Cell is advanced in timing from serving, hence TDMA arrives earlier
                    // => Smaller Timing Advance and OTD is -ve
                    otd_hbit -= 2500 ;
                  }
                  else
                  {
                    // Cell is retarted in timing from serving, hence TDMA arrives later
                    // => Larger Timing Advance and OTD is +ve
                  }

                  t1_hbit = (WORD32) (otd_hbit + (WORD32) static_ho_fail_aset->new_timing_advance);

                  if(t1_hbit < 0) t1_hbit = 0;

                  new_ta = t1_hbit;

                  // Ensure TA is never set to > 63.
                  if(new_ta > 63)
                  {
                    if(nci == 1)
                    // Out of range TA must trigger a HO failure procedure.
                    // GSM04.08, $3.4.4.4 and $10.5.2.39.
                    {
                      // Send confirmation message to L3.
                      l1a_send_confirmation(MPHC_TA_FAIL_IND,RRM1_QUEUE);

                      // End of process.
                      return;
                    }
                    else
                    // Max TA is 63.
                      {
                        new_ta = 63;
                      }
                    }

                    // Save computed TA in the new set.
                    // This new TA shall be applied on 1st frame of new channel.
                    free_set->new_timing_advance = (UWORD8)new_ta;
                    free_set->timing_advance     = free_set->new_timing_advance;
                  }
                  break;

                case MPHC_PRE_SYNC_HO_REQ:
                // Pre-Synchronous Handover...
                {
                  // no action for this message
                }
                break;

                case MPHC_ASYNC_HO_REQ:
                // Asynchronous Handover...
                {
                  // no action for this message
                }
                break;
              } // End switch...

              // 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 follow
              // the generic rules of the Semaphore shared between L1A and L1S.
              // Save the "timeslot difference" between new and old configuration
              // in "tn_difference".
              // 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 += free_set->chan1.desc.timeslot_no - l1a_l1s_com.dl_tn;
              l1a_l1s_com.dl_tn         = free_set->chan1.desc.timeslot_no;  // Save new TN id.

              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.

              // Give new msg code to L1S.
              // Rem: only 2 cases handled by L1S, SYNC and ASYNC.
              if(SignalCode == MPHC_ASYNC_HO_REQ)
              {
                l1a_l1s_com.dedic_set.SignalCode = MPHC_ASYNC_HO_REQ;
              }
              else
              {
                l1a_l1s_com.dedic_set.SignalCode = MPHC_SYNC_HO_REQ;
              }

              if (((l1a_l1s_com.dedic_set.SignalCode == MPHC_ASYNC_HO_REQ )
                 || (l1a_l1s_com.dedic_set.SignalCode == MPHC_SYNC_HO_REQ ))
                 && (l1a_l1s_com.dedic_set.aset != NULL)
                 && (l1a_l1s_com.l1s_en_task[DEDIC] == TASK_DISABLED))
                   l1a_l1s_com.l1s_en_task[DEDIC] = TASK_ENABLED;

              #if (TRACE_TYPE==5) && FLOWCHART
                 trace_flowchart_dedic(l1a_l1s_com.dedic_set.SignalCode);
              #endif

              // End of process.
              end_process=1;// return;
            } // if ((fb_found == FALSE) || (sb_found == FALSE) || (bsic != free_set->cell_desc.bsic))
          } // case L1C_FBSB_INFO:
          break;
#endif // #if ((REL99 == 1) && (FF_BHO == 1))
          default:
          // End of process.
          //----------------
          {
            end_process = 1;
          }
        } // end of "switch(SignalCode)".
      }
      break;
    } // end of "switch".
  } // end of "while"
} // end of procedure.

/*-------------------------------------------------------*/
/* l1a_dedic6_process()                                  */
/*-------------------------------------------------------*/
/* Description : This state machine handles the 6 strong.*/
/* neighbor cells management in dedicated mode.          */
/*                                                       */
/* Remark: in dedicated mode there is no reason to use   */
/* the task parameters semaphores since there is no      */
/* ambiguity and no asynchronous/synchronous conflict to */
/* care about.                                           */
/*                                                       */
/* Starting messages:        L1C_DEDIC_DONE              */
/*                                                       */
/* Result messages (input):  L1C_FB_INFO                 */
/*                           L1C_SB_INFO                 */
/*                           L1C_SBCONF_INFO             */
/*                                                       */
/* Reset messages (input):   MPHC_CHANNEL_RELEASE        */
/*                                                       */
/*-------------------------------------------------------*/
#if (L1_12NEIGH == 0)

void l1a_dedic6_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET              = 0,
    WAIT_INIT          = 1,
    WAIT_FB_RESULT     = 2,
    WAIT_SB_RESULT     = 3,
    WAIT_SBCONF_RESULT = 4
  };

         UWORD8  *state      = &l1a.state[DEDIC_6];
         UWORD32  SignalCode = msg->SignalCode;
  static UWORD8   nb_fb_attemp;

  // use only in packet transfer mode
  // these variables memorize this SBCNF parameters.
  static UWORD32  time_alignmt_mem;
  static UWORD32  fn_offset_mem;

  while(1)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset DEDIC6 tasks.
        l1a_l1s_com.l1s_en_task[SB51]    = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[FB51]    = TASK_DISABLED;

        l1a_l1s_com.l1s_en_task[SB26]    = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[FB26]    = TASK_DISABLED;

        l1a_l1s_com.l1s_en_task[SBCNF26] = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[SBCNF51] = TASK_DISABLED;
      }
      break;

      case WAIT_INIT:
      {
        #if (L1_GPRS)
          // This machine works only for DEDICATED MODE and PACKET TRANSFER MODE
          // (Remark: PACKET TRANSFER MODE activated == PDTCH task activated)
          if((l1a_l1s_com.mode != DEDIC_MODE) && (l1a_l1s_com.l1s_en_task[PDTCH] != TASK_ENABLED)) return;
        #else
          // This machine works only for DEDICATED MODE.
          if (l1a_l1s_com.mode != DEDIC_MODE) return;
        #endif


        if(SignalCode == MPHC_NCELL_FB_SB_READ)
        // Request to make a synchro. ACQUISITION attempt with the given ARFCN.
        //---------------------------------------------------------------------
        // L1 makes 1 attempt to read the Frequency Burst (FBNEW task).
        //          1 attempt to read the Synchro Burst (SB2 task).
        {
          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is the dedicated mode during an handover fail
          // the request must be ignored.
          // Therefor the reporting message with a faillure indication is sent back
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

            // Reset state machine.
            *state = RESET;

            // End of process.
            return;
          }
          else
          {
            // Set task semaphores.
            l1a_l1s_com.task_param[FB51] = SEMAPHORE_SET;     // Set FB51    task semaphore.
            l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;     // Set FB26    task semaphore.
            l1a_l1s_com.task_param[SB51] = SEMAPHORE_SET;     // Set SB51    task semaphore.
            l1a_l1s_com.task_param[SB26] = SEMAPHORE_SET;     // Set SB26    task semaphore.
            l1a_l1s_com.task_param[SBCNF51] = SEMAPHORE_SET;  // Set SBCNF51 task semaphore.
            l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;  // Set SBCNF26 task semaphore.

            // This process always use the first element of "nsync" structure.
            l1a_l1s_com.nsync.current_list_size = 0;

            // Download Radio Freq Nb from the command message.
            // Other "nsync" parameters are unused.
            l1a_l1s_com.nsync.list[0].radio_freq = ((T_MPHC_NCELL_FB_SB_READ *)(msg->SigP))->radio_freq;

            // Step in state machine.
            *state = WAIT_FB_RESULT;

            // Enable FB task.
            if (l1a_l1s_com.mode == DEDIC_MODE)
            {
               UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;

               if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
               {
                 nb_fb_attemp              = 1;           // 1 attempt for FB51 detection.
                 l1a_l1s_com.l1s_en_task[FB51] = TASK_ENABLED;
               }
               else
               {
                 nb_fb_attemp              = 11;          // 11 attempts for FB26 detection.
                 l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED;
               }
            }
            #if (L1_GPRS)
              else
              {  // packet transfer mode
                nb_fb_attemp                  = 11;          // 11 attempts for FB26 detection.
                l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED;
              }
            #endif

            // End of process.
            return;
          }
        }


        else
        if(SignalCode == MPHC_NCELL_SB_READ)
        // Request to make a synchro. CONFIRMATION attempt with the given ARFCN.
        //---------------------------------------------------------------------
        // L1 makes 1 attempt to read the Synchro Burst (SBCONF task).
        {
          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is the dedicated mode during an handover fail
          // The request must be ignored
          // Therefor the reporting message with a failure indication is sent back
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

            // Reset state machine.
            *state = RESET;

            // End of process.
            return;
          }
          else
          {
            UWORD32  time_alignmt;
            UWORD32  fn_offset;

            // Set semaphores for all neighbor relative task.
            l1a_l1s_com.task_param[FB51] = SEMAPHORE_SET;     // Set FB51    task semaphore.
            l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;     // Set FB26    task semaphore.
            l1a_l1s_com.task_param[SB51] = SEMAPHORE_SET;     // Set SB51    task semaphore.
            l1a_l1s_com.task_param[SB26] = SEMAPHORE_SET;     // Set SB26    task semaphore.
            l1a_l1s_com.task_param[SBCNF51] = SEMAPHORE_SET;  // Set SBCNF51 task semaphore.
            l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;  // Set SBCNF26 task semaphore.


            // Download ARFCN & timing information from the command message.
            time_alignmt = ((T_MPHC_NCELL_SB_READ *)(msg->SigP))->time_alignmt;
            fn_offset    = ((T_MPHC_NCELL_SB_READ *)(msg->SigP))->fn_offset;
            time_alignmt_mem = time_alignmt;
            fn_offset_mem    = fn_offset;

            // Sub the serving cell timeslot number to the Neigh./Serving timing
            // difference to format it for L1S use.
            l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
            l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

            // Save neighbor information in the neighbor confirmation cell structure.
            l1a_l1s_com.nsync.list[0].radio_freq   = ((T_MPHC_NCELL_SB_READ *)(msg->SigP))->radio_freq;
            l1a_l1s_com.nsync.list[0].time_alignmt = time_alignmt;
            l1a_l1s_com.nsync.list[0].fn_offset    = fn_offset;

            // Step in state machine.
            *state = WAIT_SBCONF_RESULT;

            // Enable SBCONF task.
            if (l1a_l1s_com.mode == DEDIC_MODE)
            {
              UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;

              if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
                l1a_l1s_com.l1s_en_task[SBCNF51] = TASK_ENABLED;
              else
                l1a_l1s_com.l1s_en_task[SBCNF26] = TASK_ENABLED;
            }
            #if (L1_GPRS)
              else
              {
                // packet transfer mode
                l1a_l1s_com.l1s_en_task[SBCNF26] = TASK_ENABLED;
              }
            #endif

            // End of process.
            return;
          }
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break; // case WAIT_INIT


      case WAIT_FB_RESULT:
      {
        // Use incoming message.
        //----------------------
        if(SignalCode == L1C_FB_INFO)
        {
          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is trhe dedicated mode during an handover fail
          // The monitoring task must be stopped
          // And the reporting message with a failure indication must be sent back
          {
            // Disable the FB detection task
            l1a_l1s_com.l1s_en_task[FB26] = TASK_DISABLED;

            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

            // Reset state machine.
            *state = RESET;
          }
          else
          {
            BOOL    fb_found;

            // get result from message parameters.
            fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

            if(fb_found == TRUE)
            // FB attempt is a success.
            //-------------------------
            {
              // Step in state machine.
              *state = WAIT_SB_RESULT;

              // Enable SB task.
              if (l1a_l1s_com.mode == DEDIC_MODE)
              {
                UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
                if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
                // case SDCCH, mutliframe 51...
                {
                  l1a_l1s_com.l1s_en_task[FB51] = TASK_DISABLED;  // Disable FB51 task.
                  l1a_l1s_com.task_param[SB51]  = SEMAPHORE_SET;  // Set synchro semaphore for SB51 task.
                  l1a_l1s_com.l1s_en_task[SB51] = TASK_ENABLED;   // Enable SB51.
                }
                else
                // Dedicated D26 mode or Packet Transfer mode.
                {
                  l1a_l1s_com.l1s_en_task[FB26] = TASK_DISABLED;  // Disable FB26 task.
                  l1a_l1s_com.task_param[SB26]  = SEMAPHORE_SET;  // Set synchro semaphore for SB26 task.
                  l1a_l1s_com.l1s_en_task[SB26] = TASK_ENABLED;   // Enable SB51.
                }
              }
              #if (L1_GPRS)
                else
                { // packet transfer mode
                  l1a_l1s_com.l1s_en_task[FB26] = TASK_DISABLED;  // Disable FB26 task.
                  l1a_l1s_com.task_param[SB26]  = SEMAPHORE_SET;  // Set synchro semaphore for SB26 task.
                  l1a_l1s_com.l1s_en_task[SB26] = TASK_ENABLED;   // Enable SB51.
                  l1a_l1s_com.nsync.list[0].sb26_attempt =0;
                }
              #endif

              // End of process.
              return;
            }
            else
            // FB attempt failed.
            //-------------------
            {
              // REM:
              // case SDCCH, mutliframe 51..., FB51: 1  attempt.
              // case TCH,   mutliframe 26..., FB26: 11 attempts.

              if(--nb_fb_attemp == 0)
              {
                // Disable the FB detection task
                l1a_l1s_com.l1s_en_task[FB26] = TASK_DISABLED;

                // Send reporting message with a faillure indication.
                l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

                // Reset state machine.
                *state = RESET;
              }
              else
                return;
            } // endif fb_found
          }// endif l1a_l1s_com.dedic_set.handover_fail_mode
        }
        else
        // test in mode D26: L1C_DEDIC_DONE
        if(SignalCode == L1C_DEDIC_DONE)
        // New channel activated.
        //-----------------------
        {
          UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
          //---------------------------------------------
          // We restart the FB detection from scratch !!!
          //---------------------------------------------

          // Set semaphores for all neighbor relative task.
          l1a_l1s_com.task_param[FB51] = SEMAPHORE_SET;  // Set FB51    task semaphore.
          l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;  // Set FB26    task semaphore.

          // Step in state machine.
          *state = WAIT_FB_RESULT;

          if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
          {
            nb_fb_attemp                  = 1;           // 1 attempt for FB51 detection.
            l1a_l1s_com.l1s_en_task[FB51] = TASK_ENABLED;
          }
          else
          {
            nb_fb_attemp                  = 11;          // 11 attempts for FB26 detection.
            l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED;
          }
          // End of process.
           return;
        }
        #if (L1_GPRS)
        else
          // a new synchronisation was performed
          if(((SignalCode == L1P_TRANSFER_DONE) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->tn_difference!=0))
             || (SignalCode == L1P_ALLOC_EXHAUST_DONE)
             || (SignalCode == L1P_REPEAT_ALLOC_DONE)
             || ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *) (msg->SigP))->tn_difference!=0) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all==0)))

          // New channel activated.
          //-----------------------
          {
            //---------------------------------------------
            // We restart the FB detection from scratch !!!
            //---------------------------------------------

            // Set semaphores for all neighbor relative task.
            l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;  // Set FB26    task semaphore.

            // Step in state machine.
            *state = WAIT_FB_RESULT;

            nb_fb_attemp                  = 11;          // 11 attempts for FB26 detection.
            l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED;

            // End of process.
             return;
          }
        #endif
        else
        #if (L1_GPRS)
          // End of packet transfer mode if TBF downlink and uplink have been released
          if((SignalCode == MPHC_STOP_DEDICATED_REQ) ||
            ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)))
        #else
          if(SignalCode == MPHC_STOP_DEDICATED_REQ)
        #endif
          // Reset messages.
          //----------------
          {
            // Step in state machine.
            *state = RESET;
          }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      case WAIT_SB_RESULT:
      {
        if(SignalCode == L1C_SB_INFO)
        // Synchro Burst acquisition attempt result.
        //------------------------------------------
        {
          BOOL  sb_found = ((T_L1C_SB_INFO *)(msg->SigP))->sb_flag;

          #if (L1_GPRS)
             static UWORD8 SB26_attempt_counter =0;
          #endif

          if(sb_found == TRUE)
          // SB detection is a success.
          {
            UWORD32  *fn_offset_ptr    = &(((T_L1C_SB_INFO *)(msg->SigP))->fn_offset);
            UWORD32  *time_alignmt_ptr = &(((T_L1C_SB_INFO *)(msg->SigP))->time_alignmt);

           #if (L1_GPRS)
              if(l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
              {
                SB26_attempt_counter = 0; // reset for next time
              }
            #endif


            // Correct "fn_offset" and "time_alignmt" to report the true
            // Serving/Neighbor time difference.
            //  1) Shift 20 bit since result is from a SB detection.
            //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
            l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
            l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);

            // This process must be reset.
            *state = RESET;
          }

          else
          // SB detection failled.
          {
          #if L1_GPRS
             if(l1a_l1s_com.l1s_en_task[DEDIC] == TASK_ENABLED)
         //---------------------------------------------
         // Dedicated mode tasks are enabled.
         //---------------------------------------------
            {
         #endif

               // Send reporting message with a faillure indication.
               l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

               // This process must be reset.
               *state = RESET;
        #if L1_GPRS
             }
        else
         if(l1a_l1s_com.l1s_en_task[PDTCH] == TASK_ENABLED)
         //---------------------------------------------
         // Packet Transfer mode task is enabled.
         //---------------------------------------------
         {

            SB26_attempt_counter++;

            if (SB26_attempt_counter >= 2)
            {
              // Send reporting message with a faillure indication.
              l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

              SB26_attempt_counter = 0;

              // This process must be reset.
              *state = RESET;
            }
            else
            {
                // End of process.
                return;
            }
         }
       #endif

          }
        }

        else
        // test in mode D26: L1C_DEDIC_DONE
        if (SignalCode == L1C_DEDIC_DONE)
        // New channel activated.
        //-----------------------
        {
          UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;
          //---------------------------------------------
          // We restart the FB detection from scratch !!!
          //---------------------------------------------

          // Disable SB26 and SB51
          l1a_l1s_com.l1s_en_task[SB51] = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[SB26] = TASK_DISABLED;

          // Set semaphores for all neighbor relative task.
          l1a_l1s_com.task_param[FB51] = SEMAPHORE_SET;  // Set FB51    task semaphore.
          l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;  // Set FB26    task semaphore.

          // Step in state machine.
          *state = WAIT_FB_RESULT;

          if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
          {
            nb_fb_attemp                  = 1;           // 1 attempt for FB51 detection.
            l1a_l1s_com.l1s_en_task[FB51] = TASK_ENABLED;
          }
          else
          {
            nb_fb_attemp                  = 11;          // 11 attempts for FB26 detection.
            l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED;
          }

          // End of process.
          return;
        }
        #if (L1_GPRS)
        else
          // a new synchronisation was performed
          if(((SignalCode == L1P_TRANSFER_DONE) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->tn_difference!=0))
             || (SignalCode == L1P_ALLOC_EXHAUST_DONE)
             || (SignalCode == L1P_REPEAT_ALLOC_DONE)
             || ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *) (msg->SigP))->tn_difference!=0) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all==0)))


          // New channel activated.
          //-----------------------
          {
            //---------------------------------------------
            // We restart the FB detection from scratch !!!
            //---------------------------------------------

            // Disable SB26 and SB51
            l1a_l1s_com.l1s_en_task[SB26] = TASK_DISABLED;

            // Set semaphores for all neighbor relative task.
            l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;  // Set FB26    task semaphore.

            // Step in state machine.
            *state = WAIT_FB_RESULT;

            nb_fb_attemp                  = 11;          // 11 attempts for FB26 detection.
            l1a_l1s_com.l1s_en_task[FB26] = TASK_ENABLED;

            // End of process.
            return;
          }
        #endif

        else
        #if (L1_GPRS)
          // in packet transfer mode: test PDTCH to be sure that TBF downlink and uplink are released
          if((SignalCode == MPHC_STOP_DEDICATED_REQ) ||
            ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)))
        #else
          if(SignalCode == MPHC_STOP_DEDICATED_REQ)
        #endif
        // Reset messages.
        //----------------
        {
          // Step in state machine.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;

      case WAIT_SBCONF_RESULT:
      {
        if(SignalCode == L1C_SBCONF_INFO)
        // Synchro Burst acquisition attempt result.
        //------------------------------------------
        {
          UWORD8  sb_found = ((T_L1C_SBCONF_INFO *)(msg->SigP))->sb_flag;

          if(sb_found == TRUE)
          // SB detection is a success.
          {
            UWORD32  *fn_offset_ptr    = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_offset);
            UWORD32  *time_alignmt_ptr = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->time_alignmt);

            // Correct "fn_offset" and "time_alignmt" to report the true
            // Serving/Neighbor time difference.
            //  1) Shift 20 bit since result is from a SB detection.
            //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
            l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
            l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);

            // This process must be reset.
            *state = RESET;
          }

          else
          // SB detection failled.
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

            // This process must be reset.
            *state = RESET;
          }
        }

        else
        #if (L1_GPRS)
          // a new synchronisation was performed
          if((SignalCode == L1C_DEDIC_DONE)
             || ((SignalCode == L1P_TRANSFER_DONE) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->tn_difference!=0))
             || ((SignalCode == L1P_TBF_RELEASED)  && (((T_L1P_TBF_RELEASED  *) (msg->SigP))->tn_difference!=0) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all==0))
             || (SignalCode == L1P_ALLOC_EXHAUST_DONE) || (SignalCode == L1P_REPEAT_ALLOC_DONE))
        #else
          if (SignalCode == L1C_DEDIC_DONE)
        #endif
        // New channel activated.
        //-----------------------
        {
          UWORD32  time_alignmt= 0; //omaps00090550
          UWORD32  fn_offset =0;    //omaps00090550

          // update the SBCNF26 parameters

          // disable SBCNF26 task
          l1a_l1s_com.l1s_en_task[SBCNF26] = TASK_DISABLED;

          // Set semaphores for SBCNF26 task.
          l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;

          time_alignmt = time_alignmt_mem;
          fn_offset    = fn_offset_mem;

          // Sub the serving cell timeslot number to the Neigh./Serving timing
          // difference to format it for L1S use.
          l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
          l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

          l1a_l1s_com.nsync.list[0].time_alignmt = time_alignmt;
          l1a_l1s_com.nsync.list[0].fn_offset    = fn_offset;

          l1a_l1s_com.l1s_en_task[SBCNF26] = TASK_ENABLED;

          // Step in state machine.
          *state = WAIT_SBCONF_RESULT;

          // End of process.
          return;
        }

        else
        #if (L1_GPRS)
          // End of packet transfer mode if TBF downlink and uplink have been released
          if((SignalCode == MPHC_STOP_DEDICATED_REQ) ||
            ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)))
        #else
          if(SignalCode == MPHC_STOP_DEDICATED_REQ)
        #endif
        // Reset messages.
        //----------------
        {
          // Step in state machine.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          // End of process.
          return;
        }
      }
      break;
    } // end of "switch".
  } // end of "while"
} // end of procedure.
#endif



//==================================================================//
//==================================================================//
//==================================================================//
//==================================================================//
//==================================================================//
//==================================================================//
//==================================================================//
#if (L1_12NEIGH ==1)
void l1a_dedic6_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET              = 0,
    WAIT_INIT          = 1,
    NSYNC_CONFIG       = 2,
    SELECT_BEST_NSYNC  = 3,
    WAIT_NSYNC_RESULT  = 4,
    STOP_NSYNC         = 5
    #if (L1_EOTD==1)
     ,SCELL_CONFIG     = 6
    #endif
  };

  UWORD8  *state      = &l1a.state[DEDIC_6];
  UWORD32  SignalCode = msg->SignalCode;

  //#if !L1_R99
  static UWORD8   nb_fb_attempt;
  //#endif

  // For EOTD purpose we need of flag to identify 1st/last SB Serving Cell
  #if (L1_EOTD==1)
    static BOOL  first_scell;
    static BOOL  last_scell;
    static BOOL  eotd_started;
  #endif

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // Step in state machine.
        *state = WAIT_INIT;

        // Reset of process is embbeded in other state to
        // avoid conflicts between processes using the same
        // L1S tasks (Initial Netwirk sync + Idle 6 strongest)
      }
      break;


      case WAIT_INIT:
      {
        #if (L1_GPRS)
          // This machine works only for DEDICATED MODE and PACKET TRANSFER MODE
          // (Remark: PACKET TRANSFER MODE activated == PDTCH task activated)
          if((l1a_l1s_com.mode != DEDIC_MODE) && (l1a_l1s_com.l1s_en_task[PDTCH] != TASK_ENABLED)) return;
        #else
          // This machine works only for DEDICATED MODE.
          if (l1a_l1s_com.mode != DEDIC_MODE) return;
        #endif

        // Request to make a synchro. ACQUISITION attempt with the given ARFCN.
        //---------------------------------------------------------------------
        if ((SignalCode == MPHC_NCELL_FB_SB_READ) || (SignalCode == MPHC_NCELL_SB_READ) ||
            (SignalCode == MPHC_NCELL_SYNC_REQ) ||(SignalCode == MPHC_NCELL_LIST_SYNC_REQ) )
        {
          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is the dedicated mode during an handover fail
          // So the monitoring tasks must ALL be stopped and the reporting
          // message with a failure indication must be sent back
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, 0);

            *state = STOP_NSYNC;
            break;
          }
          else
          {
            #if (L1_EOTD==1)
              // Check request validity for this process: for EOTD, nsync must be FREE...
              if( (SignalCode == MPHC_NCELL_LIST_SYNC_REQ) &&
                  (((T_MPHC_NCELL_LIST_SYNC_REQ *)(msg->SigP))->eotd == TRUE) &&
                  (l1a_l1s_com.nsync.current_list_size != 0) )
                // End of process.
                return;
            #endif

            l1a_l1s_com.nsync.first_in_list=0; //reset first_in_list

            // Set semaphores for all neighbor relative task.
            l1a_l1s_com.task_param[NSYNC]= SEMAPHORE_SET;     // Set NSYNC   task semaphore.
            l1a_l1s_com.task_param[FB51] = SEMAPHORE_SET;     // Set FB51    task semaphore.
            l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;     // Set FB26    task semaphore.
            l1a_l1s_com.task_param[SB51] = SEMAPHORE_SET;     // Set SB51    task semaphore.
            l1a_l1s_com.task_param[SB26] = SEMAPHORE_SET;     // Set SB26    task semaphore.
            l1a_l1s_com.task_param[SBCNF51] = SEMAPHORE_SET;  // Set SBCNF51 task semaphore.
            l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;  // Set SBCNF26 task semaphore.

            // Step in state machine.
            *state = NSYNC_CONFIG;
          }
        }

        // No action in this machine for other messages.
        else
        {
          // End of process.
          return;
        }
      }
      break;


      case NSYNC_CONFIG:
      {
        UWORD8   neigh_id = l1a_l1s_com.nsync.first_in_list;
        UWORD32  time_alignmt;
        UWORD32  fn_offset;

        // Request to acquire FB/SB or to confirm FB or SB from one ncell.
        //----------------------------------------------------------------
        // Abort if there is no room for a new neighbour synchro request.
        if(l1a_l1s_com.nsync.current_list_size >= NBR_NEIGHBOURS)
        {
          *state = WAIT_NSYNC_RESULT;
          // end of this process
          return;
        }

        // There is at least one free location within L1 structure. Find it!

        while((l1a_l1s_com.nsync.list[neigh_id].status != NSYNC_FREE))
        {
          neigh_id++;
          if (neigh_id == NBR_NEIGHBOURS) neigh_id=0;
        }

        // TEMPORARY Code to insure transition between
        // OLD and NEW "6 strongest Interface"
        //----------------------------------------------
        if (SignalCode == MPHC_NCELL_FB_SB_READ)
        {
          // Init timing_validity and read radio freq.
          l1a_l1s_com.nsync.list[neigh_id].timing_validity = 0;
          l1a_l1s_com.nsync.list[neigh_id].radio_freq = ((T_MPHC_NCELL_FB_SB_READ *)(msg->SigP))->radio_freq;
          l1a_l1s_com.nsync.list[neigh_id].time_alignmt = 0;
          l1a_l1s_com.nsync.list[neigh_id].fn_offset    = 0;

          // Ncell WAITING
          l1a_l1s_com.nsync.list[neigh_id].status  = NSYNC_WAIT;

          // Increment list size
          l1a_l1s_com.nsync.current_list_size += 1;
        }
        else
        if (SignalCode == MPHC_NCELL_SB_READ)
        {
          // Init timing_validity and read radio freq.
          l1a_l1s_com.nsync.list[neigh_id].timing_validity = 2;
          l1a_l1s_com.nsync.list[neigh_id].radio_freq   = ((T_MPHC_NCELL_SB_READ *)(msg->SigP))->radio_freq;
          time_alignmt = ((T_MPHC_NCELL_SB_READ *)(msg->SigP))->time_alignmt;
          fn_offset    = ((T_MPHC_NCELL_SB_READ *)(msg->SigP))->fn_offset;

          // Ncell WAITING
          l1a_l1s_com.nsync.list[neigh_id].status  = NSYNC_WAIT;

          // Increment list size
          l1a_l1s_com.nsync.current_list_size += 1;
        }
        else
        if (SignalCode == MPHC_NCELL_SYNC_REQ)
        {
          // Init timing_validity and read radio freq.
          l1a_l1s_com.nsync.list[neigh_id].timing_validity =((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->timing_validity;
          l1a_l1s_com.nsync.list[neigh_id].radio_freq = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq;

#if (L1_FF_MULTIBAND == 1)
          {
            UWORD8 physical_band_id;
            physical_band_id = 
                l1_multiband_radio_freq_convert_into_physical_band_id(l1a_l1s_com.nsync.list[neigh_id].radio_freq);
            L1_MULTIBAND_TRACE_PARAMS(MULTIBAND_PHYSICAL_BAND_TRACE_ID,multiband_rf[physical_band_id].gsm_band_identifier);
          }
#endif /*#if (L1_FF_MULTIBAND == 1)*/
          

          if (l1a_l1s_com.nsync.list[neigh_id].timing_validity != 0)
          {
            time_alignmt = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->time_alignmt;
            fn_offset    = ((T_MPHC_NCELL_SYNC_REQ *)(msg->SigP))->fn_offset;
            #if ((REL99 == 1) && (FF_RTD == 1)) // RTD feature
              if (l1a_l1s_com.nsync.list[neigh_id].timing_validity == 3)
              {
                l1a_l1s_com.nsync.list[neigh_id].nb_fb_attempt = 2 ;
                l1a_l1s_com.nsync.list[neigh_id].fb26_position = 255 ;
              }
            #endif
          }
          else
          {
            l1a_l1s_com.nsync.list[neigh_id].time_alignmt = 0;
            l1a_l1s_com.nsync.list[neigh_id].fn_offset    = 0;
          }

          // Ncell WAITING
          l1a_l1s_com.nsync.list[neigh_id].status  = NSYNC_WAIT;

          // Increment list size
          l1a_l1s_com.nsync.current_list_size += 1;
        }

        if ( (SignalCode == MPHC_NCELL_SYNC_REQ) || (SignalCode == MPHC_NCELL_SB_READ) )
        {
          // Correct timing info from request message with serving cell info.
          //-----------------------------------------------------------------
          if ( l1a_l1s_com.nsync.list[neigh_id].timing_validity != 0)
          {
            // correct timing
            l1a_correct_timing (neigh_id,time_alignmt,fn_offset);
          }
        }

        if ( SignalCode == MPHC_NCELL_LIST_SYNC_REQ )
        {
          // Request to read FB/SB or SB from 1 to 12 neighbour cells.
          //----------------------------------------------------------
          UWORD8  nbr_free = (UWORD8) (NBR_NEIGHBOURS) - l1a_l1s_com.nsync.current_list_size;
          UWORD8 list_size = ((T_MPHC_NCELL_LIST_SYNC_REQ *)(msg->SigP))->list_size;
          T_MPHC_NCELL_LIST_SYNC_REQ *pt = ((T_MPHC_NCELL_LIST_SYNC_REQ *)(msg->SigP));
          UWORD8  i;

          // Abort if there is no room for a new neighbour synchro request.
          if ( (l1a_l1s_com.nsync.current_list_size >= NBR_NEIGHBOURS) ||
               (nbr_free < list_size) )
          {
            *state = WAIT_NSYNC_RESULT;

            // end of this process
            return;
          }

          #if (L1_EOTD==1)
          // Abort if list is not empty before receiving EOTD request ...
          if ((pt->eotd == TRUE) && (l1a_l1s_com.nsync.current_list_size !=0))
          {
            *state = WAIT_NSYNC_RESULT;

            // end of this process
            return;
          }

            // store Eotd flag
            l1a_l1s_com.nsync.eotd_meas_session = pt->eotd;
          #endif

          // Download neighbour info from request message.
          //----------------------------------------------
          for (i=0; i<list_size; i++,neigh_id++)
          {
            if (neigh_id == NBR_NEIGHBOURS) neigh_id = 0;

            // Look for first free location within L1 structure.
            // There is at least one free location within L1 structure. Find it!
            while((l1a_l1s_com.nsync.list[neigh_id].status != NSYNC_FREE))
            {
              neigh_id++; if(neigh_id == NBR_NEIGHBOURS) neigh_id=0;;
            }

            l1a_l1s_com.nsync.list[neigh_id].radio_freq      = pt->ncell_list[i].radio_freq;
            l1a_l1s_com.nsync.list[neigh_id].timing_validity = pt->ncell_list[i].timing_validity;

            if( l1a_l1s_com.nsync.list[neigh_id].timing_validity != 0)
            {
              UWORD32  time_alignmt;
              UWORD32  fn_offset;

              // Download ARFCN, timing information and bitmap from the command message.
              time_alignmt   = pt->ncell_list[i].time_alignmt;
              fn_offset      = pt->ncell_list[i].fn_offset;

              // correct timing
              l1a_correct_timing (neigh_id,time_alignmt,fn_offset);
              #if ((REL99 == 1) && (FF_RTD == 1)) // RTD feature
                if (l1a_l1s_com.nsync.list[neigh_id].timing_validity == 3)
                {
                  l1a_l1s_com.nsync.list[neigh_id].nb_fb_attempt = 2 ;
                  l1a_l1s_com.nsync.list[neigh_id].fb26_position = 255 ;
                }
              #endif
            }
            else
            {
              l1a_l1s_com.nsync.list[neigh_id].fn_offset    = 0;
              l1a_l1s_com.nsync.list[neigh_id].time_alignmt = 0;
            }
             // set Ncell WAITING
            l1a_l1s_com.nsync.list[neigh_id].status  = NSYNC_WAIT;

            // Increment list size
            l1a_l1s_com.nsync.current_list_size += 1;

          } // end for
        } // end if MPHC_NCELL_LIST_SYNC_REQ

        #if (L1_EOTD ==1)
          if ( l1a_l1s_com.nsync.eotd_meas_session == TRUE)
          {
            // Step in state machine.
            *state = SCELL_CONFIG;
          }
          else
        #endif
        {
          // Step in state machine.
          *state = SELECT_BEST_NSYNC;
        }
      }
      break; // case NSYNC_CONFIG


      #if (L1_EOTD==1)
        case SCELL_CONFIG:
        {

          UWORD32 fn_offset=0;
          UWORD32 time_alignmt=0;

          // Enable L1S activity on the Serving Cell confirmation task
          // selects 1st Serving cell monitoring
          if (eotd_started == FALSE)
          {
             eotd_started = TRUE;
             first_scell    = TRUE;
          }
          // selects last Serving cell monitoring
          else
          {
             eotd_started = FALSE;
             last_scell   = TRUE;
          }

          // In Eotd : Serving cell is not part of the list
          //-----------------------------------------------
          // But it must be the 1st monitored
          // Sub the serving cell timeslot number to the Neigh./Serving timing
          // difference to format it for L1S use.
          #if (L1_EOTD_QBIT_ACC== 1)
            time_alignmt = l1a_l1s_com.nsync.serv_time_alignmt;
            fn_offset    = l1a_l1s_com.nsync.serv_fn_offset;
          #endif

          l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
          l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

          // Load Serving cell in last position [NBR_NEIGHBOURS]
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].radio_freq   = l1a_l1s_com.Scell_info.radio_freq;
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].fn_offset    = fn_offset;
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].time_alignmt = time_alignmt;
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].timing_validity = 2;
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].fn_offset_mem   = 0;
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].time_alignmt_mem= 0;

          // Increment list size
          l1a_l1s_com.nsync.current_list_size += 1;

          // Enable Serving cell monitoring
          l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status  = NSYNC_PENDING;
          l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

          // Step in state machine.
          *state = WAIT_NSYNC_RESULT;

          // End of process.
          return;
        }
      #endif

      case SELECT_BEST_NSYNC:
      {
        BOOL exec_pending_task = FALSE;
        UWORD8 id_acquisition;
        UWORD8 i = 0;

        // list empty return to STOP_NSYNC
        //---------------------------
        if (l1a_l1s_com.nsync.current_list_size == 0)
        {
          #if (L1_EOTD==1)
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
            {
              *state = SCELL_CONFIG;          // Step in state machine.
              break;
            }
            else
          #endif
          {
            *state = STOP_NSYNC;             // reset process
            break;
          }
        }

        // disable all tasks
        l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[FB51]  = TASK_DISABLED; 
        l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED; 
        l1a_l1s_com.l1s_en_task[SB51]  = TASK_DISABLED; 
        l1a_l1s_com.l1s_en_task[SB26]  = TASK_DISABLED; 
        l1a_l1s_com.l1s_en_task[SBCNF26]  = TASK_DISABLED; 
        l1a_l1s_com.l1s_en_task[SBCNF51]  = TASK_DISABLED; 

        // Set semaphores for all neighbor relative task.
        l1a_l1s_com.task_param[NSYNC]= SEMAPHORE_SET;     // Set NSYNC   task semaphore.
        l1a_l1s_com.task_param[FB51] = SEMAPHORE_SET;     // Set FB51    task semaphore.
        l1a_l1s_com.task_param[FB26] = SEMAPHORE_SET;     // Set FB26    task semaphore.
        l1a_l1s_com.task_param[SB51] = SEMAPHORE_SET;     // Set SB51    task semaphore.
        l1a_l1s_com.task_param[SB26] = SEMAPHORE_SET;     // Set SB26    task semaphore.
        l1a_l1s_com.task_param[SBCNF51] = SEMAPHORE_SET;  // Set SBCNF51 task semaphore.
        l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;  // Set SBCNF26 task semaphore.


        // Look if there is an ACQUISITION in progress (PENDING) in order to disable
        // other cells.
        // If MF51, ACQUISITION means FB and SB. If MF26, ACQUISITION means FB only
        //---------------------------------------------------------------------------
        // If so, let the new request in WAIT ...
        while ( (i<NBR_NEIGHBOURS) && (exec_pending_task==FALSE))
        {
          if (l1a_l1s_com.nsync.list[i].status == NSYNC_PENDING)
          {   // check FB or SB acquisition

             if ( l1a_l1s_com.nsync.list[i].timing_validity == 0 )
             {
                exec_pending_task = TRUE;
             }
             else if (l1a_l1s_com.mode == DEDIC_MODE)
             {
                UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;

              #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
                if( (l1a_l1s_com.nsync.list[i].timing_validity == SB_ACQUISITION_PHASE)
              #else
                if( (l1a_l1s_com.nsync.list[i].timing_validity == 3)
              #endif
                    &&((channel_type == SDCCH_4) || (channel_type == SDCCH_8)) )
                    exec_pending_task = TRUE;
             }
          }
          i++;
        }

        // If there is an ACQUISITION in progress, put all other tasks in WAIT
        //--------------------------------------------------------------------
        if (exec_pending_task == TRUE)
        {
          // if This SB acquisition comes from an FB CONFIRMATION, there may be some SB or
          // FB CONFIRMATIONS in PENDING state ==> put them in WAIT to insure FB/SB acquisition.
          UWORD8 cell_in_acquisition = i-1;

        #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
          if (l1a_l1s_com.nsync.list[cell_in_acquisition].timing_validity == SB_ACQUISITION_PHASE)
        #else
          if (l1a_l1s_com.nsync.list[cell_in_acquisition].timing_validity == 3)
        #endif
          { //This case is only for MF51
            for (i=0; i < NBR_NEIGHBOURS; i++)
              if ((l1a_l1s_com.nsync.list[i].status == NSYNC_PENDING) && (i != cell_in_acquisition))
                   l1a_l1s_com.nsync.list[i].status = NSYNC_WAIT;
          }

          // enable NSYNC
          l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

          // Step in state machine.
          *state = WAIT_NSYNC_RESULT;

          // End of process.
          return;
        }

        // Otherwise : may be some other tasks (everything but FB aquisition) to set PENDING
        // In case we are in MF51, these tasks are SB and FB confirmation
        // In case we are in MF26, these tasks are SB and FB confirmation and SB acquisition
        //------------------------------------------------------

        exec_pending_task = FALSE;
          for (i=0; i < NBR_NEIGHBOURS; i++)
        {
          if ( (l1a_l1s_com.nsync.list[i].status == NSYNC_WAIT) ||
               (l1a_l1s_com.nsync.list[i].status == NSYNC_PENDING) )
          {
            // set all other requested tasks PENDING
            if ( l1a_l1s_com.nsync.list[i].timing_validity != 0 )
            {
              l1a_l1s_com.nsync.list[i].status = NSYNC_PENDING;
              exec_pending_task = TRUE;
              // initialise FB attempts for FB CONFIRMATION
              if (l1a_l1s_com.nsync.list[i].timing_validity == 1)
              #if ((REL99 == 1) && (FF_BHO == 1))
                l1a_l1s_com.nsync.list[i].nb_fb_attempt = 1;
              #else
               nb_fb_attempt = 1;
              #endif
            }
          }
        }

        // If there are no pending task, perhaps there is an FB aquisition task to set pending.
        // In this case it is the older request, i.e. first_in_list.
        if (exec_pending_task == FALSE)
        {
          id_acquisition = l1a_l1s_com.nsync.first_in_list;
          // id has already been found.......
          l1a_l1s_com.nsync.list[id_acquisition].status = NSYNC_PENDING;

          if (l1a_l1s_com.mode == DEDIC_MODE)
          {
            UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;

            if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
            {
              #if ((REL99 == 1) && (FF_BHO == 1))
                if (l1a_l1s_com.nsync.list[id_acquisition].timing_validity != 3)
                  l1a_l1s_com.nsync.list[id_acquisition].nb_fb_attempt = 1;;
              #else
              nb_fb_attempt = 1;           // 1 attempt for FB51 detection.
              #endif
            }
            else
            {
              #if ((REL99 == 1) && (FF_BHO == 1))
                l1a_l1s_com.nsync.list[id_acquisition].nb_fb_attempt = 11;
              #else
              nb_fb_attempt = 11;          // 11 attempts for FB26 detection.
              #endif // #if ((REL99 == 1) && (FF_BHO == 1))
            }
          }
          #if (L1_GPRS)
          else
          {
            // packet transfer mode
            #if ((REL99 == 1) && (FF_BHO == 1))
              if (l1a_l1s_com.nsync.list[i].timing_validity == 0)
                l1a_l1s_com.nsync.list[id_acquisition].nb_fb_attempt = 11; // 11 attempts for FB26 detection.
              else if (l1a_l1s_com.nsync.list[i].timing_validity == 1)
                l1a_l1s_com.nsync.list[id_acquisition].nb_fb_attempt = 1;
            #else
            nb_fb_attempt  = 11;          // 11 attempts for FB26 detection.
            #endif //#if ((REL99 == 1) && (FF_BHO == 1))
          }
          #endif
        }

        // enable NSYNC
        l1a_l1s_com.l1s_en_task[NSYNC]           = TASK_ENABLED;

        // Step in state machine.
        *state = WAIT_NSYNC_RESULT;

        // End of process.
        end_process = 1;
      }
      break; // case SELECT_BEST_NSYNC

      case WAIT_NSYNC_RESULT:
      {

        if(SignalCode == L1C_FB_INFO)
        // Frequency Burst acquisition attempt result.
        //--------------------------------------------
        {
          BOOL    fb_found;
          UWORD8  neigh_id         = ((T_L1C_FB_INFO *)(msg->SigP))->neigh_id;
          UWORD16 neigh_radio_freq = ((T_L1C_FB_INFO *)(msg->SigP))->radio_freq;

          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_SYNC_REQ message has been received
          // in the same frame than this L1s message)
          #if ((REL99 == 1) && (FF_BHO == 1))
          if ((neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)||
              ((neigh_radio_freq == l1a_l1s_com.nsync.list[neigh_id].radio_freq)&&
              (l1a_l1s_com.nsync.list[neigh_id].status==NSYNC_FREE)))
          #else
           if (neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)
          #endif
          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is the dedicated mode during an handover fail
          // The monitoring tasks must be stopped
          // And the reporting message with a failure indication must be sent back
          {
            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);

            #if (L1_EOTD==1)
              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                // Stop Eotd session.
                l1a_l1s_com.nsync.eotd_meas_session = FALSE;

                // Set mode DEDIC
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;
              }
            #endif

            // This process must be reset
            *state = STOP_NSYNC;
            break;
          }

          // Get result from the message.
          fb_found = ((T_L1C_FB_INFO*)(msg->SigP))->fb_flag;

          if(fb_found == TRUE)
          // FB attempt is a success.
          // same process Now for DEDIC and PDTCH !!!!
          {
            // request was FB Confirmation + SB acquisition .....
          #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
            l1a_l1s_com.nsync.list[neigh_id].timing_validity = SB_ACQUISITION_PHASE ;
          #else
            l1a_l1s_com.nsync.list[neigh_id].timing_validity = 3;
          #endif
            l1a_l1s_com.nsync.list[neigh_id].sb26_attempt = 0;

            *state = SELECT_BEST_NSYNC;

            // Must break here to make sure the scheduler
            // runs immediately, else the next synchro attempt is not
            // started and we get a lock-up condition.
            break;
          }
          else
          // FB attempt failed.
          //-------------------
          {
          #if ((REL99 == 1) && (FF_RTD == 1)) // RTD feature
            if ((l1a_l1s_com.nsync.list[neigh_id].timing_validity != 0) && (l1a_l1s_com.mode == DEDIC_MODE))
            {
              UWORD8 channel_type = l1a_l1s_com.dedic_set.aset->achan_ptr->desc_ptr->channel_type;

              if((channel_type == SDCCH_4) || (channel_type == SDCCH_8))
                l1a_l1s_com.nsync.list[neigh_id].nb_fb_attempt = 1; // force attempt to 1 because we are in SDCCH
            }

            l1a_l1s_com.nsync.list[neigh_id].nb_fb_attempt-- ;
            if (l1a_l1s_com.nsync.list[neigh_id].nb_fb_attempt == 0)

          #else
            --nb_fb_attempt;
            if (nb_fb_attempt == 0)
          #endif
            {
              // if attempt was an FB confirmation, go back to FB full acquisition
              // and set it to WAIT state
              if (l1a_l1s_com.nsync.list[neigh_id].timing_validity == 1)
              {
                l1a_l1s_com.nsync.list[neigh_id].timing_validity = 0;
                l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_WAIT;

                // Step in state machine.
                *state = SELECT_BEST_NSYNC;

                // Must break here otherwise a SYNC IND (failure)
                // is generated for this event, when we really want the
                // FB acquisition to start from scratch with timing_validity=0.
                // If the subsequent process fails, then an indication will be
                // posted to L3.
                break;
              }

              // Send reporting message with a faillure indication.
              l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);

              // Remove cell from list.
              l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_FREE;
              l1a_l1s_com.nsync.current_list_size    -= 1;

              if ((l1a_l1s_com.nsync.current_list_size != 0) && (neigh_id == l1a_l1s_com.nsync.first_in_list))
              {
                while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
                {
                  l1a_l1s_com.nsync.first_in_list++;
                  if (l1a_l1s_com.nsync.first_in_list==NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
                }
              }
              // Step in state machine.
              *state = SELECT_BEST_NSYNC;

              // Must break here to make sure the scheduler
              // runs immediately, else the next synchro attempt is not
              // started and we get a lock-up condition.
              break;
            }
          #if ((REL99 == 1) && (FF_RTD == 1)) // RTD feature
            else
            {  // we have to restore timing information which are destroyed after fb search failure
             if (l1a_l1s_com.nsync.list[neigh_id].timing_validity == 3)
             {
              // restore timing and frame information
              l1a_l1s_com.nsync.list[neigh_id].fn_offset    = l1a_l1s_com.nsync.list[neigh_id].fn_offset_mem;
              l1a_l1s_com.nsync.list[neigh_id].time_alignmt = l1a_l1s_com.nsync.list[neigh_id].time_alignmt_mem;
              // apply timing correction
              l1a_correct_timing (neigh_id,l1a_l1s_com.nsync.list[neigh_id].time_alignmt,l1a_l1s_com.nsync.list[neigh_id].fn_offset);
             }
            }
          #endif
          } // End FB failed

          // End of process.
          return;

        } // End L1C_FB_INFO

        else
        if(SignalCode == L1C_SB_INFO)
        // Synchro Burst acquisition attempt result.
        //------------------------------------------
        {
          BOOL         sb_found    = ((T_L1C_SB_INFO *)(msg->SigP))->sb_flag;
          UWORD8       neigh_id    = ((T_L1C_SB_INFO *)(msg->SigP))->neigh_id;
          UWORD16 neigh_radio_freq = ((T_L1C_SB_INFO *)(msg->SigP))->radio_freq;

          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_SYNC_REQ message has been received
          // in the same frame than this L1s message)
          if (neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)
          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is the dedicated mode during an handover fail
          // The monitoring tasks must be stopped
          // And the reporting message with a failure indication must be sent back
          {

            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);

            #if (L1_EOTD==1)

              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                // Stop Eotd session.
                l1a_l1s_com.nsync.eotd_meas_session = FALSE;

                // Set mode DEDIC
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;
              }
            #endif

            // This process must be reset
            *state = STOP_NSYNC;
            break;
          }

          if (sb_found == TRUE)
          // SB detection is a success...
          //-----------------------------
          {
            // Read Results.
            UWORD32  *fn_offset_ptr    = &(((T_L1C_SB_INFO *)(msg->SigP))->fn_offset);
            UWORD32  *time_alignmt_ptr = &(((T_L1C_SB_INFO *)(msg->SigP))->time_alignmt);

            // Correct "fn_offset" and "time_alignmt" to report the true
            // Serving/Neighbor time difference.
            //  1) Shift 20 bit since result is from a SB detection.
            //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
            l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
            l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);

            #if (L1_EOTD==1)
              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                // compute EOTD data
                l1a_compute_Eotd_data(&first_scell,neigh_id, SignalCode, msg);

                // Set mode DEDIC
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;

                #if (L1_EOTD_QBIT_ACC   ==1)
                if (neigh_id != 12)
                {
                  l1a_compensate_sync_ind((T_MPHC_NCELL_SYNC_IND *)(msg->SigP));
                }
                if( (neigh_id == 12) && (last_scell== TRUE) )
                {
                  l1a_l1s_com.nsync.serv_fn_offset    = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset;
                  l1a_l1s_com.nsync.serv_time_alignmt = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt;
                }
                #endif
              }
            #endif

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
          }

          else
          // SB detection failed.
          {
            // Fix BUG2842 & BUG2864. In packet transfer SB aquisition task can be delayed
            // by a higer prioritary task. Two following attempts are re-scheduled.
            // First one can fail and we must not init process neither report any
            // failure indication to upper layers.
            if (l1a_l1s_com.nsync.list[neigh_id].sb26_attempt == 2)
            { // sb26_attempt = 2 : first attempt
              // sb26_attempt = 3 : second attempt
               return;
            }
            #if (L1_EOTD ==1)
              // Set mode DEDIC
              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;
                // Forward the result msg to L3.
                l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
              }
              else
            #endif

              // Send reporting message with a faillure indication.
              l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);
          }

          // Remove cell from list.
          l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_FREE;
          l1a_l1s_com.nsync.current_list_size    -= 1;

          #if (L1_EOTD ==1)
            // Stop EOTD monitoring after last Serving cell result
            //====================================================
            if (last_scell == TRUE)
          {
             l1a_l1s_com.nsync.eotd_meas_session = FALSE;
             *state = STOP_NSYNC;
          }
          else
          {
          #endif
            if ((l1a_l1s_com.nsync.current_list_size != 0) && (neigh_id == l1a_l1s_com.nsync.first_in_list))
            {
               while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
               {
                  l1a_l1s_com.nsync.first_in_list++;
                  if (l1a_l1s_com.nsync.first_in_list==NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
               }
            }
          // Step in state machine.
          *state = SELECT_BEST_NSYNC;
          #if (L1_EOTD ==1)
          }
          #endif

        } // End L1C_SB_INFO

        else
        if(SignalCode == L1C_SBCONF_INFO)
        // Synchro Burst confirmation attempt result.
        //-------------------------------------------
        {
          UWORD8  neigh_id        = ((T_L1C_SBCONF_INFO *)(msg->SigP))->neigh_id;
          BOOL    sb_found        = ((T_L1C_SBCONF_INFO *)(msg->SigP))->sb_flag;
          UWORD16 neigh_radio_freq = ((T_L1C_SBCONF_INFO *)(msg->SigP))->radio_freq;

          // Check if this neighbor wasn't removed from the list
          // (it's possible if MPHC_STOP_NCELL_SYNC_REQ message has been received
          // in the same frame than this L1s message)
          if (neigh_radio_freq != l1a_l1s_com.nsync.list[neigh_id].radio_freq)
          {
             //REM: the message is not sent to L3
             return;// Stay in current state.
          }

          if (l1a_l1s_com.dedic_set.handover_fail_mode)
          // The current state is the dedicated mode during an handover fail
          // The monitoring tasks must be stopped
          // And the reporting message with a failure indication must be sent back
          {

            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);

            #if (L1_EOTD==1)

              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                // Stop Eotd session.
                l1a_l1s_com.nsync.eotd_meas_session = FALSE;

                // Set mode DEDIC
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;
              }
            #endif

            // This process must be reset
            *state = STOP_NSYNC;
            break;
          }

          if(sb_found == TRUE)
          // SB detection is a success.
          {
            UWORD32  *fn_offset_ptr    = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->fn_offset);
            UWORD32  *time_alignmt_ptr = &(((T_L1C_SBCONF_INFO *)(msg->SigP))->time_alignmt);

            // Correct "fn_offset" and "time_alignmt" to report the true
            // Serving/Neighbor time difference.
            //  1) Shift 20 bit since result is from a SB detection.
            //  2) Add the serving cell timeslot number to the Serving/Neighbor time difference.
            l1a_add_time_for_nb(time_alignmt_ptr, fn_offset_ptr);
            l1a_add_timeslot(time_alignmt_ptr, fn_offset_ptr, l1a_l1s_com.dl_tn);

            #if (L1_EOTD==1)
              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                // compute EOTD data
                l1a_compute_Eotd_data(&first_scell,neigh_id,SignalCode,msg);

                // Set mode DEDIC
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;

                #if (L1_EOTD_QBIT_ACC ==1)
                  if (neigh_id != 12)
                  {
                     l1a_compensate_sync_ind((T_MPHC_NCELL_SYNC_IND *)(msg->SigP));
                  }
                  if( (neigh_id == 12) && (last_scell== TRUE) )
                  {
                     l1a_l1s_com.nsync.serv_fn_offset    = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->fn_offset;
                     l1a_l1s_com.nsync.serv_time_alignmt = ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->time_alignmt;
                  }
                #endif
              }
            #endif

            // Forward the result msg to L3.
            l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
          }

          else
          // SB detection failed.
          {
            #if (L1_EOTD ==1)
              // Set mode DEDIC
              if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              {
                ((T_MPHC_NCELL_SYNC_IND *)(msg->SigP))->mode = 1;
                // Forward the result msg to L3.
                l1a_send_result(MPHC_NCELL_SYNC_IND, msg, RRM1_QUEUE);
              }
              else
            #endif

            // Send reporting message with a faillure indication.
            l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, neigh_id);
          }

           // Disable a neigh sync. reading.
          l1a_l1s_com.nsync.list[neigh_id].status = NSYNC_FREE;
          l1a_l1s_com.nsync.current_list_size    -= 1;

           #if (L1_EOTD ==1)
          // reset first_scell flag
          first_scell = FALSE;

            // Stop EOTD monitoring after last Serving cell result
            //====================================================
          if (last_scell == TRUE)
          {
            l1a_l1s_com.nsync.eotd_meas_session = FALSE;
            *state = STOP_NSYNC;
          }
          else
          {
          #endif
            if ((l1a_l1s_com.nsync.current_list_size != 0) && (neigh_id == l1a_l1s_com.nsync.first_in_list))
            {
               while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
               {
                 l1a_l1s_com.nsync.first_in_list++;
                 if(l1a_l1s_com.nsync.first_in_list==NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
               }
            }
          // Step in state machine.
          *state = SELECT_BEST_NSYNC;
          #if (L1_EOTD ==1)
          }
          #endif


        } // End L1C_SBCONF_INFO

        else
        if((SignalCode == MPHC_NCELL_FB_SB_READ) || (SignalCode == MPHC_NCELL_SB_READ) ||
           (SignalCode == MPHC_NCELL_SYNC_REQ) || (SignalCode == MPHC_NCELL_LIST_SYNC_REQ))
        // New Request to READ the FB/SB or SB from a given carrier.
        // Request to READ the FB/SB or SB of 1 to 12 carriers.
        //--------------------------------------------------------
        {
          #if (L1_EOTD ==1)
            // during EOTD update of list is forbidden.....
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
              // Stay in current state.
              return;
            else
          #endif
          // Step in state machine.
          *state = NSYNC_CONFIG;
        } // End new NCELL REQ

        else
        if(SignalCode == MPHC_STOP_NCELL_SYNC_REQ)
        // Request to STOP neighbour cell activity for certain carriers.
        //--------------------------------------------------------------
        {
          UWORD8  i,j;
          UWORD8  array_size;

          array_size = ((T_MPHC_STOP_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq_array_size;

         #if (L1_EOTD ==1)
            // Only stop for ALL neighbours in list are accepted.
            if (l1a_l1s_com.nsync.eotd_meas_session == TRUE)
            {
              if ( (array_size != l1a_l1s_com.nsync.current_list_size) &&
                   (array_size != NBR_NEIGHBOURS) )
                // Stay in current state.
                return;
            }
            // Stop Eotd session.
            l1a_l1s_com.nsync.eotd_meas_session = FALSE;
          #endif

          // Disable neighbor sync. tasks.
          l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;
          l1a_l1s_com.l1s_en_task[FB51]  = TASK_DISABLED; 
          l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED; 
          l1a_l1s_com.l1s_en_task[SB51]  = TASK_DISABLED; 
          l1a_l1s_com.l1s_en_task[SB26]  = TASK_DISABLED; 
          l1a_l1s_com.l1s_en_task[SBCNF26]  = TASK_DISABLED; 
          l1a_l1s_com.l1s_en_task[SBCNF51]  = TASK_DISABLED; 

          if(array_size != NBR_NEIGHBOURS)
          {
            // Stop some of the Neighb. synchro.
            for(i=0;i<array_size;i++)
            {
              UWORD16  radio_freq = ((T_MPHC_STOP_NCELL_SYNC_REQ *)(msg->SigP))->radio_freq_array[i];

              // Search for same value within L1 structure.
              j=0;
              while(!((radio_freq == l1a_l1s_com.nsync.list[j].radio_freq) &&
                      (l1a_l1s_com.nsync.list[j].status != NSYNC_FREE)) &&
                    (j < NBR_NEIGHBOURS))
              {
                j++;
              }

              // If found, reset L1 structure for this carrier.
              if(j<NBR_NEIGHBOURS)
              {
                l1a_l1s_com.nsync.list[j].status = NSYNC_FREE;
                l1a_l1s_com.nsync.current_list_size --;
                #if 0	/* FreeCalypso: match TCS211 object */
                  if (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.active_fb_id].radio_freq == radio_freq)
                    l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED;
                #endif
              }
            }
          }
          else
          {
            // Stop all the Neighb. BCCH reading.
            l1a_l1s_com.nsync.current_list_size = 0;

            // clear also last location...
            for(i=0;i<NBR_NEIGHBOURS+1;i++)
              l1a_l1s_com.nsync.list[i].status = NSYNC_FREE;
          }

          // Send confirmation message to L3.
          l1a_send_confirmation(MPHC_STOP_NCELL_SYNC_CON,RRM1_QUEUE);

          // All neigh synchro have been removed.
          if(l1a_l1s_com.nsync.current_list_size == 0)
          {
            // Tasks already disabled.
            // This process must be reset.
            *state = STOP_NSYNC;
          }
          else
          {
            // Check if first in list was removed from the list. Go to next first in list
            while (l1a_l1s_com.nsync.list[l1a_l1s_com.nsync.first_in_list].status == NSYNC_FREE)
            {
              l1a_l1s_com.nsync.first_in_list++;
              if (l1a_l1s_com.nsync.first_in_list==NBR_NEIGHBOURS) l1a_l1s_com.nsync.first_in_list = 0;
            }

            // Set semaphores for all neighbor relative task before re-enebling NSYNC task.
            l1a_l1s_com.task_param[NSYNC]  = SEMAPHORE_SET;
            l1a_l1s_com.task_param[FB51]   = SEMAPHORE_SET;
            l1a_l1s_com.task_param[FB26]   = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SB51]   = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SB26]   = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SBCNF51] = SEMAPHORE_SET;
            l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;

            // Enable neighbour sync task.
            l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;

            // Step in state machine.
            *state = SELECT_BEST_NSYNC;
          }
        } // End MPHC_STOP_NCELL_SYNC_REQ

        else
        #if (L1_GPRS)
          // a new synchronisation was performed
          if ( (SignalCode == L1C_DEDIC_DONE)
            || ((SignalCode == L1P_TRANSFER_DONE) && (((T_L1P_TRANSFER_DONE *) (msg->SigP))->tn_difference!=0))
            || (SignalCode == L1P_ALLOC_EXHAUST_DONE)
            || (SignalCode == L1P_REPEAT_ALLOC_DONE)
            || ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *) (msg->SigP))->tn_difference!=0) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all==0)))
        #else  //L1_GPRS
            // test in mode D26: L1C_DEDIC_DONE : // New channel activated.
            if (SignalCode == L1C_DEDIC_DONE)
        #endif //L1_GPRS

              // New channel activated or new synchronisation was performed
              //-----------------------------------------------------------
            {
              UWORD32 time_alignmt;
              UWORD32 fn_offset;
              UWORD8  i;


              if ( (SignalCode == L1C_DEDIC_DONE) &&
                ((l1a.confirm_SignalCode == MPHC_SYNC_HO_CON) ||
                (l1a.confirm_SignalCode == MPHC_PRE_SYNC_HO_CON) ||
                (l1a.confirm_SignalCode == MPHC_ASYNC_HO_CON) ||
                (l1a.confirm_SignalCode == MPHC_HANDOVER_FAIL_CON)) )
              {
              #if 0	/* LoCosto L1 code, doesn't match TCS211 */
                l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;
                l1a_l1s_com.l1s_en_task[FB51]  = TASK_DISABLED;
                l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED;
                l1a_l1s_com.l1s_en_task[SB51]  = TASK_DISABLED;
                l1a_l1s_com.l1s_en_task[SB26]  = TASK_DISABLED;
                l1a_l1s_com.l1s_en_task[SBCNF26]  = TASK_DISABLED;
                l1a_l1s_com.l1s_en_task[SBCNF51]  = TASK_DISABLED;

                // In case of a handover, it is hard to update neighbor timings with timing changes.
                // Therefore all pending request are restarted as FB acquisition.
                // If an EOTD session was running, the 300 ms duration constraint of the session can't
                // be achieved. L1 returns a fail to L3 for the session.

              #if (L1_EOTD ==1)
                for(i=NBR_NEIGHBOURS+1;i>0;i--)
              #else
                for(i=0;i<NBR_NEIGHBOURS;i++)
              #endif
                {
                  if ( (l1a_l1s_com.nsync.list[i-1].status == NSYNC_PENDING)||
                     (l1a_l1s_com.nsync.list[i-1].status == NSYNC_WAIT) )
                  {
                    l1a_l1s_com.nsync.list[i-1].timing_validity = 0;
                    l1a_l1s_com.nsync.list[i-1].time_alignmt = 0;
                    l1a_l1s_com.nsync.list[i-1].fn_offset    = 0;
                    // force WAIT state
                    l1a_l1s_com.nsync.list[i-1].status = NSYNC_WAIT;

                  #if (L1_EOTD ==1)
                    if ( l1a_l1s_com.nsync.eotd_meas_session == TRUE )
                    {
                      //If an EOTD session is pending, return a fail for remaining requests
                      l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, i-1);
                    }
                  #endif
                  } // if
                } // for

              #if (L1_EOTD ==1)
                if ( l1a_l1s_com.nsync.eotd_meas_session == TRUE )
                {
                  // If the code goes there, an EOTD session is aborting.
                  // return a fail for last serving cell and reset L1A state machine
                  l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, NBR_NEIGHBOURS);
                  l1a_l1s_com.nsync.eotd_meas_session = FALSE;
                  *state = STOP_NSYNC;
                  break;
                }
                else
              #endif
                {
                  // Step in state machine.
                  *state = SELECT_BEST_NSYNC;

                  // Enable neighbour sync task.
                  l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;
                } // if
              #else
                /* code from TSM30 version, matches TCS211 object */
                #if (L1_EOTD ==1)
                  // FN and time reference are WRONG for remaining neigbours....
                  // --> abort all.
                  l1a_l1s_com.nsync.eotd_meas_session = FALSE;
                #endif
                // Step in state machine.
                *state = STOP_NSYNC;                
                break;
              #endif
              } // if

            else
            {
              // Channel changes : Restart all neighbors
              //-----------------------------------------
              // propagate new dl_tn to all neigbours remaining in EOTD_list !!!
              // Reset process. and then restart all tasks.
              l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[FB51]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SB51]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SB26]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SBCNF26]  = TASK_DISABLED;
              l1a_l1s_com.l1s_en_task[SBCNF51]  = TASK_DISABLED;

#if (L1_EOTD ==1)
              for(i=0;i<NBR_NEIGHBOURS+1;i++)
#else
                for(i=0;i<NBR_NEIGHBOURS;i++)
#endif
                {
                  if ( (l1a_l1s_com.nsync.list[i].status == NSYNC_PENDING)||
                    (l1a_l1s_com.nsync.list[i].status == NSYNC_WAIT) )
                  {
                    // reset SB acquisitions : need to restart from FB !!!!
                  #if ((REL99 == 1) && ((FF_BHO == 1) || (FF_RTD == 1)))
                    if (l1a_l1s_com.nsync.list[i].timing_validity == SB_ACQUISITION_PHASE)
                  #else
                    if( l1a_l1s_com.nsync.list[i].timing_validity == 3 )   // SB acquisition
                  #endif
                    {
                      l1a_l1s_com.nsync.list[i].timing_validity = 0;
                    #if ((REL99 == 1) && (FF_BHO == 1))
                      l1a_l1s_com.nsync.list[i].status = NSYNC_WAIT ;
                     #endif
                    }

                    // FB or SB Confirmations : update timing info
                    if ((l1a_l1s_com.nsync.list[i].timing_validity == 2) || // SB confirmation
                      (l1a_l1s_com.nsync.list[i].timing_validity == 1))   // FB confirmation
                    {
                      // update the SBCNF26 parameters
#if (L1_EOTD==1)
                      if ( (i==12) && (l1a_l1s_com.nsync.eotd_meas_session == TRUE))
                      {
                        // Sub the serving cell timeslot number to the Neigh./Serving timing
                        // difference to format it for L1S use.
#if (L1_EOTD_QBIT_ACC== 1)
                        time_alignmt = l1a_l1s_com.nsync.serv_time_alignmt;
                        fn_offset    = l1a_l1s_com.nsync.serv_fn_offset;
#else
                        time_alignmt = l1a_l1s_com.nsync.list[i].time_alignmt_mem;
                        fn_offset    = l1a_l1s_com.nsync.list[i].fn_offset_mem;
#endif
                        l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].fn_offset_mem   = 0;
                        l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].time_alignmt_mem= 0;
                      }
                      else
#endif
                      {
                        time_alignmt = l1a_l1s_com.nsync.list[i].time_alignmt_mem;
                        fn_offset    = l1a_l1s_com.nsync.list[i].fn_offset_mem;
                      }

                      // Sub the serving cell timeslot number to the Neigh./Serving timing
                      // difference to format it for L1S use.
                      l1a_sub_timeslot(&time_alignmt, &fn_offset, l1a_l1s_com.dl_tn);
                      l1a_sub_time_for_nb(&time_alignmt, &fn_offset);

                      l1a_l1s_com.nsync.list[i].time_alignmt = time_alignmt;
                      l1a_l1s_com.nsync.list[i].fn_offset    = fn_offset;
                    }

                    // force WAIT state
                    l1a_l1s_com.nsync.list[i].status = NSYNC_WAIT;
                  }
                }
                //------------------------------------------------------------
                // We restart the FB/SB and SBCONF detection from scratch !!!
                //------------------------------------------------------------
                // Set semaphores for all neighbor relative task before re-enebling NSYNC task.
                l1a_l1s_com.task_param[NSYNC]  = SEMAPHORE_SET;
                l1a_l1s_com.task_param[FB51]   = SEMAPHORE_SET;
                l1a_l1s_com.task_param[FB26]   = SEMAPHORE_SET;
                l1a_l1s_com.task_param[SB51]   = SEMAPHORE_SET;
                l1a_l1s_com.task_param[SB26]   = SEMAPHORE_SET;
                l1a_l1s_com.task_param[SBCNF51] = SEMAPHORE_SET;
                l1a_l1s_com.task_param[SBCNF26] = SEMAPHORE_SET;

                // For EOTD : if the 1st serving cell SB is pending
                // or if last serving cell SB is pending
                // (when the channel change occured),we must re-start from 1st SB
                // of serving cell.
                //
                // during WAIT_NSYNC_RESULT
                // =========================
                //    first_scell  eotd_started last_scell
                //      T           T         F       waiting for 1st SB Serving cell
                //      F           T         F       waiting for SBs Neighbor cells
                //      F           F         T       waiting for Last SB Serving cell
                //      F           F         F       no EOTD
                //
#if (L1_EOTD == 1)
                if ( (first_scell == TRUE) || (last_scell == TRUE))
                {
                  // force PENDING state  for SERVING CELL
                  l1a_l1s_com.nsync.list[NBR_NEIGHBOURS].status = NSYNC_PENDING;

                  // Step in state machine.
                  *state = WAIT_NSYNC_RESULT;

                  // Enable neighbour sync task.
                  l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;


                  // Must be a return there otherwise there is a lockup on
                  // handover/channel changes test condition (need to free
                  // this message...)
                  return;
                }
#endif
                // Step in state machine.
                *state = SELECT_BEST_NSYNC;

                // Enable neighbour sync task.
                l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;
         }  // end Else
       }  // End CHANNEL CHANGE or HANDOVERS

       else
       #if (L1_GPRS)
         // End of packet transfer mode if TBF downlink and uplink have been released
          if((SignalCode == MPHC_STOP_DEDICATED_REQ) ||
             ((SignalCode == L1P_TBF_RELEASED) && (((T_L1P_TBF_RELEASED *)(msg->SigP))->released_all)))
       #else
          if(SignalCode == MPHC_STOP_DEDICATED_REQ)
       #endif
       // Reset messages.
       //----------------
       {
         #if (L1_EOTD==1)
           // Stop Eotd session.
           l1a_l1s_com.nsync.eotd_meas_session = FALSE;
         #endif

          // Step in state machine.
          *state = STOP_NSYNC;
        }
#if ((REL99 == 1) && (FF_BHO == 1))
        else
        if( ((SignalCode == MPHC_SYNC_HO_REQ) ||
             (SignalCode == MPHC_PRE_SYNC_HO_REQ) ||
             (SignalCode == MPHC_PSEUDO_SYNC_HO_REQ) ||
             (SignalCode == MPHC_ASYNC_HO_REQ)
            )
         && (l1a_l1s_com.dedic_set.handover_type == BLIND_HANDOVER) )
         {
           UWORD8 i;

           l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;
           l1a_l1s_com.l1s_en_task[FB51]  = TASK_DISABLED;
           l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED;
           l1a_l1s_com.l1s_en_task[SB51]  = TASK_DISABLED;
           l1a_l1s_com.l1s_en_task[SB26]  = TASK_DISABLED;
           l1a_l1s_com.l1s_en_task[SBCNF26]  = TASK_DISABLED;
           l1a_l1s_com.l1s_en_task[SBCNF51]  = TASK_DISABLED;

           // In case of a handover, it is hard to update neighbor timings with timing changes.
           // Therefore all pending request are restarted as FB acquisition.
           // If an EOTD session was running, the 300 ms duration constraint of the session can't
           // be achieved. L1 returns a fail to L3 for the session.
         #if (L1_EOTD ==1)
           for(i=NBR_NEIGHBOURS+1;i>0;i--)
         #else
           for(i=0;i<NBR_NEIGHBOURS;i++)
         #endif
           {
             if ( (l1a_l1s_com.nsync.list[i-1].status == NSYNC_PENDING)||
                  (l1a_l1s_com.nsync.list[i-1].status == NSYNC_WAIT) )
             {
               l1a_l1s_com.nsync.list[i-1].timing_validity = 0;
               l1a_l1s_com.nsync.list[i-1].time_alignmt = 0;
               l1a_l1s_com.nsync.list[i-1].fn_offset    = 0;
               // force WAIT state
               l1a_l1s_com.nsync.list[i-1].status = NSYNC_WAIT;

             #if (L1_EOTD ==1)
               if ( l1a_l1s_com.nsync.eotd_meas_session == TRUE )
               {
                 //If an EOTD session is pending, return a fail for remaining requests
                 l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, i-1);
               }
             #endif
             } // if
           } // for

         #if (L1_EOTD ==1)
           if ( l1a_l1s_com.nsync.eotd_meas_session == TRUE )
           {
             // If the code goes there, an EOTD session is aborting.
             // return a fail for last serving cell and reset L1A state machine
             l1a_report_failling_ncell_sync(MPHC_NCELL_SYNC_IND, NBR_NEIGHBOURS);
             l1a_l1s_com.nsync.eotd_meas_session = FALSE;
             *state = STOP_NSYNC;
             break;
           }
           else
         #endif
           {
             // Step in state machine.
             *state = SELECT_BEST_NSYNC;

             // Enable neighbour sync task.
             l1a_l1s_com.l1s_en_task[NSYNC] = TASK_ENABLED;
           } // if
         }
#endif // #if ((REL99 == 1) && (FF_BHO == 1))
        // No action in this machine for other messages.
        else
        {
          // End of process.
          return;
        }
      }
      break;

      case STOP_NSYNC:
      {
        UWORD8 i;

        // Reset process.
        // WARNING : NSYNC task and nsync_list are COMMON to dedic and Idle....
        l1a_l1s_com.l1s_en_task[FB51]  = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[FB26]  = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[SB51]  = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[SB26]  = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[SBCNF26]  = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[SBCNF51]  = TASK_DISABLED;
        l1a_l1s_com.l1s_en_task[NSYNC] = TASK_DISABLED;

        // Disable all neigh sync. reading.
        l1a_l1s_com.nsync.current_list_size   = 0;


#if (L1_EOTD==1)
        // reset EOTD flags
        first_scell  =FALSE;
        last_scell   =FALSE;
        eotd_started =FALSE;
        l1a_l1s_com.nsync.eotd_toa_phase = 0;
        l1a_l1s_com.nsync.eotd_meas_session = FALSE;
        l1a_l1s_com.nsync.eotd_cache_toa_tracking = 0;
        l1a_l1s_com.nsync.eotd_toa_tracking = 0;
        for (i=0; i<NBR_NEIGHBOURS+1; i++) l1a_l1s_com.nsync.list[i].status = NSYNC_FREE;
#else
        for (i=0; i<NBR_NEIGHBOURS; i++) l1a_l1s_com.nsync.list[i].status = NSYNC_FREE;
#endif
        // Step in state machine.
        *state = WAIT_INIT;

        // End of process
        end_process = 1;

      }
      break;

    } // end of "switch".
  } // end of "while"
} // end of procedure.

#endif

/*-------------------------------------------------------*/
/* l1a_dedic_ba_list_meas_process()                      */
/*-------------------------------------------------------*/
/* Description : This state machine handles neigbor cell */
/* measurement process in DEDICATED mode with BA list.   */
/*                                                       */
/* Starting messages:        L1C_DEDIC_DONE              */
/* ------------------                                    */
/*  L1 starts then the periodic BA list receive level    */
/*  monitoring.                                          */
/*                                                       */
/* Subsequent messages:      MPHC_UPDATE_BA_LIST         */
/* --------------------                                  */
/*  L1 changes the BA list and starts the periodic BA    */
/*  list receive level monitoring with this new list.    */
/*                                                       */
/* Result messages (input):  L1C_MEAS_DONE               */
/* ------------------------                              */
/*  This is the periodic reporting message from L1s.     */
/*                                                       */
/* Result messages (output): MPHC_MEAS_REPORT            */
/* -------------------------                             */
/*  This is the periodic reporting message to L3.        */
/*                                                       */
/* Reset messages (input):   MPHC_STOP_DEDICATED_REQ     */
/* -----------------------                               */
/*  BA list neigbor cell measurement process in DEDICATED*/
/*  is stopped by this message.                          */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_dedic_ba_list_meas_process(xSignalHeaderRec *msg)
{
  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1,
    WAIT_RESULT = 3

  };

          UWORD8  *state      = &l1a.state[D_NMEAS];
          UWORD32  SignalCode = msg->SignalCode;
  static  BOOL     meas_valid;

  BOOL end_process = 0;
  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
        // step in state machine.
        *state = WAIT_INIT;

        // Reset D_NMEAS process.
        l1a_l1s_com.l1s_en_meas &= D_BAMS_MEAS_MASK; // Reset D_BAMS Measurement enable flag.
      }
      break;

      case WAIT_INIT:
      {
#if 0	/* FreeCalypso: match TCS211 object */

#if (OP_SAP == 0)
        if (SignalCode == MPHC_UPDATE_BA_LIST)
#else
        if (SignalCode == MPHC_UPDATE_BA_LIST_REQ)
#endif /* if (OP_SAP == 0) */
        // One reporting period has been completed.
        //-----------------------------------------
        {
          UWORD16 i;

          // Set parameter synchro semaphore for D_BAMS task.
          l1a_l1s_com.meas_param |= D_BAMS_MEAS;

          // Reset the BA list structure.
          l1a_reset_ba_list();

          // Next measurement report must indicate INVALID.
          meas_valid = FALSE;

          // Enable Dedicated mode BA list measurement task.
          l1a.l1a_en_meas[D_NMEAS] |= D_BAMS_MEAS;

          // Reset present flag to avoid to mix 2 updates in case of
          // an update already pending within "l1a_l1s_com.ba_list.new_list".
          // This case can occur after a Handover and both previous and new
          // serving cells are requesting an update.
          l1a_l1s_com.ba_list.new_list_present = FALSE;

          // Download new list within L1A_L1S_COM structure.
#if (OP_SAP == 0)
          l1a_l1s_com.ba_list.new_list = *((T_MPHC_UPDATE_BA_LIST *)(msg->SigP));
#else
          l1a_l1s_com.ba_list.new_list = *((T_MPHC_UPDATE_BA_LIST_REQ *)(msg->SigP));
#endif /* if (OP_SAP == 0) */

            // Download new list.
          for(i=0;i<l1a_l1s_com.ba_list.new_list.num_of_chans;i++)
          {
#if (OP_SAP == 0)
            l1a_l1s_com.ba_list.A[i].radio_freq = l1a_l1s_com.ba_list.new_list.chan_list.A[i];
#else
            l1a_l1s_com.ba_list.A[i].radio_freq = l1a_l1s_com.ba_list.new_list.chan_list.BA[i];
#endif  /* if (OP_SAP == 0) */

          }

          l1a_l1s_com.ba_list.ba_id       = l1a_l1s_com.ba_list.new_list.ba_id;
          l1a_l1s_com.ba_list.nbr_carrier = l1a_l1s_com.ba_list.new_list.num_of_chans;

          // Set present flag only when the list has been downloaded.
          l1a_l1s_com.ba_list.new_list_present = TRUE;

          // step in state machine.
          *state = WAIT_RESULT;
        }
        else
#endif	/* FreeCalypso TCS211 reconstruction */

        if(SignalCode == L1C_DEDIC_DONE)
        // We enter DEDICATED mode.
        //-------------------------
        {
#if 0	/* FreeCalypso: match TCS211 object */
#if (CODE_VERSION == NOT_SIMULATION)
          if (l1a_l1s_com.ba_list.nbr_carrier == 0)
             return;
#endif
#endif

          // Set parameter synchro semaphore for D_BAMS task.
          l1a_l1s_com.meas_param |= D_BAMS_MEAS;

          // Reset the BA list structure.
          l1a_reset_ba_list();

          // Next measurement report must indicate INVALID.
          meas_valid = FALSE;

          // Enable Dedicated mode BA list measurement task.
          l1a.l1a_en_meas[D_NMEAS] |= D_BAMS_MEAS;

          // step in state machine.
          *state = WAIT_RESULT;
        }

        // End of process.
        end_process = 1;
      }
      break;

      case WAIT_RESULT:
      {
        if(SignalCode == L1C_MEAS_DONE)
        // One reporting period has been completed.
        //-----------------------------------------
        {
          // Fill "meas_valid" parameter.
          ((T_MPHC_MEAS_REPORT*)(msg->SigP))->meas_valid = meas_valid;

          // Forward result message to L3.
          l1a_send_result(MPHC_MEAS_REPORT, msg, RRM1_QUEUE);

          // Next measurement report must indicate VALID.
          meas_valid = TRUE;

          // End of process.
          return;
        }

        if(SignalCode == MPHC_UPDATE_BA_LIST)
        // One reporting period has been completed.
        //-----------------------------------------
        {
          // Reset present flag to avoid to mix 2 updates in case of
          // an update already pending within "l1a_l1s_com.ba_list.new_list".
          // This case can occur after a Handover and both previous and new
          // serving cells are requesting an update.
          l1a_l1s_com.ba_list.new_list_present = FALSE;

          // Download new list within L1A_L1S_COM structure.
          l1a_l1s_com.ba_list.new_list = *((T_MPHC_UPDATE_BA_LIST *)(msg->SigP));

          // Set present flag only when the list has been downloaded.
          l1a_l1s_com.ba_list.new_list_present = TRUE;

          // End of process.
          return;
        }

        else
      #if ((REL99 == 1) && (FF_BHO == 1))
        if ((SignalCode == MPHC_STOP_DEDICATED_REQ) ||
            (((SignalCode == MPHC_SYNC_HO_REQ) ||
              (SignalCode == MPHC_PRE_SYNC_HO_REQ) ||
              (SignalCode == MPHC_PSEUDO_SYNC_HO_REQ) ||
              (SignalCode == MPHC_ASYNC_HO_REQ)
             ) &&
             (l1a_l1s_com.dedic_set.handover_type == BLIND_HANDOVER)
            )
           )
      #else
        if(SignalCode == MPHC_STOP_DEDICATED_REQ)
      #endif // #if ((REL99 == 1) && (FF_BHO == 1))
        // We exit DEDICATED mode.
        {
          // Stop D_BAMS_MEAS task.
          l1a_l1s_com.l1s_en_meas &= D_BAMS_MEAS_MASK;

          // When leaving dedicated mode we must clear the NEW BA
          // present flag to keep L1 and L1 in step and to avoid
          // taking it into account on the next Dedicated mode
          // session.

          // Check inf any NEW BA available, if so download it...
          if(l1a_l1s_com.ba_list.new_list_present == TRUE)
          {
            UWORD16 i;

            // Download new list.
            for(i=0;i<l1a_l1s_com.ba_list.new_list.num_of_chans;i++)
            {
              l1a_l1s_com.ba_list.A[i].radio_freq = l1a_l1s_com.ba_list.new_list.chan_list.A[i];
            }

            l1a_l1s_com.ba_list.ba_id       = l1a_l1s_com.ba_list.new_list.ba_id;
            l1a_l1s_com.ba_list.nbr_carrier = l1a_l1s_com.ba_list.new_list.num_of_chans;

            l1a_l1s_com.ba_list.new_list_present = 0;
          }

          // Step in state machine.
          *state = RESET;
        }

        else
        if(SignalCode == L1C_DEDIC_DONE)
        // Reset messages.
        //----------------
        {
          // Step in state machine.
          *state = RESET;
        }

        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          end_process = 1;
        }
      }
      break;
    } // end of "switch".
  } // end of "while"
} // end of procedure.

/*-------------------------------------------------------*/
/* l1a_freq_band_configuration ()                        */
/*-------------------------------------------------------*/
/* Description : This state machine handles the frequency*/
/*band configuration: E_GSM900, GSM900, DCS1800, PCS1900,*/
/*DUAL, DUALEXT, DUALEXT_PCS1900...                      */
/*                                                       */
/* Starting messages:        MPHC_INIT_L1_REQ            */
/*                                                       */
/* Result messages (input):  none                        */
/* Result messages (output): MPHC_INIT_L1_CON           */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
void l1a_freq_band_configuration(xSignalHeaderRec *msg)
{
  UWORD32  SignalCode = msg->SignalCode;
  UWORD8   *state      = &l1a.state[INIT_L1];

  enum states
  {
    RESET       = 0,
    WAIT_INIT   = 1
  };

  BOOL end_process = 0;

  while(!end_process)
  {
    switch(*state)
    {
      case RESET:
      {
         // Step in state machine.
         *state = WAIT_INIT;
      }
      break;

      case WAIT_INIT:
      {

        if (SignalCode == MPHC_INIT_L1_REQ)
        // Request from L3 which defined the standard, GSM, E-GSM, DCS1800,  DUALEXT...
        //-------------------------------------------------------------------------------
        {
#if (L1_FF_MULTIBAND == 0)
          l1_config.std.id = ((T_MPHC_INIT_L1_REQ *)(msg->SigP))->radio_band_config;
#else
          UWORD8 physical_band_id;
static    UWORD8 rf_band_id_to_l23_band_id[]={PGSM900, GSM850, DCS1800, PCS1900};
#endif


          Cust_init_std();
          l1_tpu_init_light();
#if (L1_FF_MULTIBAND == 0)

          

          #if (TRACE_TYPE == 5)
            trace_sim_freq_band_configuration(l1_config.std.id);
          #endif

#endif /*if (L1_FF_MULTIBAND == 0)*/

          // Forward result message to L3.
#if (L1_FF_MULTIBAND == 0)

          l1a_send_confirmation(MPHC_INIT_L1_CON,RRM1_QUEUE);

#else // L1_FF_MULTIBAND  1 below

          msg = os_alloc_sig(sizeof(T_MPHC_INIT_L1_CON));
          DEBUGMSG(status, NU_ALLOC_ERR)
          msg->SignalCode = MPHC_INIT_L1_CON;
          for (physical_band_id = 0; physical_band_id < RF_NB_SUPPORTED_BANDS; physical_band_id ++)
          {
            ((T_MPHC_INIT_L1_CON *)(msg->SigP))->multiband_power_class[physical_band_id].radio_band
                =
                rf_band_id_to_l23_band_id[multiband_rf[physical_band_id].gsm_band_identifier];
            ((T_MPHC_INIT_L1_CON *)(msg->SigP))->multiband_power_class[physical_band_id].power_class
                = multiband_rf[physical_band_id].power_class;
            l1a_l1s_com.powerclass[physical_band_id]=multiband_rf[physical_band_id].power_class;
          }
          for (physical_band_id=RF_NB_SUPPORTED_BANDS; physical_band_id<NB_MAX_GSM_BANDS; physical_band_id++)
          {
           ((T_MPHC_INIT_L1_CON *)(msg->SigP))->multiband_power_class[physical_band_id].radio_band = 0xFF;   
          }
          os_send_sig(msg, RRM1_QUEUE);

#endif // #if (L1_FF_MULTIBAND == 0) else 

          // This process must be reset.
          *state = RESET;
          return;
        }
        else
        // No action in this machine for other messages.
        //----------------------------------------------
        {
          end_process = 1;
        }
        break;
      }
    } // End of switch
  } // End of while
}

/*-------------------------------------------------------*/
/* l1a_checkmsg_compatibility ()                        */
/*-------------------------------------------------------*/
/* Description : This checks the message compatibility, If the */
/*received message is not compatible with current scenario, */
/*delay the message or ignore the message.*/
/*                                                       */
/*                                                       */
/* Result messages (input):  xSignalHeaderRec *msg    */
/* Result messages (output): none           */
/* Reset messages (input):   none                        */
/*                                                       */
/*-------------------------------------------------------*/
#if(L1_CHECK_COMPATIBLE == 1)
void l1a_checkmsg_compatibility    (xSignalHeaderRec *msg)
{
  UWORD32   SignalCode  = msg->SignalCode;



  /* stop_req is set to True, if ringer stop message is received from MMI */
  if((SignalCode == MMI_AAC_STOP_REQ) || (SignalCode == MMI_MP3_STOP_REQ))
  {
     l1a.stop_req = TRUE;
  }

  /* This disables vocoder if vocoder is enabled and set vcr_wait to TRUE */
  /* to trigger VCH_R msg when AAC/MP3 is stopped completely. */
  /* This is the case of inband tone where first VCH_R is recvieved and */
  /* then ringer is started  */
  if((SignalCode == MMI_AAC_START_REQ) || (SignalCode == MMI_MP3_START_REQ))
  {
     if (l1a.vocoder_state.enabled == TRUE) {

          l1a.vcr_wait   = TRUE;
	   l1a.vch_auto_disable = TRUE;
   	}
  }

  /* This is to trigger VCH_R message if  message is delayed earliar */
  /* and ringer is stopped completely */
  if ((l1a.stop_req == TRUE) && (l1a.vcr_wait==TRUE))
  {
     if ((SignalCode  == L1_MP3_DISABLE_CON) ||
	   (SignalCode  == L1_AAC_DISABLE_CON))
     {
         xSignalHeaderRec    *msg_vcr;
	  msg_vcr = os_alloc_sig(sizeof(T_MMI_TCH_VOCODER_CFG_REQ));
	  DEBUGMSG(status,NU_ALLOC_ERR)
	  msg_vcr->SignalCode = MMI_TCH_VOCODER_CFG_REQ;
	  ((T_MMI_TCH_VOCODER_CFG_REQ *) (msg_vcr->SigP))->vocoder_state = l1a.vcr_msg_param;
	  os_send_sig(msg_vcr,L1C1_QUEUE);
	  DEBUGMSG(status,NU_SEND_QUEUE_ERR)
         l1a.vcr_wait = FALSE;
         l1a.stop_req = FALSE;
	  {
            char str[25];
             sprintf(str,"TRIGGER VCH");
             rvt_send_trace_cpy((T_RVT_BUFFER)str,trace_info.l1_trace_user_id,strlen(str),RVT_ASCII_FORMAT);
   	  }
      }
}


  /* vcr_wait is set to TRUE to delay the VCH_R if MP3/AAC is not stopped completey*/
  if(SignalCode == MMI_TCH_VOCODER_CFG_REQ)
   {
     l1a.vcr_msg_param = ((T_MMI_TCH_VOCODER_CFG_REQ *) (msg->SigP))->vocoder_state;

     //  MP3 ON or AAC ON
    if ((!((l1a.state[L1A_MP3_STATE] == 0) || (l1a.state[L1A_MP3_STATE] == 1))) ||
	  (!((l1a.state[L1A_AAC_STATE] == 0) || (l1a.state[L1A_AAC_STATE] == 1))))
    {
       l1a.vcr_wait   = TRUE;
	msg->SignalCode = NULL;
	{
             char str[25];
             sprintf(str,"VCH DELAY");
             rvt_send_trace_cpy((T_RVT_BUFFER)str,trace_info.l1_trace_user_id,strlen(str),RVT_ASCII_FORMAT);
 	}
   }
 }
}
#endif