/**
 * @file obc_app.c
 *
 * @brief This file contains functions that provides demonstration of
 *        usage of TC TM Library APIs
 *
 * The functions provided in the file provides demonstration on
 * usage of TC TM library APIs
 */
/*********************************************************************/
#include <stdio.h>
#include "tc_common.h"
#include "tm_common.h"
#include "tc_tm_lib_common.h"
#include "exo_osal.h"
#include "exo_common.h"
#include "exo_ral_cmn.h"
#include "obc_tc_tm.h"
#include "obc_icd.h"
#include "obc_main.h"
#include "obc_ipc.h"
#include "obc_main_fsm_hdlr.h"
#include "obc_bringup_test.h"

#include "ipcc_common.h"
#include "ipcc_lib_common.h"
#include "obc_intf_ctrl_msg.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "exo_osal_mem_debug.h"
#include "exo_osal_mem_management.h"
//#include <pthread.h>
#include <sys/select.h>
#include "schedular.h"
#include "sm_api.h"
#include "logger.h"
#include "gps_app.h"
#include "eps_ctrlr.h"
#include "err_handler.h"
#include "obc_mcu_info.h"
#include "tc_tm_mngr_buffer.h"
#include "exo_io_al_sos_timer.h"
#include "../drivers/bsp/GEN2/inc/exo_gpio.h"
#ifndef LINUX_TEMP_PORT
#include "nvm.h"
#endif
#include "exo_tctm_ipc.h"
#include "system_init_exit.h"

//#TBD: The following include can be removed once the OS abstracted delay
//      is implemented

#ifdef LINUX_TEMP_PORT
#include <unistd.h>
#else
#include "stm32f7xx_hal.h"
#endif

#include "otsu.h"
#include "file_transfer.h"
#include "exo_osal_mem_debug.h"


#define OBC_HEALTH_DATA_TIMER_IN_SEC  (1000*60*2)

extern volatile uint8_t system_error;
extern uint16_t rst_count;
#ifndef LINUX_TEMP_PORT
extern reset_cause_t reset_cause;
extern uint32_t start_time;
#endif

exo_sw_dbg_cb exo_sw_dbg = {0};

/**
 * @brief Global variables for timer to send OBC health data
 */

static os_timer_handle_ptr  obc_health_data_timer;
/**
 * @brief Global variables for thread and IPC operations
 */

os_itc_msg_handle_t obc_rcv_ipc_msg;
os_thread_handle_ptr otsu_thread; // Check other thread instance.
os_itc_msg_handle_t obc_tc_ipc_msg;
os_itc_msg_handle_t obc_tm_ipc_msg;

char PLACE_IN_EXT_RAM_MEM tty_dcdu[1000] ;
extern uint32 tm_rsp_id;
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_otsu_gs_contact;
extern uint8_t PLACE_IN_EXT_RAM_MEM comms_first_gs_contact ;
obc_pck_data tm_rsp;
s_obc_sock_info icd_soc_inf;
uint8_t obc_test_sns_rsp=0;
uint8_t obc_test_gpio_exp_rsp=0;
uint8_t obc_test_spi_uart_conv_rsp=0;
uint8_t obc_nvm_commit_rsp=0;
uint8_t obc_nvm_commit_prdcty_tim_rsp=0;
uint8_t obc_test_gpio_rsp=0;
uint16 obc_evnt_trig = 0;
uint16 lut_cfg_rsp = 0;
uint8_t sch_ctrl_rsp = 0;
uint32 seg_exec_info_rsp = 0;
uint32 seg_rcv_info_rsp = 0;

obc_pck_data eps_data;

s_tc_frame *obc_tc_listner_thread_tc_frame = NULL;

s_ipcc_terminator obc_sample_app_main_ipcc_term PLACE_IN_EXT_RAM_MEM;

/**
 * @brief This API listens for a TC through the IPC interface and
 *        invokes TC handler api if a valid TC is received
 *
 * @param[in] params   : pointer to optional parameters.
 *
 * @return None
 * @retval None
 */
static void obc_main_thread (void * params);

ft_tctm_payload_tx ft_pld_tx;
strFTM_queue_tctm_info s_ftm_queue_tm_frame;
strFTM_queue_tctm_info s_ftm_queue_tc_frame;
static void obc_ft_tctm_sender_thread(void *params);
//static void obc_eps_send_tc(uint8_t *msg_tc, uint8_t msg_tc_len);


#ifdef LINUX_TEMP_PORT
static uint8_t otsu_sdram_write_clbk_linux(ptr_typ mem_address, uint8_t *payload_ptr, uint16_t payload_len);
#endif
#if 0
static void obc_eps_send_tc(uint8_t *msg_tc, uint8_t msg_tc_len)
{
	os_itc_msg_handle_t msg_hdl;
	msg_hdl.src_entity      = OBC_MAIN;
	msg_hdl.Msg_id        = EPS_FW_UPT_TC;
	msg_hdl.Msg_len         = msg_tc_len;
	msg_hdl.pld.pld_ptr = msg_tc;
	os_itc_msg_send(&msg_hdl, EPS_TASK, os_send_itc_wait);
}
#endif
#ifndef LINUX_TEMP_PORT
static void obc_otsu_send_tc(uint16_t tc_id, uint8_t *msg_tc, uint8_t msg_tc_len);
static void obc_otsu_send_shutdwn_rqst(void);

static void obc_otsu_send_tc(uint16_t tc_id, uint8_t *msg_tc, uint8_t msg_tc_len)
{
	os_itc_msg_handle_t msg_hdl;
	msg_hdl.src_entity 	= OBC_MAIN;
	msg_hdl.Msg_id 		= OTSU_TCTM_SERVICE;
	msg_hdl.Msg_len 	= msg_tc_len;
	msg_hdl.pld.pld_ptr = msg_tc;
	msg_hdl.pld_info 	= tc_id;
	os_itc_msg_send(&msg_hdl,OBC_OTSU, os_send_itc_wait);
}

static void obc_otsu_send_shutdwn_rqst(void)
{
	os_itc_msg_handle_t msg_hdl;
	msg_hdl.src_entity 	= OBC_MAIN;
	msg_hdl.Msg_id 	= OTSU_GS_SOFT_RESET_RQST;
	msg_hdl.Msg_len 	= 0;
	msg_hdl.pld.pld_ptr = NULL;
	os_itc_msg_send(&msg_hdl,OBC_OTSU, os_send_itc_wait);
}
#endif


void ft_send_tc_to_ftm(uint16 tc_id, uint8 *tc_data, uint16 tc_data_len, uint16_t app_id)
{
	uint16_t u8cnt;

	if(tc_data != NULL)
	{
		s_ftm_queue_tc_frame.Q_payload_ptr = ft_get_queue_rx_buffer_address();
		for(u8cnt = 0; u8cnt < tc_data_len ; u8cnt++)
		{
			s_ftm_queue_tc_frame.Q_payload_ptr[u8cnt] = tc_data[u8cnt];
		}
		s_ftm_queue_tc_frame.Q_payload_len = tc_data_len;
		s_ftm_queue_tc_frame.tc_tm_id = tc_id;
		s_ftm_queue_tc_frame.src_dst_id = app_id;
		os_queue_send(ft_queue_hdle_rcv, &s_ftm_queue_tc_frame, os_send_itc_wait);
	}
	else
	{
		DEBUG_CPRINT(("OBC receive Null error\n"));
		log_id(LOG_ERROR,LOG_OBC,OBC_RECEIVE_NULL_ERROR);
	}
}




#ifdef LINUX_TEMP_PORT

static uint8_t otsu_sdram_write_clbk_linux(ptr_typ mem_address, uint8_t *payload_ptr, uint16_t payload_len)
{
	uint8_t ret_busy_sts = 0;
	uint16_t u16cnt;

	if(payload_ptr != NULL)
	{
		for (u16cnt = 0; u16cnt < payload_len; u16cnt = u16cnt+1)
		{
			*( uint8_t*) (mem_address + u16cnt) = payload_ptr[u16cnt];
		}
		ret_busy_sts = 1;
	}
	return ret_busy_sts;
}
#endif


uint8 obc_tc_gps_loc_data1_dec(const uint8 *data)
{
	uint8 status = 1;
	obc_pck_data tm_info;
	gps_location_data1 gps_data;
	os_memset(&gps_data,0,sizeof(gps_location_data1));
#ifndef LINUX_TEMP_PORT
	status = oem7_get_gpgga(&gps_data);
#else
	status =0;
#endif
	if(status == 0)
	{
		tm_info.rx_data_len=sizeof(gps_location_data1);
		tm_info.rx_data = (uint8_t*)&gps_data;
	}
	else
	{
		tm_info.rx_data_len=1;
		tm_info.rx_data = (uint8_t*)&status;
	}
	tm_info.tm_rsp_id = TM_GPS_GET_NMEA_GPGGA;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}

uint8 obc_tc_gps_loc_data2_dec(const uint8 *data)
{
	uint8 status =1;
	obc_pck_data tm_info;
	gps_location_data2 gps_data;
	os_memset(&gps_data,0,sizeof(gps_location_data2));
#ifndef LINUX_TEMP_PORT
	status = oem7_get_gprmc(&gps_data);
#else
	status =0;
#endif
	if(status == 0)
	{
		tm_info.rx_data = (uint8_t*)&gps_data;
		tm_info.rx_data_len=sizeof(gps_location_data2);
	}
	else
	{
		tm_info.rx_data_len=1;
		tm_info.rx_data = (uint8_t*)&status;
	}
	tm_info.tm_rsp_id = TM_GPS_GET_NMEA_GPRMC;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}


