

/**
 * @file obc_main_fsm_hdlr.c
 *
 * @brief #TODO
 *
 * #TODO
 *
 */
/*********************************************************************/
#include <stdio.h>
#include "obc_main_fsm_hdlr.h"
#include "obc_intf_ctrl_msg.h"
#include "obc_tc_tm.h"
#include"exo_common.h"
#include "file_transfer.h"
#include "otsu.h"
#include "obc_ipc.h"
#include "obc_icd.h"
#include "obc_main.h"
#include "sm_api.h"
#include "exo_ahw_al_temp_sensor_common.h"
#include "exo_ahw_al_psm_common.h"
#include "exo_tctm_ipc.h"
#include "schedular.h"

#include "nvm.h"

icm_tc_pld_info_s tc_pld_info;
uint8_t *obc_tc_listner_thread_buffer;
uint16_t obc_tc_listner_thread_bytesize = 0;

uint8 *obc_tc_listner_thread_data;
uint16 obc_tc_listner_thread_icd_data_len;

uint8 obc_otsu_shutdown_ind =0;

uint8_t sub_mod_sts[OBC_SUB_MOD_MAX] = {0};

uint8_t obc_eps_bat_sts = 0;
uint8_t obc_eps_dev_sts = 0;
uint8_t obc_eps_dev_id = 0;
#ifndef LINUX_TEMP_PORT
extern uint16_t rst_count;
#else
uint16_t rst_count = 0;
#endif
extern volatile uint8_t system_error;

extern strFTM_queue_tctm_info s_ftm_queue_tc_frame;

extern uint32 tm_rsp_id;
extern uint16_t sequence_number;
extern uint8_t radio_module_id;

typedef uint8 (*OBC_SM_HDLR)(os_itc_msg_handle_t *payload);

OBC_SM_HDLR obc_fsm_hdlr[OBC_MAX_NUM_STATE] = {\
    &obc_init_state_hdlr,\
    &obc_active_pwr_critical_state_hdlr,\
    &obc_active_pwr_safe_state_hdlr,\
    &obc_active_pwr_normal_state_hdlr,\
    &obc_power_save_state_hdlr,\
    &obc_reset_state_hdlr,
    &obc_error_state_hdlr,
};

#ifndef LINUX_TEMP_PORT

static void send_obc_shutdown_sts(void);


/**
 * @brief This function send obc shutdown status to OTSU module
 */
static void send_obc_shutdown_sts(void)
{
	os_itc_msg_handle_t msg_hdl;
	msg_hdl.src_entity 	= OBC_MAIN;
	msg_hdl.Msg_id 	= OTSU_OBC_HANDSHAKE_DONE;
	msg_hdl.Msg_len 	= 0;
	msg_hdl.pld.pld_ptr = NULL;
    os_itc_msg_send(&msg_hdl,OBC_OTSU, os_send_itc_wait);
}
#endif

uint8 obc_fsm(uint8_t state, os_itc_msg_handle_t *payload)
{
    return obc_fsm_hdlr[state](payload);
}

