
/**
 * @file comms_csw_fsm_hdlr.c
 *
 * @brief This file has the S-Band driver FSM implemenation and the relevant functions
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
/*********************************************************************/
#include <stdio.h>
#include "sm_api.h"
#include "comms_sband_sim.h"
#include "comms_sband_init.h"
#include "comms_ipc.h"
#include "comms_csw.h"
#include "exo_common.h"
#include "comms_sband_rx.h"
#include "exo_io_al_sos_timer.h"

#include "otsu.h"
#include "comms_sband_csp.h"
#include "tc_tm_mngr.h"
#ifdef S_BAND_SIM_CB
#include "comms_sband_sim.h"
#endif
#include "comms_sband_intf.h"

#include "comms_sband_api_map.h"
#include "comms_sband_xlink_api.h"
#include "comms_sband_xlink_sock.h"
#include "comms_sband_xlink_ss.h"
#include "logger.h"

#include "obc_tc_tm.h"
#include "comms_sband_intf.h"
#include "comms_sband_tmr.h"
#include "sdr_app_main.h"
#include "exo_tctm_ipc.h"
#include "eps_ctrlr.h"

uint32_t sband_cfg_seq = 0;
s_sdr_gpass_beacon_cfg sband_gpass_cfg={0};
extern uint16_t PLACE_IN_EXT_RAM_MEM sband_tc_tm_id;
extern os_sem_handle_ptr tx_win_on_sem;
extern uint32_t sband_rep_cnt;

extern uint8_t sband_iqs_tx_ON;

extern sys_time_s PLACE_IN_EXT_RAM_MEM get_t_iqs;

extern os_timer_handle_ptr sband_tx_tm_on;

extern os_timer_handle_ptr sband_cmd_wait_timer;

/** Scheduler based ground contact flag */
extern volatile uint8_t PLACE_IN_EXT_RAM_MEM sband_sch_gs_contact;

/** Timer for S-Band Periodic HK Sync **/
extern os_timer_handle_ptr sband_tm_periodic_read;

/** OTSU Callback status */
uint8_t PLACE_IN_EXT_RAM_MEM comms_otsu_cb_sts = 0;
uint8_t comms_gscontact_confirm_status_flag = 0xFF;

/** S-Band module first ground contact status */
uint8_t PLACE_IN_EXT_RAM_MEM comms_sband_first_gs_contact = 0;

extern s_sdr_tmr_cfg PLACE_IN_EXT_RAM_MEM sband_tmr_cfg; ///< S-Band timer configuration structure
extern uint32_t PLACE_IN_EXT_RAM_MEM tm_store_cnt; ///< TM storage count
sys_time_date_s PLACE_IN_EXT_RAM_MEM tim_get_fs_st; ///< Time/date structure

s_comms_tx_tm PLACE_IN_EXT_RAM_MEM tx_tm_cfg; ///< TX TM configuration structure
s_comms_tm_prop PLACE_IN_EXT_RAM_MEM  xlink_sys_param; ///< System parameter structure

/** S_Band driver System configuration control block */
s_comms_csp_tm PLACE_IN_EXT_RAM_MEM csp_tm_global;

extern s_sdr_rssi_cfg PLACE_IN_EXT_RAM_MEM sband_rssi_cfg;

/** S-Band TC-TM buffer */
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_csw_rx_buf[512];

s_sdr_beacon_pld sband_beacon_data;

uint8_t sband_prd_key_status = 0;
uint8_t sband_reset_status = 0;

extern SERVICE_DEVICE_CONF_STRUCT PLACE_IN_EXT_RAM_MEM	 sband_serv_device_conf;
extern s_comms_xlinks_net_prop_cfg PLACE_IN_EXT_RAM_MEM iqs_net_prop_glob;

/** Declaration of S-Driver FSM function pointer */
typedef uint8_t (*CSW_SM_HDLR)(uint16_t msg_id, void *payload);

/** Definition of S-BAND Driver FSM function pointer */
CSW_SM_HDLR comms_fsm_hdlr[COMMS_MAX_NUM_STATE] = {\
    &comms_init_state_hdlr,\
        &comms_boot_state_hdlr,\
        &comms_dfu_state_hdlr,\
        &comms_cfg_state_hdlr,\
        &comms_calib_state_hdlr,\
        &comms_sleep_idle_state_hdlr,\
        &comms_active_state_hdlr,\
        &comms_safe_mode_state_hdlr,\
        &comms_error_state_hdlr,\
        &comms_bypass_state_hdlr\
};

/** S-Band ground contact flag */
volatile uint8_t sband_gs_contact_valid = 0;

#ifndef LINUX_TEMP_PORT

/**
 * @brief This function send ground contact status to OTSU module
 * Sends the OTSU ground sync status message.
 * 
 * @param[in] sts Ground sync status value.
 */
void send_otsu_gssync_sts(uint8_t sts)
{
    os_itc_msg_handle_t msg_hdl;
    msg_hdl.src_entity 	= COMMS_SBAND_CTLR;
    msg_hdl.pld_info 	= sts;
    msg_hdl.Msg_id 		= OTSU_GS_SYNC_RCV;
    msg_hdl.Msg_len 	= 0;
    msg_hdl.pld.pld_ptr = NULL;
    os_itc_msg_send(&msg_hdl,OBC_OTSU, os_send_itc_wait);
    comms_gscontact_confirm_status_flag = 0xAA;
}
#endif

/**
 * @brief This function check the sband ground contact
  * @brief Check if S-Band ground station contact is valid.
  *
  * Checks if the current ground station contact window is valid.
  *
  * @return 1 if valid, 0 if invalid.
 */
uint8_t is_sband_gs_contact_valid(void)
{
    return sband_gs_contact_valid;
}

/**
 * @brief This function update the sband ground contact status
  *
  * Updates the S-Band ground contact status based on current time.
  *
  * @param[in] state New ground contact state. 
 */
void sband_gs_contact_status_upd(uint16_t state)
{
    if(state == SBAND_TC_TM_ST_REQ)
    {
        sband_gs_contact_valid = 1;
    }
    else if(state == SBAND_TC_TM_STOP_REQ)
    {
        sband_gs_contact_valid = 0;
    }

}