uint8 obc_tc_gps_date_time_dec(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info;
	gps_time_data gps_data;
	os_memset(&gps_data,0,sizeof(gps_time_data));
#ifndef LINUX_TEMP_PORT
	status = oem7_get_gpzda(&gps_data);
#else
	status =0;
#endif
	if(status == 0)
	{
		tm_info.rx_data = (uint8_t*)&gps_data;
		tm_info.rx_data_len=sizeof(gps_time_data);
	}
	else
	{
		tm_info.rx_data_len = 1;
		tm_info.rx_data = (uint8_t*)&status;
	}
	tm_info.tm_rsp_id = TM_GPS_GET_DATE_TIME;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}


uint8 obc_tc_gps_pos_velcty_dec(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info;
	s_oem7_best_xyz gps_data;
	os_memset(&gps_data,0,sizeof(s_oem7_best_xyz));
#ifndef LINUX_TEMP_PORT
	status = oem7_get_bestxyz(&gps_data);
#else
	status =0;
#endif
	if(status == 0)
	{
		tm_info.rx_data = (uint8_t*)&gps_data;
		tm_info.rx_data_len=sizeof(s_oem7_best_xyz);
	}
	else
	{
		tm_info.rx_data_len = 1;
		tm_info.rx_data = (uint8_t*)&status;
	}
	tm_info.tm_rsp_id = TM_GPS_GET_3D_POSITION_VELOCITY;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}


uint8 obc_tc_gps_get_location_info_dec(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info;
	gps_loc_info gps_data;
	os_memset(&gps_data,0,sizeof(gps_loc_info));
#ifndef LINUX_TEMP_PORT
	status = gps_get_location_info(&gps_data);
#else
	status =0;
#endif
	if(status == 0)
	{
		tm_info.rx_data = (uint8_t*)&gps_data;
		tm_info.rx_data_len=sizeof(gps_loc_info);
	}
	else
	{
		tm_info.rx_data_len = 1;
		tm_info.rx_data = (uint8_t*)&status;
	}
	tm_info.tm_rsp_id = TM_GPS_GET_LOCATION_INFO;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}

/**
 * @brief This function set the timer periodicity of
 * GPS Sync time
 */
uint8 obc_tc_gps_set_time_sync_prdcty_dec(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info = {0};
	gps_set_sync_time_prdcty((uint32_t)(*data));

	status = 0;
	tm_info.rx_data_len = 1;
	tm_info.rx_data = (uint8_t*)&status;
	tm_info.tm_rsp_id = TM_GPS_SET_TIME_SYNC_PRDCTY;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}

/**
 * @brief This function get the timer periodicity of
 * GPS Sync time
 */
uint8 obc_tc_gps_get_time_sync_prdcty(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info = {0};
	uint32_t timer_prdcty = 0;
	//Read the GPS Sync timer periodicity in NVM
	timer_prdcty = gps_get_sync_time_prdcty();

	status = 0;
	tm_info.rx_data_len = sizeof(status) + sizeof(timer_prdcty);
	tm_info.rx_data = os_malloc_eram(tm_info.rx_data_len);
	tm_info.rx_data[0] = status;
	os_memcpy(&tm_info.rx_data[1], &timer_prdcty, sizeof(timer_prdcty));
	tm_info.tm_rsp_id = TM_GPS_GET_TIME_SYNC_PRDCTY;
	obc_pack_tm_data(&tm_info);

	os_free(tm_info.rx_data);
	status = TCTM_OK;
	return status;
}

/**
 * @brief This function handle the sync GPS time
 */
uint8 obc_tc_gps_sync_time(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info = {0};
	uint8_t sync_timer_flag = 1;
	uint8_t* recv_epoch = NULL;
	recv_epoch = os_malloc_eram(8);
	//sync gps time
	status = gps_sync_time(recv_epoch, sync_timer_flag);
	tm_info.rx_data_len = 8 + sizeof(status);
	tm_info.rx_data = os_malloc_eram(tm_info.rx_data_len);
	tm_info.rx_data[0] = status;
	os_memcpy(&tm_info.rx_data[1], recv_epoch, 8);
	tm_info.tm_rsp_id = TM_SYNC_GPS_TIME;
	obc_pack_tm_data(&tm_info);

	os_free(tm_info.rx_data);
	status = TCTM_OK;
	os_free(recv_epoch);
	return status;
}

/**
 * @brief This function get the GPS time information
 */
uint8 obc_tc_get_gps_time(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info;
	s_oem7_time* gps_time = NULL;
	gps_time = os_malloc_eram(sizeof(s_oem7_time));
	//Get GPS Time
	status = oem7_get_time_info(gps_time);

	tm_info.rx_data_len = sizeof(s_oem7_time) + sizeof(status);
	tm_info.rx_data = os_malloc(tm_info.rx_data_len);
	tm_info.rx_data[0] = status;
	os_memcpy(tm_info.rx_data+1, gps_time, sizeof(s_oem7_time));
	tm_info.tm_rsp_id = TM_GPS_GET_GPS_TIME_INFO;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	os_free(tm_info.rx_data);
	os_free(gps_time);
	return status;
}


uint8 obc_tc_gps_compute_tle_dec(const uint8 *data)
{
	uint8 status=1;
	obc_pck_data tm_info;
	orbit_tle_t gps_data;
	os_memset(&gps_data,0,sizeof(orbit_tle_t));
#ifndef LINUX_TEMP_PORT
	status = gps_compute_orbital_elements(&gps_data);
#else
	status =0;
#endif
	if(status == 0)
	{
		tm_info.rx_data = (uint8_t*)&gps_data;
		tm_info.rx_data_len=sizeof(orbit_tle_t);
	}
	else
	{
		tm_info.rx_data_len = 1;
		tm_info.rx_data = (uint8_t*)&status;
	}
	tm_info.tm_rsp_id = TM_GPS_COMPUTE_TLE;
	obc_pack_tm_data(&tm_info);

	status = TCTM_OK;
	return status;
}