uint8 obc_init_state_hdlr(os_itc_msg_handle_t *payload)
{
	uint16_t tc_ipc_id = 0;
#ifdef OBC_ENBL_DBG_PRNT
    int loop = 0;
    loop=loop;
#endif

    if(payload->src_entity == TC_TM_MANAGER_IPC_RECEIVE)
  	{
  		tc_ipc_id = payload->pld_info;
  	}
  	else
  	{
  		tc_ipc_id = payload->Msg_id;
  	}
    uint8 state = OBC_INIT_STATE;

    //os_status_t status;
    switch(tc_ipc_id)
    {
        case OBC_TMR_EXPRY_EVNT:
            {
                /*Send OBC health data to HM framework*/
                obc_timer_exp_send_health_info();
            }
            break;
        case SBAND_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ACTIVE;
            }
            break;
        case XBAND_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ACTIVE;
            }
            break;
        case UHF_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ACTIVE;
            }
            break;
        case SCH_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ACTIVE;
            }
            break;
        case ADCS_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ACTIVE;
            }
            break;
        case OTSU_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ACTIVE;
            }
            break;
        case TC_TM_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ACTIVE;
            }
            break;
        case PLD_SERVER_OBC_INIT_RSP:
            {
                uint8_t pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_ACTIVE;
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_DEINIT_RSP rcvd :%d\n", pld_id));
                //obc_send_ipc_msg(OBC_EPS_INIT_RSP, EPS_TASK);
            }
            break;
        case SEN_OBC_INIT_RSP:
            {
                uint8_t sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_ACTIVE;
            }
            break;

        case SBAND_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();

                if(obc_otsu_shutdown_ind)
                {
                    uint8_t hw_sts = 0;
                    //obc_send_ipc_msg_pld_eps(EPS_TASK,EPS_SET_CHNL_STATE,HW_S_BAND,(uint8_t *)&hw_sts,1);
                    obc_send_ipc_msg_pld_eps(EPS_TASK,104,HW_S_BAND,(uint8_t *)&hw_sts,1);
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;
        case XBAND_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_INACTIVE;
            }
            break;

        case UHF_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_INACTIVE;
            }
            break;

        case TC_TM_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_INACTIVE;

                if(obc_otsu_shutdown_ind)
                {
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;
        case ADCS_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_INACTIVE;

                if(obc_otsu_shutdown_ind)
                {
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;
        case PLD_SERVER_OBC_DEINIT_RSP:
            {
                uint8_t pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_INACTIVE;

                DEBUG_CPRINT(("\n PLD_SERVER_OBC_DEINIT_RSP rcvd :%d\n", pld_id));
                if(obc_otsu_shutdown_ind)
                {
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;
        case SCH_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_INACTIVE;

                if(obc_otsu_shutdown_ind)
                {
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;
        case OTSU_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_INACTIVE;
                //obc_send_ipc_msg(OBC_EPS_DEINIT_RSP, EPS_TASK);

                if(obc_otsu_shutdown_ind)
                {
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;

        case SEN_OBC_DEINIT_RSP:
            {
                uint8_t sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_INACTIVE;

                if(obc_otsu_shutdown_ind)
                {
                    obc_otsu_deinit_rsp_hdlr();
                }
            }
            break;

        case PLD_SERVER_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_PLD_SRVR] = SW_ERROR;
            }
            break;

        case OTSU_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ERROR;
            }
            break;

        case ADCS_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ERROR;
            }
            break;

        case SBAND_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ERROR;
            }
            break;

        case XBAND_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ERROR;
            }
            break;

        case UHF_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ERROR;
            }
            break;

        case TC_TM_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ERROR;
            }
            break;

        case SCH_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ERROR;
            }
            break;

        case EPS_OBC_BAT_STS_IND:
            {
                obc_eps_bat_sts = *((uint8_t *)payload->pld.pld_ptr);

                state = obc_eps_battery_sts_proc(obc_eps_bat_sts);
            }
            break;

        case EPS_OBC_DEV_STS_IND:
            {
                os_memcpy(&obc_eps_dev_id,  ((uint8_t *)payload->pld.pld_ptr)+0,1);
                os_memcpy(&obc_eps_dev_sts, ((uint8_t *)payload->pld.pld_ptr)+1,1);

                obc_eps_proc_dev_sts(obc_eps_dev_id, obc_eps_dev_sts);
            }
            break;

        case TC_DST_OBC:
            {
                obc_tc_listner_thread_buffer= payload->pld.pld_ptr;
                obc_tc_listner_thread_bytesize = payload->Msg_len;

                //Sequence number field is skipped for now and TC data is passed to TC decoder
                //TODO Use Sequence number for correlation ID in future
                obc_tc_hdlr(payload->Msg_id, payload->Msg_len, (uint8_t *)payload->pld.pld_ptr);

#ifdef OBC_ENBL_DBG_PRNT
                //DEBUG_CPRINT(("OBC APP: Received TM data: "));
            for(loop = 0; loop < obc_tc_listner_thread_bytesize; loop++)
            {
                //DEBUG_CPRINT(("%x ", obc_tc_listner_thread_buffer[loop]));
            }
            //DEBUG_CPRINT(("\n"));

#endif
        }
        break;
        case SBAND_OBC_GROUND_SYNC_IND:
        {
            obc_proc_sband_ground_sync_ind();
        }
        break;

        case SBAND_OBC_HEALTH_CHECK_REQ:
        {
            obc_proc_sband_health_check_req();
        }
        break;

        case OTSU_OBC_SHUTDOWN_REQ:
        {
            obc_shutdown_hdlr();
            state = OBC_INIT_STATE;
        }
        break;
        /** - Req from SDR for Beacon Health metrics */
        case SDR_APP_OBC_MH_REQ:
        {
            obc_sdr_beacon_health_metric_enc();

        }
        break;
        case OBC_TC_TM_CHNG_QUEUE_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_QUEUE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;

        case OBC_TC_TM_CHNG_SUB_MOD_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_MODULE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;
        case OBC_HM_TEST_CASE_RSP:
		{
			  /**  - Send the response back to GS */
			  obc_pck_data rsp;
			  rsp.tm_rsp_id = TM_HM_TEST_CASE_REQ;
			  rsp.rx_data = (uint8_t*)payload->pld.pld_ptr;
			  obc_pack_tm_data(&rsp);
		}
		break;
        default:
            state = OBC_INIT_STATE;
    }

    return state;
}