/**
 * @brief This function send the sband ground contact status
 * Updates S-Band ground contact status for ITC with callbacks. 
 *
 * @param[in] state New ground contact state.
 */
void sband_gs_contact_status_upd_itc(uint16_t state, uint8_t radio_id)
{
    //uint8_t radio_id = COMMS_SBAND_IQS;
    uint8 prev_val = sband_gs_contact_valid;

    sband_gs_contact_status_upd(state);
    if(sband_gs_contact_valid != prev_val)
    {
        DEBUG_CPRINT(("\n TM Storage IPC %d",state));
        log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,TM_STORAGE_IPC__u16_,state);
        sband_send_ipc_pld(state,TM_STORAGE,sizeof(uint8),&radio_id);
    }

}

/**
 * @brief This function send the backdoor ground contact status
 */
void backdoor_soc_gs_contact_status_upd_itc(uint16_t state)
{
    uint8_t radio_id = GS2_BACK_DOOR_SOC;
    uint8 prev_val = sband_gs_contact_valid;

    sband_gs_contact_status_upd(state);
    if(sband_gs_contact_valid != prev_val)
    {
        DEBUG_CPRINT(("\n TM Storage IPC %d",state));
        log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,TM_STORAGE_IPC__u16_,state);
        sband_send_ipc_pld(state,TM_STORAGE,sizeof(uint8),&radio_id);
    }

}

/**
 * @brief This function handle comms initialization state
 * Handles S-Band initialization state events.
 * 
 * @param[in] msg_id Received message ID.
 * @param[in] payload Message payload.
 *
 * @return Next state.
 */
uint8_t comms_init_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_INIT_STATE;
    int8_t status = COMMS_IPC_OK;

    DEBUG_CPRINT(("received response for COMMS_INIT : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_RESET__u16_,msg_id);
    switch (msg_id)
    {
        case OBC_SBAND_INIT_REQ:
            {
                comms_sband_nvm_init();  

                state = COMMS_CFG_STATE;

                sband_cfg_seq = SBAND_GET_DEVICE_CFG;
                os_timer_start(sband_cmd_wait_timer,100);

            }
            break;

        case OBC_SBAND_DEINIT_REQ:
            {
                comms_sband_rssi_hdlr(OBC_SBAND_DEINIT_REQ);

                comms_sband_cfg_nvm_write();
                comms_sband_xlinks_cfg_nvm_write();
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
                sband_send_ipc(SBAND_OBC_DEINIT_RSP,OBC_MAIN);
            }
            break;

        case OTSU_SBAND_SYNC_REQ:
            {
                /** OTSU Call back - Success*/
                if(!sband_gs_contact_valid)
                {
                    comms_otsu_cb_sts = 1;
                }
                else
                {
#ifndef LINUX_TEMP_PORT
                    send_otsu_gssync_sts(1);
#endif
                }
            }
            break;

        case SBAND_TX_PERIODIC_BEACON_TMR_EXP:
            {
                DEBUG_CPRINT(("\n SBAND_TX_PERIODIC_BEACON_TMR_EXP ignored "));
                log_id(LOG_INFO_L1,LOG_COMMS,SBAND_TX_PERIODIC_BEACON_TMR_EXP_IGNORED);
            }
            break;

        case SBAND_TM_PERIODIC_READ:
            {
                DEBUG_CPRINT(("\n SBAND_TM_PERIODIC_READ ignored "));
                log_id(LOG_INFO_L1,LOG_COMMS,SBAND_TM_PERIODIC_READ_IGNORED);
            }
            break;

        case OBC_SBAND_HEALTH_CHECK_REQ:
            {
                DEBUG_CPRINT(("\n OBC_SBAND_HEALTH_CHECK_REQ ignored "));
                log_id(LOG_INFO_L1,LOG_COMMS,OBC_SBAND_HEALTH_CHECK_REQ_IGNORED);
            }
            break;

        case SCH_SBAND_GS_ST_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_ST_IND in init state "));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_ST_IND);
                sband_sch_gs_contact = 1;
            }
            break;

        case SCH_SBAND_GS_STOP_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_STOP_IND in init state"));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_STOP_IND);
                sband_sch_gs_contact = 0;
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
            }
            break;
        case SBAND_RX_ON_TIMER_EXP:
            {
                DEBUG_CPRINT(("\n SBAND_RX_ON_TIMER_EXP in init state"));
                log_id(LOG_INFO_L1,LOG_COMMS,SBAND_RX_ON_TMR_EXP_INIT_STATE);
            }
            break;

        case SDR_APP_SBAND_MH_REQ:
            {
                DEBUG_CPRINT(("\n SDR_APP_SBAND_MH_REQ"));
                log_id(LOG_INFO_L1,LOG_COMMS,SDR_APP_SBAND_MH_REQ);
                sdr_app_sdr_ctrl_sband_mh_req(payload);
            }
            break;
        case SDR_APP_SDR_CTRL_SDR_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_sdr_cfg_req(payload);
            }
            break;
        case SDR_APP_SDR_CTRL_MODE_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_mode_cfg_req(payload);
            }
            break;
        case SDR_APP_SDR_CTRL_TMR_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_tmr_cfg_req(payload);
            }
            break;
        case SDR_APP_SDR_CTRL_RSSI_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_rssi_cfg_req(payload);
            }
            break;
        case SDR_APP_SDR_CTRL_TM_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_tm_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_SENS_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_sens_cfg_req(payload);
            }
            break;

        case SDR_APP_SBAND_BEACON_DATA_IND:
            {
                /** Nothing to be done */
                DEBUG_CPRINT(("\n SDR_APP_SBAND_BEACON_DATA_IND in init state "));
                log_id(LOG_INFO_L1,LOG_COMMS,SDR_APP_SBAND_BEACON_DATA_IND_INIT_STATE);
            }
            break;
        case SBAND_REINIT_TMR_EXP:
            {
                sband_reinit_exp_hdlr();
            }
            break;
        case SBAND_TX_WIN_ON_REQ:
            {
                sband_iqs_tx_ON = 0;
                os_sem_give(tx_win_on_sem);
            }
            break;
        case SBAND_IQS_TX_WIN_OFF:
            {
                sband_iqs_tx_ON = 0;
            }
            break;
        case SBAND_UNKNOWN_TC_TM_HDLR:
            {
                status = TC_STS_UNKNOWN_TC_TM;
                sband_tc_tm_set_rsp_hdlr(sband_tc_tm_id,status);
            }
            break;
        case SDR_APP_SDR_CTRL_GPASS_CFG:
            {
                sdr_app_sdr_ctrl_sband_sdr_gpass_cfg_req(payload);
            }
            break;

        default:
            {
            }
            break;
    }

    return state;
}

