#include "obc_icd.h"
#include "obc_main.h"
#include "obc_tc_tm.h"
#include "exo_common.h"

#include <sys/socket.h>
#include <arpa/inet.h>
//#include <pthread.h>
#include "obc_intf_ctrl_msg.h"


#include "file_transfer.h"
#include "ft_upload.h"
#include "ft_dwnld.h"
#include "exo_io_al_sos_timer.h"
#include "exo_tctm_ipc.h"
#include "gps_app.h"
#include "comms_sband_csp.h"
#include "logger.h"

#define ICD_CLIENTS_CNT        10 

int32 icdSocket = -1;
uint16 rsp_enc_id_val = 0;
extern s_obc_sock_info icd_soc_inf;
extern uint16 obc_evnt_trig;
extern uint16 ps_hw_id;
uint16 ps_vm_id ;
extern ft_tctm_payload_tx ft_pld_tx;
obc_radio_pwr_on rpo;
obc_get_curr_time gct;
uint8 num_app_id,obc_icd_rsp_enc_skt_srv_num_hw,total_app_id;
uint16 buff_len,obc_app_qos_pri_len;
uint8 *app_id_list_ptr,*hw_id_list_ptr,*obc_app_qos_pri_ptr;

uint16 num_app, obc_encode_icd_cmd_num_hw = 0;
uint16 app_info_buff_len, hw_info_buff_len;
icm_ps_pwr_off_info_s ppoi;
icm_gs_pass_info_s gpi;
uint8 node_state = 0;
icm_pld_hw_pwr_off_info_s phw_poi;
icm_vm_pwr_off_info_s poi;
obc_rst_recv_updt rru;
uint32 obc_staged_tc_id = 0;
extern exo_sw_dbg_cb exo_sw_dbg;
int32 clientsocket[ICD_CLIENTS_CNT];

#include "exo_osal_rsrc_sync.h"

os_sem_handle_ptr rsp_enc_id_sem;
os_sem_handle_ptr rsp_enc_id_lock_sem;


void set_enc_id(uint16_t rsp_enc_id_loc)
{
    os_sem_take(rsp_enc_id_lock_sem,os_wait_forever);
    rsp_enc_id_val = rsp_enc_id_loc;

    os_sem_give(rsp_enc_id_lock_sem);
}

void set_enc_id_indicate(uint16_t rsp_enc_id)
{
    set_enc_id(rsp_enc_id);
    ipcc_send_ipc_msg_pld(0, OBC_IPCC_SEND, (uint8_t*)&rsp_enc_id_val, sizeof(rsp_enc_id_val), OBC_IPCC_SEND);
}