uint8 obc_active_pwr_critical_state_hdlr(os_itc_msg_handle_t *payload)
{
	uint16_t tc_ipc_id = 0;
#ifdef OBC_ENBL_DBG_PRNT
    int loop = 0;
    loop=loop;
#endif
    if(payload->src_entity == TC_TM_MANAGER_IPC_RECEIVE)
	{
		tc_ipc_id = payload->pld_info;
	}
	else
	{
		tc_ipc_id = payload->Msg_id;
	}
	uint8 state = OBC_ACTIVE_PWR_CRITICAL_STATE;
    switch(tc_ipc_id)
    {

        case OBC_TMR_EXPRY_EVNT:
            {
                /*Send OBC health data to HM framework*/
                obc_timer_exp_send_health_info();
            }
            break;
        case SBAND_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ACTIVE;
            }
            break;
        case XBAND_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ACTIVE;
            }
            break;
        case UHF_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ACTIVE;
            }
            break;
        case SCH_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ACTIVE;
            }
            break;
        case ADCS_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ACTIVE;
            }
            break;
        case OTSU_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ACTIVE;
            }
            break;
        case TC_TM_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ACTIVE;
            }
            break;
        case PLD_SERVER_OBC_INIT_RSP:
            {
                uint8_t pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_ACTIVE;
                //obc_send_ipc_msg(OBC_EPS_INIT_RSP, EPS_TASK);
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_INIT_RSP rcvd :%d\n", pld_id));
            }
            break;
        case SEN_OBC_INIT_RSP:
            {
                uint8_t sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_ACTIVE;
            }
            break;

        case SBAND_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();
            }
            break;

        case XBAND_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();
            }
            break;

        case UHF_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_INACTIVE;
            }
            break;

        case TC_TM_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_INACTIVE;
            }
            break;
        case ADCS_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_INACTIVE;
            }
            break;
        case PLD_SERVER_OBC_DEINIT_RSP:
            {
                uint8_t  pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_INACTIVE;
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_DEINIT_RSP rcvd :%d\n", pld_id));
            }
            break;
        case SCH_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_INACTIVE;
            }
            break;
        case OTSU_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_INACTIVE;
                //obc_send_ipc_msg(OBC_EPS_DEINIT_RSP, EPS_TASK);
            }
            break;

        case SEN_OBC_DEINIT_RSP:
            {
                uint8_t sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_INACTIVE;
            }
            break;

        case PLD_SERVER_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_PLD_SRVR] = SW_ERROR;
            }
            break;

        case OTSU_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ERROR;
            }
            break;

        case ADCS_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ERROR;
            }
            break;

        case SBAND_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ERROR;
            }
            break;

        case XBAND_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ERROR;
            }
            break;

        case UHF_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ERROR;
            }
            break;

        case TC_TM_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ERROR;
            }
            break;

        case SCH_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ERROR;
            }
            break;

        case EPS_OBC_DEV_STS_IND:
            {
                os_memcpy(&obc_eps_dev_id, (uint8_t *)(payload->pld.pld_ptr)+0,1);
                os_memcpy(&obc_eps_dev_sts,(uint8_t *)(payload->pld.pld_ptr)+1 ,1);

                obc_eps_proc_dev_sts(obc_eps_dev_id, obc_eps_dev_sts);
            }
            break;

        case EPS_OBC_BAT_STS_IND:
            {
                obc_eps_bat_sts= *((uint8_t *)payload->pld.pld_ptr);

                state = obc_eps_battery_sts_proc(obc_eps_bat_sts);
            }
            break;

        case TC_DST_OBC:
            {
                obc_tc_listner_thread_buffer= payload->pld.pld_ptr;
                obc_tc_listner_thread_bytesize = payload->Msg_len;

                //Sequence number field is skipped for now and TC data is passed to TC decoder
                //TODO Use Sequence number for correlation ID in future
                obc_tc_hdlr(payload->Msg_id, payload->Msg_len, (uint8_t *)payload->pld.pld_ptr);

#ifdef OBC_ENBL_DBG_PRNT
                //DEBUG_CPRINT(("OBC APP: Received TM data: "));
            for(loop = 0; loop < obc_tc_listner_thread_bytesize; loop++)
            {
                //DEBUG_CPRINT(("%x ", obc_tc_listner_thread_buffer[loop]));
            }
            //DEBUG_CPRINT(("\n"));

#endif
        }
        break;

        case OTSU_OBC_SHUTDOWN_REQ:
        {
            obc_shutdown_hdlr();
            state = OBC_INIT_STATE;
        }
        break;


        case SBAND_OBC_HEALTH_CHECK_REQ:
        {
            obc_proc_sband_health_check_req();
        }
        break;

        case SBAND_OBC_GROUND_SYNC_IND:
        {
            obc_proc_sband_ground_sync_ind();
        }
        break;
        /** - Req from SDR for Beacon Health metrics */
        case SDR_APP_OBC_MH_REQ:
        {
            obc_sdr_beacon_health_metric_enc();

        }
        break;
        case OBC_TC_TM_CHNG_QUEUE_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_QUEUE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;

        case OBC_TC_TM_CHNG_SUB_MOD_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_MODULE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;
        case OBC_HM_TEST_CASE_RSP:
		{
			  /**  - Send the response back to GS */
			  obc_pck_data rsp;
			  rsp.tm_rsp_id = TM_HM_TEST_CASE_REQ;
			  rsp.rx_data = (uint8_t*)payload->pld.pld_ptr;
			  obc_pack_tm_data(&rsp);
		}
		break;

        default:
            state = OBC_ACTIVE_PWR_CRITICAL_STATE;
    }

    return state;
}