/**
 * @brief This function handle the comms boot state
 * Handles S-Band boot state events.
 *
 * @param[in] msg_id Received message ID.
 * @param[in] payload Message payload. 
 * 
 * @return Next state.
 */
uint8_t comms_boot_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_BOOT_STATE;
    int8_t status = COMMS_IPC_OK;

    DEBUG_CPRINT(("received response for COMMS_BOOT : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_BOOT__u16_,msg_id);
    switch (msg_id)
    {
        case COMMS_BOOT_DONE:
            DEBUG_CPRINT(("In BOOT_DONE state \n "));
            log_id(LOG_INFO_L1,LOG_COMMS,IN_BOOT_DONE_STATE);
            state = COMMS_DFU_STATE;
            //TODO:Firmware update API to be added
            //comms_csw_trans_msg.Msg_id = COMMS_INTRNL_FRMWR_UPDT_REQ;
            DEBUG_CPRINT(("In BOOT_DONE state, status of internal dfu request is %d \n ",status));
            log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,IN_BOOT_DONE_STATE_cm_STATUS_OF_INTERNAL_DFU_REQUEST_IS__s8_,status);
            break;

        case COMMS_BOOT_FAIL:
            DEBUG_CPRINT(("BOOT_FAIL event \n"));
            log_id(LOG_ERROR,LOG_COMMS,BOOT_FAIL_EVENT);
            state = COMMS_ERROR_STATE;
            break;

        default:
            state = COMMS_SAFE_MODE_STATE ;
            break;
    }
    return state;
}

/**
 * @brief This function handles comms DFU state
 * Handles S-Band DFU state events.
 * 
 * @param[in] msg_id Received message ID.
 * @param[in] payload Message payload.
 *
 * @return Next state.
 */
uint8_t comms_dfu_state_hdlr(uint16_t msg_id, void *payload)
{
    uint32_t udp_temp_ip_addr = 0;
    uint8_t state = COMMS_DFU_STATE;

    int8_t status = COMMS_IPC_OK;

    DEBUG_CPRINT(("received response for COMMS_DFU : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_DFU__u16_,msg_id);
    switch (msg_id)
    {
        case SBAND_FW_CFG_UPD_IND:
            {
                comms_sband_proc_fw_cfg();
                
                sband_cfg_seq = SBAND_SET_RESET;
                os_timer_start(sband_cmd_wait_timer,1000);
            }
            break;

        case SBAND_TX_WIN_ON_REQ:
            {
                sband_iqs_tx_ON = 0;
                os_sem_give(tx_win_on_sem);
            }
            break;
        case SBAND_IQS_TX_WIN_OFF:
            {
                sband_iqs_tx_ON = 0;
            }
            break;

        case SBAND_SET_RESET:
            {
                status  = sband_proc_tc(SERVICE_SET | SERVICE_RESET);
                DEBUG_CPRINT(("\n[SBAND] RESET STS :%d\n",status));

                sband_cfg_seq = SBAND_GET_FEATURE_SELECT;
                os_timer_start(sband_cmd_wait_timer,5000);
            }
            break;
        case SBAND_GET_FEATURE_SELECT:
            {
                status  = sband_proc_tc(SERVICE_GET | SERVICE_FEATURE_SELECT);
                DEBUG_CPRINT(("\n[SBAND] FEATURE SELECT STS :%d\n",status));

                sband_cfg_seq = SBAND_GET_DEVICE_CFG;
                os_timer_start(sband_cmd_wait_timer,100);
            }
            break;
        case SBAND_GET_DEVICE_CFG:
            {
                status = sband_proc_tc(SERVICE_GET | SERVICE_DEVICE_CONF);
                DEBUG_CPRINT(("\n[SBAND] GET DEVICE CFG STS :%d\n",status));

                sband_cfg_seq = SBAND_SET_DEVICE_CFG;
                os_timer_start(sband_cmd_wait_timer,1000);
            }
            break;
        case SBAND_SET_DEVICE_CFG:
            {
                status = comms_sband_xlink_tx_cfg();
                DEBUG_CPRINT(("\nIQS TIME PRO_KEY TX configuration status: %d",status));
                status = comms_sband_xlink_rx_cfg();
                DEBUG_CPRINT(("\nIQS TIME PRO_KEY RX configuration status: %d",status));
                status  = sband_proc_tc_pld((SERVICE_SET|SERVICE_DEVICE_CONF), (uint8_t*)&sband_serv_device_conf);
                DEBUG_CPRINT(("\nIQS TIME PRO_KEY SET status: %d",status));

                sband_cfg_seq = SBAND_SET_DEVICE_CFG_RX_TX_ON;
                os_timer_start(sband_cmd_wait_timer,1000);

            }
            break;
        case SBAND_SET_DEVICE_CFG_RX_TX_ON:
            {
                comms_sband_rx_tx_turn_on();

                sband_cfg_seq = SBAND_SET_RX_RCV_CFG;
                os_timer_start(sband_cmd_wait_timer,2000);

            }
            break;
        case SBAND_SET_RX_RCV_CFG:
            {
                comms_sband_rx_rcv_cfg();

                sband_cfg_seq = SBAND_SET_IP_ADR_CFG;
                os_timer_start(sband_cmd_wait_timer,1000);

            }
            break;
        case SBAND_SET_IP_ADR_CFG:
            {
                udp_temp_ip_addr = xlink_get_udp_temp_ip_addr(iqs_net_prop_glob.dev_ip_temp);

                sband_proc_tc_pld((SERVICE_SET | SERVICE_IP_ADR),(uint8_t *)&udp_temp_ip_addr);

                DEBUG_CPRINT(("[SBAND] NVM Read RX configuration status: %d",status));
                log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,NVM_READ_RX_CONFIURATION_STATUS__s8_,status);

                sband_cfg_seq = SBAND_FW_CFG_END_IND;
                os_timer_start(sband_cmd_wait_timer,1000);

            }
            break;
        case SBAND_CMD_TMR_EXP:
            {
                if(sband_cfg_seq != 0)
                {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
                    DEBUG_CPRINT(("\n[SBAND] sband_cfg_seq: %ld\n",sband_cfg_seq));
#pragma GCC diagnostic pop
                    sband_send_ipc(sband_cfg_seq, COMMS_SBAND_CTLR);
                }
                sband_cfg_seq = 0;
            }
            break;

        case SBAND_FW_CFG_END_IND:
            {
                state = COMMS_ACTIVE_STATE;
                DEBUG_CPRINT(("ACTIVE STATE SET IN DFU"));
                comms_sband_rssi_hdlr(OBC_SBAND_INIT_REQ);
                if(sband_sch_gs_contact)
                {
                      if(!sband_gpass_cfg.gpass_beacon_tx_enb)
                        {
                            sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,COMMS_SBAND_IQS);
                        }
                        else
                        {   
                            sband_rep_cnt=0;
                            DEBUG_CPRINT(("\n SBAND_SDR_APP_BEACON_DATA_REQ sent"));
                            log_id(LOG_INFO_L1,LOG_COMMS,SBAND_SDR_APP_BEACON_DATA_REQ_SENT);
                            sband_send_ipc(SBAND_SDR_APP_BEACON_DATA_REQ, SDR_APP);
                        }
                }
                else
                {
                    sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,DEFAULT_COMMS_RADIO_ID); 
                    os_timer_start(sband_tx_tm_on,sband_tmr_cfg.sdr_tm_tx_tmr);
                }

                comms_sband_get_vers();
            }
            break;

        case SCH_SBAND_GS_ST_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_ST_IND"));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_ST_IND);
                sband_sch_gs_contact = 1;
            }
            break;

        case SCH_SBAND_GS_STOP_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_STOP_IND"));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_STOP_IND);
                sband_sch_gs_contact = 0;
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
            }
            break;

        case SBAND_TM_PERIODIC_READ:
            {
                if(sband_tmr_cfg.sdr_tm_read_tmr >= sband_rssi_cfg.rssi_prd_tmr)
                {
                    DEBUG_CPRINT(("\nRSSI_RD_CNT at TM_READ TIMER ENT at DFU \n"));
                    DEBUG_CPRINT(("\nsband rssi_prd_timer %d \n", sband_rssi_cfg.rssi_prd_tmr));
                    tm_store_cnt = sband_tmr_cfg.sdr_tm_read_tmr/sband_rssi_cfg.rssi_prd_tmr;
                    os_timer_start(sband_tm_periodic_read, sband_rssi_cfg.rssi_prd_tmr);
                }
                else
                {
                    tm_store_cnt = 1;
                    os_timer_start(sband_tm_periodic_read, sband_tmr_cfg.sdr_tm_read_tmr);
                }
            }
            break;

        case SBAND_TX_PERIODIC_BEACON_TMR_EXP:
            {
                DEBUG_CPRINT(("\n SBAND_TX_PERIODIC_BEACON_TMR_EXP @ DFU"));
            }
            break;

        case SBAND_UNKNOWN_TC_TM_HDLR:
            {
                status = TC_STS_UNKNOWN_TC_TM;
                sband_tc_tm_set_rsp_hdlr(sband_tc_tm_id,status);
            }
            break;
        case SDR_APP_SDR_CTRL_GPASS_CFG:
            {
                sdr_app_sdr_ctrl_sband_sdr_gpass_cfg_req(payload);
            }
            break;

        default:
            state = COMMS_DFU_STATE;
            break;
    }
    return state;
}

