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
+ −