uint8 obc_active_pwr_safe_state_hdlr(os_itc_msg_handle_t *payload)
{
	uint16_t tc_ipc_id = 0;
#ifdef OBC_ENBL_DBG_PRNT
    int loop = 0;
    loop=loop;
#endif

    if(payload->src_entity == TC_TM_MANAGER_IPC_RECEIVE)
      {
      	tc_ipc_id = payload->pld_info;
      }
      else
      {
      	tc_ipc_id = payload->Msg_id;
      }
    uint8 state = OBC_ACTIVE_PWR_SAFE_STATE;
    switch(tc_ipc_id)
    {
        case OBC_TMR_EXPRY_EVNT:
            {
                /*Send OBC health data to HM framework*/
                obc_timer_exp_send_health_info();
            }
            break;
        case SBAND_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ACTIVE;
            }
            break;
        case XBAND_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ACTIVE;
            }
            break;
        case UHF_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ACTIVE;
            }
            break;
        case SCH_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ACTIVE;
            }
            break;
        case ADCS_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ACTIVE;
            }
            break;
        case OTSU_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ACTIVE;
            }
            break;
        case TC_TM_OBC_INIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ACTIVE;
            }
            break;
        case PLD_SERVER_OBC_INIT_RSP:
            {
                uint8 pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_ACTIVE;
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_INIT_RSP rcvd :%d\n", pld_id));
                //obc_send_ipc_msg(OBC_EPS_INIT_RSP, EPS_TASK);
            }
            break;
        case SEN_OBC_INIT_RSP:
            {
                uint8 sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_ACTIVE;
            }
            break;

        case SBAND_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();
            }
            break;

        case XBAND_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();
            }
            break;

        case UHF_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_INACTIVE;
            }
            break;

        case TC_TM_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_INACTIVE;
            }
            break;
        case ADCS_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_INACTIVE;
            }
            break;
        case PLD_SERVER_OBC_DEINIT_RSP:
            {
                uint8 pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_INACTIVE;
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_DEINIT_RSP rcvd :%d\n", pld_id));
            }
            break;
        case SCH_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_INACTIVE;
            }
            break;
        case SEN_OBC_DEINIT_RSP:
            {
                uint8 sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_INACTIVE;
                //obc_send_ipc_msg(OBC_EPS_DEINIT_RSP, EPS_TASK);
            }
            break;

        case OTSU_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_INACTIVE;
                //obc_send_ipc_msg(OBC_EPS_DEINIT_RSP, EPS_TASK);
            }
            break;

        case PLD_SERVER_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_PLD_SRVR] = SW_ERROR;
            }
            break;

        case OTSU_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ERROR;
            }
            break;

        case ADCS_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ERROR;
            }
            break;

        case SBAND_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ERROR;
            }
            break;

        case XBAND_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ERROR;
            }
            break;

        case UHF_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ERROR;
            }
            break;

        case TC_TM_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ERROR;
            }
            break;

        case SCH_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ERROR;
            }
            break;

        case EPS_OBC_DEV_STS_IND:
            {
                os_memcpy(&obc_eps_dev_id, ((uint8_t *)(payload->pld.pld_ptr) + 0),1);
                os_memcpy(&obc_eps_dev_sts,((uint8_t *)(payload->pld.pld_ptr) + 1), 1);

                obc_eps_proc_dev_sts(obc_eps_dev_id, obc_eps_dev_sts);
            }
            break;

        case EPS_OBC_BAT_STS_IND:
            {
                obc_eps_bat_sts = *(uint8_t *)payload->pld.pld_ptr;

                state = obc_eps_battery_sts_proc(obc_eps_bat_sts);
            }
            break;


        case TC_DST_OBC:
        case TC_DST_FTM_OTSU:
        case TC_DST_FTM_DBGLOG:
        case TC_DST_FTM_OBC_COMMS:
        case TC_DST_FTM_OBC_EPS:
        case TC_DST_FTM_OBC_ADCS:
            {
            	if(payload->pld_info != TC_DST_OBC)
            	{
            		/* FTM use this to identify APP id */
            		s_ftm_queue_tc_frame.src_dst_id = payload->pld_info;
            	}
                obc_tc_listner_thread_buffer= payload->pld.pld_ptr;
                obc_tc_listner_thread_bytesize = payload->Msg_len;

                //Sequence number field is skipped for now and TC data is passed to TC decoder
                //TODO Use Sequence number for correlation ID in future
                obc_tc_hdlr(payload->Msg_id, payload->Msg_len, (uint8_t *)payload->pld.pld_ptr);

#ifdef OBC_ENBL_DBG_PRNT
                //DEBUG_CPRINT(("OBC APP: Received TM data: "));
            for(loop = 0; loop < obc_tc_listner_thread_bytesize; loop++)
            {
                //DEBUG_CPRINT(("%x ", obc_tc_listner_thread_buffer[loop]));
            }
            //DEBUG_CPRINT(("\n"));

#endif
        }
        break;

        case OTSU_OBC_SHUTDOWN_REQ:
        {
            obc_shutdown_hdlr();
            state = OBC_INIT_STATE;
        }
        break;


        case SBAND_OBC_HEALTH_CHECK_REQ:
        {
            obc_proc_sband_health_check_req();
        }
        break;

        case SBAND_OBC_GROUND_SYNC_IND:
        {
            obc_proc_sband_ground_sync_ind();
        }
        break;
        /** - Req from SDR for Beacon Health metrics */
        case SDR_APP_OBC_MH_REQ:
        {
            obc_sdr_beacon_health_metric_enc();

        }
        break;
        case OBC_TC_TM_CHNG_QUEUE_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_QUEUE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;

        case OBC_TC_TM_CHNG_SUB_MOD_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_MODULE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;
        case OBC_HM_TEST_CASE_RSP:
		{
			  /**  - Send the response back to GS */
			  obc_pck_data rsp;
			  rsp.tm_rsp_id = TM_HM_TEST_CASE_REQ;
			  rsp.rx_data = (uint8_t*)payload->pld.pld_ptr;
			  obc_pack_tm_data(&rsp);
		}
		break;
        default:
            state = OBC_ACTIVE_PWR_SAFE_STATE;
    }

    return state;
}