/**
 * @brief This function handle comms configuration states
 * Handles S-Band configuration state events.
 *
 * @param[in] msg_id Received message ID. 
 * @param[in] payload Message payload.
 * 
 * @return Next state.
 */
uint8_t comms_cfg_state_hdlr(uint16_t msg_id, void *payload)
{
    uint32_t udp_temp_ip_addr = 0;
    uint8_t state = COMMS_CFG_STATE;
    int8_t status = COMMS_IPC_OK;

    DEBUG_CPRINT(("received response for COMMS_CFG : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_CFG__u16_,msg_id);

    switch (msg_id)
    {
        case OBC_SBAND_DEINIT_REQ:
            {
                comms_sband_rssi_hdlr(OBC_SBAND_DEINIT_REQ);

                comms_sband_cfg_nvm_write();
                comms_sband_xlinks_cfg_nvm_write();
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
                sband_send_ipc(SBAND_OBC_DEINIT_RSP,OBC_MAIN);
                sband_cfg_seq = 0;
                os_timer_stop(sband_cmd_wait_timer);

                state = COMMS_INIT_STATE;
            }
            break;

        case SCH_SBAND_GS_ST_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_ST_IND in init state "));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_ST_IND);
                sband_sch_gs_contact = 1;
            }
            break;

        case SCH_SBAND_GS_STOP_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_STOP_IND in init state"));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_STOP_IND);
                sband_sch_gs_contact = 0;
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
            }
            break;
        case OTSU_SBAND_SYNC_REQ:
            {
                /** OTSU Call back - Success*/
                if(!sband_gs_contact_valid)
                {
                    comms_otsu_cb_sts = 1;
                }
                else
                {
#ifndef LINUX_TEMP_PORT
                    send_otsu_gssync_sts(1);
#endif
                }
            }
            break;

        case SBAND_TX_WIN_ON_REQ:
            {
                sband_iqs_tx_ON = 0;
                os_sem_give(tx_win_on_sem);
            }
            break;
        case SBAND_IQS_TX_WIN_OFF:
            {
                sband_iqs_tx_ON = 0;
            }
            break;
        case SBAND_SET_RESET:
            {
                status  = sband_proc_tc(SERVICE_SET | SERVICE_RESET); 
                DEBUG_CPRINT(("\n[SBAND] RESET STS :%d\n",status));

                sband_cfg_seq = SBAND_GET_FEATURE_SELECT;
                os_timer_start(sband_cmd_wait_timer,5000);
            }
            break;
        case SBAND_GET_FEATURE_SELECT:
            {
                status  = sband_proc_tc(SERVICE_GET | SERVICE_FEATURE_SELECT);
                DEBUG_CPRINT(("\n[SBAND] FEATURE SELECT STS :%d\n",status));

                sband_cfg_seq = SBAND_GET_DEVICE_CFG;
                os_timer_start(sband_cmd_wait_timer,100);
            }
            break;
        case SBAND_GET_DEVICE_CFG:
            {
                status = sband_proc_tc(SERVICE_GET | SERVICE_DEVICE_CONF);
                DEBUG_CPRINT(("\n[SBAND] GET DEVICE CFG STS :%d\n",status));

                sband_cfg_seq = SBAND_SET_DEVICE_CFG;
                os_timer_start(sband_cmd_wait_timer,1000);
            }
            break;
        case SBAND_SET_DEVICE_CFG:
            {
                status = comms_sband_xlink_tx_cfg();
                DEBUG_CPRINT(("\nIQS TIME PRO_KEY TX configuration status: %d",status));
                status = comms_sband_xlink_rx_cfg();
                DEBUG_CPRINT(("\nIQS TIME PRO_KEY RX configuration status: %d",status));
                status  = sband_proc_tc_pld((SERVICE_SET|SERVICE_DEVICE_CONF), (uint8_t*)&sband_serv_device_conf);
                DEBUG_CPRINT(("\nIQS TIME PRO_KEY SET status: %d",status));

                sband_cfg_seq = SBAND_SET_DEVICE_CFG_RX_TX_ON;
                os_timer_start(sband_cmd_wait_timer,500);

            }
            break;
        case SBAND_SET_DEVICE_CFG_RX_TX_ON:
            {
                comms_sband_rx_tx_turn_on();

                sband_cfg_seq = SBAND_SET_RX_RCV_CFG;
                os_timer_start(sband_cmd_wait_timer,500);

            }
            break;
        case SBAND_SET_RX_RCV_CFG:
            {
                comms_sband_rx_rcv_cfg();
                sband_cfg_seq = SBAND_SET_IP_ADR_CFG;
                os_timer_start(sband_cmd_wait_timer,500);

            }
            break;
        case SBAND_SET_IP_ADR_CFG:
            {
                udp_temp_ip_addr = xlink_get_udp_temp_ip_addr(iqs_net_prop_glob.dev_ip_temp);

                sband_proc_tc_pld((SERVICE_SET | SERVICE_IP_ADR),(uint8_t *)&udp_temp_ip_addr);

                DEBUG_CPRINT(("[SBAND] NVM Read RX configuration status: %d",status));
                log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,NVM_READ_RX_CONFIURATION_STATUS__s8_,status);

                sband_cfg_seq = SBAND_CFG_END_IND;
                os_timer_start(sband_cmd_wait_timer,500);

            }
            break;
        case SBAND_CMD_TMR_EXP:
            {
                if(sband_cfg_seq != 0)
                {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat"
                    DEBUG_CPRINT(("\n[SBAND] sband_cfg_seq: %ld\n",sband_cfg_seq));
#pragma GCC diagnostic pop
                    sband_send_ipc(sband_cfg_seq, COMMS_SBAND_CTLR);
                }
                sband_cfg_seq = 0;
            }
            break;
            case SBAND_CFG_END_IND:
            {
                state = COMMS_ACTIVE_STATE;

                comms_sband_rssi_hdlr(OBC_SBAND_INIT_REQ);

                if(sband_tc_tm_id == TC_SBAND_SET_PROD_KEY)
                {
                    if(sband_sch_gs_contact)
                    {
                        sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,COMMS_SBAND_IQS); // need to check if previously active
                    }
                    else
                    {
                        sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,DEFAULT_COMMS_RADIO_ID); // need to check if previously active
                        os_timer_start(sband_tx_tm_on,sband_tmr_cfg.sdr_tm_tx_tmr);
                    }

                    sband_tc_tm_set_rsp_hdlr(TM_SBAND_SET_PROD_KEY,sband_prd_key_status);
                }
                else if(sband_tc_tm_id == TC_SBAND_SET_RESET)
                {
                    if(sband_sch_gs_contact)
                    {
                        sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,COMMS_SBAND_IQS); 
                    }
                    else
                    {
                        sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,DEFAULT_COMMS_RADIO_ID); 
                        os_timer_start(sband_tx_tm_on,sband_tmr_cfg.sdr_tm_tx_tmr);
                    }

                    sband_tc_tm_set_rsp_hdlr(TM_SBAND_SET_RESET,sband_reset_status);
                }
                else
                {
                    /** Nothing to be done */
                    sband_send_ipc(SBAND_OBC_INIT_RSP,OBC_MAIN);

                    if(sband_sch_gs_contact)
                    {
                        if(!sband_gpass_cfg.gpass_beacon_tx_enb)
                        {
                            sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,COMMS_SBAND_IQS);
                        }
                        else
                        {
                            DEBUG_CPRINT(("\n SBAND_SDR_APP_BEACON_DATA_REQ sent"));
                            log_id(LOG_INFO_L1,LOG_COMMS,SBAND_SDR_APP_BEACON_DATA_REQ_SENT);
                            sband_send_ipc(SBAND_SDR_APP_BEACON_DATA_REQ, SDR_APP);
                        }
                    }
                }
            }
            break;

        case SBAND_RX_ON_TIMER_EXP:
            {
                /** Nothing to be done */
            }
            break;

        case SDR_APP_SBAND_MH_REQ:
            {
                DEBUG_CPRINT(("\n SDR_APP_SBAND_MH_REQ"));
                log_id(LOG_INFO_L1,LOG_COMMS,SDR_APP_SBAND_MH_REQ);
                sdr_app_sdr_ctrl_sband_mh_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_SDR_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_sdr_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_MODE_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_mode_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_TMR_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_tmr_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_RSSI_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_rssi_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_TM_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_tm_cfg_req(payload);
            }
            break;

        case SDR_APP_SBAND_BEACON_DATA_IND:
            {
                /** Nothing to be done */
            }
            break;

        case SBAND_REP_TMR_EXP:
            {
                /** Nothing to be done */
            }
            break;

        case SBAND_FW_CFG_START_REQ:
            {
                state = COMMS_DFU_STATE;
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
                sband_send_ipc(SBAND_FW_CFG_UPD_IND, COMMS_SBAND_CTLR);
            }
            break;

        case SDR_APP_SDR_CTRL_GPASS_CFG:
            {
                sdr_app_sdr_ctrl_sband_sdr_gpass_cfg_req(payload);
            }
            break;            

        case SBAND_FW_CFG_STOP_REQ:
            {
                status = TC_STS_FW_UP_DELAY;
                sband_tc_tm_set_rsp_hdlr(TM_COMMS_FW_CFG,status);
            }
            break;

        case SBAND_REINIT_TMR_EXP:
            {
                /** Nothing to be done */
            }
            break;

        case SBAND_UNKNOWN_TC_TM_HDLR:
            {
                status = TC_STS_UNKNOWN_TC_TM;
                sband_tc_tm_set_rsp_hdlr(sband_tc_tm_id,status);
            }
            break;

        default:
            state = COMMS_CFG_STATE ;
            break;
    }
    return state;
}

