view src/cs/layer1/cfile/l1_async.c @ 303:f76436d19a7a default tip

!GPRS config: fix long-standing AT+COPS chance hanging bug There has been a long-standing bug in FreeCalypso going back years: sometimes in the AT command bring-up sequence of an ACI-only MS, the AT+COPS command would produce only a power scan followed by cessation of protocol stack activity (only L1 ADC traces), instead of the expected network search sequence. This behaviour was seen in different FC firmware versions going back to Citrine, and seemed to follow some law of chance, not reliably repeatable. This bug has been tracked down and found to be specific to !GPRS configuration, stemming from our TCS2/TCS3 hybrid and reconstruction of !GPRS support that was bitrotten in TCS3.2/LoCosto version. ACI module psa_mms.c, needed only for !GPRS, was missing in the TCS3 version and had to be pulled from TCS2 - but as it turns out, there is a new field in the MMR_REG_REQ primitive that needs to be set correctly, and that psa_mms.c module is the place where this initialization needed to be added.
author Mychaela Falconia <falcon@freecalypso.org>
date Thu, 08 Jun 2023 08:23:37 +0000
parents 4e78acac3d88
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