uint8 obc_active_pwr_normal_state_hdlr(os_itc_msg_handle_t *payload)
{
#ifdef OBC_ENBL_DBG_PRNT
    int loop = 0;
#endif
    uint16_t tc_ipc_id = 0;
    uint8 state = OBC_ACTIVE_PWR_NORM_STATE;

    //DEBUG_CPRINT(("\nOBC Normal state Entry - Mesg_id : %ld\n",payload->pld_info));
    if(payload->src_entity == TC_TM_MANAGER_IPC_RECEIVE)
    {
    	tc_ipc_id = payload->pld_info;
    }
    else
    {
    	tc_ipc_id = payload->Msg_id;
    }
    switch(tc_ipc_id)
    {
        case OBC_TMR_EXPRY_EVNT:
            {   
                /*Send OBC health data to HM framework*/
                obc_timer_exp_send_health_info();
            }
            break;
        case SBAND_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n SBAND_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ACTIVE;
            }
            break;
        case XBAND_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n XBAND_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ACTIVE;
            }
            break;
        case UHF_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n UHF_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ACTIVE;
            }
            break;
        case SCH_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n SCH_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ACTIVE;
            }
            break;
        case ADCS_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n ADCS_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ACTIVE;
            }
            break;
        case OTSU_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n OTSU_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ACTIVE;
            }
            break;
        case TC_TM_OBC_INIT_RSP:
            {
                DEBUG_CPRINT(("\n TC_TM_OBC_INIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ACTIVE;
            }
            break;
        case PLD_SERVER_OBC_INIT_RSP:
            {
                uint8 pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_ACTIVE;
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_INIT_RSP rcvd :%d\n", pld_id));
                //obc_send_ipc_msg(OBC_EPS_INIT_RSP, EPS_TASK);
            }
            break;
        case SEN_OBC_INIT_RSP:
            {
                uint8 sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_ACTIVE;
                DEBUG_CPRINT(("\n SEN_OBC_INIT_RSP rcvd :%d\n", sen_id));
            }
            break;

        case SBAND_OBC_DEINIT_RSP:
            {
                DEBUG_CPRINT(("\n SBAND_OBC_DEINIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();
            }
            break;

        case XBAND_OBC_DEINIT_RSP:
            {
                DEBUG_CPRINT(("\n XBAND_OBC_DEINIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_INACTIVE;
                //status = comms_sband_suspend();
            }
            break;

        case UHF_OBC_DEINIT_RSP:
            {
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_INACTIVE;
            }
            break;

        case TC_TM_OBC_DEINIT_RSP:
            {
                DEBUG_CPRINT(("\n TC_TM_OBC_DEINIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_INACTIVE;
            }
            break;
        case ADCS_OBC_DEINIT_RSP:
            {
                DEBUG_CPRINT(("\n ADCS_OBC_DEINIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_INACTIVE;
            }
            break;
        case PLD_SERVER_OBC_DEINIT_RSP:
            {
                uint8 pld_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[pld_id] = SW_INACTIVE;
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_DEINIT_RSP rcvd :%d\n", pld_id));
            }
            break;
        case SCH_OBC_DEINIT_RSP:
            {
                DEBUG_CPRINT(("\n SCH_OBC_DEINIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_INACTIVE;
            }
            break;
        case OTSU_OBC_DEINIT_RSP:
            {
                DEBUG_CPRINT(("\n OTSU_OBC_DEINIT_RSP rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_INACTIVE;
                //obc_send_ipc_msg(OBC_EPS_DEINIT_RSP, EPS_TASK);
            }
            break;
        case SEN_OBC_DEINIT_RSP:
            {
                uint8 sen_id = *(uint8_t *)payload->pld.pld_ptr;
                sub_mod_sts[sen_id] = SW_INACTIVE;
                DEBUG_CPRINT(("\n SEN_OBC_DEINIT_RSP rcvd: %d \n",sen_id));
            }
            break;


        case PLD_SERVER_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n PLD_SERVER_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_PLD_SRVR] = SW_ERROR;
            }
            break;

        case OTSU_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n OTSU_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_OTSU] = SW_ERROR;
            }
            break;

        case ADCS_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n ADCS_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_ADCS] = SW_ERROR;
            }
            break;

        case SBAND_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n SBAND_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_S_BAND] = SW_ERROR;
            }
            break;

        case XBAND_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n XBAND_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_X_BAND] = SW_ERROR;
            }
            break;

        case UHF_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n UHF_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_UHF] = SW_ERROR;
            }
            break;

        case TC_TM_OBC_ERROR_IND:
            {
                DEBUG_CPRINT(("\n TC_TM_OBC_ERROR_IND rcvd\n"));
                sub_mod_sts[OBC_SUB_MOD_TC_TM] = SW_ERROR;
            }
            break;

        case SCH_OBC_ERROR_IND:
            {
                sub_mod_sts[OBC_SUB_MOD_SCH] = SW_ERROR;
                DEBUG_CPRINT(("\n SCH_OBC_ERROR_IND rcvd\n"));
            }
            break;

        case EPS_OBC_BAT_STS_IND:
            {
                DEBUG_CPRINT(("\n EPS_OBC_BAT_STS_IND rcvd\n"));
                obc_eps_bat_sts = *(uint8_t *)payload->pld.pld_ptr;

                state = obc_eps_battery_sts_proc(obc_eps_bat_sts);
            }
            break;

        case EPS_OBC_DEV_STS_IND:
            {
                DEBUG_CPRINT(("\n EPS_OBC_DEV_STS_IND rcvd\n"));
                os_memcpy(&obc_eps_dev_id,  (uint8_t *)payload->pld.pld_ptr + 0,1);
                os_memcpy(&obc_eps_dev_sts, (uint8_t *)payload->pld.pld_ptr + 1,1);

                obc_eps_proc_dev_sts(obc_eps_dev_id, obc_eps_dev_sts);
            }
            break;

        case TC_DST_OBC:
        case TC_DST_FTM_OTSU:
        case TC_DST_FTM_DBGLOG:
        case TC_DST_FTM_OBC_COMMS:
        case TC_DST_FTM_OBC_EPS:
        case TC_DST_FTM_OBC_ADCS:
            {
            	if(payload->pld_info != TC_DST_OBC)
            	{
            		/* FTM use this to identify APP id */
            		s_ftm_queue_tc_frame.src_dst_id = payload->pld_info;
            	}

                obc_tc_listner_thread_buffer= payload->pld.pld_ptr;
                obc_tc_listner_thread_bytesize = payload->Msg_len;

                //Sequence number field is skipped for now and TC data is passed to TC decoder
                //TODO Use Sequence number for correlation ID in future
                obc_tc_hdlr(payload->Msg_id, payload->Msg_len, (uint8_t *)payload->pld.pld_ptr);

#ifdef OBC_ENBL_DBG_PRNT
                //DEBUG_CPRINT(("OBC APP: Received TM data: "));
            for(loop = 0; loop < obc_tc_listner_thread_bytesize; loop++)
            {
                //DEBUG_CPRINT(("%x ", obc_tc_listner_thread_buffer[loop]));
            }
            //DEBUG_CPRINT(("\n"));

#endif
        }
        break;

        case TC_SCH_PS_TRIG:
        {
            uint32 *ps_data = (uint32*)payload->pld.pld_ptr;
            switch(ps_data[0])
            {
                case SCH_STAGED_TC:
                    {
                        obc_icd_ps_stgd_tc((uint32_t)ps_data[1]);
                    }
                    break;
                case SCH_VM_ON:
                    {
                        obc_icd_vm_pwr_ctrl(ps_data[1],1);
                    }
                    break;
                case SCH_VM_OFF:
                    {
                        obc_icd_vm_pwr_ctrl(ps_data[1],0);
                    }
                    break;
                default:
                    {
                    }
                    break;
            }
        }
        break;
#if 0
        case TC_DST_PLD_TC:
        case TC_DST_PLD_SW:
        case TC_DST_PLD_NET:
        case TC_DST_PLD_ZES:
        case TC_DST_PLD_SL:
        case TC_DST_FTM_PS_COMMS:
        case TC_DST_PLD_SRVR:
        {
            DEBUG_CPRINT(("\nMessage recived in PLD_SERVER \n"));
            tc_pld_info.tc_id = payload->Msg_id;
            tc_pld_info.src_id = payload->src_entity;
            tc_pld_info.dst_id = payload->pld_info;
            tc_pld_info.tc_pld_len = payload->Msg_len;
            tc_pld_info.tc_pld_buff = os_malloc(tc_pld_info.tc_pld_len);

            //Sequence number field is skipped for now and TC data is passed to TC decoder
            //TODO Use Sequence number for correlation ID in future
            os_memcpy(tc_pld_info.tc_pld_buff, ((uint8_t *)payload->pld.pld_ptr+2+1), tc_pld_info.tc_pld_len);

            //For FTP related TC TM messages, messages are sent with unique FTP ICD Message ID
            //to enable PS CTRL SW to prioritize FTP ICD messages over other ICD messages
            if((tc_pld_info.tc_id == TC_FTCI) || \
                    (tc_pld_info.tc_id == TC_FTFCI) || \
                    (tc_pld_info.tc_id == TC_FTSR) || \
                    (tc_pld_info.tc_id == TC_FTDS) || \
            	    (tc_pld_info.tc_id == TC_FTDB))
            {
                obc_ps_ftp_msg_cmd_enc (&obc_tc_listner_thread_data,&obc_tc_listner_thread_icd_data_len,&tc_pld_info);
            }
            else
            {
                obc_ps_tc_tm_msg_cmd_enc (&obc_tc_listner_thread_data,&obc_tc_listner_thread_icd_data_len,&tc_pld_info);
            }
            obc_icd_socket_send(obc_tc_listner_thread_data,obc_tc_listner_thread_icd_data_len);

            os_free(obc_tc_listner_thread_data);
            obc_tc_listner_thread_data = NULL;

/*Functional flow need to be reviewed consumer flow is not clear*/
            os_free(tc_pld_info.tc_pld_buff);
  //          tc_pld_info.tc_pld_buff = NULL;
        }

        break;
#endif

        case OTSU_OBC_SHUTDOWN_REQ:
        {
            obc_shutdown_hdlr();
            state = OBC_INIT_STATE;
        }
        break;


        case SBAND_OBC_HEALTH_CHECK_REQ:
        {
            obc_proc_sband_health_check_req();
        }
        break;

        case SBAND_OBC_GROUND_SYNC_IND:
        {
            obc_proc_sband_ground_sync_ind();
        }
        break;
        /** - Req from SDR for Beacon Health metrics */
        case SDR_APP_OBC_MH_REQ:
        {
            obc_sdr_beacon_health_metric_enc();

        }
        break;
        case OBC_TC_TM_CHNG_QUEUE_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_QUEUE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;

        case OBC_TC_TM_CHNG_SUB_MOD_PRIORITY_RSP:
        {
            /**  - Send the response back to GS */
            obc_pck_data rsp;
            rsp.tm_rsp_id = TM_CHNGE_MODULE_PRIORITY;
            rsp.rx_data = (uint8_t*)&payload->pld.pld_data;
            obc_pack_tm_data(&rsp);
        }
        break;

        case OBC_HM_TEST_CASE_RSP:
        {
			  /**  - Send the response back to GS */
			  obc_pck_data rsp;
			  rsp.tm_rsp_id = TM_HM_TEST_CASE_REQ;
			  rsp.rx_data = (uint8_t*)payload->pld.pld_ptr;
			  obc_pack_tm_data(&rsp);
		}
		break;


        default:
        state = OBC_ACTIVE_PWR_NORM_STATE;
    }

    return state;
}