/**
 * @brief This function handle comms calibration state
 * Handles S-Band calibration state events.
 *
 * @param[in] msg_id Received message ID.
 * @param[in] payload Message payload.
 * 
 * @return Next state. 
 */
uint8_t comms_calib_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_CALIB_STATE;
    int8_t status = COMMS_IPC_OK;

    DEBUG_CPRINT(("received response for COMMS_CLAIB : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_CLAIB__u16_,msg_id);
    switch (msg_id)
    {
        case COMMS_CALIB_DONE:
            DEBUG_CPRINT(("In CALIB_DONE state \n "));
            log_id(LOG_INFO_L1,LOG_COMMS,IN_CALIB_DONE_STATE);
            state = COMMS_SLEEP_IDLE_STATE;
            //comms_csw_trans_msg.Msg_id =  COMMS_INTRNL_SLEEP_REQ;

            DEBUG_CPRINT(("sending internal sleep request \n"));
            log_id(LOG_INFO_L1,LOG_COMMS,SENDING_INTERNAL_SLEEP_REQUEST);
            DEBUG_CPRINT(("In CALIB_DONE state, status of internal sleep request is %d \n ",status));
            log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,IN_CALIB_DONE_STATE_cm_STATUS_OF_INTERNAL_SLEEP_REQUEST_IS__s8_,status);
            break;

        case COMMS_CALIB_FAIL:
            DEBUG_CPRINT(("CALIB_FAIL event \n"));
            log_id(LOG_ERROR,LOG_COMMS,CALIB_FAIL_EVENT);
            state = COMMS_ERROR_STATE ;
            break;

        default:
            state = COMMS_SAFE_MODE_STATE ;
            break;
    }
    return state;
}