void obc_icd_rsp_enc_socket_server_thread(void *params)
{
    os_itc_msg_handle_t ipcc_itc_msg;
    uint8 *data = NULL;
    uint16 data_len;

    // For resource locking
    os_sem_create_count(&rsp_enc_id_lock_sem, 1, 1, "OBC_ICD_ENC_LOCK");

    // For IPC
    os_sem_create_count(&rsp_enc_id_sem, 1, 0, "OBC_IPC_ENC_ID");

    DEBUG_CPRINT(("\nICD thread entry\n"));
    log_id(LOG_INFO_L1,LOG_IPCC,ICD_thread_entry);
    set_enc_id(0);
#define os_sem_give ral_sem_give
    while(1)
    {

        os_itc_msg_rcv(OBC_IPCC_SEND, &ipcc_itc_msg,os_wait_forever);
        /*Control variable - Increments on every response sent to PS*/
        exo_sw_dbg.ipcc_dbg.no_ipcc_rsp_sent++;

        switch(ipcc_itc_msg.src_entity)
        {
            case OBC_MAIN:
                {
                    uint8_t dev_id = 0;
                    switch(ipcc_itc_msg.Msg_id)
                    {
                        case OBC_PLD_SERVER_INIT_REQ:
                            {
                                os_memcpy(&dev_id,ipcc_itc_msg.pld.pld_ptr,sizeof(dev_id));
                                DEBUG_CPRINT(("\nOBC_PLD_SERVER_INIT_REQ recvd, %d",dev_id));
                                log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,OBC_PLD_SERVER_INIT_REQ_recvd__u8_,dev_id);
                                ipcc_send_ipc_msg_pld(PLD_SERVER_OBC_INIT_RSP , OBC_MAIN,&dev_id,1, OBC_IPCC_SEND);

                            }
                            break;
                        case  OBC_PLD_SERVER_DEINIT_REQ:
                            {
                                os_memcpy(&dev_id,ipcc_itc_msg.pld.pld_ptr,sizeof(dev_id));
                                DEBUG_CPRINT(("\nOBC_PLD_SERVER_DEINIT_REQ recvd, %d",dev_id));
                                log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,OBC_PLD_SERVER_DEINIT_REQ_recvd__u8_,dev_id);
                                ipcc_send_ipc_msg_pld(PLD_SERVER_OBC_DEINIT_RSP , OBC_MAIN,&dev_id,1, OBC_IPCC_SEND);

                            }
                            break;
                    }
                }
                break;

            case COMMS_XBAND_CTLR:
                {
                    switch(ipcc_itc_msg.Msg_id)
                    {
                        case XBAND_OBC_IPCC_SEND_REQ:
                            {
                                obc_ps_xband_cmd_enc(&data, &data_len,ipcc_itc_msg.Msg_len,ipcc_itc_msg.pld.pld_ptr);
                                obc_icd_socket_send(data,data_len);
                                os_free(data);
                                data = NULL;
                            }
                            break;
                    }
                }
                break;

            case OBC_IPCC_SEND:
                {
                    obc_flash_write_handler();

                    if(rsp_enc_id_val)
                    {
                        switch(rsp_enc_id_val)
                        {
                            case PS_OBC_TRGT_POINT_REQ:
                                {
                                    ps_obc_trgt_pt_rsp_enc(&data, &data_len, 1);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_GNSS_LOC_REQ:
                            {
                            	    gps_loc_info* gps_loc = os_malloc(sizeof(gps_loc_info));
                            	    gps_get_location_info(gps_loc);
                                    ps_obc_gnss_loc_rsp_enc(&data, &data_len,gps_loc);
                                    obc_icd_socket_send(data,data_len);
                                    os_free((uint8_t*)gps_loc);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_GET_CURR_TIME_REQ:
                                {
                                	uint32_t* tm_epoch = os_malloc(4);
                                	*tm_epoch = get_crnt_time_date_in_epoch();
                                    ps_obc_get_curr_time_rsp_enc(&data, &data_len,*tm_epoch);
                                    obc_icd_socket_send(data,data_len);
                                    os_free((uint8_t*)tm_epoch);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_GNSS_PRD_LOC_REQ:
                                {
                                	ps_obc_gnss_prd_loc_rsp_enc(&data, &data_len,0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_GNSS_TLE_DATA_REQ:
                                {
                                    gps_tle_data* gps_tle = os_malloc(sizeof(gps_tle_data)) ;
                                    gps_get_cartesian_pos_velcty(gps_tle);
                                    ps_obc_gnss_tle_data_rsp_enc(&data, &data_len, gps_tle);
                                    obc_icd_socket_send(data,data_len);
                                    os_free((uint8_t*)gps_tle);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_GNSS_PRD_TLE_DATA_REQ:
                                {
                                	ps_obc_gnss_prd_tle_data_rsp_enc(&data, &data_len,0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_KEEP_ALIVE_REQ:
                                {
                                    ps_obc_keep_alive_rsp_enc(&data, &data_len);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_SCHD_PS_PWR_ON_REQ:
                                {
                                    ps_obc_schd_ps_pwr_on_rsp_enc(&data, &data_len,0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_RADIO_PWR_ON_REQ:
                                {
                                    rpo.pwr_on_rsp = 0;
                                    rpo.pwr_on_retry_req_dur = 0;
                                    ps_obc_radio_pwr_on_rsp_enc(&data, &data_len,&rpo);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_RADIO_RX_ENBL_DSBL_CMD:
                                {
                                    ps_obc_radio_rx_enbl_dsbl_rsp_enc(&data, &data_len,0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_RADIO_PWR_OFF_CMD:
                                {
                                    ps_obc_radio_pwr_off_rsp_enc(&data, &data_len,0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_REG_ORBIT_TRIG_CMD:
                                {
                                    ps_obc_reg_orbit_trig_rsp_enc(&data, &data_len, 0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_REG_GRND_STN_PASS_NTF_CMD:
                                {
                                    ps_obc_reg_grnd_stn_ps_ntf_rsp_enc(&data, &data_len, 0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_PWR_ON_HNDSK_NTF:
                                {
                                    obc_ps_rtc_time_s time_date_rtc;
                                    get_crnt_time_date((sys_time_date_s *)&time_date_rtc);

                    				obc_ps_utc_time_s time_date_utc;
                                    uint16 len = sizeof(obc_ps_utc_time_s);

                    				time_date_utc.year = time_date_rtc.year;
                    				time_date_utc.month = time_date_rtc.month;
                    				time_date_utc.date = time_date_rtc.date;
                    				time_date_utc.hour = time_date_rtc.hour;
                    				time_date_utc.min = time_date_rtc.min;
                    				time_date_utc.sec = time_date_rtc.sec;
                    				DEBUG_CPRINT(("PS UTC Time configuration %d/%d/%d %d:%d:%d\n",\
                    						time_date_utc.date,time_date_utc.month, time_date_utc.year, \
                    						time_date_utc.hour, time_date_utc.min, time_date_utc.sec));
                                log_id_with_three_arg(LOG_INFO_L1,LOG_IPCC,PS_UTC_Time_Configuration__u8__u8__u16_,time_date_utc.date,time_date_utc.month, time_date_utc.year);
                                log_id_with_three_arg(LOG_INFO_L1,LOG_IPCC,PS_UTC_Time_Configuration__u8__u8__u8_,time_date_utc.hour, time_date_utc.min, time_date_utc.sec);
                                    obc_ps_utc_time_cfg_cmd_enc(&data, &data_len,len,(uint8*)&time_date_utc);

                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;

                                    ps_obc_pwr_on_hndske_ntf_rsp_enc(&data, &data_len);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_RADIO_DATA_TX_CPLT_NTF:
                                {
                                    ps_obc_radio_data_tx_cplt_ntf_rsp_enc(&data, &data_len, 0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_SSD_ERR_NTF:
                                {
                                    ps_obc_ssd_err_ntf_rsp_enc(&data, &data_len, 0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_PS_HW_ERR_RECOV_NTF:
                                {
                                    ps_obc_ps_hw_err_recov_ntf_rsp_enc(&data, &data_len, 0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_PS_SHUTDOWN_NTF:
                                {
                                    ps_obc_ps_shutdown_ntf_rsp_enc(&data, &data_len, 0);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_PS_HW_PWR_ON_CMD:
                                {
                                    /** Send ITC to EPS for payload power ON */
                                    uint32_t *eps_req = os_malloc(sizeof(uint32_t) * 2);
                                    if(eps_req)
                                    {
                                        eps_req[0] = obc_get_eps_chnl_id_from_pld_hw_id(ps_hw_id);
                                        if(MAX_SAT_DEV_CNT > eps_req[0])
                                        {
                                            eps_req[1] = PWR_ON;
                                            os_itc_msg_handle_t ps_itc_msg;
                                            ps_itc_msg.Msg_id = EPS_SET_CHNL_STATE;
                                            ps_itc_msg.src_entity = OBC_IPCC_SEND;
                                            ps_itc_msg.Msg_len = (sizeof(uint32_t) * 2);
                                            ps_itc_msg.pld.pld_ptr = (void*)eps_req;
                                            os_itc_msg_send(&ps_itc_msg, EPS_TASK, os_send_itc_wait);
                                            ps_obc_ps_hw_pwr_on_rsp_enc(&data, &data_len, 0,0);
                                        }
                                        else
                                        {
                                            /** TBD: Enum for failure status to PS */
                                            ps_obc_ps_hw_pwr_on_rsp_enc(&data, &data_len, 0,4);
                                            os_free(eps_req);
                                        }
                                    }
                                    else
                                    {
                                        DEBUG_CPRINT(("Malloc failed in PS_OBC_PS_HW_PWR_ON_CMD\n"));
                                        log_id(LOG_ERROR,LOG_IPCC,Malloc_failed_in_PS_OBC_PS_HW_PWR_ON_CMD);
                                        ps_obc_ps_hw_pwr_on_rsp_enc(&data, &data_len, 0,1);
                                    }
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_PS_HW_PWR_OFF_CMD:
                                {
                                    /** Send ITC to EPS for payload power off */
                                    uint32_t *eps_req = os_malloc(sizeof(uint32_t) * 2);
                                    if(eps_req)
                                    {
                                        eps_req[0] = obc_get_eps_chnl_id_from_pld_hw_id(ps_hw_id);
                                        if(MAX_SAT_DEV_CNT > eps_req[0])
                                        {
                                            eps_req[1] = PWR_OFF;
                                            os_itc_msg_handle_t ps_itc_msg;
                                            ps_itc_msg.Msg_id = EPS_SET_CHNL_STATE;
                                            ps_itc_msg.src_entity = OBC_IPCC_SEND;
                                            ps_itc_msg.Msg_len = sizeof(uint32_t) * 2;
                                            ps_itc_msg.pld.pld_ptr = (void*)eps_req;
                                            os_itc_msg_send(&ps_itc_msg, EPS_TASK, os_send_itc_wait);
                                            ps_obc_ps_hw_pwr_off_rsp_enc(&data, &data_len, 0);
                                        }
                                        else
                                        {
                                            ps_obc_ps_hw_pwr_off_rsp_enc(&data, &data_len, 4);
                                            os_free(eps_req);
                                        }
                                    }
                                    else
                                    {
                                        DEBUG_CPRINT(("Malloc failed in PS_OBC_PS_HW_PWR_OFF_CMD\n"));
                                        log_id(LOG_ERROR,LOG_IPCC,Malloc_failed_in_PS_OBC_PS_HW_PWR_OFF_CMD);
                                        ps_obc_ps_hw_pwr_off_rsp_enc(&data, &data_len, 1);
                                    }
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_OBC_APP_ID_LIST_REQ:
                                {
                                    num_app_id = 5;
                                    //Frame structure - Number of APP + 2 Byte APP ID + 2 Byte Peer APP ID + ....
                                    buff_len = (1+(2+2)*num_app_id);
                                    app_id_list_ptr = os_malloc(buff_len);
                                    *app_id_list_ptr = num_app_id;
                                    ps_obc_obc_app_id_list_rsp_enc(&data, &data_len,app_id_list_ptr,buff_len);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_OBC_HW_ID_LIST_REQ:
                                {
                                    obc_icd_rsp_enc_skt_srv_num_hw = 5;
                                    //Frame structure - Number of HW + 2 Byte HW ID + ....
                                    buff_len = (1+(2*obc_icd_rsp_enc_skt_srv_num_hw));
                                    hw_id_list_ptr = os_malloc(buff_len);
                                    *hw_id_list_ptr = obc_icd_rsp_enc_skt_srv_num_hw;
                                    ps_obc_obc_hw_id_list_rsp_enc(&data, &data_len,hw_id_list_ptr,buff_len);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            case PS_OBC_OBC_APP_QoS_PRI_LIST_REQ:
                                {
                                    total_app_id = 5;
                                    //Frame structure - Number of APP + 2 Byte APP ID + 1 Byte APP ID QoS + 1 Byte APP ID PWD + ....
                                    obc_app_qos_pri_len = (1+(2+1+1)*total_app_id);
                                    obc_app_qos_pri_ptr = os_malloc(obc_app_qos_pri_len);
                                    *obc_app_qos_pri_ptr = total_app_id;
                                    ps_obc_obc_app_qos_pri_list_rsp_enc(&data, &data_len,obc_app_qos_pri_ptr,obc_app_qos_pri_len);
                                    obc_icd_socket_send(data,data_len);
                                    os_free(data);
                                    data = NULL;
                                    break;
                                }
                            default :
                                {
                                    icm_default_rsp_enc_hdlr();
                                }
                        }
                        //            rsp_enc_id = 0;
                        set_enc_id(0);
                    }
                }
                break;
        }
#if 1
        if(ipcc_itc_msg.pld.pld_ptr)
        {
            os_free(ipcc_itc_msg.pld.pld_ptr);
            ipcc_itc_msg.pld.pld_ptr = NULL;
        }
#endif

    }
}


void obc_file_rx_init(void)
{
    ft_pld_tx.send_request = 0;


//    ft_register_obc_trasnmitter_cblk(ft_payload_obc_sdram);
//    ft_register_obc_flashbusy_sts_cblk(obc_flash_handler_busycheck);

//	ft_register_receiver_app(APP_ID, app1234_notificataion_api_dwld);

}


void obc_encode_icd_cmd(uint16 cmd_id, uint16 arg1, uint8_t *tc_data)
{
    uint8 *data, *buf_ptr = NULL;
    uint16 *app_id_info_ptr, *hw_id_info_ptr = NULL;
    uint16 data_len;
    /*Control variable - Increments on every command or notification or request sent*/
    exo_sw_dbg.ipcc_dbg.ipcc_cmd_ntf_req_sent++;
    switch(cmd_id)
    {
        case OBC_PS_PWR_OFF_CMD:
            {
                ppoi.shut_tmr_min = 0;
                ppoi.shut_tmr_sec = 2;
                ppoi.shut_tmr_ms = 0;
                ppoi.shut_purpose = ICM_SP_LOW_BTRY;
                obc_ps_pwr_off_cmd_enc(&data,&data_len, &ppoi);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_PLD_HW_PWR_OFF_CMD:
            {
                phw_poi.pld_hw_id = 0x4001;
                phw_poi.shut_tmr_min = 2;
                phw_poi.shut_tmr_sec = 40;
                phw_poi.shut_tmr_ms = 200;
                phw_poi.shut_purpose = ICM_SP_LOW_BTRY;
                obc_ps_pld_hw_pwr_off_cmd (&data,&data_len,&phw_poi);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_VM_PWR_OFF_CMD:
            {
                poi.vm_id = arg1;
                poi.shut_tmr_min = 3;
                poi.shut_tmr_sec = 60;
                poi.shut_tmr_ms = 200;
                poi.shut_purpose = ICM_SP_LOW_BTRY;
                DEBUG_CPRINT(("Power OFF VM ID is %hd",poi.vm_id));
                log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,Power_OFF_VM_ID_is__u16_,poi.vm_id);
                obc_ps_vm_pwr_off_cmd (&data,&data_len,&poi);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_VM_PWR_ON_CMD:
            {
                DEBUG_CPRINT(("Power ON VM ID is %hd",arg1));
                log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,Power_ON_VM_ID_is__u16_,poi.vm_id);
                obc_ps_vm_pwr_on_cmd_enc (&data,&data_len,arg1);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_KEEP_ALIVE_REQ:
            {
                obc_ps_keep_alive_req_enc (&data,&data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_PS_APP_ID_LIST_REQ:
            {
                obc_ps_ps_app_id_list_req_enc (&data,&data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_PS_APP_PRI_LIST_REQ:
            {
                obc_ps_ps_app_pri_list_req_enc(&data,&data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_PS_HW_ID_LIST_REQ:
            {
                obc_ps_ps_hw_id_list_req_enc(&data,&data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_PS_HW_PRI_LIST_REQ:
            {
                obc_ps_ps_hw_pri_list_req_enc(&data,&data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_STAGED_TC_CMD:
            {
                if(0 == obc_staged_tc_id)
                {
                    obc_staged_tc_id = 100;
                }
                obc_ps_staged_tc_cmd_enc(&data, &data_len, obc_staged_tc_id);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_GS_PASS_NTF:
            {
                gpi.rem_tmr_min = 5;
                gpi.rem_tmr_sec = 10;
                gpi.rem_tmr_ms = 100;
                gpi.radio_comm_intf_type = ICM_RD_COMM_XBAND;
                obc_ps_gs_pass_ntf_enc(&data,&data_len,&gpi);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_STATE_UPDT_NTF:
            {
                node_state = ICM_NODE_STE_ACT;
                obc_ps_state_updt_ntf(&data,&data_len,node_state);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_RADIO_PWR_ON_NTF:
            {
                obc_ps_radio_pwr_on_ntf_enc(&data,&data_len,1);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_RADIO_PWR_OFF_NTF:
            {
                obc_ps_radio_pwr_off_ntf_enc(&data,&data_len,1);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_OBC_KEEP_ALIVE_NTF:
            {
                obc_ps_obc_keep_alive_ntf_enc (&data,&data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_OBC_APP_ID_LIST_NTF:
            {
                num_app = 5;
                //Frame structure - Number of APP + 2 Byte APP ID + 2 Byte Peer APP ID + ....
                app_info_buff_len = (1+(2+2)*num_app);
                buf_ptr = os_malloc(app_info_buff_len);
                *buf_ptr = num_app;
                app_id_info_ptr = (uint16*)(buf_ptr+1);
                //Refer HW_ID_Mapping XL sheet for information on HW ID list and APP ID list encoding
                //TBD - ICD document need to be updated on the APP ID size information
                *app_id_info_ptr++ = 0x2001;
                *app_id_info_ptr++ = 0x88;
                *app_id_info_ptr++ = 0x2002;
                *app_id_info_ptr++ = 0x89;
                *app_id_info_ptr++ = 0x2003;
                *app_id_info_ptr++ = 0x8a;
                *app_id_info_ptr++ = 0x2004;
                *app_id_info_ptr++ = 0x8b;
                *app_id_info_ptr++ = 0x2005;
                *app_id_info_ptr++ = 0x8c;

                obc_ps_obc_app_id_list_ntf_enc (&data, &data_len, buf_ptr, app_info_buff_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                obc_evnt_trig = OBC_PS_OBC_HW_ID_LIST_NTF;
                obc_encode_icd_cmd(obc_evnt_trig,0,NULL);
                break;
            }
        case OBC_PS_OBC_FIRM_UPDT_NTF:
            {
                obc_ps_obc_frim_updt_ntf_enc (&data,&data_len,1);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_OBC_RST_RECV_UPDT_NTF:
            {
                rru.reset_recovery_state = 1;
                rru.reset_type = 2;
                obc_ps_obc_rst_recv_updt_ntf_enc (&data,&data_len, &rru);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_OBC_HW_ID_LIST_NTF:
            {
                obc_encode_icd_cmd_num_hw = 5;
                //Frame structure - Number of HW + 2 Byte HW ID + 2 Byte HW ID + ....
                hw_info_buff_len = (1+(2*obc_encode_icd_cmd_num_hw));
                buf_ptr = os_malloc(hw_info_buff_len);
                *buf_ptr = obc_encode_icd_cmd_num_hw;
                hw_id_info_ptr = (uint16*)(buf_ptr+1);
                //Refer HW_ID_Mapping XL sheet for information on HW ID list and APP ID list encoding
                //TBD - ICD document need to be updated on the HW ID size information
                *hw_id_info_ptr++ = 0x01;
                *hw_id_info_ptr++ = 0x02;
                *hw_id_info_ptr++ = 0x03;
                *hw_id_info_ptr++ = 0x04;
                *hw_id_info_ptr++ = 0x05;

                obc_ps_obc_hw_id_list_ntf_enc (&data, &data_len, buf_ptr, hw_info_buff_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_OBC_HW_ERR_RECOV_NTF:
            {
                obc_ps_obc_hw_err_recov_ntf_enc(&data, &data_len,2);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }

        case OBC_PS_SIMU_PS_PWR_ON_CMD:
            {
                obc_ps_simu_ps_pwr_on_cmd_enc (&data, &data_len);
                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_UTC_TIME_CMD:
            {
                obc_ps_rtc_time_s time_date_rtc;
                get_crnt_time_date((sys_time_date_s *)&time_date_rtc);
				
				obc_ps_utc_time_s time_date_utc;
                uint16 len = sizeof(obc_ps_utc_time_s);
				
				time_date_utc.year = time_date_rtc.year;
				time_date_utc.month = time_date_rtc.month;
				time_date_utc.date = time_date_rtc.date;
				time_date_utc.hour = time_date_rtc.hour;
				time_date_utc.min = time_date_rtc.min;
				time_date_utc.sec = time_date_rtc.sec;
				DEBUG_CPRINT(("PS UTC Time configuration %d/%d/%d %d:%d:%d\n",\
						time_date_utc.date,time_date_utc.month, time_date_utc.year, \
						time_date_utc.hour, time_date_utc.min, time_date_utc.sec));
                log_id_with_three_arg(LOG_INFO_L1,LOG_IPCC,PS_UTC_Time_Configuration__u8__u8__u16_,time_date_utc.date,time_date_utc.month, time_date_utc.year);
                log_id_with_three_arg(LOG_INFO_L1,LOG_IPCC,PS_UTC_Time_Configuration__u8__u8__u8_,time_date_utc.hour, time_date_utc.min, time_date_utc.sec);
                obc_ps_utc_time_cfg_cmd_enc(&data, &data_len,len,(uint8*)&time_date_utc);

                obc_icd_socket_send(data,data_len);
                os_free(data);
                data = NULL;
                break;
            }
        case OBC_PS_TEMP_INFO:
        {
        	obc_ps_get_temp_info_enc (&data, &data_len);
			obc_icd_socket_send(data,data_len);
			os_free(data);
			data = NULL;
			break;
        }

        case OBC_PS_TIME_INFO:
		{
			obc_ps_get_time_info_enc (&data, &data_len);
			obc_icd_socket_send(data,data_len);
			os_free(data);
			data = NULL;
			break;
		}

        case OBC_PS_CHIP_INFO:
		{
			obc_ps_get_chip_info_enc (&data, &data_len);
			obc_icd_socket_send(data,data_len);
			os_free(data);
			data = NULL;
			break;
		}

        case OBC_PS_EXT_MEM:
		{
			obc_ps_get_ext_mem_enc (&data, &data_len);
			obc_icd_socket_send(data,data_len);
			os_free(data);
			data = NULL;
			break;
		}

        case OBC_PS_GET_SBAND_FIRM_FILES:
   		{

   			obc_ps_get_sband_firm_files(&data, &data_len);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}

        case OBC_PS_SBAND_FIRM_TFTP_STRT:
   		{

   			obc_ps_sband_firm_tftp_strt(&data, &data_len, tc_data);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}

        case OBC_PS_DEL_SBAND_FIRM_FILE:
   		{

   			obc_ps_del_sband_firm_file(&data, &data_len, tc_data);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}
        case OBC_PS_CURR_TIME_NTF:
   		{
   			obc_ps_curr_time_ntf_enc(&data, &data_len, tc_data);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}
        case OBC_PS_GNSS_LOC_NTF:
   		{
   			obc_ps_gnss_loc_ntf_enc(&data, &data_len, tc_data);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}
        case OBC_PS_GNSS_TLE_DATA_NTF:
   		{
   			obc_ps_gnss_tle_data_ntf_enc(&data, &data_len, tc_data);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}
        case OBC_PS_GNSS_COMPUTE_TLE:
   		{
   			obc_ps_gnss_compute_tle_enc(&data, &data_len, tc_data);
   			obc_icd_socket_send(data,data_len);
   			os_free(data);
   			data = NULL;
   			break;
   		}
        default:
            {
                DEBUG_CPRINT(("Encoder not enabled for IPCC ID %hd. Please retry\n",cmd_id));
                log_id_with_one_arg(LOG_ERROR,LOG_IPCC,Encoder_not_enabled_for_IPCC_ID__u16_,cmd_id);
            }
    }
}

uint8_t socket_error_cnt = 0;
uint8_t lwip_reset_flag = 0;
void obc_icd_socket_listen_server_thread (void * unused)
{
    obc_server_param params;  
    static uint16_t                       PLACE_IN_EXT_RAM_MEM ipcc_buff[SRS4_CAN_MTU];
#ifdef LINUX_TEMP_PORT
    params.port = (icd_soc_inf.port);
    params.addr = inet_addr(icd_soc_inf.ip_addr);
#else
    params.port = PS_SRVR_PORT;
    ip4_addr_t usb_ipaddr;

#ifdef PSOBC_ETH_EN
    IP4_ADDR(&usb_ipaddr, ETH_IP_ADDR0, ETH_IP_ADDR1, ETH_IP_ADDR2, ETH_IP_ADDR3);
#else
    IP4_ADDR(&usb_ipaddr, USB_IP_ADDR0, USB_IP_ADDR1, USB_IP_ADDR2, USB_IP_ADDR3);
#endif
    params.addr =usb_ipaddr.addr;
#endif

    params.ipcc_frame = (s_ipcc_frame *) os_malloc(sizeof(s_ipcc_frame));
    params.ipcc_frame->cmac_hmac = (uint8 *) os_malloc(SHA256_HASH_SIZE);
    params.ipcc_frame->ipcc_data = (uint8 *) ipcc_buff;
    icm_data_dec_hdlr_map();
    while(1)
    {
        obc_icd_app_socket_server_init(params.addr, params.port, params.ipcc_frame);
        socket_error_cnt++;
        if(socket_error_cnt > LWIP_RESET_CNT_THRES)
        {
            lwip_reset_flag = 1;
        }

    }

}

void obc_icd_socket_send(uint8 *data, uint16 data_len)
{
    s_ipcc_frame *ipcc_orig_app;
    //int32 port = atoi(icd_tx_soc_inf.port_num);
    //int32 addr = inet_addr(icd_tx_soc_inf.ip_addr);
    uint8 *dst;
    uint16 ipcc_len = data_len;
    int32 size = 0;
    //uint32 loop = 0;

    /* Encryption related params */
    s_ipcc_crypt_params param;
    uint8 key[] = {0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                   0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

    uint8 iv[16] = {0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

    os_memcpy(param.iv, iv, 16);
    param.key_size = 256;
    param.key = (unsigned char *)os_malloc(param.key_size);
    os_memcpy(param.key, key, param.key_size);
    param.encrypt_mode = IPCC_CRYPT_AES_CFB8;
    ipcc_orig_select_encryption(&param);

    /* Send buffer and frame memory allocations */
    ipcc_orig_app = (s_ipcc_frame *) os_malloc(sizeof(s_ipcc_frame));
    dst = (unsigned char *) os_malloc(sizeof(s_ipcc_frame)+ipcc_len);

    ipcc_orig_select_encryption(&param);
    ipcc_orig_init(ipcc_orig_app);
    //ipcc_orig_reset_seq_no();
    ipcc_orig_cfg_sof(ipcc_orig_app, 0xA5);
	//Encryption is disable for increase ftm throughtput
    ipcc_orig_cfg_ipcc_ctrl(ipcc_orig_app, IPCC_ENCRPT);
    ipcc_orig_cfg_qos(ipcc_orig_app, 1);
    ipcc_orig_cfg_sa_id(ipcc_orig_app, 1);
    ipcc_orig_cfg_da_id(ipcc_orig_app, 13);
    ipcc_orig_cfg_ipcc_id(ipcc_orig_app, 24);

    ipcc_orig_cfg_ipcc_len(ipcc_orig_app, ipcc_len);
    ipcc_orig_cfg_ipcc_data (ipcc_orig_app, data);
 //   DEBUG_CPRINT(("ICM Encoded byte stream: "));
 //   for(loop = 0; loop < ipcc_len; loop++)
 //           DEBUG_CPRINT(("%x ", data[loop]));
 //   DEBUG_CPRINT(("\n"));
    //ipcc_orig_app->cmac_hmac = (uint8_t *) os_malloc(SHA256_HASH_SIZE);
    bzero(dst, size);
    size = ipcc_pack(dst, ipcc_orig_app);
 //   DEBUG_CPRINT(("ICM Complete frame: "));
 //   for(loop = 0; loop < size; loop++)
 //           DEBUG_CPRINT(("%x ", dst[loop]));
 //   DEBUG_CPRINT(("\n"));
    size = write(icdSocket, dst, size);
    os_free(ipcc_orig_app);
    ipcc_orig_app = NULL;
    os_free(dst);
    dst = NULL;
    os_free(param.key);
    param.key = NULL;
    DEBUG_CPRINT(("[SOCKET_ICD] Successfully transferred data of size %d\n",size));
    //close(icdSocket);
    //size = tcp_send(addr, port, dst, size);
    return;
}


uint8 icd_rcv_buffer[IPCC_LENGTH_MAX];
uint8 icd_residue_buffer[IPCC_LENGTH_MAX];
uint16 icd_residue_len = 0;

void obc_icd_app_socket_server_init(uint32 addr, uint32 port, s_ipcc_frame *ipcc_orig)
{
    int32 sockfd=0, ret,maxsd=0,sd;
    struct sockaddr_in serverAddr={0};
    int32 i, socketcount, bytesize;
    struct sockaddr_in newAddr={0};
    int32 status = -1;
    int32 unpacked_size = -1;
    fd_set readfds;
    FD_ZERO(&readfds);
    uint8 *buffer = NULL;

    socklen_t addr_size=0;


    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if(sockfd < 0){
        DEBUG_CPRINT(("OBC APP: [-]Error in creating ICD Socket.\n"));
        log_id(LOG_ERROR,LOG_IPCC,Error_in_creating_ICD_socket);
        //exit(1);
    }
    DEBUG_CPRINT(("OBC APP: [+]Server Socket is created.\n"));
        log_id(LOG_ERROR,LOG_IPCC,Server_socket_is_created);

    memset(&serverAddr, '\0', sizeof(serverAddr));
    serverAddr.sin_family = AF_INET;
    serverAddr.sin_port = htons(port);
    serverAddr.sin_addr.s_addr = addr;

    for (i = 0; i < ICD_CLIENTS_CNT; i++)
    {
        clientsocket[i] = 0;
    }

    ret = bind(sockfd, (struct sockaddr*)&serverAddr, sizeof(serverAddr));
    if(ret < 0){
        DEBUG_CPRINT(("OBC APP: [-]Error in binding ICD Socket..\n"));
        log_id(LOG_ERROR,LOG_IPCC,Error_in_binding_ICD_socket);
        //exit(1);
    }

    if(listen(sockfd, ICD_CLIENTS_CNT) == 0){
        DEBUG_CPRINT(("OBC APP: [+]Listening for ICD Socket connection request....\n"));
        log_id(LOG_INFO_L1,LOG_IPCC,Listening_for_ICD_Socket_connection_request);
    }else
    {
        DEBUG_CPRINT(("OBC APP: [-]Error in listening to ICD Socket.\n"));
        log_id(LOG_ERROR,LOG_IPCC,Error_in_listening_to_ICD_Socket);
    }

    while(1)
    {
        bzero(icd_rcv_buffer, sizeof(icd_rcv_buffer));
        FD_ZERO(&readfds);
        FD_SET( sockfd, &readfds);
        maxsd = sockfd;

        for(i=0;i<ICD_CLIENTS_CNT;i++)
        {
            sd = clientsocket[i];
            if(sd>0)
                FD_SET(clientsocket[i],&readfds);
            if(sd>maxsd)
            {
                maxsd = sd;
            }
        }

        socketcount = select( maxsd+1, &readfds, NULL, NULL, NULL );

        if(socketcount<1)
        {
            DEBUG_CPRINT(("OBC APP: [-]Error in selecting ICD socket"));
            log_id(LOG_ERROR,LOG_IPCC,Error_in_selecting_to_ICD_Socket);
        }

        if(FD_ISSET(sockfd, &readfds))
        {
                icdSocket = accept(sockfd, (struct sockaddr*)&newAddr, &addr_size);

                if(icdSocket < 0)
                {
                    DEBUG_CPRINT(("OBC APP: [-]Error in accepting ICD Socket.\n"));
                    log_id(LOG_ERROR,LOG_IPCC,Error_in_accepting_ICD_Socket);
                    break;
                    //exit(1);
                }
                else
                {
                    DEBUG_CPRINT(("OBC APP: ICD Socket Accept success\n"));
                    log_id(LOG_INFO_L1,LOG_IPCC,ICD_Socket_accept_success);
                }
                //DEBUG_CPRINT(OBC APP: [+]Connection accepted from %s:%d\n",
                //inet_ntoa(newAddr.sin_addr), ntohs(newAddr.sin_port)));
                for(i=0;i<ICD_CLIENTS_CNT;i++)
                {
                    if(clientsocket[i]==0)
                    {
                        clientsocket[i]=icdSocket;
                        break;
                    }
                }
        }
        else
        {
            for(i=0;i<ICD_CLIENTS_CNT;i++)
            {
                sd = clientsocket[i];
                if(FD_ISSET(sd, &readfds))
                {
                    bytesize = recv(sd, icd_rcv_buffer, IPCC_LENGTH_MAX,MSG_DONTWAIT);//MSG_WAITALL
                     if(bytesize==0)
                    {
                        DEBUG_CPRINT(("Recieve bytesize zero\n"));
                        log_id(LOG_INFO_L1,LOG_IPCC,Receive_bytesize_zero);
                        close(sd);
                        clientsocket[i]=0;
                        icd_residue_len = 0;
                        /*Control variable - Increments on every failure of IPCC receive*/
                        exo_sw_dbg.ipcc_dbg.ipcc_rcv_fail++;
                    }
                    else if(bytesize>0)
                    {
                        icdSocket = sd;
                        /* Trigger TM encoding */
                        DEBUG_CPRINT(("[SOCKET_ICD] Successfully Received data .. %d\n",bytesize));
                        log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,Successfully_Received_data__u32_,bytesize);
#if 0
                        status=ipcc_unpack_trigger((const unsigned char *)buffer,
                                                   ipcc_orig);
                         if(status < 0)
                         {
                             DEBUG_CPRINT(("OBC APP: [-]Error in IPCC unpack. Exiting thread\n"));
                    //         os_thread_delete(NULL);
                         }
#else

                         if(0 != icd_residue_len)
                         {
                             os_memcpy(&icd_residue_buffer[icd_residue_len], icd_rcv_buffer, bytesize);
                             bytesize = bytesize + icd_residue_len;
                             buffer = icd_residue_buffer;
							 icd_residue_len = 0;
                         }
                         else
                         {
                             buffer = icd_rcv_buffer;
                         }

                         /*Control variable - Increments on every successful IPCC receive*/
                         exo_sw_dbg.ipcc_dbg.ipcc_rcv_succ++;
                         /**  - Reset this to zero before processing IPCC */
                         unpacked_size = 0;
                         do
                         {

                             status = ipcc_unpack_trigger((const unsigned char *)&buffer[unpacked_size],
                                     ipcc_orig, bytesize - unpacked_size);

                             /** Status holds the number ot bytes unpacked on succes case else error code */
                             if(IPCC_FULL_FRAME_NOT_RCVD == status)
                             {
                                 icd_residue_len = bytesize - unpacked_size;
                                 os_memcpy(icd_residue_buffer, &buffer[unpacked_size], icd_residue_len);
                                 DEBUG_CPRINT(("OBC APP: [-]Full frame not receivevd Remaing Len:- %d", icd_residue_len));
                                 log_id_with_one_arg(LOG_ERROR,LOG_IPCC,Full_frame_not_received_Remaining_Len__u16_,icd_residue_len);
                                 break;
                             }
                             else if(status < 0)
                             {
                                 icd_residue_len = 0;
                                 DEBUG_CPRINT(("OBC APP: [-]Error in IPCC unpack. Exiting thread\n"));
                                 log_id(LOG_ERROR,LOG_IPCC,Error_in_IPCC_unpack_Exiting_thread);
                                 //         os_thread_delete(NULL);
                                 break;
                             }
                             unpacked_size += status;
                             DEBUG_CPRINT(("OBC APP: Total Byte size %d remaining Byte size %d\n",\
                                         bytesize, (bytesize - unpacked_size)));
                             log_id_with_two_arg(LOG_INFO_L1,LOG_IPCC,Total_Byte_size__u32__u32_, bytesize, (bytesize - unpacked_size));

                         }while(unpacked_size < bytesize);
#endif
                    }
                     else
                     {
                         //Socket might have closed
                     }

               }
            }
        }
    }
    close(sockfd);
}

int obc_icd_print_data( s_ipcc_frame * ipcc_frame)
{
    s_ipcc_crypt_params param;
    uint8 key[] = {0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
                   0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                   0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

    uint8 iv[16] = {0xff, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
                    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f};

    s_ipcc_ctrl ctrl_param;
    uint16 ipcc_len = 0;
    uint16 seq_no = 0;
    int loop = 0;
    //DEBUG_CPRINT(("OBC APP: Triggered print data function \n"));
    if( NULL != ipcc_frame && NULL != ipcc_frame->ipcc_data)
    {
        ipcc_term_extract_seq_no(ipcc_frame, &seq_no);
        obc_icd_validate_seq_num(seq_no);
        ipcc_term_extract_ipcc_ctrl(ipcc_frame, &ctrl_param);
        ipcc_term_extract_ipcc_len(ipcc_frame, &ipcc_len);
        if(ctrl_param.encrypt)
        {
            DEBUG_CPRINT(("OBC APP: Received Data is encrypted \n"));
            log_id(LOG_INFO_L1,LOG_IPCC,Received_data_is_encrypted);
            os_memcpy(param.iv, iv, 16);
            param.key_size = 256;
            param.key = (unsigned char *)os_malloc(param.key_size);
            os_memcpy(param.key, key, param.key_size);
            param.encrypt_mode = IPCC_CRYPT_AES_CFB8;
            ipcc_orig_decrypt_data(&param,
                                (const unsigned char *)ipcc_frame->ipcc_data,ipcc_len,
                                (unsigned char *)ipcc_frame->ipcc_data);
//           DEBUG_CPRINT(("OBC APP: Decrypted data is "));
//            for(loop = 0; loop < ipcc_len; loop++)
//               DEBUG_CPRINT(("%x ", ipcc_frame->ipcc_data[loop]));
//           DEBUG_CPRINT(("\n"));
            ps_icm_crrn_id_dec((const unsigned char*)ipcc_frame->ipcc_data, ipcc_len);
            os_free(param.key);
            param.key = NULL;

        }
        else
        {
            DEBUG_CPRINT(("OBC APP: Received Data is unencrypted \n"));
            log_id(LOG_INFO_L1,LOG_IPCC,Received_data_is_unencrypted);
            DEBUG_CPRINT(("OBC APP: ipcc_seqno is %d \n", ipcc_frame->seq_no));
            log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,Ipcc_seqno_is__u16_,ipcc_frame->seq_no);
            DEBUG_CPRINT(("OBC APP: Data is "));
            log_id(LOG_INFO_L1,LOG_IPCC,Data_is);
         //   for(loop = 0; loop < ipcc_len; loop++)
         //       DEBUG_CPRINT(("%x ", ipcc_frame->ipcc_data[loop]));
            log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,_u8_,ipcc_frame->ipcc_data[loop]);
         //   DEBUG_CPRINT(("\n"));
            ps_icm_crrn_id_dec((const unsigned char*)ipcc_frame->ipcc_data, ipcc_len);
        }
    }
    return 0;
}

void obc_icd_validate_seq_num(uint16 actual_seq_no)
{
    static uint16 expected_seq_no = 1;
    uint32 missing_frames , i = 0;
    if(expected_seq_no != actual_seq_no)
    {
      if(actual_seq_no > expected_seq_no)
      {
          missing_frames = actual_seq_no - expected_seq_no;
          for (i=0; i<missing_frames; i++)
          {
              DEBUG_CPRINT((" Warning !!! Missing frame. Sequence number : %d \n",expected_seq_no));
              log_id_with_one_arg(LOG_INFO_L1,LOG_IPCC,Warning_Missing_frame_sequence_number__u16_,expected_seq_no);
              expected_seq_no++;
          }
      }
      else
      {
      }

    }
    expected_seq_no++;
}
#if 0
int32_t tcp_send(uint32_t addr, uint32_t port, uint8_t *data, uint32_t size)
{
    int32_t status;
    int sockfd;
    struct sockaddr_in servaddr;

    // socket create and verification
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd == -1) {
        DEBUG_CPRINT(("socket creation failed...\n"));
        status = sockfd;
    }
    else
    {
        bzero(&servaddr, sizeof(servaddr));

        // assign IP, PORT
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = addr;
        servaddr.sin_port = htons(port);

        //DEBUG_CPRINT((" connecting to server .."));
        // connect the client socket to server socket
        while (connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0)
        {
            //DEBUG_CPRINT(("."));
            /* wait for server */
        }

        //DEBUG_CPRINT(("SOCKET: connected to the server..\n"));
        status = write(sockfd, data, size);
        DEBUG_CPRINT(("SOCKET: data transferred .. %ld\n", status));


        // close the socket
        close(sockfd);
    }
    return status;
}

#endif

int ipcc_send_ipc_msg_pld(uint16_t msg_id, uint16 dst_id, uint8_t *pld, uint8_t pld_size, uint16 src_id)
{
    os_itc_msg_handle_t ipcc_send_ipc;

    // Prepare IPC data
    ipcc_send_ipc.src_entity = src_id;

    //TODO - Update value with macro - This should be taken care once header file is available with macro when porting is done
    ipcc_send_ipc.Msg_id = msg_id;
    ipcc_send_ipc.Msg_len = pld_size;
    if(pld_size)
    {
        ipcc_send_ipc.pld.pld_ptr = os_malloc(pld_size);
        os_memcpy(ipcc_send_ipc.pld.pld_ptr,pld,pld_size);
    }
    else
    {
        ipcc_send_ipc.pld.pld_ptr = NULL;
    }

    int ipcc_ipc_sts = 0;
    ipcc_ipc_sts = os_itc_msg_send(&ipcc_send_ipc,dst_id,os_send_itc_wait);
    if(ral_success == ipcc_ipc_sts)
    {

    }
    else
    {
        os_free(ipcc_send_ipc.pld.pld_ptr);
        DEBUG_CPRINT(("OBC APP ITC Message send fail\n"));
        log_id(LOG_INFO_L1,LOG_IPCC,OBC_APP_ITC_Message_send_fail);
    }
    return ipcc_ipc_sts;
}

void obc_icd_vm_pwr_ctrl(uint16_t _vm_id,uint8_t _on_off)
{
	if(_on_off == 1)
	{
		ps_vm_id = _vm_id;
		obc_encode_icd_cmd(OBC_PS_VM_PWR_ON_CMD,_vm_id,NULL);
	}
	else if(_on_off == 0)
	{
        poi.vm_id = _vm_id;
        poi.shut_tmr_min = 0;
        poi.shut_tmr_sec = 0;
        poi.shut_tmr_ms = 0;
        poi.shut_purpose = ICM_SP_SYS_SHUT;
		obc_encode_icd_cmd(OBC_PS_VM_PWR_OFF_CMD,_vm_id,NULL);
	}
}


void obc_icd_ps_stgd_tc(uint32_t _stgd_tc_id)
{
	obc_staged_tc_id = _stgd_tc_id;
	obc_encode_icd_cmd(OBC_PS_STAGED_TC_CMD,0,NULL);
}
uint8 obc_get_eps_chnl_id_from_pld_hw_id(uint16 pld_hw_id)
{
    switch(pld_hw_id)
    {
        case PLD_HW_ID_TRANS:
            {
                return HW_PL_TRANSCELESTIAL;
            }
            break;
        case PLD_HW_ID_NETRA:
            {
                return HW_PL_NETRA;
            }
            break; 
        case PLD_HW_ID_SCANWAY:
            {
                return HW_PL_SCANWAY;
            }
            break; 
        default:
            {
                return MAX_SAT_DEV_CNT;
            }
            break;
    }
}