uint8 obc_power_save_state_hdlr(os_itc_msg_handle_t *payload)
{
    uint8 state = OBC_POWER_SAVE_STATE;
    switch(payload->Msg_id)
    {
        case 0:
        {
        }
        break;

        default:
        state = OBC_POWER_SAVE_STATE;
    }

    return state;
}

uint8 obc_reset_state_hdlr(os_itc_msg_handle_t *payload)
{
    uint8 state = OBC_RESET_STATE;
    switch(payload->Msg_id)
    {
        case 0:
        {
        }
        break;

        default:
        state = OBC_RESET_STATE;
    }

    return state;
}

uint8 obc_error_state_hdlr(os_itc_msg_handle_t *payload)
{
    uint8 state = OBC_ERROR_STATE;
    switch(payload->Msg_id)
    {
        case 0:
        {
        }
        break;

        default:
        state = OBC_ERROR_STATE;
    }

    return state;
}

uint8_t obc_eps_battery_sts_proc(uint8_t obc_eps_bat_sts)
{
    uint8_t state = 0;

    switch(obc_eps_bat_sts)
    {
        case HW_BTRY_CRTCAL:
            {
                state = OBC_ACTIVE_PWR_CRITICAL_STATE;

                if(sub_mod_sts[OBC_SUB_MOD_SCH] != SW_INACTIVE)
                {
                    obc_send_ipc_msg(OBC_SCH_DEINIT_REQ, ORBIT_CONOPS_SCHEDULER);
                }
            }
            break;
        case HW_BTRY_SAFE:
            {
                state = OBC_ACTIVE_PWR_SAFE_STATE;

                if(sub_mod_sts[OBC_SUB_MOD_TC_TM] != SW_INACTIVE)
                {
                    obc_send_ipc_msg(OBC_TC_TM_DEINIT_REQ, TC_TM_MANAGER_IPC_RECEIVE);
                }
                if(sub_mod_sts[OBC_SUB_MOD_OTSU] != SW_INACTIVE)
                {
                    //obc_send_ipc_msg(OBC_OTSU_INIT_REQ, OBC_OTSU);
                }
            }
            break;
        case HW_BTRY_NORMAL:
            {
                state = OBC_ACTIVE_PWR_NORM_STATE;

                if(sub_mod_sts[OBC_SUB_MOD_SCH] != SW_ACTIVE)
                {
                    obc_send_ipc_msg(OBC_SCH_INIT_REQ, ORBIT_CONOPS_SCHEDULER);
                }
            }
            break;
     //   case HW_BTRY_FULL:
       //     {
         //       state = OBC_ACTIVE_PWR_NORM_STATE;
           // }
           // break;
        default:
            break;

    }

    if(obc_otsu_shutdown_ind)
    {
        state = OBC_INIT_STATE;
    }

    if(state != sm_get_state(OBC_MAIN_FSM))
    {
    	obc_send_ipc_msg(OBC_SDR_APP_BAT_CH_IND,SDR_APP);
    }
    DEBUG_CPRINT(("\n Received battery stats in OBC_FSM st:%d :%d\n",state,obc_eps_bat_sts));
    return state;
}