/**
 * @brief This API handle the comms idle state
 * Handles S-Band sleep/idle state events.
 *
 * @param[in] msg_id Received message ID. 
 * @param[in] payload Message payload.
 *
 * @return Next state.
 */
uint8_t comms_sleep_idle_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_SLEEP_IDLE_STATE;
    int8_t status = COMMS_IPC_OK;

    DEBUG_CPRINT(("received response for COMMS_SLEEP : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_SLEEP__u16_,msg_id);
    switch (msg_id)
    {
        case COMMS_SLEEP_DONE:
            DEBUG_CPRINT(("In SLEEP_IDLE_DONE state \n "));
            log_id(LOG_INFO_L1,LOG_COMMS,IN_SLEEP_IDLE_DONE_STATE);
            state = COMMS_ACTIVE_STATE;
            //comms_csw_trans_msg.Msg_id =  COMMS_INTRNL_TX_REQ;
            DEBUG_CPRINT(("sending internal tx request \n"));
            log_id(LOG_INFO_L1,LOG_COMMS,SENDING_INTERNAL_TX_REQUEST);
            DEBUG_CPRINT(("In SLEEP_DONE state, status of internal tx request is %d \n ",status));
            log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,IN_SLEEP_DONE_STATE_cm_STATUS_OF_INTERNAL_TX_REQUEST_IS__s8_,status);
            break;

        case COMMS_SLEEP_FAIL:
            DEBUG_CPRINT(("SLEEP_IDLE_FAIL event \n"));
            log_id(LOG_ERROR,LOG_COMMS,SLEEP_IDLE_FAIL_EVENT);
            state = COMMS_ERROR_STATE ;
            break;

        default:
            state = COMMS_SAFE_MODE_STATE ;
            break;
    }
    return state;
}

/**
 * @brief This API handle the comms active states
 * Handles S-Band active state events.
 *
 * @param[in] msg_id Received message ID.
 * @param[in] payload Message payload.
 * 
 * @return Next state.
 */