int32_t obc_tc_hdlr(uint16 tc_id, uint16 tc_data_len, uint8 *tc_data)
{
	/*Control variable - Increments on every TC received*/
	exo_sw_dbg.obc_dbg.no_tc_rcvd++;
	set_seq_no_radio_id(tc_data);
	tc_data = tc_data+TC_PLD_IDX;
	// os_itc_msg_handle_t eps_msg_hdl={0};
	switch(tc_id)
	{
	//GPS based telecommands
	case TC_GPS_GET_NMEA_GPGGA:
		obc_tc_gps_loc_data1_dec(tc_data); //gpgga
		break;
	case TC_GPS_GET_NMEA_GPRMC:
		obc_tc_gps_loc_data2_dec(tc_data);   //gprmc
		break;
	case TC_GPS_GET_DATE_TIME:
		obc_tc_gps_date_time_dec(tc_data);   //gpzda
		break;
	case TC_GPS_GET_3D_POSITION_VELOCITY:
		obc_tc_gps_pos_velcty_dec(tc_data);
		break;
	case TC_GPS_COMPUTE_TLE:
		obc_tc_gps_compute_tle_dec(tc_data);
		break;
	case TC_GPS_GET_LOCATION_INFO:
		obc_tc_gps_get_location_info_dec(tc_data);
		break;
	case TC_GPS_SET_TIME_SYNC_PRDCTY:
		obc_tc_gps_set_time_sync_prdcty_dec(tc_data);
		break;
	case TC_GPS_GET_TIME_SYNC_PRDCTY:
		obc_tc_gps_get_time_sync_prdcty(tc_data);
		break;
	case TC_SYNC_GPS_TIME:
		obc_tc_gps_sync_time(tc_data);
		break;
	case TC_GPS_GET_GPS_TIME_INFO:
		obc_tc_get_gps_time(tc_data);
		break;

	case TC_THRUSTER_SET_MODE:
	case TC_THRUSTER_GET_MODE:
	case TC_THRUSTER_SET_FIRING_DURATION:
	case TC_THRUSTER_GET_FIRING_DURATION:
	case TC_THRUSTER_GET_INPUT_POWER_CONSMP:
	case TC_THRUSTER_SET_RADIATOR_TEMP_LIMIT:
	case TC_THRUSTER_GET_RADIATOR_TEMP_LIMIT:
	case TC_THRUSTER_SET_TANK_PRESSURE_LIMIT:
	case TC_THRUSTER_GET_TANK_PRESSURE_LIMIT:
	case TC_THRUSTER_GET_REMAINING_PROPELLANT:
		//case TC_THRUSTER_GET_ACTIVE_STATUS:
		case TC_THRUSTER_GET_ONBOARD_TEMPERATURE:
			thruster_tc_hdlr(tc_id,tc_data,tc_data_len);
			break;



#if 0
		case TC_PWR_CTRL_SBAND:
		{
			obc_tc_sband_pwr_ctrl_dec(tc_data);
		}
		break;

		case TC_PWR_CTRL_XBAND:
		{
			obc_tc_xband_pwr_ctrl_dec(tc_data);
		}
		break;

		case TC_PWR_CTRL_ADCS:
		{
			obc_tc_adcs_pwr_ctrl_dec(tc_data);
		}
		break;
		case TC_PWR_CTRL_THRUSTER:
		{
			obc_tc_thrust_pwr_ctrl_dec(tc_data);
		}
		break;

		case TC_PWR_CTRL_EDGE_BOARD:
		{
			obc_tc_edge_board_pwr_ctrl_dec(tc_data);
		}
		break;

		case TC_PS_PWR_ON:
		{
			obc_tc_ps_pwr_on_dec(tc_data);
		}
		break;

		case TC_PLD_HW_PWR_ON:
		{
			obc_tc_pld_hw_pwr_on_dec(tc_data);
		}
		break;
#endif
		case TC_PLD_VM_PWR_ON:
		{
			obc_tc_pld_vm_pwr_on_dec(tc_data);
		}
		break;
#if 0
		case TC_PLD_HW_PWR_OFF:
		{
			obc_tc_pld_hw_pwr_off_dec(tc_data);
		}
		break;
#endif
		case TC_PLD_VM_PWR_OFF:
		{
			obc_tc_pld_vm_pwr_off_dec(tc_data);
		}
		break;
#if 0
		case TC_PS_PWR_OFF:
		{
			obc_tc_ps_pwr_off_dec(tc_data);
		}
		break;
#endif
		case TC_TTY_START:
		{
			obc_tc_tty_start_dec(tc_data);
		}
		break;

		case TC_TTY_END:
		{
			obc_tc_tty_end_dec(tc_data);
		}
		break;

		case TC_TTY_DEBUG:
		{
			obc_tc_tty_data_dec(tc_data,(uint8*)tty_dcdu,tc_data_len);
			//DEBUG_CPRINT(("TTY debug command recieved: %s\n",tty_dcdu));
		}
		break;

		case TC_GET_SYS_UPTIME:
		{
			tm_rsp_id = TM_GET_SYS_UPTIME;
			obc_pack_tm_data(NULL);
		}
		break;

		case TC_GET_PROC_UTIL_INFO:
		{
			tm_rsp_id = TM_GET_PROC_UTIL_INFO;

#ifndef LINUX_TEMP_PORT
obc_get_cpu_stats(tc_data);
#else
obc_pack_tm_data(NULL);
#endif
		}
		break;

		case TC_GET_MEM_UTIL_INFO:
		{
			tm_rsp_id = TM_GET_MEM_UTIL_INFO;
			obc_pack_tm_data(NULL);
		}
		break;

		case TC_GET_FTM_SAVECONTEXT_STS:
		{
			obc_pck_data tm_data_info;
			tm_data_info.tx_data = tc_data;
			tm_data_info.tm_rsp_id = TM_GET_FTM_SAVECONTEXT_STS;
			obc_pack_tm_data(&tm_data_info);
		}
		break;

		case TC_OBC_MEM_DOWLOAD:
		{
			obc_pck_data tm_data_info;
			tm_data_info.tx_data = tc_data;
			tm_data_info.tm_rsp_id = TM_OBC_MEM_DOWLOAD;
			obc_pack_tm_data(&tm_data_info);
		}
		break;
		case TC_GET_OBC_NVM_REVISION_NUM:
		{
			tm_rsp_id = TM_GET_OBC_NVM_REVISION_NUM;
			obc_pack_tm_data(NULL);
		}
		break;

		case TC_SET_SPI_INTF_PARM:
		{
			obc_tc_spi_intf_set_dec(tc_data);
		}
		break;
		case TC_SET_ETH_INTF_PARM:
		{
			obc_tc_ethernet_intf_set_dec(tc_data);
		}
		break;
		case TC_SET_CAN_INTF_PARM:
		{
			obc_tc_can_intf_set_dec(tc_data);
		}
		break;
		case TC_SET_I2C_INTF_PARM:
		{
			obc_tc_i2c_intf_set_dec(tc_data);
		}
		break;
		case TC_SET_USB_INTF_PARM:
		{
			obc_tc_usb_intf_set_dec(tc_data);
		}
		break;
		case TC_SET_UART_INTF_PARM:
		{
			obc_tc_uart_intf_set_dec(tc_data);
		}
		break;

		case TC_GET_SPI_INTF_PARM:
		{
			obc_tc_spi_intf_param_dec(tc_data);
		}
		break;
		case TC_GET_ETH_INTF_PARM:
		{
			obc_tc_ethernet_intf_param_dec(tc_data);
		}
		break;
		case TC_GET_CAN_INTF_PARM:
		{
			obc_tc_can_intf_param_dec(tc_data);
		}
		break;
		case TC_GET_I2C_INTF_PARM:
		{
			obc_tc_i2c_intf_param_dec(tc_data);
		}
		break;
		case TC_GET_USB_INTF_PARM:
		{
			obc_tc_usb_intf_param_dec(tc_data);
		}
		break;
		case TC_GET_UART_INTF_PARM:
		{
			obc_tc_uart_intf_param_dec(tc_data);
		}
		break;
#if 0
		case TC_SET_CONV_BOARD_PARM:
		{
			// obc_pck_data_s data;
			//   eps_data.tm_rsp_id = TM_SET_CONV_BOARD_PARM;
			// eps_data.tx_data = tc_data;
			//eps_data.tx_data_len = tc_data_len;

			eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
			os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
			eps_msg_hdl.Msg_len=tc_data_len;
			eps_msg_hdl.pld_info=TM_SET_CONV_BOARD_PARM;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
			//eps_tctm_code((obc_pck_data_eps*)&eps_data);
			//if(eps_data.rx_data != NULL)
				//obc_pack_tm_data(&eps_data);

		}
		break;
		case TC_SET_BATT_BOARD_PARM:
		{
#if 0
eps_data.tm_rsp_id = TM_SET_BATT_BOARD_PARM;
eps_data.tx_data = tc_data;
eps_data.tx_data_len = tc_data_len;

eps_tctm_code((obc_pck_data_eps*)&eps_data);
if(eps_data.rx_data != NULL)
	obc_pack_tm_data(&eps_data);
eps_get_btry_brd_rd_val();
#endif

eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
eps_msg_hdl.Msg_len=tc_data_len;
eps_msg_hdl.pld_info=TM_SET_BATT_BOARD_PARM;
eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
eps_msg_hdl.src_entity=OBC_MAIN;

os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;
		case TC_SET_OUT_CHNL_ENB:
		{
#if 0
			eps_data.tm_rsp_id = TM_SET_OUT_CHNL_ENB;
			eps_data.tx_data = tc_data;
			eps_data.tx_data_len = tc_data_len;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			if(eps_data.rx_data != NULL)
				obc_pack_tm_data(&eps_data);
#endif

eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
eps_msg_hdl.Msg_len=tc_data_len;
eps_msg_hdl.pld_info=TM_SET_OUT_CHNL_ENB;
eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
eps_msg_hdl.src_entity=OBC_MAIN;

os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;
		case TC_SET_OUT_CHNL_CUR_LMT:
		{
#if 0
			eps_data.tm_rsp_id = TM_SET_OUT_CHNL_CUR_LMT;
			eps_data.tx_data = tc_data;
			eps_data.tx_data_len = tc_data_len;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			if(eps_data.rx_data != NULL)
				obc_pack_tm_data(&eps_data);
#endif

eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
eps_msg_hdl.Msg_len=tc_data_len;
eps_msg_hdl.pld_info=TM_SET_OUT_CHNL_CUR_LMT;
eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
eps_msg_hdl.src_entity=OBC_MAIN;

os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;
		case TC_SET_EPS_MODE_CFG:
		{
#if 0
			eps_data.tm_rsp_id = TM_SET_EPS_MODE_CFG;
			eps_data.tx_data = tc_data;
			eps_data.tx_data_len = tc_data_len;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			if(eps_data.rx_data != NULL)
				obc_pack_tm_data(&eps_data);
#endif

eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
eps_msg_hdl.Msg_len=tc_data_len;
eps_msg_hdl.pld_info=TM_SET_EPS_MODE_CFG;
eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
eps_msg_hdl.src_entity=OBC_MAIN;

os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;

		case TC_GET_CONV_BOARD_PARM:
		{
#if 0
			// obc_pck_data_s data;
			eps_data.tm_rsp_id = TM_GET_CONV_BOARD_PARM;
			eps_data.tx_data = tc_data;
			eps_data.tx_data_len = tc_data_len;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			//tm_rsp_id = TM_GET_CONV_BOARD_PARM;
			DEBUG_CPRINT(("in main ch:%hhu\n",*tc_data));
			log_id_with_one_arg (LOG_INFO_L1,LOG_OBC,IN_MAIN_CH__u8_,*tc_data);
			obc_pack_tm_data(&eps_data);
#endif

			eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
			os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
			eps_msg_hdl.Msg_len=tc_data_len;
			eps_msg_hdl.pld_info=TM_GET_CONV_BOARD_PARM;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;

		case TC_GET_BATT_BOARD_PARM:
		{
#if 0
			//obc_pck_data_s data;
			eps_data.tm_rsp_id = TM_GET_BATT_BOARD_PARM;
			eps_data.tx_data = tc_data;
			eps_data.tx_data_len = tc_data_len;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			obc_pack_tm_data(&eps_data);
#endif

eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
eps_msg_hdl.Msg_len=tc_data_len;
eps_msg_hdl.pld_info=TM_GET_BATT_BOARD_PARM;
eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
eps_msg_hdl.src_entity=OBC_MAIN;

os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;

		case TC_GET_OUT_CHNL_PARM:
		{

#if 0
			eps_data.tm_rsp_id = TM_GET_OUT_CHNL_PARM;
			eps_data.tx_data = tc_data;
			eps_data.tx_data_len = tc_data_len;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			obc_pack_tm_data(&eps_data);
#endif
eps_msg_hdl.pld.pld_ptr=os_malloc_eram(tc_data_len);
os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
eps_msg_hdl.Msg_len=tc_data_len;
eps_msg_hdl.pld_info=TM_GET_OUT_CHNL_PARM;
eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
eps_msg_hdl.src_entity=OBC_MAIN;

os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;

		case TC_GET_EPS_MODE_CFG:
		{
#if 0
			eps_data.tm_rsp_id = TM_GET_EPS_MODE_CFG;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			obc_pack_tm_data(&eps_data);
#endif

			eps_msg_hdl.pld_info=TM_GET_EPS_MODE_CFG;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;

		case TC_GET_EPS_ALERT_INFO:
		{

#if 0
			eps_data.tm_rsp_id = TM_GET_EPS_ALERT_INFO;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			obc_pack_tm_data(&eps_data);
#endif
			eps_msg_hdl.pld_info=TM_GET_EPS_ALERT_INFO;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}break;
#if 0
		case TC_GET_EPS_VAR_VAL:
		{
			obc_tc_eps_get_var_val(tc_data);
		}break;
#endif
		case TC_GET_EPS_FW:
		{
#if 0
			eps_data.tm_rsp_id = TM_GET_EPS_FW;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			obc_pack_tm_data(&eps_data);
#endif
			eps_msg_hdl.pld_info=TM_GET_EPS_FW;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
		}
		break;
#endif
		case TC_SET_MIN_REBOOT_TIME:
		{
			obc_tc_set_min_reboot_dec(tc_data);
		}
		break;

		case TC_SET_TEMP_SNS_CFG:
		{
			obc_tc_temp_sns_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
//DEBUG_CPRINT(("instance_id = %d\n",temp_sns_para.instance_id));
			//DEBUG_CPRINT(("high_temp_thrsld = %d\n",temp_sns_para.high_temp_thrsld));
			//DEBUG_CPRINT(("low_temp_thrsld = %d\n",temp_sns_para.low_temp_thrsld));
			//DEBUG_CPRINT(("critical_temp_thrsld = %d\n",temp_sns_para.critical_temp_thrsld));
			//DEBUG_CPRINT(("adc_resolution = %d\n",temp_sns_para.adc_resolution));
#endif
		}
		break;
		case TC_SET_THRUST_CTRL_CFG:
		{
			obc_tc_thrstr_ctlr_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id = %d \n",thrstr_para.instance_id));
			//DEBUG_CPRINT(("unit_num = %d \n",thrstr_para.unit_num));
			//DEBUG_CPRINT(("mode = %d \n",thrstr_para.mode));
			//DEBUG_CPRINT(("force = %f \n",thrstr_para.force));
#endif
		}
		break;
		case TC_SET_DIG_THERM_CFG:
		{
			obc_tc_dig_therm_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id=%d \n",dgtl_thrmst_para.instance_id));
			//DEBUG_CPRINT(("high_temp_thrsld=%d\n",dgtl_thrmst_para.high_temp_thrsld));
			//DEBUG_CPRINT(("low_temp_thrsld=%d\n",dgtl_thrmst_para.low_temp_thrsld));
			//DEBUG_CPRINT(("po_pin_logic=%d\n",dgtl_thrmst_para.po_pin_logic));
			//DEBUG_CPRINT(("adc_resolution=%d\n",dgtl_thrmst_para.adc_resolution));
#endif
		}
		break;
		case TC_SET_IMU_CFG:
		{
			obc_tc_imu_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT

			//DEBUG_CPRINT(("instance_id = %d \n",imu_para.instance_id));
			//DEBUG_CPRINT(("power = %d \n",imu_para.power));
			//DEBUG_CPRINT(("odr = %d \n",imu_para.odr));
			//DEBUG_CPRINT(("bw = %d \n",imu_para.bw));
			//DEBUG_CPRINT(("range = %d \n",imu_para.range));
#endif
		}
		break;
		case TC_SET_GPIO_EXP_CFG:
		{
			obc_tc_gpio_exp_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id = %d \n",gpio_exp_para.instance_id));
			//DEBUG_CPRINT(("intr_pin_polarity = %d \n",gpio_exp_para.intr_pin_polarity));
#endif
		}
		break;
		case TC_SET_PWR_SEQ_MON_CFG:
		{
			obc_tc_pwr_seq_mntr_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id = %d \n",vltg_seq_mntr_para.instance_id));
			//DEBUG_CPRINT(("flash_lock_sts = %d \n",vltg_seq_mntr_para.flash_lock_sts));
			//DEBUG_CPRINT(("v_ref_type = %d \n",vltg_seq_mntr_para.v_ref_type));
#endif
		}
		break;
		case TC_SET_DATA_LOG_CFG:
		{
			obc_tc_data_log_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id = %d \n",data_acq_para.instance_id));
			//DEBUG_CPRINT(("chnl_num = %d \n",data_acq_para.chnl_num));
			//DEBUG_CPRINT(("pwr_dwn_optn = %d \n",data_acq_para.pwr_dwn_optn));
#endif
		}
		break;
		case TC_SET_PWR_MON_CFG:
		{
			obc_tc_pwr_mon_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id = %d \n",pwr_sns_mtr_para.instance_id));
			//DEBUG_CPRINT(("vbus_thrsld = %d \n",pwr_sns_mtr_para.vbus_thrsld));
			//DEBUG_CPRINT(("vshunt_thrsld = %d \n",pwr_sns_mtr_para.vshunt_thrsld));
			//DEBUG_CPRINT(("calibration = %d \n",pwr_sns_mtr_para.calibration));
#endif
		}
		break;
		case TC_SET_VOLT_CTRL_MON_CFG:
		{
			obc_tc_vltg_ctlr_ctlr_param_dec(tc_data);
#ifdef SNS_GET_INF_PRINT
			//DEBUG_CPRINT(("instance_id = %d \n",htswp_cntlr_para.instance_id));
			//DEBUG_CPRINT(("hotswap_sts = %d \n",htswp_cntlr_para.hotswap_sts));
#endif
		}
		break;
		case TC_GET_TEMP_SNS_CFG:
		{
			obc_tc_temp_sns_info_dec(tc_data);
		}
		break;
		case TC_GET_IMU_CFG:
		{
			obc_tc_imu_info_dec(tc_data);
		}
		break;
		case TC_GET_THRUST_CTRL_CFG:
		{
			obc_tc_thruster_ctlr_info_dec(tc_data);
		}
		break;
		case TC_GET_GPIO_EXP_CFG:
		{
			obc_tc_gpio_exp_info_dec(tc_data);
		}
		break;
		case TC_GET_DIG_THERM_CFG:
		{
			obc_tc_dgtl_thrm_info_dec(tc_data);
		}
		break;
		case TC_GET_PWR_MON_CFG:
		{
			obc_tc_pwr_mon_info_dec(tc_data);
		}
		break;
		case TC_GET_VOLT_CTRL_MON_CFG:
		{
			obc_tc_vltg_ctlr_info_dec(tc_data);
		}
		break;
		case TC_GET_PWR_SEQ_MON_CFG:
		{
			obc_tc_pwr_seq_mtr_info_dec(tc_data);
		}
		break;
		case TC_GET_DATA_LOG_CFG:
		{
			obc_tc_data_log_info_dec(tc_data);
		}
		break;
		case TC_GET_SENSOR_DATA:
		{
			obc_tc_get_sns_data_dec(tc_data);
		}
		break;

		case TC_TEST_GPIO:
		{
			obc_test_gpio_rsp = obc_gpio_test(tc_data);
			tm_rsp.tm_rsp_id =TM_TEST_GPIO ;
			obc_pack_tm_data(&tm_rsp);
		}
		break;
		case TC_TEST_SENSOR:
		{

#ifndef LINUX_TEMP_PORT
obc_test_sns_rsp=obc_test_sensor(tc_data);
#endif
tm_rsp.tm_rsp_id = TM_TEST_SENSOR;
obc_pack_tm_data(&tm_rsp);
		}
		break;
		case TC_TEST_GPIO_EXP:
		{
#ifndef LINUX_TEMP_PORT
obc_test_gpio_exp_rsp=obc_test_gpio_exp(tc_data);
#endif
tm_rsp.tm_rsp_id =TM_TEST_GPIO_EXP ;
obc_pack_tm_data(&tm_rsp);
		}
		break;

		case TC_SPI_UART_CONV_TEST:
		{
#if defined(JANUS2) || defined(GEN2)
			obc_test_spi_uart_conv_rsp = obc_test_spi_uart_conv(tc_data);
#endif
		}
		break;

		case TC_NVM_COMMIT:
		{
#ifndef LINUX_TEMP_PORT
			obc_nvm_commit_rsp=nvm_commit();
#endif
			tm_rsp.tm_rsp_id =TM_NVM_COMMIT ;
			obc_pack_tm_data(&tm_rsp);
		}
		break;

		case TC_NVM_COMMIT_PRDCTY_TIM_CFG:
		{
			uint32_t time_sec;
			os_memcpy(&time_sec,tc_data,4);
#ifndef LINUX_TEMP_PORT
			obc_nvm_commit_prdcty_tim_rsp = nvm_commit_periodicity_update(time_sec*1000);
#endif
			tm_rsp.tm_rsp_id =TM_NVM_COMMIT_PRDCTY_TIM_CFG ;
			obc_pack_tm_data(&tm_rsp);
		}
		break;
		case TC_CONOPS_SCH_LUT_CFG:
		{
			lut_cfg_rsp = conops_sch_lut_info_segmnt_copy(tc_data);
			tm_rsp_id = TM_CONOPS_SCH_LUT_CFG;
			obc_pack_tm_data(NULL);
		}
		break;

		case TC_CONOPS_SCH_LUT_RUN_CTRL:
		{
			obc_conops_sch_lut_ctrl(tc_data);
		}
		break;

		case TC_CONOPS_SCH_STS_INFO:
		{
			obc_conops_sch_status_check(tc_data);
		}
		break;

		case TC_SET_CUR_TIME:
		{
			obc_tc_set_cur_time_dec(tc_data);
		}
		break;

		case TC_PS_BRD_SELECT:
		{
			obc_tc_ps_brd_select(tc_data);
		}
		break;

		case TC_ES_BRD_SELECT:
		{
			obc_tc_es_brd_select(tc_data);
		}
		break;

		case TC_I2C_ADXL345_TEST: //911
		{
			obc_tc_i2c_adxl345_test(tc_data);
		}
		break;

		case TC_UART_TX_RX_TEST: //912
		{
			obc_tc_uart_test(tc_data);
		}
		break;

		case TC_CAN_TX_RX_TEST: //913
		{
			obc_tc_can_test(tc_data);
		}
		break;

		case TC_SPI_ADXL345_TEST: //914
		{
			obc_tc_spi_adxl345_test();
		}
		break;

		case TC_ADC_SELECT:
		{
			obc_tc_adc_brd_select(tc_data);
		}
		break;

		//        case TC_PS_SSD_BRD_SELECT:
			//        {
				//        	obc_tc_ps_ssd_select(tc_data);
				//        }
			//        break;

		case TC_ES_SSD_BRD_SELECT:
		{
			obc_tc_es_ssd_select(tc_data);
		}
		break;

		case TC_IO_BRD_SELECT:
		{
			obc_tc_io_brd_select(tc_data);
		}
		break;

		case TC_AUTO_SENSOR_TEST:
		{
			obc_tc_auto_sensor_test(tc_data);
		}
		break;


		case TC_MEMD:
		{
			DEBUG_CPRINT(("data : %d \n",tc_data[0]));
			log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,DATA__u8_,tc_data[0]);
			DEBUG_CPRINT(("data : %d \n",tc_data_len));
			log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,DATA__u16_,tc_data_len);
			uint8_t *ptr =(uint8_t*) os_malloc_eram(1);

			*ptr = tc_data[0];
			DEBUG_CPRINT(("send %p",ptr));
			log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,SEND__u8_,*ptr);
			os_thread_create(OBC_MEM_DEBUG_TC,T_OBC_MEM_DEBUG_STACK_SIZE,P_OBC_TC_DECODE,"OBC TC DECODER",(app_entry_func_t)obc_mem_debug_tc_decode,(void*)ptr,NULL,NULL);

			DEBUG_CPRINT(("testing\n"));
			log_id(LOG_INFO_L1,LOG_OBC,TESTING);
		}
		break;

		case TC_OBC_SOFT_RESET:
		{
			obc_tc_obc_soft_reset_dec(tc_data);
			if(((uint32_t)*tc_data)==1)
			{
				//TODO
				//OTSU reset
				DEBUG_CPRINT(("OTSU RESET\n"));
				log_id(LOG_INFO_L1,LOG_OBC,OTSU_RESET);
#ifndef LINUX_TEMP_PORT

				obc_otsu_send_shutdwn_rqst();
#endif
			}
			else
			{
				DEBUG_CPRINT(("FORCE SW RESET\n"));
				log_id(LOG_INFO_L1,LOG_OBC,FORCE_SW_RESET);
#ifndef LINUX_TEMP_PORT
				EXO_ASSERT(SW_TEST_RESET);
#endif
			}
			break;
		}

		case    TC_OTSU_GET_VERSION:
		case	TC_OTSU_CURRENT_STATUS:
		case	TC_OTSU_SEND_FW_UPDATE_BOOT_CFG:
		case	TC_OTSU_INTEGERATION_TEST_CMD:
		case	TC_OTSU_GET_FW_UPDATE_STS:
		case	TC_OTSU_GET_BOOT_CFG_INFO:
		case	TC_OTSU_READ_GSCONATCT_WAIT_TIME:
		case	TC_OTSU_SET_GSCONATCT_WAIT_TIME:
		case	TC_OTSU_READ_BOOTABLE_BLT1:
		case	TC_OTSU_READ_BOOTABLE_BLT2:
		case    TC_OTSU_GET_NVM_FW_VERSION:
		case	TC_OTSU_NOTIFICATION:
		{
#ifndef LINUX_TEMP_PORT
obc_otsu_send_tc(tc_id,tc_data, tc_data_len);
#endif
		}
		break;

		case TC_OBC_IPCC_TEST:
		{
			obc_ipcc_test_tc_dec(tc_data);
		}
		break;
#if 0
		case TC_SET_EPS_CTRL_DEV_TMR:
		{
			obc_tc_eps_set_dev_tmr(tc_data);
		}
		break;

		case TC_SET_EPS_BTRY_VOLT_THRSHLD:
		{
			obc_tc_eps_btry_thrshld_dec(tc_data);
		}
		break;

		case TC_SET_EPS_CTRL_CHNL_ST:
		{
			obc_tc_eps_ch_pwr_dec(tc_data);
		}
		break;
		case TC_SET_EPS_BTRY_CTRL_CH_MAP:
		{
			obc_tc_set_eps_btry_chnl_map(tc_data);
		}
		break;

		case TC_SET_EPS_SIM_EXPOSURE_TYPE:
		{
			eps_data.tm_rsp_id = TM_SET_EPS_SIM_EXPOSURE_TYPE;
			eps_data.tx_data = tc_data;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			if(eps_data.rx_data != NULL)
				obc_pack_tm_data(&eps_data);

		}
		break;
		case TC_SET_EPS_SIM_CH_CRNT:
		{
			eps_data.tm_rsp_id = TM_SET_EPS_SIM_CH_CRNT;
			eps_data.tx_data = tc_data;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			if(eps_data.rx_data != NULL)
				obc_pack_tm_data(&eps_data);

		}
		break;
		case TC_SET_EPS_SIM_BTRY_VOLT:
		{
			eps_msg_hdl.pld.pld_ptr=os_malloc(tc_data_len);
			os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
			eps_msg_hdl.Msg_len=tc_data_len;
			eps_msg_hdl.pld_info=TM_SET_EPS_SIM_BTRY_VOLT;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
#if 0
eps_data.tm_rsp_id = TM_SET_EPS_SIM_BTRY_VOLT;
eps_data.tx_data = tc_data;
eps_tctm_code((obc_pck_data_eps*)&eps_data);
if(eps_data.rx_data != NULL)
	obc_pack_tm_data(&eps_data);
#endif
		}
		break;
		case TC_SET_EPS_SIM_BTRY_TEMP:
		{
			eps_msg_hdl.pld.pld_ptr=os_malloc(tc_data_len);
			os_memcpy(eps_msg_hdl.pld.pld_ptr,tc_data,tc_data_len);
			eps_msg_hdl.Msg_len=tc_data_len;
			eps_msg_hdl.pld_info=TM_SET_EPS_SIM_BTRY_TEMP;
			eps_msg_hdl.Msg_id=OBC_EPS_TCTM_INTF;
			eps_msg_hdl.src_entity=OBC_MAIN;

			os_itc_msg_send(&eps_msg_hdl, EPS_TASK, os_send_itc_wait);
#if 0
			eps_data.tm_rsp_id = TM_SET_EPS_SIM_BTRY_TEMP;
			eps_data.tx_data = tc_data;
			eps_tctm_code((obc_pck_data_eps*)&eps_data);
			if(eps_data.rx_data != NULL)
				obc_pack_tm_data(&eps_data);
#endif
		}
		break;

		case TC_EPS_FW_UPDATE:
		{
			uint8_t *pld = NULL;
			pld = os_malloc_eram(tc_data_len);
			os_memcpy(pld, tc_data, tc_data_len);
			obc_eps_send_tc(pld, tc_data_len);

		}
		break;
		case TC_GET_EPS_BTRY_CTRL_CH_MAP:
		{
			obc_tc_get_eps_btry_chnl_map(tc_data);
		}
		break;
		case TC_GET_EPS_DEV_HW_STS:
		{
			obc_tc_eps_get_hw_sts_dec(tc_data);
		}
		break;
#endif
		case TC_SET_SSD_SLOT_SELC:
		{
			obc_tc_ssd_select_dec(tc_data);
		}
		break;
		case TC_SET_SSD_HEAT_COIL_PRDCTY:
		{
			obc_tc_set_ssd_heat_coil_periodicty_dec(tc_data);
		}
		case TC_GET_SSD_HEAT_COIL_PRDCTY:
		{
			obc_tc_get_ssd_heat_coil_periodicity(tc_data);
		}
		break;
		case TC_PS_STAGED_TC:
		{
			obc_tc_ps_staged_tc_trig(tc_data);
		}
		break;

		case TC_SSD_HEAT_COIL_ENABLE:
		{
			obc_tc_ssd_heat_select_dec(tc_data);
		}
		break;

		case TC_GET_SSD_SLOT_SELEC:
		{
			uint8_t board_id;
			os_memcpy(&board_id,tc_data,1);
			obc_tc_get_ssd_slot_selc(board_id);
		}
		break;
		case TC_GET_SSD_HEAT_COIL_STS:
		{
			uint8_t board_id;
			os_memcpy(&board_id,tc_data,1);
			obc_tc_get_ssd_heat_coil_selc(board_id);
		}
		break;

		case TC_LOG_DOWNLOAD_BLOCKS:
		case TC_LOG_LEVEL_FILTER_CONFIG:
		case TC_READ_LOG_INFO:
		case TC_LOG_DOWNLOAD_BACKUP_BLOCKS:
		{
			obc_tc_log_buf_dwnld_read_set_config(tc_id, tc_data);
		}
		break;

		case TC_SET_CONTROL_FLAG_TM_BUFFER:
		{
			obc_tc_set_ctrl_flag_tm_buffer();
		}
		break;

		case TC_SET_COMMS_TM_DLREQ:
		{
			obc_tc_set_comms_tm_dlreq();
		}
		break;

		case TC_DEFERRED_STRG:
		{
			DEBUG_CPRINT(("In TC_DEFERRED_STRG \n"));
			log_id(LOG_INFO_L1,LOG_OBC,IN_TC_DEFERRED_STRG);
			obc_tc_deffered_strg(tc_data);
		}
		break;

		case TC_EXTRNL_MEM_TEST:
		{
			//                log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,MEM_TYPE__u8_,tc_data[0]);
			//                DEBUG_CPRINT(("Operation : %d \n",tc_data[1]));
			//                log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,OPERATION__u8_,tc_data[1]);
			obc_ex_mem_test_tc_dec(tc_data);
		}
		break;
		case TC_GET_OBC_SW_STS :
		{
			tm_rsp_id = TM_GET_OBC_SW_STS;
			obc_pack_tm_data(NULL);
		}
		break;
		case TC_NVM:
		{
			obc_mem_data_dec(tc_data);
		}
		break;

		case TC_TM_MNGR_GS_CONTACT:
		{
			obc_set_gs_contact(tc_data);
		}
		break;
#if 0
		case TC_EPS_GET_BUFFER:
		{
			obc_get_eps_buffer_dec(tc_data);
		}
		break;


		case TC_EPS_HEALTH_STS:
		{
			obc_eps_get_health_sts_dec(tc_data);
		}
		break;

		case TC_EPS_GET_CRC:
		{
			obc_eps_crc_sts(tc_data);
		}
		break;
#endif
		case TC_GET_CUR_TIME:
		{
			tm_rsp_id = TM_GET_CUR_TIME;
			obc_pack_tm_data(NULL);
		}
		break;

		case TC_TCTM_DEQUEUE:
		{
			obc_tc_flush_queue(tc_data);
		}
		break;

		case TC_ERR_HANDLER_READ_FAULTS:
		case TC_ERR_HANDER_READ_GROUP_ERROR_STATUS:
		case TC_ERR_HANDLER_GET_ERROR_HISTORY:
		case TC_ERR_HANDLER_RUN_BIST:
		{
			err_tc_decoder(tc_id, tc_data);
		}
		break;

		case TC_SET_RADIO_MODULE_ID:
		{
			DEBUG_CPRINT(("Set Radio Id %d\r\n",*tc_data));
			log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,SET_RADIO_ID__u8_,*tc_data);
			log_id_with_one_arg(LOG_INFO_L1,LOG_OBC,SET_RADIO_ID__u8_,*tc_data);
			set_radio_id(*tc_data);
		}
		break;
		/** TC to get the cpu utilization of each tasks */
		case TC_OBC_GET_CPU_STATS:
		{
			tm_rsp_id = TM_OBC_GET_CPU_STATS;
			obc_pack_tm_data(NULL);
		}
		break;
		case TC_GET_PS_TEMP:
		{
			obc_get_dev_temp_info_dec(tc_data);
		}
		break;
		case TC_GET_PS_TIME:
		{
			obc_get_dev_time_info_dec(tc_data);
		}
		break;
		case TC_GET_MCU_CHIP_INFO:
		{
			obc_get_dev_chip_info_dec(tc_data);
		}
		break;
		case TC_GET_MCU_EXT_MEM_INFO:
		{
			obc_get_dev_ext_mem_dec(tc_data);
		}
		break;
		case TC_GET_MCU_INT_MEM_INFO:
		{
			//obc_get_dev_int_mem_dec(tc_data);
			tm_rsp_id = TM_GET_MCU_INT_MEM_INFO;
			obc_pack_tm_data(NULL);
		}
		break;
		case TC_GET_MCU_INT_PHERIPHARL_INFO:
		{
			//obc_get_dev_int_pher_info_dec(tc_data);
			tm_rsp_id = TM_GET_MCU_INT_PHERIPHARL_INFO;
			obc_pack_tm_data(NULL);
		}
		break;
		case TC_GET_MCU_EXT_PHERIPHARL_INFO:
		{
			//obc_get_dev_ext_pher_info_dec(tc_data);
			tm_rsp_id = TM_GET_MCU_EXT_PHERIPHARL_INFO;
			obc_pack_tm_data(NULL);
		}
		break;
		case TC_GET_MCU_RST_INFO:
		{
			//obc_get_dev_get_rst_info_dec(tc_data);
			tm_rsp_id = TM_GET_MCU_RST_INFO;
			obc_pack_tm_data(NULL);
		}break;
		case TC_GET_HEALTH_METRICS:
		{
			tc_request_health_data(tc_data);
		}
		break;
		case TC_CHNGE_QUEUE_PRIORITY:
		{
			tc_chng_queue_priority(tc_data);
		}
		break;

		case TC_CHNGE_MODULE_PRIORITY:
		{
			tc_chng_module_priority(tc_data);
		}
		break;
		case TC_PRINT_MEM_LEAK:
		{
			DEBUG_CPRINT(("mem leak\n"));
			print_mem_leak();
			tm_rsp_id = TM_PRINT_MEM_LEAK;
			obc_pack_tm_data(NULL);
		}
		break;
		case TC_GET_TCTM_DBG_INFO:
		{
			obc_get_tctm_dbg_info();
		}
		break;

		default:
		{
			DEBUG_CPRINT(("Invalid TC ID received %d\n",tc_id));
			log_id_with_one_arg(LOG_WARNING,LOG_OBC,INVALID_TC_ID_RECEIVED__u16_,tc_id);

		}
	}
	return 0;
}

void tc_obc_buff_fw_req_queue(uint32 instance_size, uint32 num_of_instance, uint8 queue_id)
{
	os_itc_msg_handle_t obc_req_ipc;
	s_tc_tm_buffer_req *buff_req = os_malloc(sizeof(s_tc_tm_buffer_req));
	if(buff_req)
	{
		os_memset(buff_req, 0, sizeof(s_tc_tm_buffer_req));
		buff_req->queue_id = queue_id;
		buff_req->instance_size = instance_size;
		buff_req->num_instance = num_of_instance;
		buff_req->wrap_dsb = 0;
		buff_req->priority = 0;
		buff_req->strg_flag = 0;
		buff_req->thresh = 0;
		obc_req_ipc.pld.pld_ptr = (void*)buff_req;
		obc_req_ipc.src_entity = OBC_MAIN;
		obc_req_ipc.Msg_id = OBC_TC_TM_BUFFER_REQ;
		os_itc_msg_send(&obc_req_ipc, HM_MANAGER_IPC_RECEIVE, os_send_itc_wait);
	}
}

void tc_obc_buff_fw_enqueue_req(uint8* data, uint8 queue_id)
{
	os_itc_msg_handle_t obc_req_ipc;
	obc_req_ipc.pld.pld_data = queue_id;
	obc_req_ipc.pld.pld_ptr = data;
	obc_req_ipc.src_entity = OBC_MAIN;
	obc_req_ipc.Msg_id = OBC_TC_TM_ENQUEUE_REQ;
	os_itc_msg_send(&obc_req_ipc, HM_MANAGER_IPC_RECEIVE, os_send_itc_wait);
}


void obc_timer_exp_send_health_info()
{
	uint64_t used_eram_mem = 0;
	uint64_t total_eram_size = 0;
#ifdef LINUX_TEMP_PORT
	float cpu_ld_linux = 0;
	uint32_t uptime_linux;
#else
	uint32_t stop_tick;
#endif

	s_obc_health_info *obc_enqueue_health_data = os_malloc(sizeof(s_obc_health_info));
	/*To get time stamp*/
	obc_enqueue_health_data->timestamp = get_crnt_time_date_in_epoch();
	/*To update current fsm state of obc*/
	obc_enqueue_health_data->fsm_state  = sm_get_state(OBC_MAIN_FSM);
	/*To get total number of resets */
	obc_enqueue_health_data->num_resets = rst_count;
	/*To get number of input/output errors*/
	obc_enqueue_health_data->io_err     = 0;
	/*To get system error*/
	obc_enqueue_health_data->sys_err    = system_error;

#ifndef LINUX_TEMP_PORT

	/* To get CPU Utilization*/
	obc_pck_data tm_data_info;
	/*In this API cpu utilization will be updated in this variable - tm_data_info.rx_data */
	obc_get_cpu_load(&tm_data_info);

	if(tm_data_info.rx_data)
	{
		/** copying cpu utilization data in obc health structure*/
		os_memcpy((char*)&obc_enqueue_health_data->cpuUtil,tm_data_info.rx_data,sizeof(float));
	}
	/*To get Mem info */
	os_heap_memory_info_s mem_info;
	/*Remaining iram memory calculation & updating health info structure*/
	get_os_heap_mem_info(&mem_info);
	obc_enqueue_health_data->iram_rem_heap = mem_info.os_total_heapsize - mem_info.os_used_heapsize;
	/*Remaining eram memory calculation & updating health info structure*/
	eram_heap_mem_cal(&used_eram_mem, &total_eram_size);
	obc_enqueue_health_data->eram_rem_heap = total_eram_size - used_eram_mem;

	/*To get uptime*/
	/* stop_tick = Current no of ticks
	 * start_tick = Initial tick when obc started
	 * uptime = stop_tick - start_tick
	 * Division by 1000 - converting ms to secs
	 * Divison by 60 - converting secs to minutes
	 */
	stop_tick = HAL_GetTick();
	obc_enqueue_health_data->uptime        = (((stop_tick - start_time))/(60*1000));

	/*To get reset cause*/
	obc_enqueue_health_data->reset_cause   = reset_cause;

	os_memcpy(&obc_enqueue_health_data->ipc_fail_cntr[0],\
			&exo_sw_dbg.obc_dbg.ipc_fail_queue_full_cntr[0],\
			sizeof(uint16_t)*OS_TASK_MAX);

	if(tm_data_info.rx_data != NULL)
	{
		os_free(tm_data_info.rx_data);
	}

#else
	/* To get CPU Utilization*/
	cpu_ld_linux = linux_get_cpuload();
	memcpy((char*)&obc_enqueue_health_data->cpuUtil,&cpu_ld_linux,sizeof(float));

	/* To get CPU Utilization*/
	iram_heap_status iram_lnx_sts;
	/*iram remaining heap memory calculation*/
	linux_get_memusage(&iram_lnx_sts);
	obc_enqueue_health_data->iram_rem_heap = iram_lnx_sts.total_mem - iram_lnx_sts.used_mem;
	/*eram remaining heap memory calculation*/
	total_eram_size = 33554432;
	used_eram_mem   = 11181694;
	obc_enqueue_health_data->eram_rem_heap = total_eram_size - used_eram_mem;

	/*To get uptime*/
	obc_enqueue_health_data->reset_cause   = 0;
	/*To get reset cause*/
	uptime_linux                           = linux_get_uptime();
	obc_enqueue_health_data->uptime        = (uptime_linux/60);           //Seconds to minutes conversion

	os_memcpy(&obc_enqueue_health_data->ipc_fail_cntr[0],\
			&exo_sw_dbg.obc_dbg.ipc_fail_queue_full_cntr[0],\
			sizeof(uint16_t)*OS_TASK_MAX);

#endif
	/*Enqueuing OBC health data to Health metric framework*/
	tc_obc_buff_fw_enqueue_req((uint8*)obc_enqueue_health_data, OBC_DATA_QUEUE_ID);
}

void obc_health_buff_timer_exp_cb()
{
	/*Upon every timer expire ipc message will be sent to OBC main */
	os_itc_msg_handle_t obc_timer_cb_ipc;
	obc_timer_cb_ipc.src_entity = OBC_MAIN;
	obc_timer_cb_ipc.pld.pld_ptr=NULL;
	obc_timer_cb_ipc.Msg_id=OBC_TMR_EXPRY_EVNT;
	os_itc_msg_send(&obc_timer_cb_ipc,OBC_MAIN, os_send_itc_wait);
	DEBUG_CPRINT(("[OBC_MAIN][HM_FW] - OBC_HEALTH_SEND_TIMER_EXPIRES\n"));

}
void obc_health_data_send_tmr_strt()
{
	/*Creating timer for enqueing OBC health data*/
	os_timer_create(&obc_health_data_timer,"send_obc_health_data",PERIODIC,obc_health_buff_timer_exp_cb,NULL);
	DEBUG_CPRINT(("[OBC_MAIN][HM_FW] - OBC_HEALTH_SEND_TIMER_CREATED\n"));
	/*Timer starts with period of 1 minute*/
	os_timer_start(obc_health_data_timer,(os_tick_time_t)OBC_HEALTH_DATA_TIMER_IN_SEC);
}


#if 0
/**
 * @brief This API sends TM through the IPC interface based
 *        on TC received
 */
static void obc_tm_send_thread (void *params)
{
	obc_pack_tm_data();
}
#endif

/**
 * @brief This API listens for a TC through the IPC interface and
 *        invokes TC handler api if a valid TC is received
 */
static void obc_main_thread (void * params)
{
	uint8_t state = 0;
	e_sm_sts sm_status;

	obc_tc_listner_thread_tc_frame = (s_tc_frame *) os_malloc_eram(sizeof(s_tc_frame));
	obc_tc_listner_thread_tc_frame->cmac_hmac = (uint8 *) os_malloc_eram(SHA256_HASH_SIZE);
	obc_tc_listner_thread_tc_frame->tc_data = (uint8 *) os_malloc_eram(1024);

	sm_status = sm_alloc(OBC_MAIN_FSM,OBC_MAX_NUM_STATE);

	obc_sband_nvm_upd_first_ground_contact();
	obc_sband_nvm_upd_otsu_ground_contact();
	obc_health_data_send_tmr_strt();


	/** TM buffering FW queue request for health data */
	/** One orbit duration = 90minutes
	 *  Every minute enqueing 1instance = 90 instance for one orbit
	 *  For 3 orbit 90*3 instance */

	tc_obc_buff_fw_req_queue(sizeof(s_obc_health_info), OBC_MAX_BUFF_SIZE, OBC_DATA_QUEUE_ID);


	if(!comms_first_gs_contact)
	{
		obc_send_ipc_msg(OBC_SCH_INIT_SYNC_TIME_REQ, ORBIT_CONOPS_SCHEDULER);
	}

	if(SM_OK == sm_status)
	{
		state = OBC_INIT_STATE;

		//#ifdef LINUX_TEMP_PORT
		state = OBC_ACTIVE_PWR_NORM_STATE;
		//#else
		//        state = OBC_INIT_STATE;
		//#endif
		sm_set_state(OBC_MAIN_FSM, state);

		while(1)
		{
			os_itc_msg_rcv(OBC_MAIN,&obc_rcv_ipc_msg,os_wait_forever); //os_wait_forever
			/*Control Variable - Incremnents on every IPC receive*/
			exo_sw_dbg.obc_dbg.obc_main_ipc_rcvd++;

			DEBUG_CPRINT(("\nOBC MAIN Entry: %d\n",state));
			log_id_with_one_arg(LOG_INFO_L3,LOG_OBC,OBC_MAIN_ENTRY__u8_,state);
			state = obc_fsm(state, &obc_rcv_ipc_msg);
			DEBUG_CPRINT(("\nOBC MAIN exit: %d\n",state));
			log_id_with_one_arg(LOG_INFO_L3,LOG_OBC,OBC_MAIN_EXIT__u8_,state);
			sm_set_state(OBC_MAIN_FSM, state);
#if 0
			switch(obc_rcv_ipc_msg.src_entity)
			{
			case HM_MANAGER_IPC_RECEIVE:
			{
				if(obc_rcv_ipc_msg.pld.pld_ptr)
				{
					os_free(obc_rcv_ipc_msg.pld.pld_ptr);
					obc_rcv_ipc_msg.pld.pld_ptr = NULL;
				}
			}
			break;

			default:
			{

			}
			}
#else
	if((obc_rcv_ipc_msg.pld.pld_ptr))
	{
		os_free(obc_rcv_ipc_msg.pld.pld_ptr);
		obc_rcv_ipc_msg.pld.pld_ptr = NULL;
	}
#endif
		}
	}
	sm_status = sm_free(OBC_MAIN_FSM);
}

int32_t obc_main_init(void)
{
	int status = 0;
	os_status_t os_sts;
#ifdef LINUX_TEMP_PORT
	DEBUG_CPRINT(("OBC ICD socket address is %s %u \n",icd_soc_inf.ip_addr,(icd_soc_inf.port)));
#else

#if 0
	os_memcpy(&icd_soc_inf.ip_addr,"190.160.0.10",sizeof("190.160.0.10")-1);
	os_memcpy(&icd_soc_inf.port_num,"6565",sizeof(4));
	// icd_soc_inf.ip_addr = "190.160.0.10";
	//  icd_soc_inf.port_num = "6565";
#endif

#endif
	//TODO Remove this function usage dependency and invoke decoder directly
	ipcc_term_add_ipcc_func(&obc_sample_app_main_ipcc_term, 24, obc_icd_print_data);

	os_sts=os_thread_create(OBC_IPCC_RECEIVE,T_OBC_IPCC_RECEIVE_STACK_SIZE,P_OBC_IPCC_RECEIVE,"OBC ICD skt lst srv", obc_icd_socket_listen_server_thread,NULL,NULL,NULL);
	os_sts=os_thread_create(OBC_IPCC_SEND,T_OBC_IPCC_SEND_STACK_SIZE,P_OBC_IPCC_SEND,"OBC ICD_enc skt srv", obc_icd_rsp_enc_socket_server_thread,NULL,NULL,NULL); //2kb

	/* Create thread that sends Telecommand binary data stream via IPC interface */
	os_sts=os_thread_create(OBC_MAIN,T_OBC_MAIN_STACK_SIZE,P_OBC_MAIN,"TM rcv", obc_main_thread,NULL,NULL,NULL);  //1024

	ft_initialisation();
#ifdef LINUX_TEMP_PORT
	ft_register_ramwrite_cblk((ft_data_write_cblk_type)otsu_sdram_write_clbk_linux);
#endif
	os_sts=os_thread_create(FTM_TCTM_SEND, T_FTM_TCTM_SEND_STACK_SIZE, P_FTM_TCTM_SEND, "ft_tx_thrd",obc_ft_tctm_sender_thread , NULL, NULL, NULL);

#ifndef LINUX_TEMP_PORT
	otsu_initialisation();
#endif
	if(1 == os_sts)
	{
		status = 0;
	}
	else
	{
		status = -1;
	}

	return status;
}


static void obc_ft_tctm_sender_thread(void *params)
{
	os_delay(3000);
	obc_file_rx_init();

	while(1)
	{
		os_queue_receive(ft_queue_hdle_sen, &s_ftm_queue_tm_frame, os_wait_forever);
		tm_rsp_id = s_ftm_queue_tm_frame.tc_tm_id;
		obc_pack_tm_data(NULL);
	}

}



uint8_t ft_payload_transmitter(uint16 tc_tm_id, uint8_t *payload_ptr, uint16_t payload_len)
{
	uint8_t ret_busy_sts = 0;
	uint16_t u16cnt;
	if(payload_ptr != NULL)
	{
		if(ft_pld_tx.send_request != 1)
		{
			ft_pld_tx.payload_ptr = os_malloc_eram(payload_len);
			if(ft_pld_tx.payload_ptr != NULL)
			{
				for(u16cnt = 0; u16cnt< payload_len; u16cnt++)
				{
					ft_pld_tx.payload_ptr[u16cnt] = payload_ptr[u16cnt];
				}
				ft_pld_tx.tc_tm_id = tc_tm_id;
				ft_pld_tx.payload_len = payload_len;
				ft_pld_tx.send_request = 1;
				ret_busy_sts = 1;
			}
		}
	}
	return ret_busy_sts;
}

void obc_sband_nvm_upd_first_ground_contact(void)
{
#ifndef LINUX_TEMP_PORT
	nvm_parameter_read(NVM_DATA,NVM_GS_FIRST_CONTACT,(uint8_t*)&comms_first_gs_contact);
#endif
}

void obc_sband_nvm_upd_otsu_ground_contact(void)
{
#ifndef LINUX_TEMP_PORT
	nvm_parameter_read(NVM_DATA,NVM_GS_OTSU_CONTACT,(uint8_t*)&comms_otsu_gs_contact);
#endif
}

void tc_request_health_data(uint8* tc_data)
{
	os_itc_msg_handle_t obc_snd_hlt_ipc_msg;
	DEBUG_CPRINT(("Submodule %d queue id %d priority is %d\n", tc_data[0],tc_data[1],\
			tc_data[2]));

	DEBUG_CPRINT(("Type is %d\n",tc_data[3]));

	uint8 type = tc_data[3];
	switch(type)
	{
	case 1:
	case 2:
	case 3:
	{
		s_tc_tm_dl_q_req *dl_req = os_malloc(sizeof(s_tc_tm_dl_q_req));
		if(dl_req)
		{
			dl_req->submod_id = tc_data[0];
			dl_req->queue_id = tc_data[1];
			dl_req->priority = tc_data[2];

			obc_snd_hlt_ipc_msg.pld.pld_ptr = (void*)dl_req;
			obc_snd_hlt_ipc_msg.pld.pld_data = get_radio_module_id();
			obc_snd_hlt_ipc_msg.src_entity = dl_req->submod_id;
			obc_snd_hlt_ipc_msg.Msg_id = OBC_TC_TM_DL_BUFFER_REQ;
			os_itc_msg_send(&obc_snd_hlt_ipc_msg,HM_MANAGER_IPC_RECEIVE, os_send_itc_wait);
		}
	}
	break;
	default:
	{
		DEBUG_CPRINT(("Invalid type %d\n",type));
	}
	break;
	}
}

void tc_chng_queue_priority(uint8* tc_data)
{
	os_itc_msg_handle_t obc_snd_hlt_ipc_msg;

	DEBUG_CPRINT(("Submodule %d queue id %d cuurent priority is %d priority is %d\n", tc_data[0],tc_data[1],\
			tc_data[3], tc_data[2]));

	DEBUG_CPRINT(("Type is %d\n",tc_data[4]));

	uint8 type = tc_data[4];
	/** Check if type is valid */
	if(type < 4)
	{
		switch(type)
		{
		/**  - one submodule, one queue's priority change */
		case 1:
			/**  - one submodule, multiple queue's priority change */
		case 2:
			/**  - All submodule, multiple queue's priority change */
		case 3:
		{
			s_tc_tm_chng_q_priority *pri_req = os_malloc(sizeof(s_tc_tm_chng_q_priority));
			if(pri_req)
			{
				pri_req->submod_id = tc_data[0];
				pri_req->queue_id = tc_data[1];
				pri_req->priority = tc_data[2];
				pri_req->cur_priority = tc_data[3];

				obc_snd_hlt_ipc_msg.pld.pld_ptr = (void*)pri_req;
				obc_snd_hlt_ipc_msg.pld.pld_data = get_radio_module_id();
				obc_snd_hlt_ipc_msg.src_entity = OBC_MAIN;
				obc_snd_hlt_ipc_msg.Msg_id = OBC_TC_TM_CHNG_QUEUE_PRIORITY_REQ;
				os_itc_msg_send(&obc_snd_hlt_ipc_msg,HM_MANAGER_IPC_RECEIVE, os_send_itc_wait);
			}
		}
		break;
		default:
		{
			DEBUG_CPRINT(("Invalid type\n"));
		}
		break;
		}
	}

}

void tc_chng_module_priority(uint8* tc_data)
{
	os_itc_msg_handle_t obc_snd_hlt_ipc_msg;

	DEBUG_CPRINT(("Submodule %d\n Current priority of the module is %d\n Module priority to be changed is %d\n", tc_data[0],tc_data[2],\
			tc_data[1]));

	s_tc_tm_chng_mod_priority *pri_req = os_malloc(sizeof(s_tc_tm_chng_mod_priority));
	if(pri_req)
	{
		pri_req->submod_id = tc_data[0];
		pri_req->priority = tc_data[1];
		pri_req->cur_priority = tc_data[2];

		obc_snd_hlt_ipc_msg.pld.pld_ptr = (void*)pri_req;
		obc_snd_hlt_ipc_msg.pld.pld_data = get_radio_module_id(); //Check with sathish
		obc_snd_hlt_ipc_msg.src_entity = OBC_MAIN;
		obc_snd_hlt_ipc_msg.Msg_id = OBC_TC_TM_CHNG_SUB_MOD_PRIORITY_REQ;
		os_itc_msg_send(&obc_snd_hlt_ipc_msg, HM_MANAGER_IPC_RECEIVE, os_send_itc_wait);
	}
}

/**
 * @brief This function to check socket connection status
 */
int check_socket_disconnected(int sockfd_info)
{
	fd_set read_fds;

	// Zero timeout for non-blocking select call
	struct timeval timeout = {0, 0};

	//set 0 initially
	FD_ZERO(&read_fds);

	//set FD
	FD_SET(sockfd_info, &read_fds);

	//Select and Check read operation, write avaialble of FD(Check any changes?)
	int ret = select(sockfd_info + 1, &read_fds, NULL, NULL, &timeout);

	if (ret < 0) {
		perror("select error");
		return 1;
	}

	if (ret == 0) {
		// No data to read and no exceptional conditions
		return 0;
	}

	//Check FD is set?
	if (FD_ISSET(sockfd_info, &read_fds))
	{
		char buffer[1];
		ret = recv(sockfd_info, buffer, 1, MSG_PEEK);
		if (ret <= 0)
		{
			// recv returns 0 or negative value means socket is
			// closed or error occurred
			if (ret == 0)
			{
				printf("Socket closed by the peer.\n");
			}
			else
			{
				perror("recv error");
			}
			return 1;
		}
	}

	return 0;
}