void obc_eps_proc_dev_sts(uint8_t dev_id, uint8_t obc_eps_dev_sts)
{
    DEBUG_CPRINT(("\n\r EPS_DEV_STS dev_id: %d, dev_sts: %d", dev_id, obc_eps_dev_sts));
    switch(dev_id)
    {
        case HW_PL_TRANSCELESTIAL:
//        case HW_PL_AICRAFT:
#ifdef JANUS1
        case HW_PL_SAYARLABS:
#endif
        case HW_PL_NETRA:
        case HW_OBC_PS_GPS_STD_PL_BRD:
            {
                if(obc_eps_dev_sts)
                {
                    obc_send_ipc_msg_pld(OBC_PLD_SERVER_INIT_REQ, OBC_IPCC_SEND,&dev_id,1);
                }
                else
                {
                    obc_send_ipc_msg_pld(OBC_PLD_SERVER_DEINIT_REQ, OBC_IPCC_SEND,&dev_id,1);
                }
            }
            break;
        case HW_PL_SERVER:
            {
                if(PWR_OFF == obc_eps_dev_sts)
                {
                    obc_encode_icd_cmd(OBC_PS_PWR_OFF_CMD,0,NULL);
                }
                if(obc_eps_dev_sts)
                {
                    obc_send_ipc_msg_pld(OBC_SEN_INIT_REQ, OBC_SENSOR_HDLR,&dev_id,1);
                }
                else
                {
                    obc_send_ipc_msg_pld(OBC_SEN_DEINIT_REQ, OBC_SENSOR_HDLR,&dev_id,1);
                }
            }
            break;
        case HW_GPS:
        case HW_EDGE_BRD:
            {
                if(obc_eps_dev_sts)
                {
                    obc_send_ipc_msg_pld(OBC_SEN_INIT_REQ, OBC_SENSOR_HDLR,&dev_id,1);
                }
                else
                {
                    obc_send_ipc_msg_pld(OBC_SEN_DEINIT_REQ, OBC_SENSOR_HDLR,&dev_id,1);
                }
            }
            break;

          case HW_UHF:
            {
                if(PWR_ON == obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_UHF_INIT_REQ, COMMS_UHF_CTLR);
                }
                else if(PWR_OFF == obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_UHF_DEINIT_REQ, COMMS_UHF_CTLR);
                }
            }
            break;

        case HW_X_BAND:
            {
                if(PWR_ON == obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_XBAND_INIT_REQ, COMMS_XBAND_CTLR);
                }
                else if(PWR_OFF == obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_XBAND_DEINIT_REQ, COMMS_XBAND_CTLR);
                }
            }
            break;
        case HW_S_BAND:
            {
                if(PWR_ON == obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_SBAND_INIT_REQ, COMMS_SBAND_CTLR);
                }
                else if(PWR_OFF == obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_SBAND_DEINIT_REQ, COMMS_SBAND_CTLR);
                    obc_send_ipc_msg(OBC_TC_TM_DEINIT_REQ, TC_TM_MANAGER_IPC_RECEIVE);
                    //obc_send_ipc_msg(OBC_OTSU_DEINIT_REQ, OBC_OTSU);
                }
            }
            break;
        case HW_ADCS:
            {
                if(obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_ADCS_INIT_REQ, ADCS_CONTROLLER);
                }
                else
                {
                    obc_send_ipc_msg(OBC_ADCS_DEINIT_REQ, ADCS_CONTROLLER);
                }
            }
            break;

        case HW_PROP_UNIT_THRUSTER:
            {
                if(obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_ADCS_THRUST_INIT_IND, ADCS_CONTROLLER);
                }
                else
                {
                    obc_send_ipc_msg(OBC_ADCS_THRUST_DEINIT_IND, ADCS_CONTROLLER);
                }
            }
            break;