uint8_t comms_active_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_ACTIVE_STATE;
    int8_t status = COMMS_IPC_OK;
    status = status;

    DEBUG_CPRINT(("received response for COMMS_ACTIVE_STATE : %d \n", msg_id));
    log_id_with_one_arg(LOG_INFO_L1,LOG_COMMS,RECEIVED_RESPONSE_FOR_COMMS_ACTIVE_STATE__u16_,msg_id);
    switch (msg_id)
    {
        /** Added for error handling */
        case OBC_SBAND_INIT_REQ:
            {
                comms_sband_nvm_init();  

                state = COMMS_CFG_STATE;

                sband_cfg_seq = SBAND_GET_DEVICE_CFG;
                os_timer_start(sband_cmd_wait_timer,100);

            }
            break;

        case OBC_SBAND_DEINIT_REQ:
            {
                comms_sband_rssi_hdlr(OBC_SBAND_DEINIT_REQ);
#ifdef SDR_SBAND_SRS4
                comms_sband_cfg_nvm_write();
#endif
                comms_sband_xlinks_cfg_nvm_write();
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
                sband_send_ipc(SBAND_OBC_DEINIT_RSP,OBC_MAIN);

                state = COMMS_INIT_STATE;
            }
            break;

        case OTSU_SBAND_SYNC_REQ:
            {
                /** OTSU Call back - Success*/
                if(!sband_gs_contact_valid)
                {
                    comms_otsu_cb_sts = 1;
                }
                else
                {
#ifndef LINUX_TEMP_PORT
                    send_otsu_gssync_sts(1);
#endif
                }
            }
            break;

        case SBAND_TX_PERIODIC_BEACON_TMR_EXP:
            {
                DEBUG_CPRINT(("\n SBAND_TX_PERIODIC_BEACON_TMR_EXP"));
                log_id(LOG_INFO_L1,LOG_COMMS,SBAND_TX_PERIODIC_BEACON_TMR_EXP);

                DEBUG_CPRINT(("\n SBAND_SDR_APP_BEACON_DATA_REQ sent"));
                log_id(LOG_INFO_L1,LOG_COMMS,SBAND_SDR_APP_BEACON_DATA_REQ_SENT);
                sband_send_ipc(SBAND_SDR_APP_BEACON_DATA_REQ, SDR_APP);
            }
            break;

        case SBAND_TM_PERIODIC_READ:
            {
                comms_sband_rssi_hdlr(SBAND_TM_PERIODIC_READ);
                //sband_xlinks_health_report_tm();
            }
            break;

        case OBC_SBAND_HEALTH_CHECK_REQ:
            {
                DEBUG_CPRINT(("\n OBC_SBAND_HEALTH_CHECK_REQ"));
                log_id(LOG_INFO_L1,LOG_COMMS,OBC__SBAND_HEALTH_CHECK_REQ);
#ifdef SDR_SBAND_SRS4
                sband_health_report_tm();
#endif
            }
            break;

        case SCH_SBAND_GS_ST_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_ST_IND"));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_ST_IND);

                sband_sch_gs_contact = 1;
                
                /* condition check for beacon tx enable configurable option */
                if(!sband_gpass_cfg.gpass_beacon_tx_enb)
                {
                    DEBUG_CPRINT(("\n SBAND start req sent"));
                    sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,COMMS_SBAND_IQS);
                }
                else
                {
                    sband_rep_cnt = 0;
                    DEBUG_CPRINT(("\n SBAND_SDR_APP_BEACON_DATA_REQ sent"));
                    log_id(LOG_INFO_L1,LOG_COMMS,SBAND_SDR_APP_BEACON_DATA_REQ_SENT);
                    sband_send_ipc(SBAND_SDR_APP_BEACON_DATA_REQ, SDR_APP);
                }
            }
            break;

        case SCH_SBAND_GS_STOP_IND:
            {
                DEBUG_CPRINT(("\n SCH_SBAND_GS_STOP_IND"));
                log_id(LOG_INFO_L1,LOG_COMMS,SCH__SBAND_GS_STOP_IND);
                sband_sch_gs_contact = 0;
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
            }
            break;

        case SBAND_RX_ON_TIMER_EXP:
            {
                comms_sband_rssi_hdlr(SBAND_RX_ON_TIMER_EXP);
            }
            break;

        case SDR_APP_SBAND_MH_REQ:
            {
                DEBUG_CPRINT(("\n SDR_APP_SBAND_MH_REQ"));
                log_id(LOG_INFO_L1,LOG_COMMS,SDR_APP_SBAND_MH_REQ);
                sdr_app_sdr_ctrl_sband_mh_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_SDR_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_sdr_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_MODE_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_mode_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_TMR_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_tmr_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_RSSI_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_rssi_cfg_req(payload);
            }
            break;

        case SDR_APP_SDR_CTRL_TM_CFG_REQ:
            {
                sdr_app_sdr_ctrl_sband_tm_cfg_req(payload);
            }
            break;

        case SDR_APP_SBAND_BEACON_DATA_IND:
            {
                os_memcpy(&sband_beacon_data,payload,sizeof(s_sdr_beacon_pld));
                comms_sband_beacon_tx((uint8_t *)&sband_beacon_data,sizeof(s_sdr_beacon_pld));
            }
            break;

        case SBAND_REP_TMR_EXP:
            {
                comms_sband_beacon_tx((uint8_t *)&sband_beacon_data,sizeof(s_sdr_beacon_pld));
            }
            break;

        case SBAND_FW_CFG_START_REQ:
            {
                state = COMMS_DFU_STATE;
                sband_gs_contact_status_upd_itc(SBAND_TC_TM_STOP_REQ,COMMS_SBAND_IQS);
                sband_send_ipc(SBAND_FW_CFG_UPD_IND, COMMS_SBAND_CTLR);
            }
            break;

        case SBAND_FW_CFG_STOP_REQ:
            {
                status = TC_STS_FW_UP_DELAY;
                sband_tc_tm_set_rsp_hdlr(TM_COMMS_FW_CFG,status);
            }
            break;

        case SBAND_REINIT_TMR_EXP:
            {
                if(sband_sch_gs_contact)
                {
                    sband_gs_contact_status_upd_itc(SBAND_TC_TM_ST_REQ,COMMS_SBAND_IQS);
                }
            }
            break;

        case SBAND_UNKNOWN_TC_TM_HDLR:
            {
                status = TC_STS_UNKNOWN_TC_TM;
                sband_tc_tm_set_rsp_hdlr(sband_tc_tm_id,status);
            }
            break;

        case SBAND_TX_WIN_ON_REQ:
            {
                DEBUG_CPRINT(("\n SBAND_TX_WIN_ON_REQ RTC Time-%d:%d:%d",get_t_iqs.hour, get_t_iqs.min, get_t_iqs.sec));
                sband_iqs_tx_ON = 1;
                status = comms_sband_xlink_tx_on(sband_iqs_tx_ON);

                os_sem_give(tx_win_on_sem);
            }
            break;
        case SBAND_IQS_TX_WIN_OFF:
            {
        	//iqs device config off
        	get_rtc_time(&get_t_iqs);
        	DEBUG_CPRINT(("\nSBAND_IQS_TX_WIN_OFF RTC Time-%d:%d:%d",get_t_iqs.hour, get_t_iqs.min, get_t_iqs.sec));
                DEBUG_CPRINT(("\n\rIQS TX_WIN_OFF: "));

                sband_iqs_tx_ON = 0;
                status = comms_sband_xlink_tx_on(sband_iqs_tx_ON);
            }
            break;
        case SBAND_RESET_CFG:
            {
                state = COMMS_CFG_STATE;
                sband_cfg_seq = SBAND_SET_RESET;
                os_timer_start(sband_cmd_wait_timer,1000);
            }
            break;

      case SDR_APP_SDR_CTRL_GPASS_CFG:
            {
                sdr_app_sdr_ctrl_sband_sdr_gpass_cfg_req(payload);
            }
            break;


        case SBAND_PROD_KEY_CFG:
            {
                state = COMMS_CFG_STATE;
                sband_cfg_seq = SBAND_SET_RESET;
                os_timer_start(sband_cmd_wait_timer,1000);
            }
            break;
        default:
            state = COMMS_ACTIVE_STATE ;
            break;

    }
    return state;
}