#ifdef JANUS1
        case HW_PL_ZES:
            {
                if(obc_eps_dev_sts)
                {
                    obc_send_ipc_msg(OBC_ZES_INIT_REQ, ORBIT_CONOPS_SCHEDULER);
                }
                else
                {
                    obc_send_ipc_msg(OBC_ZES_DEINIT_REQ, ORBIT_CONOPS_SCHEDULER);
                }
            }
            break;
#endif
    }
}

void obc_shutdown_hdlr(void)
{
    uint8 mod_id =0;

    obc_otsu_shutdown_ind =1;

    for(mod_id=0;mod_id<OBC_SUB_MOD_MAX;mod_id++)
    {
        nvm_parameter_write(NVM_DATA,NVM_SW_PL_TRANSCELESTIAL+mod_id,(uint8_t*)&sub_mod_sts[mod_id]);
        if(SW_ACTIVE == sub_mod_sts[mod_id])
        {
            obc_eps_proc_dev_sts(mod_id, SW_INACTIVE);
        }
    }
    //obc_send_ipc_msg(OBC_OTSU_SHUTDOWN_RSP, OBC_OTSU);
}

void obc_otsu_deinit_rsp_hdlr(void)
{
    uint8 mod_id =0;
    uint8 mod_sts = 0;

    for(mod_id=0;mod_id<OBC_SUB_MOD_MAX;mod_id++)
    {
        DEBUG_CPRINT(("\nOTSU Deinit SUB_MOD_STS: %d\n",sub_mod_sts[mod_id]));
        if(SW_INACTIVE == sub_mod_sts[mod_id])
        {
            mod_sts = 0;
        }
        else
        {
            mod_sts = 1;
            break;
        }
    }

    if(!mod_sts)
    {
        obc_otsu_shutdown_ind =0;
        DEBUG_CPRINT(("\nOTSU SHUT DOWN response done\n\n "));
#ifndef LINUX_TEMP_PORT
        send_obc_shutdown_sts();
#endif
        //obc_send_ipc_msg(OBC_OTSU_SHUTDOWN_RSP, OBC_OTSU);
    }
}

void obc_sdr_beacon_health_metric_enc(void)
{
    /** Variable to store OBC beacon health metrtic */
    s_obc_beacon_info obc_beacon_hm = {0};

    /** Store the the OBC's current state */
    obc_beacon_hm.fsm_state = sm_get_state(OBC_MAIN_FSM);

    /** Store OBC's number of resets */
    obc_beacon_hm.num_resets = rst_count;

    /** Store IO error's */
    obc_beacon_hm.io_err = 0;

    /** Store System error's */
    obc_beacon_hm.sys_err = system_error;

    /** Send response to SDR APP */
    obc_send_ipc_msg_pld(OBC_SDR_APP_MH_RSP,SDR_APP,(uint8_t*)&obc_beacon_hm, sizeof(obc_beacon_hm));
    DEBUG_CPRINT(("######### IPC SEND REQUEST #######"));
}
void obc_proc_sband_ground_sync_ind(void)
{
    obc_send_ipc_msg(OBC_SCH_STOP_SYNC_TIME_REQ, ORBIT_CONOPS_SCHEDULER);
    obc_send_ipc_msg(OBC_ADCS_HEALTH_CHECK_REQ, ADCS_CONTROLLER);
    obc_send_ipc_msg(OBC_SBAND_HEALTH_CHECK_REQ, COMMS_SBAND_CTLR);
#ifndef LINUX_TEMP_PORT
    obc_send_ipc_msg(OBC_EPS_HEALTH_CHECK_REQ, EPS_TASK);
    obc_send_ipc_msg(OBC_SEN_HEALTH_CHECK_REQ, OBC_SENSOR_HDLR);
#endif
    tm_rsp_id = TM_GET_OBC_SW_STS;
    sequence_number = 0;
    radio_module_id = COMMS_S_BAND;
    obc_pack_tm_data(NULL);
}

void obc_proc_sband_health_check_req(void)
{
    obc_send_ipc_msg(OBC_ADCS_HEALTH_CHECK_REQ, ADCS_CONTROLLER);
    obc_send_ipc_msg(OBC_SBAND_HEALTH_CHECK_REQ, COMMS_SBAND_CTLR);
#ifndef LINUX_TEMP_PORT
    obc_send_ipc_msg(OBC_EPS_HEALTH_CHECK_REQ, EPS_TASK);
    obc_send_ipc_msg(OBC_SEN_HEALTH_CHECK_REQ, OBC_SENSOR_HDLR);
#endif

    tm_rsp_id = TM_GET_OBC_SW_STS;
    sequence_number = 0;
    radio_module_id = COMMS_S_BAND;
    obc_pack_tm_data(NULL);
}