/**
 * @brief This functions handle the comms safe mode state
 * @brief S-Band safe mode state handler. 
 *
 * Implements safe mode actions:
 * - Stops periodic telemetry collection.
 * - Sends safe mode notification message.
 * - Waits for reset/recovery command.
 *
 * @param[in] msg_id Received message ID   
 * @param[in] payload Message payload 
 * @return Next state 
 */
uint8_t comms_safe_mode_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_SAFE_MODE_STATE;
    return state;
}

/**
 * @brief This function handle the comms error state
 * @brief S-Band error state handler.
 * 
 * Implements error state actions:
 * - Stops S-Band threads and timers.
 * - Sends error notification message. 
 * - Waits for reset command to restart S-Band.
 *
 * @param[in] msg_id Received message ID 
 * @param[in] payload Message payload 
 * @return Next state
 */
uint8_t comms_error_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_ERROR_STATE;
    return state;
}

/**
 * @brief This function handling Bypass the comms states
 * @brief S-Band bypass state handler.
 * 
 * Implements bypass mode actions:
 * - Disables standard TC packet handling.
 * - Sends all received frames directly to client.
 * - Forwards any transmit requests directly to radio. 
 * - Periodic telemetry and beaconing still enabled.
 *
 * Allows bypassing link layer protocol for debugging.
 * 
 * @param[in] msg_id Received message ID (unused).
 * @param[in] payload Message payload (unused).
 * @return Next state (stays in bypass state).
 */
uint8_t comms_bypass_state_hdlr(uint16_t msg_id, void *payload)
{
    uint8_t state = COMMS_BYPASS_STATE;
#ifdef COMMS_TIME_DEBUG
    get_crnt_time_date(&tim_get_fs_st);
    DEBUG_CPRINT(("\nIQS TIME GET FSM_ST_ENT %d:%d:%d Msg_id - %d",tim_get_fs_st.hour, tim_get_fs_st.minute, tim_get_fs_st.seconds, msg_id ));
    log_id_with_four_arg(LOG_INFO_L2,LOG_COMMS,IQS_TIME_GET_FSM_ST_ENT_u8__u8__u8__MSG_ID__u8_,tim_get_fs_st.hour, tim_get_fs_st.minute, tim_get_fs_st.seconds, msg_id);
#endif 

    DEBUG_CPRINT(("\nCOMMS_BYPASS_State\n"));
    log_id(LOG_INFO_L1,LOG_COMMS,COMMS__BYPASS_STATE);

    switch (msg_id)
    {
        default:
            state = COMMS_SAFE_MODE_STATE ;
            break;
    }
#ifdef COMMS_TIME_DEBUG
    get_crnt_time_date(&tim_get_fs_st);
    DEBUG_CPRINT(("\nIQS TIME FSM_ST_EXT %d:%d:%d",tim_get_fs_st.hour, tim_get_fs_st.minute, tim_get_fs_st.seconds));
    log_id_with_three_arg(LOG_INFO_L2,LOG_COMMS,IQS_TIME_GET_FSM_ST_EXT_u8__u8__u8__,tim_get_fs_st.hour, tim_get_fs_st.minute, tim_get_fs_st.seconds);
#endif
    return state;

}

/**
 * @brief This API handle the comms finite states machine
 * @brief S-Band FSM handler function.
 *
 * Dispatches current state handler based on state enum.
 * Contains mapping of states to handler functions.
 *
 * @param[in] state Current S-Band state.
 * @param[in] msg_id Received message ID.
 * @param[in] payload Message payload data.
 * @return Next S-Band state from state handler.
 */
uint8_t comms_fsm_hdlr_fn(uint8_t state,uint16_t msg_id, void *payload)
{
    return(comms_fsm_hdlr[state](msg_id,payload));

}

#ifdef SDR_SBAND_SRS4
/**
 * @brief This function monitor and report the sband health metrics
 * Collects and sends telemetry on current S-Band 
 * driver health and statistics.
 */
void sband_health_report_tm(void)
{
    uint16_t seq_no = 0;
    int32_t status = COMMS_IPC_OK;
    uint16_t rx_size = 0;
    os_memset(comms_csw_rx_buf,0,sizeof(comms_csw_rx_buf));

    status = SDR_SBAND_GET_TM_PROP((s_comms_tm_prop *)&comms_csw_rx_buf[TM_PLD_IDX],rx_size);
    rx_size = sizeof(s_comms_tm_prop);
    comms_tc_tm_get_rsp_hdlr(TM_GET_COMMS_TM_INFO, status,(uint8_t *)&seq_no, rx_size);

    os_memset(comms_csw_rx_buf,0,sizeof(comms_csw_rx_buf));
    status = SDR_SBAND_GET_TX_TM_PROP((s_comms_tx_tm *)&comms_csw_rx_buf[TM_PLD_IDX],&rx_size);
    rx_size = sizeof(s_comms_tx_tm);
    comms_tc_tm_get_rsp_hdlr(TM_GET_COMMS_TX_TM_INFO, status,(uint8_t *)&seq_no, rx_size);
}
#endif

/**
 * @brief Handle S-Band re-initialization.
 *
 * Performs re-init steps on unrecoverable error:
 * - Stops S-Band threads and timers.
 * - Resets global data structures.
 * - Restarts driver threads and state machine.
 */
void sband_reinit_exp_hdlr(void)
{
    uint32_t eps_req[2];
    eps_req[0] = HW_S_BAND;
    eps_req[1] = PWR_ON;

    sband_send_ipc_pld(EPS_SET_CHNL_STATE,EPS_TASK,sizeof(eps_req),(uint8_t *)eps_req);
}

