#include "obc_intf_ctrl_msg.h"
#include "obc_tc_tm.h"
#include "exo_common.h"
#include "obc_icd.h"
#include "obc_ipc.h"
#include "exo_tctm_ipc.h"
#include "obc_mcu_info.h"
#include "oem7_gps.h"
#include "gps_app.h"
#include "exo_osal.h"

uint8_t icd_socket_conn_sts = 0;
/*!
 * @brief Function pointer declaration for decoder APIs
 */
int8 (*icm_data_dec_fn[ICM_CRRN_ID_MAX]) (const uint8 *data, uint16 len) PLACE_IN_EXT_RAM_MEM;

/*!
 * @brief Global variables declarations for storing decoded response
 */
//extern uint16 rsp_enc_id;
extern uint16 obc_evnt_trig;
extern uint32 tm_rsp_id;
static icm_trgt_pt_req_s tpr;
icm_reg_orbt_trig_s rot;
icm_reg_grnd_stn_ps_ntf_s rgspn;
icm_tm_pld_info_s tm_pld_info;
uint8 ps_pwr_ste;
uint16 ps_hw_id;
#if 0
uint8 ps_pld_hw_pwr_off_rsp;
#endif
uint8 ps_shut_rsp;
uint8 ps_vm_pwr_off_rsp;
uint8 ps_vm_pwr_on_rsp;

uint8 ps_keep_alive_rsp_ind;
uint8 obc_ps_grnd_stn_pass_ntf_rsp;
uint8 obc_ps_radio_pwr_on_ntf_rsp;
uint8 obc_ps_radio_pwr_off_ntf_rsp;
uint8 *tc_tm_rsp_ptr; uint16 tc_tm_rsp_len;
uint16 recovered_hardware_id;
uint8 radio_id;
ps_shutdown_ntf psd;
schd_ps_pwr_on_req spor;
radio_rx_enbl_dsbl radio_info;
uint16 buf_len;
uint8* buf_ptr;
uint8 num_of_ent;
uint8* app_id_qos_pwd_ptr;
uint8* hw_id_qos_pwd_ptr;

/*********************************************************************************/
/************** Command, Request, Notification Encoder Functions *****************/
/*********************************************************************************/

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS power off command
 */
int8 obc_ps_pwr_off_cmd_enc (uint8 **data, uint16* len, icm_ps_pwr_off_info_s *ppoi)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 5;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_PWR_OFF_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = ppoi->shut_tmr_min; *data += 1;
    **data = ppoi->shut_tmr_sec; *data += 1;
    os_memcpy(*data,&ppoi->shut_tmr_ms,2); *data += 2;
    **data = ppoi->shut_purpose;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS keep alive request from OBC
 */
int8 obc_ps_keep_alive_req_enc (uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    hdr.crrn_id = OBC_PS_KEEP_ALIVE_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS APP ID list request from OBC
 */
int8 obc_ps_ps_app_id_list_req_enc (uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    hdr.crrn_id = OBC_PS_PS_APP_ID_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_app_pri_list_req_enc(uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    hdr.crrn_id = OBC_PS_PS_APP_PRI_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_id_list_req_enc(uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    hdr.crrn_id = OBC_PS_PS_HW_ID_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_pri_list_req_enc(uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    hdr.crrn_id = OBC_PS_PS_HW_PRI_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

int8 obc_ps_staged_tc_cmd_enc(uint8 **data, uint16* len, uint32 staged_tc_id)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 4;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_STAGED_TC_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,&staged_tc_id,4); *data += 4;

    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Ground station pass notification request
 */
int8 obc_ps_gs_pass_ntf_enc (uint8 **data, uint16* len, icm_gs_pass_info_s *gpi)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 5;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_GS_PASS_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = gpi->rem_tmr_min; *data += 1;
    **data = gpi->rem_tmr_sec; *data += 1;
    os_memcpy(*data,&gpi->rem_tmr_ms,2); *data += 2;
    **data = gpi->radio_comm_intf_type;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * OBC state update notification
 */
int8 obc_ps_state_updt_ntf (uint8 **data, uint16* len, uint8 ste_info)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_STATE_UPDT_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = ste_info; *data += 1;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Radio power ON notification from OBC to PS
 */
int8 obc_ps_radio_pwr_on_ntf_enc (uint8 **data, uint16* len, uint8 radio_id)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_RADIO_PWR_ON_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = radio_id;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Radio power OFF notification from OBC to PS
 */
int8 obc_ps_radio_pwr_off_ntf_enc (uint8 **data, uint16* len, uint8 radio_id)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_RADIO_PWR_OFF_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = radio_id;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * OBC alive notification to PS
 */
int8 obc_ps_obc_keep_alive_ntf_enc (uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_OBC_KEEP_ALIVE_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * OBC notification of APP ID list
 */
int8 obc_ps_obc_app_id_list_ntf_enc (uint8 **data, uint16* len, uint8* app_id_info_buff, uint32 buf_len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = buf_len;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_OBC_APP_ID_LIST_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data, app_id_info_buff, buf_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_obc_frim_updt_ntf_enc (uint8 **data, uint16* len, uint8 frim_updt_state)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_OBC_FIRM_UPDT_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = frim_updt_state;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_obc_rst_recv_updt_ntf_enc (uint8 **data, uint16* len, obc_rst_recv_updt* rru)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 2;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_OBC_RST_RECV_UPDT_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,rru,sizeof(obc_rst_recv_updt));

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * OBC notification of HW ID list
 */
int8 obc_ps_obc_hw_id_list_ntf_enc (uint8 **data, uint16* len, uint8* hw_id_info_buff, uint32 buf_len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = buf_len;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_OBC_HW_ID_LIST_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data, hw_id_info_buff, buf_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_obc_hw_err_recov_ntf_enc (uint8 **data, uint16* len, uint16 hw_id_rcvd)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 1;
    *len = (hdr_len + data_len);
    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = OBC_PS_OBC_HW_ERR_RECOV_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,&hw_id_rcvd,1);
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}
/*!
 * @brief This API encodes the Interface Control Messsage for
 * Payload Hardware power off command
 */
int8 obc_ps_pld_hw_pwr_off_cmd (uint8 **data, uint16* len, icm_pld_hw_pwr_off_info_s *phw_poi)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 7;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_PLD_HW_PWR_OFF_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,&phw_poi->pld_hw_id,2); *data += 2;
    **data = phw_poi->shut_tmr_min; *data += 1;
    **data = phw_poi->shut_tmr_sec; *data += 1;
    os_memcpy(*data,&phw_poi->shut_tmr_ms,2); *data += 2;
    **data = phw_poi->shut_purpose;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Massless payload VM power off command
 */
int8 obc_ps_vm_pwr_off_cmd (uint8 **data, uint16* len, icm_vm_pwr_off_info_s *poi)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = sizeof(icm_vm_pwr_off_info_s);
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_VM_PWR_OFF_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,poi,data_len);
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}
/*!
 * @brief This API encodes the Interface Control Messsage for
 * Massless payload VM power ON command
 */
int8 obc_ps_vm_pwr_on_cmd_enc (uint8 **data, uint16* len, uint16 ps_vm_id)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 6;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    os_memset(hdr_data,0, 4);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_VM_PWR_ON_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    DEBUG_CPRINT(("Inside encoding Function***\n Power OFF VM ID is %hd \n HDR %x\n", ps_vm_id,*hdr_data));
                    
    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,&ps_vm_id,2);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * TC TM Message from OBC to PS
 */
int8 obc_ps_tc_tm_msg_cmd_enc (uint8 **data, uint16* len, \
        icm_tc_pld_info_s *tc_pld_info)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = (6+tc_pld_info->tc_pld_len);
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    memset((void*)hdr_data,0,(*len));
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_TC_TM_MSG_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,&tc_pld_info->tc_id,sizeof(tc_pld_info->tc_id)); *data += sizeof(tc_pld_info->tc_id);
    **data = tc_pld_info->src_id; *data += 1;
    **data = tc_pld_info->dst_id; *data += 1;
    os_memcpy(*data,&tc_pld_info->tc_pld_len,sizeof(tc_pld_info->tc_pld_len)); *data+=sizeof(tc_pld_info->tc_pld_len);
    os_memcpy(*data,tc_pld_info->tc_pld_buff,tc_pld_info->tc_pld_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * FTP TC TM Message from OBC to PS
 */
int8 obc_ps_ftp_msg_cmd_enc (uint8 **data, uint16* len, \
        icm_tc_pld_info_s *tc_pld_info)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = (6+tc_pld_info->tc_pld_len);
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    memset((void*)hdr_data,0,(*len));
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_FTP_MSG_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,&tc_pld_info->tc_id,sizeof(tc_pld_info->tc_id)); *data += sizeof(tc_pld_info->tc_id);
    **data = tc_pld_info->src_id; *data += 1;
    **data = tc_pld_info->dst_id; *data += 1;
    os_memcpy(*data,&tc_pld_info->tc_pld_len,sizeof(tc_pld_info->tc_pld_len)); *data += sizeof(tc_pld_info->tc_pld_len);
    os_memcpy(*data,tc_pld_info->tc_pld_buff,tc_pld_info->tc_pld_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * TC TM Message from OBC to PS
 */
int8 obc_ps_simu_ps_pwr_on_cmd_enc (uint8 **data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 0;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_SIMU_PS_PWR_ON_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

int8 obc_ps_get_temp_info_enc(uint8 **data, uint16* len)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = 0;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_TEMP_INFO;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	status = ICM_OK;
	return status;
}

int8 obc_ps_get_time_info_enc(uint8 **data, uint16* len)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = 0;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_TIME_INFO;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	status = ICM_OK;
	return status;
}

int8 obc_ps_get_chip_info_enc(uint8 **data, uint16* len)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = 0;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_CHIP_INFO;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	status = ICM_OK;
	return status;
}

int8 obc_ps_get_ext_mem_enc(uint8 **data, uint16* len)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = 0;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_EXT_MEM;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	status = ICM_OK;
	return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * IQS firmware update - To get list of firmware files available in PS
 */
int8 obc_ps_get_sband_firm_files(uint8 **data, uint16* len)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = 0;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_GET_SBAND_FIRM_FILES;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	status = ICM_OK;
	return status;

}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * IQS firmware update - To start file transfer to IQS through TFTP
 */
int8 obc_ps_sband_firm_tftp_strt(uint8 **data, uint16* len, uint8 *pld_data)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = TFTP_START_TC_DATA_FRAME;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_SBAND_FIRM_TFTP_STRT;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	/* Encode data parameters */
	 *data += hdr_len;
	 os_memcpy(*data,&pld_data[2],TFTP_START_TC_DATA_FRAME);    //First two byte to indicate IPCC command ID

	 *data = (uint8*)hdr_data;


	status = ICM_OK;
	return status;


}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * IQS firmware update - To delete firmware files in PS
 */
int8 obc_ps_del_sband_firm_file(uint8 **data, uint16* len, uint8* pld_data)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = TFTP_FILE_DEL_TC_DATA_FRAME;

	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_DEL_SBAND_FIRM_FILE;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

	*data += hdr_len;
	os_memcpy(*data,&pld_data[2],TFTP_FILE_DEL_TC_DATA_FRAME);                      //First two byte to indicate IPCC command ID

	*data = (uint8*)hdr_data;


	status = ICM_OK;
	return status;

}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Massless payload VM power ON command
 */
int8 obc_ps_xband_cmd_enc(uint8 **data, uint16* len, uint16 data_size, uint8 *data_ptr)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = data_size;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_XBAND_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,data_ptr,data_size);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_utc_time_cfg_cmd_enc(uint8 **data, uint16* len, uint16 data_size, uint8 *data_ptr)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = data_size;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = OBC_PS_UTC_TIME_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,data_ptr,data_size);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}


int8 obc_ps_curr_time_ntf_enc(uint8 **data, uint16* len, uint8_t* pld_data)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = 4;
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_NTF;
	hdr.crrn_id = OBC_PS_CURR_TIME_NTF;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

    *data += hdr_len;
    os_memcpy(*data,pld_data,data_len);

     *data = (uint8*)hdr_data;
	status = ICM_OK;
	return status;
}


int8 obc_ps_gnss_loc_ntf_enc(uint8 **data, uint16* len, uint8_t* pld_data)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = sizeof(gps_loc_info);
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_NTF;
	hdr.crrn_id = OBC_PS_GNSS_LOC_NTF;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

    *data += hdr_len;
    os_memcpy(*data,pld_data,data_len);

     *data = (uint8*)hdr_data;
	status = ICM_OK;
	return status;
}


int8 obc_ps_gnss_tle_data_ntf_enc(uint8 **data, uint16* len, uint8_t* pld_data)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = sizeof(gps_tle_data);
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_NTF;
	hdr.crrn_id = OBC_PS_GNSS_TLE_DATA_NTF;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

    *data += hdr_len;
    os_memcpy(*data,pld_data,data_len);

     *data = (uint8*)hdr_data;
	status = ICM_OK;
	return status;
}

int8 obc_ps_gnss_compute_tle_enc(uint8 **data, uint16* len, uint8_t* pld_data)
{
	int8 status;
	icm_header_s hdr;
	uint16 hdr_len = 4, data_len = sizeof(gps_tle_data);
	*len = (hdr_len + data_len);

	unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
	*data = (uint8*)hdr_data;

	/* Encode header information */
	hdr.crrn_type = CRRN_TYPE_CMD;
	hdr.crrn_id = OBC_PS_GNSS_COMPUTE_TLE;
	hdr.data_len = data_len;

	*hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
			| hdr.crrn_id << CRRN_ID_POS \
			| hdr.data_len << CRRN_DATA_LEN_POS);

    *data += hdr_len;
    os_memcpy(*data,pld_data,data_len);

     *data = (uint8*)hdr_data;
	status = ICM_OK;
	return status;
}
/*********************************************************************************/
/************** Command, Request, Notification Decoder Functions *****************/
/*********************************************************************************/

/*!
 * @brief This API maps the ICM CRRN decoder function pointers
 * to respective CRRN ID
 */
int8 icm_data_dec_hdlr_map(void)
{
    int8 status;
    uint32 i;
    for(i = 0; i< ICM_CRRN_ID_MAX; i++)
    {
        icm_data_dec_fn[i] = icm_default_data_dec;
    }

    /* Decoder handler mapping */

    icm_data_dec_fn[OBC_PS_PWR_OFF_CMD] = obc_ps_pwr_off_rsp_dec;
    icm_data_dec_fn[OBC_PS_VM_PWR_OFF_CMD] = obc_ps_vm_pwr_off_rsp_dec;
    icm_data_dec_fn[OBC_PS_VM_PWR_ON_CMD] = obc_ps_vm_pwr_on_rsp_dec;
#if 0
    icm_data_dec_fn[OBC_PS_PLD_HW_PWR_OFF_CMD] = obc_ps_pld_hw_pwr_off_rsp_dec;
#endif
    icm_data_dec_fn[OBC_PS_TC_TM_MSG_CMD] = obc_ps_tc_tm_msg_rsp_dec;
    icm_data_dec_fn[OBC_PS_FTP_MSG_CMD] = obc_ps_ftp_msg_rsp_dec;
    icm_data_dec_fn[OBC_PS_KEEP_ALIVE_REQ] = obc_ps_keep_alive_rsp_dec;
    icm_data_dec_fn[OBC_PS_GS_PASS_NTF] = obc_ps_grnd_stn_ps_rsp_dec;
    icm_data_dec_fn[OBC_PS_RADIO_PWR_ON_NTF] = obc_ps_radio_pwr_on_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_RADIO_PWR_OFF_NTF] = obc_ps_radio_pwr_off_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_OBC_FIRM_UPDT_NTF] = obc_ps_obc_frim_updt_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_OBC_RST_RECV_UPDT_NTF] = obc_ps_obc_rst_recv_updt_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_OBC_HW_ERR_RECOV_NTF] = obc_ps_obc_hw_err_recov_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_PS_APP_ID_LIST_REQ] = obc_ps_ps_app_id_list_rsp_dec;
    icm_data_dec_fn[OBC_PS_PS_APP_PRI_LIST_REQ] = obc_ps_ps_app_pri_list_rsp_dec;
    icm_data_dec_fn[OBC_PS_PS_HW_ID_LIST_REQ] = obc_ps_ps_hw_id_list_rsp_dec;
    icm_data_dec_fn[OBC_PS_PS_HW_PRI_LIST_REQ] = obc_ps_ps_hw_pri_list_rsp_dec;
    icm_data_dec_fn[OBC_PS_STAGED_TC_CMD] = obc_ps_staged_tc_rsp_dec;
    icm_data_dec_fn[OBC_PS_XBAND_CMD ] = obc_ps_xband_rsp_dec;
    icm_data_dec_fn[OBC_PS_UTC_TIME_CMD] = obc_ps_utc_time_cfg_rsp_dec;
    icm_data_dec_fn[OBC_PS_TEMP_INFO] = obc_ps_get_temp_info_rsp_dec;
    icm_data_dec_fn[OBC_PS_TIME_INFO] = obc_ps_get_time_info_rsp_dec;
    icm_data_dec_fn[OBC_PS_CHIP_INFO] = obc_ps_get_chip_info_rsp_dec;
    icm_data_dec_fn[OBC_PS_EXT_MEM] = obc_ps_get_ext_mem_rsp_dec;
    icm_data_dec_fn[OBC_PS_GET_SBAND_FIRM_FILES] = obc_ps_get_sband_firm_files_res_dec;
    icm_data_dec_fn[OBC_PS_SBAND_FIRM_TFTP_STRT] = obc_ps_sband_firm_tftp_strt_res_dec;
    icm_data_dec_fn[OBC_PS_DEL_SBAND_FIRM_FILE] = obc_ps_del_sband_firm_file_res_dec;

    icm_data_dec_fn[OBC_PS_CURR_TIME_NTF] = obc_ps_curr_time_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_GNSS_LOC_NTF] = obc_ps_gnss_loc_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_GNSS_TLE_DATA_NTF] = obc_ps_gnss_tle_data_ntf_rsp_dec;
    icm_data_dec_fn[OBC_PS_GNSS_COMPUTE_TLE] = obc_ps_gnss_compute_tle_rsp_dec;


    icm_data_dec_fn[PS_OBC_TRGT_POINT_REQ] = ps_obc_trgt_pt_req_dec;
    icm_data_dec_fn[PS_OBC_KEEP_ALIVE_REQ] = ps_obc_keep_alive_req_dec;
    icm_data_dec_fn[PS_OBC_SCHD_PS_PWR_ON_REQ] =  ps_obc_schd_ps_pwr_on_req_dec;
    icm_data_dec_fn[PS_OBC_RADIO_PWR_ON_REQ] =  ps_obc_radio_pwr_on_req_dec;
    icm_data_dec_fn[PS_OBC_OBC_APP_ID_LIST_REQ] = ps_obc_obc_app_id_list_req_dec;
    icm_data_dec_fn[PS_OBC_OBC_HW_ID_LIST_REQ] = ps_obc_obc_hw_id_req_dec;
    icm_data_dec_fn[PS_OBC_OBC_APP_QoS_PRI_LIST_REQ] = ps_obc_obc_app_qos_pri_list_req_dec;
    icm_data_dec_fn[PS_OBC_RADIO_PWR_OFF_CMD] =  ps_obc_radio_pwr_off_cmd_dec;
    icm_data_dec_fn[PS_OBC_RADIO_RX_ENBL_DSBL_CMD] =  ps_obc_radio_rx_enbl_dsbl_cmd_dec;
    icm_data_dec_fn[PS_OBC_REG_ORBIT_TRIG_CMD] = ps_obc_reg_orbit_trig_cmd_dec;
    icm_data_dec_fn[PS_OBC_REG_GRND_STN_PASS_NTF_CMD] = ps_obc_reg_grnd_stn_pass_ntf_cmd_dec;
    icm_data_dec_fn[PS_OBC_RADIO_TX_ENBL_DSBL_CMD] = ps_obc_radio_tx_enbl_dsbl_cmd_dec;
    icm_data_dec_fn[PS_OBC_STATE_UPDT_NTF] = ps_obc_ste_updt_ntf_dec;
    icm_data_dec_fn[PS_OBC_PWR_ON_HNDSK_NTF] = ps_obc_pwr_on_hndske_ntf_dec;
    icm_data_dec_fn[PS_OBC_KEEP_ALIVE_NTF] = ps_obc_keep_alive_ntf_dec;
    icm_data_dec_fn[PS_OBC_RADIO_DATA_TX_CPLT_NTF] = ps_obc_radio_data_tx_cplt_ntf_dec;
    icm_data_dec_fn[PS_OBC_SSD_ERR_NTF] = ps_obc_ssd_err_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_FIRM_UPDT_NTF] = ps_obc_ps_firm_updt_ntf_dec;
    icm_data_dec_fn[PS_OBC_PLD_HW_FIRM_UPDT_NTF] = ps_obc_pld_hw_firm_updt_ntf_dec;
    icm_data_dec_fn[PS_OBC_VM_FIRM_UPDT_NTF] = ps_obc_vm_firm_updt_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_RST_RECV_UPDT_NTF] = ps_obc_ps_rst_rcv_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_APP_ID_LIST_NTF] = ps_obc_ps_app_id_list_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_ID_LIST_NTF] = ps_obc_ps_hw_id_list_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_ERR_RECOV_NTF] = ps_obc_ps_hw_err_recov_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_SHUTDOWN_NTF] =  ps_obc_ps_shutdown_ntf_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_PWR_ON_CMD] = ps_obc_ps_hw_pwr_on_cmd_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_PWR_OFF_CMD] = ps_obc_ps_hw_pwr_off_cmd_dec;
    icm_data_dec_fn[PS_OBC_SBAND_FIRM_TFTP_CPLT] = ps_obc_sband_firm_tftp_cplt_ntf_dec;

    icm_data_dec_fn[PS_OBC_GNSS_LOC_REQ] = ps_obc_gnss_loc_req_dec;
    icm_data_dec_fn[PS_OBC_GET_CURR_TIME_REQ] =  ps_obc_get_curr_time_req_dec;
    icm_data_dec_fn[PS_OBC_GNSS_PRD_LOC_REQ] = ps_obc_gnss_prd_loc_req_dec;
    icm_data_dec_fn[PS_OBC_GNSS_TLE_DATA_REQ] = ps_obc_gnss_tle_data_req_dec;
    icm_data_dec_fn[PS_OBC_GNSS_PRD_TLE_DATA_REQ] = ps_obc_gnss_prd_tle_data_req_dec;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the CRRN ID when response is received
 */
int8 ps_icm_crrn_id_dec(const uint8 *data, uint16 len)
{
    int8 status;
    obc_pck_data ipcc_cmd_resp;
    icm_header_s hdr;
    unsigned int *hdr_data = (unsigned int*)data;

    /* Decode header information */
    hdr.data_len = (((*hdr_data) & CRRN_DATA_LEN_MASK) >> CRRN_DATA_LEN_POS);
    hdr.crrn_id  = (((*hdr_data) & CRRN_ID_MASK) >> CRRN_ID_POS);
    hdr.crrn_type = (((*hdr_data) & CRRN_TYPE_MASK) >> CRRN_TYPE_POS);
    DEBUG_CPRINT(("Type: %d, ID: %d, Len: %d\n",hdr.crrn_type, hdr.crrn_id, hdr.data_len));

    if(hdr.crrn_id != 5)
    {
    ipcc_cmd_resp.tm_rsp_id = TM_OBC_IPCC_TEST;
    ipcc_cmd_resp.tx_data_len = len+1;
    ipcc_cmd_resp.tx_data = os_malloc(len+1);
    ipcc_cmd_resp.tx_data[0] = OBC_PS_IPCC_RESP_RCV_NTF;
    os_memcpy(&ipcc_cmd_resp.tx_data[1], data, len);
    obc_pack_tm_data(&ipcc_cmd_resp);
    }

    
    icd_socket_conn_sts = 1;
    icm_data_dec_fn[hdr.crrn_id](data,len);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API has the default handling for messages for which decoder
 * are not assigned
 */
int8 icm_default_data_dec(const uint8 *data, uint16 len)
{
    int8 status = ICM_DEC_HDLR_UNASIGN;
    DEBUG_CPRINT(("ICM Decoder handler not assigned for current CRRN ID\n"));
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * Target pointing request from PS
 */
int8 ps_obc_trgt_pt_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    tpr.pld_hw_id = *dp++;
    os_memcpy(&tpr.lat,dp,4); dp +=4;
    os_memcpy(&tpr.longit,dp,4); dp += 4;
    os_memcpy(&tpr.alt,dp,4); dp += 4;
    tpr.act_tmr_min = *dp++;
    tpr.act_tmr_sec = *dp++;
    os_memcpy(&tpr.act_tmr_ms,dp,2);

    //rsp_enc_id = PS_OBC_TRGT_POINT_REQ;
    set_enc_id_indicate(PS_OBC_TRGT_POINT_REQ);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * GNSS location request
 */
int8 ps_obc_gnss_loc_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

//    rsp_enc_id = PS_OBC_GNSS_LOC_REQ;
    set_enc_id_indicate(PS_OBC_GNSS_LOC_REQ);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS keep alive request to OBC
 */
int8 ps_obc_keep_alive_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

//    rsp_enc_id = PS_OBC_KEEP_ALIVE_REQ;
    set_enc_id_indicate(PS_OBC_KEEP_ALIVE_REQ );
    DEBUG_CPRINT(("Keep alive request received from PS\n"));

    status = ICM_OK;
    return status;
}

int8 ps_obc_schd_ps_pwr_on_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */

    os_memcpy(&spor,dp,sizeof(schd_ps_pwr_on_req));
    DEBUG_CPRINT(("schld powr on req sec:%d mins:%d hours:%d days:%d\n",spor.timer_seconds,spor.timer_minutes,spor.timer_hours,spor.timer_days));
    //rsp_enc_id = PS_OBC_SCHD_PS_PWR_ON_REQ;
    set_enc_id_indicate(PS_OBC_SCHD_PS_PWR_ON_REQ );

    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_pwr_on_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */

    radio_id = *dp;
    DEBUG_CPRINT(("OBC powr on req radio id %d\n",radio_id));
    //rsp_enc_id = PS_OBC_RADIO_PWR_ON_REQ;
    set_enc_id_indicate(PS_OBC_RADIO_PWR_ON_REQ );

    status = ICM_OK;
    return status;
}
int8 ps_obc_obc_app_id_list_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

    //rsp_enc_id = PS_OBC_OBC_APP_ID_LIST_REQ;
    set_enc_id_indicate(PS_OBC_OBC_APP_ID_LIST_REQ);

    status = ICM_OK;
    return status;
}
int8 ps_obc_obc_hw_id_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

    //rsp_enc_id = PS_OBC_OBC_HW_ID_LIST_REQ;
    set_enc_id_indicate(PS_OBC_OBC_HW_ID_LIST_REQ);;

    status = ICM_OK;
    return status;
}
int8 ps_obc_obc_app_qos_pri_list_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    //rsp_enc_id = PS_OBC_OBC_APP_QoS_PRI_LIST_REQ;
    set_enc_id_indicate(PS_OBC_OBC_APP_QoS_PRI_LIST_REQ);

    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_pwr_off_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */

    radio_id = *dp;
    DEBUG_CPRINT(("OBC powr of cmd radio id %d\n",radio_id));
    //rsp_enc_id = PS_OBC_RADIO_PWR_OFF_CMD;
    set_enc_id_indicate(PS_OBC_RADIO_PWR_OFF_CMD);

    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_rx_enbl_dsbl_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */

    radio_info.radio_mod_id = *dp++;
    radio_info.radio_rx_enable_disable = *dp;
    DEBUG_CPRINT(("OBC powr of cmd radio id %d enable/disable %d\n",radio_info.radio_mod_id,radio_info.radio_rx_enable_disable));
    //rsp_enc_id = PS_OBC_RADIO_RX_ENBL_DSBL_CMD;
    set_enc_id_indicate(PS_OBC_RADIO_RX_ENBL_DSBL_CMD ); 

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * registration request for alert when specified orbit is reached
 */
int8 ps_obc_reg_orbit_trig_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    rot.pld_hw_id = *dp++;
    os_memcpy(&rot.lat,dp,4); dp += 4;
    os_memcpy(&rot.longit,dp,4); dp += 4;
    os_memcpy(&rot.alt,dp,4); dp += 4;
    rot.alrt_tmr_min = *dp++;
    rot.alrt_tmr_sec = *dp++;
    os_memcpy(&rot.alrt_tmr_ms,dp,2);

    //rsp_enc_id = PS_OBC_REG_ORBIT_TRIG_CMD;
    set_enc_id_indicate(PS_OBC_REG_ORBIT_TRIG_CMD  ); 

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * registration request for ground station pass alert
 */
int8 ps_obc_reg_grnd_stn_pass_ntf_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    rgspn.pld_hw_id = *dp++;
    rgspn.grnd_stn_id = *dp++;
    rgspn.alrt_tmr_min = *dp++;
    rgspn.alrt_tmr_sec = *dp++;
    os_memcpy(&rgspn.alrt_tmr_ms,dp,2); dp += 2;
    rgspn.purpose = *dp;

//    rsp_enc_id = PS_OBC_REG_GRND_STN_PASS_NTF_CMD;
    set_enc_id_indicate(PS_OBC_REG_GRND_STN_PASS_NTF_CMD   ); 

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * Radio module TX enable disable control command
 */
int8 ps_obc_radio_tx_enbl_dsbl_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint8 radio_module_id;
    uint8 tx_control;
    CPRINT_VARIABLE_UNUSED(radio_module_id);
    CPRINT_VARIABLE_UNUSED(tx_control);
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    radio_module_id = *dp++;
    tx_control = *dp;

    DEBUG_CPRINT(("Received Radio Module ID is %d\n",radio_module_id));
    DEBUG_CPRINT(("TX control type is %d\n",tx_control));

    /* Respective handler need to be added here */

  //  //rsp_enc_id = PS_OBC_RADIO_TX_ENBL_DSBL_CMD;
//    set_enc_id_indicate(PS_OBC_RADIO_TX_ENBL_DSBL_CMD);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS node state update notification
 */
int8 ps_obc_ste_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ps_pwr_ste = *dp;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS power on handshake notification
 */
int8 ps_obc_pwr_on_hndske_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint32 magic_keyvalue = 0;

    /* Decode data */
    os_memcpy(&magic_keyvalue,dp,4);
    if(PS_MAGIC_VAL == magic_keyvalue)
    {
        DEBUG_CPRINT(("PS Power ON handshake message received\n"));
    }

//    rsp_enc_id = PS_OBC_PWR_ON_HNDSK_NTF;
    set_enc_id_indicate(PS_OBC_PWR_ON_HNDSK_NTF );

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS keep alive notification
 */
int8 ps_obc_keep_alive_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;

    DEBUG_CPRINT(("PS Keep alive notification received \n"));

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS radio data transmission complete notification
 */
int8 ps_obc_radio_data_tx_cplt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 radio_mod_id;
    CPRINT_VARIABLE_UNUSED(radio_mod_id);
    /* Decode data */
    radio_mod_id = *dp;
    DEBUG_CPRINT(("Radio data tx complete notification obtained for Radio module ID %d\n",radio_mod_id));
    /* Respective handler need to be updated here */

//    rsp_enc_id = PS_OBC_RADIO_DATA_TX_CPLT_NTF;
    set_enc_id_indicate(PS_OBC_RADIO_DATA_TX_CPLT_NTF  );

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification of SSD error
 */
int8 ps_obc_ssd_err_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 ssd_err_type;
    uint8 err_sect_id;
    CPRINT_VARIABLE_UNUSED(err_sect_id);
    /* Decode data */
    ssd_err_type = *dp++;
    DEBUG_CPRINT(("SSD error type is %d\n",ssd_err_type));
    if(ssd_err_type)
    {
        err_sect_id = *dp;
        DEBUG_CPRINT(("Bad SSD number is %d\n",err_sect_id));
    }

    /* Respective handler need to be updated here */

    //rsp_enc_id = PS_OBC_SSD_ERR_NTF;
    set_enc_id_indicate(PS_OBC_SSD_ERR_NTF  );

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification PS firmware update status
 */
int8 ps_obc_ps_firm_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 firmware_updt_sts;
    CPRINT_VARIABLE_UNUSED(firmware_updt_sts);
    /* Decode data */
    firmware_updt_sts = *dp;
    DEBUG_CPRINT(("Firmware update status is %d\n",firmware_updt_sts));

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification Payload hardware firmware update status
 */
int8 ps_obc_pld_hw_firm_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint16 hw_id;
    uint8 firmware_updt_sts;
    CPRINT_VARIABLE_UNUSED(firmware_updt_sts);
    /* Decode data */
    os_memcpy(&hw_id,dp,2); dp+=2;
    firmware_updt_sts = *dp;
    DEBUG_CPRINT(("Firmware update status for PLD HW ID %d is %d\n",hw_id,firmware_updt_sts));

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification of Massless Payload Virtual Machine firmware update status
 */
int8 ps_obc_vm_firm_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint16 id;
    uint8 firmware_updt_sts;
    CPRINT_VARIABLE_UNUSED(firmware_updt_sts);
    /* Decode data */
    os_memcpy(&id,dp,2); dp+=2;
    firmware_updt_sts = *dp;
    DEBUG_CPRINT(("Firmware update status for VM ID %d is %d\n",id,firmware_updt_sts));

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification of PS reset recovery notification
 */
int8 ps_obc_ps_rst_rcv_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 recovery_ste;
    uint8 reset_type;
    CPRINT_VARIABLE_UNUSED(recovery_ste);
    CPRINT_VARIABLE_UNUSED(reset_type);
    /* Decode data */
    recovery_ste = *dp++;
    reset_type = *dp;
    DEBUG_CPRINT(("Recovery state is %d\n",recovery_ste));
    DEBUG_CPRINT(("Reset type is %d\n",reset_type));

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification of PS APP ID list information
 */
int8 ps_obc_ps_app_id_list_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 num_app;
    uint16 app_id, i;
    uint16* ptr;
    CPRINT_VARIABLE_UNUSED(app_id);
    /* Decode data */
    num_app = *dp;
    ptr = (uint16*)(dp+1);
    for(i=0; i< num_app; i++)
    {
        app_id = *ptr++;
        DEBUG_CPRINT(("APP ID is %x\n",app_id));
        app_id = *ptr++;
        DEBUG_CPRINT(("Peer APP ID is %x\n",app_id));
    }

    /* Respective handler need to be updated here */

    /* Invoke next set of events */
    obc_evnt_trig = OBC_PS_OBC_APP_ID_LIST_NTF;
    obc_encode_icd_cmd(obc_evnt_trig,0,NULL);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS notification of PS HW ID list information
 */
int8 ps_obc_ps_hw_id_list_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 num_hw;
    uint16 hw_id, i;
    uint16* ptr;
    CPRINT_VARIABLE_UNUSED(hw_id);
    /* Decode data */
    num_hw = *dp;
    ptr = (uint16*)(dp+1);
    for(i=0; i< num_hw; i++)
    {
        hw_id = *ptr++;
        DEBUG_CPRINT(("HW ID is %x\n",hw_id));
    }

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}

int8 ps_obc_ps_hw_err_recov_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    os_memcpy(&recovered_hardware_id,dp,2);
    //DEBUG_CPRINT(("received hardware ID %d\n",recovered_hardware_id));
    //rsp_enc_id = PS_OBC_PS_HW_ERR_RECOV_NTF;
    set_enc_id_indicate(PS_OBC_PS_HW_ERR_RECOV_NTF);

    status = ICM_OK;
    return status;
}

int8 ps_obc_ps_shutdown_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    os_memcpy(&psd,dp,sizeof(ps_shutdown_ntf));
    DEBUG_CPRINT(("received shutdown time mins: %d sec: %d millisec: %d\n",psd.shutdown_timer_minutes,psd.shutdown_timer_seconds,psd.shutdown_timer_milliseconds));
//    rsp_enc_id = PS_OBC_PS_SHUTDOWN_NTF;
    set_enc_id_indicate(PS_OBC_PS_SHUTDOWN_NTF);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS hardware power on command
 */
int8 ps_obc_ps_hw_pwr_on_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    os_memcpy(&ps_hw_id,dp,2);

    //rsp_enc_id = PS_OBC_PS_HW_PWR_ON_CMD;
    set_enc_id_indicate(PS_OBC_PS_HW_PWR_ON_CMD );

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS hardware power off command
 */
int8 ps_obc_ps_hw_pwr_off_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    os_memcpy(&ps_hw_id,dp,2);

    //rsp_enc_id = PS_OBC_PS_HW_PWR_OFF_CMD;
    set_enc_id_indicate(PS_OBC_PS_HW_PWR_OFF_CMD);

    status = ICM_OK;
    return status;
}

int8 ps_obc_sband_firm_tftp_cplt_ntf_dec(const uint8 *data, uint16 len)
{
	int8 status;
	const uint8 *dp = (data + ICM_HDR_LEN);

	/* Decode data */
	if(0 == *dp)
	{
		 DEBUG_CPRINT(("TFTP file transfer to SBAND Completed"));
	}
	else
	{
		 DEBUG_CPRINT(("TFTP file transfer to SBAND Failed"));
	}

	status = ICM_OK;
	return status;

}

int8 ps_obc_get_curr_time_req_dec(const uint8 *data, uint16 len)
{
	    int8 status;

	    DEBUG_CPRINT(("OBC get time request\n"));
	    //rsp_enc_id = PS_OBC_GET_CURR_TIME_REQ;
	    set_enc_id_indicate(PS_OBC_GET_CURR_TIME_REQ);

	    status = ICM_OK;
	    return status;
}

int8 ps_obc_gnss_prd_loc_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    gps_set_loc_ntfy_prdcty((uint16_t)*dp);
    set_enc_id_indicate(PS_OBC_GNSS_PRD_LOC_REQ);

    status = ICM_OK;
    return status;
}

int8 ps_obc_gnss_tle_data_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

    set_enc_id_indicate(PS_OBC_GNSS_TLE_DATA_REQ);

    status = ICM_OK;
    return status;
}

int8 ps_obc_gnss_prd_tle_data_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    gps_set_tle_data_ntfy_prdcty((uint16_t)*dp);
    set_enc_id_indicate(PS_OBC_GNSS_PRD_TLE_DATA_REQ);

    status = ICM_OK;
    return status;
}

/*********************************************************************************/
/************************* Response Decoder Functions ****************************/
/*********************************************************************************/

/*!
 * @brief This API decodes the Interface Control Message of
 * PS shutdown response
 */
#if 1
int8 obc_ps_pwr_off_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ps_shut_rsp = *dp;

    status = ICM_OK;
    return status;
}
#endif

/*!
 * @brief This API decodes the Interface Control Message of
 * PS Payload hardware power off response
 */
#if 0
int8 obc_ps_pld_hw_pwr_off_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint16 tm_len = 4;
    uint8 *tm_data = NULL;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ps_pld_hw_pwr_off_rsp = *dp;

    /* When shutdown handling is successful in PS */
    if(0 == ps_pld_hw_pwr_off_rsp)
    {
        /* TODO - Invoke EPS power ON command here - respective power rail should be passed as argument */
        /* TRANS - Output Channel 1
         * AICraft - Output Channel 4
         * ZES - Output Channel 7
         * SAYAR - Output Channel 8
         * NETRA - Output Channel 9
         */
        //TODO - Update the status of EPS in below variable
        ps_pld_hw_pwr_off_rsp = 0;

        /* Send TM response */
        tm_data = (uint8_t *) os_malloc(tm_len);
        obc_tm_pld_hw_pwr_off_enc(tm_data, (uint32)ps_pld_hw_pwr_off_rsp);
        obc_prepare_ipc_msg(tm_data, tm_len, TM_PLD_HW_PWR_OFF ,TM_SRC_OBC);
        os_free(tm_data);
        tm_data = NULL;
    }
    /* When shutdown handling failed in PS - Send TM failure response */
    else
    {
        /* Send TM response */
        tm_data = (uint8_t *) os_malloc(tm_len);
        obc_tm_pld_hw_pwr_off_enc(tm_data, (uint32)ps_pld_hw_pwr_off_rsp);
        obc_prepare_ipc_msg(tm_data, tm_len, TM_PLD_HW_PWR_OFF ,TM_SRC_OBC);
        os_free(tm_data);
        tm_data = NULL;
    }

    status = ICM_OK;
    return status;
}
#endif

/*!
 * @brief This API decodes the Interface Control Message of
 * PS Massless Payload Virtual Machine power off response
 */
#if 1
int8 obc_ps_vm_pwr_off_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ps_vm_pwr_off_rsp = *dp;


    status = ICM_OK;
    return status;
}
#endif

/*!
 * @brief This API decodes the Interface Control Message of
 * PS Massless Payload Virtual Machine power off response
 */
#if 1
int8 obc_ps_vm_pwr_on_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ps_vm_pwr_on_rsp = *dp;

    status = ICM_OK;
    return status;
}
#endif
/*!
 * @brief This API decodes the Interface Control Message of
 * TC_TM response from PS
 */
int8 obc_ps_tc_tm_msg_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    const uint8 *dp = (data + ICM_HDR_LEN);
    uint16 *ptr_2b = NULL;

    /* Decode data */
    ptr_2b = (uint16 *)dp;
    tm_pld_info.tm_id = *ptr_2b; dp += 2;

    tm_pld_info.src_id = *dp++;
    tm_pld_info.dst_id = *dp++;
    ptr_2b = (uint16 *) dp;
    tm_pld_info.tm_pld_len = *ptr_2b; dp += 2;

    if(tm_pld_info.tm_pld_len > 0)
    {
        tm_pld_info.tm_pld_buff = os_malloc(tm_pld_info.tm_pld_len);
        os_memcpy(tm_pld_info.tm_pld_buff,dp,tm_pld_info.tm_pld_len);
    }
    else
    {
        int8_t status = -1;
        //pack status is failure
        tm_pld_info.tm_pld_len = sizeof(status);
        tm_pld_info.tm_pld_buff = os_malloc(tm_pld_info.tm_pld_len);
        os_memcpy(tm_pld_info.tm_pld_buff,&status,tm_pld_info.tm_pld_len);
    }
    DEBUG_CPRINT(("TM ID is %d\n",tm_pld_info.tm_id));
    DEBUG_CPRINT(("SRC ID is %d\n",tm_pld_info.src_id));
    DEBUG_CPRINT(("DST ID is %d\n",tm_pld_info.dst_id));
    DEBUG_CPRINT(("TM PLD Len is %d\n",tm_pld_info.tm_pld_len));
    DEBUG_CPRINT(("TM PLD is %d %d\n",tm_pld_info.tm_pld_buff[0], tm_pld_info.tm_pld_buff[1]));

    /* The TM encode function can be invoked directly by the application
     * under its own thread context by providing the filled in
     * structure information. Otherwise, if the application wants
     * to send it by a separate thread, then global variable (tm_rsp_id)
     * can be updated and triggered as shown in this example */

    /* Trigger TM encoding */
    obc_prepare_ipc_msg(tm_pld_info.tm_pld_buff, tm_pld_info.tm_pld_len, tm_pld_info.tm_id, TM_SRC_PS);
    os_free(tm_pld_info.tm_pld_buff);
    tm_pld_info.tm_pld_buff = NULL;
    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * FTP TC_TM response from PS
 */
int8 obc_ps_ftp_msg_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    const uint8 *dp = (data + ICM_HDR_LEN);
    uint16 *ptr_2b = NULL;

    /* Decode data */
    ptr_2b = (uint16 *)dp;
    tm_pld_info.tm_id = *ptr_2b; dp += 2;

    tm_pld_info.src_id = *dp++;
    tm_pld_info.dst_id = *dp++;
    ptr_2b = (uint16 *) dp;
    tm_pld_info.tm_pld_len = *ptr_2b; dp += 2;

    tm_pld_info.tm_pld_buff = os_malloc(tm_pld_info.tm_pld_len);
    os_memcpy(tm_pld_info.tm_pld_buff,dp,tm_pld_info.tm_pld_len);
    DEBUG_CPRINT(("TM ID is %d\n",tm_pld_info.tm_id));
    DEBUG_CPRINT(("SRC ID is %d\n",tm_pld_info.src_id));
    DEBUG_CPRINT(("DST ID is %d\n",tm_pld_info.dst_id));
    DEBUG_CPRINT(("TM PLD Len is %d\n",tm_pld_info.tm_pld_len));
    DEBUG_CPRINT(("TM PLD is %d %d\n",tm_pld_info.tm_pld_buff[0], tm_pld_info.tm_pld_buff[1]));

    /* The TM encode function can be invoked directly by the application
     * under its own thread context by providing the filled in
     * structure information. Otherwise, if the application wants
     * to send it by a separate thread, then global variable (tm_rsp_id)
     * can be updated and triggered as shown in this example */

    /* Trigger TM encoding */
    obc_prepare_ipc_msg(tm_pld_info.tm_pld_buff, tm_pld_info.tm_pld_len, tm_pld_info.tm_id, TM_SRC_PS);
    os_free(tm_pld_info.tm_pld_buff);
    tm_pld_info.tm_pld_buff = NULL;
    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS keep alive response
 */
int8 obc_ps_keep_alive_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    /* Update response indication */
    ps_keep_alive_rsp_ind++;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS response for ground station pass alert
 */
int8 obc_ps_grnd_stn_ps_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    obc_ps_grnd_stn_pass_ntf_rsp = *dp;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS response for Radio power on notification
 */
int8 obc_ps_radio_pwr_on_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    obc_ps_radio_pwr_on_ntf_rsp = *dp;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * PS response for Radio power off notification
 */
int8 obc_ps_radio_pwr_off_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    obc_ps_radio_pwr_off_ntf_rsp = *dp;

    status = ICM_OK;
    return status;
}
int8 obc_ps_obc_frim_updt_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    /* Decode data */
    DEBUG_CPRINT(("Response recevied from obc_frim_updt_ntf\n"));

    status = ICM_OK;
    return status;
}
int8 obc_ps_obc_hw_err_recov_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint8 hw_err_recov_ntf_rsp;
    const uint8 *dp = (data + ICM_HDR_LEN);
    CPRINT_VARIABLE_UNUSED(hw_err_recov_ntf_rsp);
    /* Decode data */
    hw_err_recov_ntf_rsp = *dp;
    DEBUG_CPRINT(("Response recevied from obc_hw_err_recov_ntf %d\n",hw_err_recov_ntf_rsp));

    status = ICM_OK;
    return status;
}


int8 obc_ps_obc_rst_recv_updt_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    /* Decode data */
    DEBUG_CPRINT(("Response recevied from obc_rst_recv_updt_ntf\n"));

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_app_id_list_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 num_app;
    uint16 app_id=0, i=0;
    app_id=app_id;
    uint16* ptr;

    /* Decode data */
    num_app = *dp;
    ptr = (uint16*)(dp+1);
    for(i=0; i< num_app; i++)
    {
        app_id = *ptr++;
        //DEBUG_CPRINT(("APP ID is %x\n",app_id));
        app_id = *ptr++;
        //DEBUG_CPRINT(("Peer APP ID is %x\n",app_id));
    }

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_id_list_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8 num_hw, i;
    uint16 hw_id;

    /* Decode data */
    num_hw = *dp++;
    //DEBUG_CPRINT(("Response recevied total hw id %d\n",num_hw));
    for(i = 0; i< num_hw; i++)
    {
        os_memcpy(&hw_id,dp,2); dp+=2;
        //DEBUG_CPRINT(("hw id  %x\n",hw_id));
    }

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_app_pri_list_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint8 temp_len = *data;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8* tmp;

    /* Decode data */
    app_id_qos_pwd_ptr = os_malloc(temp_len);
    os_memcpy(app_id_qos_pwd_ptr,dp,temp_len);
    tmp = app_id_qos_pwd_ptr;
    DEBUG_CPRINT(("Response recevied number of enteries %d\n",*tmp++));
    int i=0;
    while(i < (temp_len-1))
    {
        DEBUG_CPRINT(("app id qos pwd %x\n",*tmp++));
        i++;
    }
    /** To mitigate compilation issue when debug c print disabled */
    UNUSED(tmp);

    os_free(app_id_qos_pwd_ptr);
    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_pri_list_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint8 temp_len = *data;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint8* tmp;

    /* Decode data */
    hw_id_qos_pwd_ptr = os_malloc(temp_len);
    os_memcpy(hw_id_qos_pwd_ptr,dp,temp_len);
    tmp = hw_id_qos_pwd_ptr;
    DEBUG_CPRINT(("Response recevied number of enteries %d\n",*tmp++));
    int i=0;
    while(i < (temp_len-1))
    {
        DEBUG_CPRINT(("hw id qos pwd %x\n",*tmp++));
        i++;
    }
    /** To mitigate compilation issue when debug c print disabled */
    UNUSED(tmp);
    os_free(hw_id_qos_pwd_ptr);
    status = ICM_OK;
    return status;
}

int8 obc_ps_staged_tc_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    CPRINT_VARIABLE_UNUSED(dp);
    /* Decode data */
    DEBUG_CPRINT(("Response for Staged TC is %hhd\n",*dp));

    status = ICM_OK;
    return status;
}

int8 obc_ps_xband_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    obc_send_ipc_msg_pld(OBC_XBAND_IPCC_RCV_RSP,COMMS_XBAND_CTLR,(uint8_t*)dp,len);

    status = ICM_OK;
    return status;
}

int8 obc_ps_utc_time_cfg_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    CPRINT_VARIABLE_UNUSED(dp);
    DEBUG_CPRINT(("OBC Time CNFG responce: %d\n",*dp));
//    obc_send_ipc_msg_pld(,,dp,len);

    status = ICM_OK;
    return status;
}

int8 obc_ps_get_temp_info_rsp_dec(const uint8 *data, uint16 len)
{
	int8 status;
	uint8_t device_id=1;
	obc_pck_data ipcc_cmd_resp;
	    const uint8 *dp = (data + ICM_HDR_LEN);
	    CPRINT_VARIABLE_UNUSED(dp);
	    DEBUG_CPRINT(("OBC Time CNFG responce: %d\n",*dp));
	// obc_send_ipc_msg_pld(,,dp,len);
	    ipcc_cmd_resp.tm_rsp_id = TM_GET_PS_TEMP;
	    ipcc_cmd_resp.tx_data =(uint8_t*)os_malloc(2);
	    ipcc_cmd_resp.tx_data[0] = device_id;
	    ipcc_cmd_resp.tx_data[1] = (uint8_t)*dp;
	    ipcc_cmd_resp.tx_data_len = 2;
	    obc_pack_tm_data(&ipcc_cmd_resp);
	    status = ICM_OK;
	    return status;
}

int8 obc_ps_get_time_info_rsp_dec(const uint8 *data, uint16 len)
{
	int8 status;
	uint8_t device_id=1;
	obc_pck_data ipcc_cmd_resp;
	    const uint8 *dp = (data + ICM_HDR_LEN);
	    CPRINT_VARIABLE_UNUSED(dp);
	    DEBUG_CPRINT(("OBC Time CNFG responce: %d\n",*dp));
	// obc_send_ipc_msg_pld(,,dp,len);
	    ipcc_cmd_resp.tm_rsp_id = TM_GET_PS_TIME;
	    ipcc_cmd_resp.tx_data =(uint8_t*)os_malloc(9);
		ipcc_cmd_resp.tx_data[0] = device_id;
		os_memcpy(&ipcc_cmd_resp.tx_data[1],dp,8);
		ipcc_cmd_resp.tx_data_len = 9;
	    obc_pack_tm_data(&ipcc_cmd_resp);
	    status = ICM_OK;
	    return status;
}

int8 obc_ps_get_chip_info_rsp_dec(const uint8 *data, uint16 len)
{
	int8 status;
	uint8_t device_id = 1;
	obc_pck_data ipcc_cmd_resp;
	    const uint8 *dp = (data + ICM_HDR_LEN);
	    CPRINT_VARIABLE_UNUSED(dp);
	    DEBUG_CPRINT(("OBC Time CNFG responce: %d\n",*dp));
	// obc_send_ipc_msg_pld(,,dp,len);
	    ipcc_cmd_resp.tm_rsp_id = TM_GET_MCU_CHIP_INFO;
	    ipcc_cmd_resp.tx_data =(uint8_t*)os_malloc(sizeof(mcu_get_chip_info_s));
	    ipcc_cmd_resp.tx_data[0] = device_id;
	    os_memcpy(&ipcc_cmd_resp.tx_data[1],dp,sizeof(mcu_get_chip_info_s)-1);
	    //ipcc_cmd_resp.tx_data = (uint8_t*)dp;
	    ipcc_cmd_resp.tx_data_len = sizeof(mcu_get_chip_info_s);
	    obc_pack_tm_data(&ipcc_cmd_resp);
	    status = ICM_OK;
	    return status;
}

int8 obc_ps_get_ext_mem_rsp_dec(const uint8 *data, uint16 len)
{
	int8 status;
	obc_pck_data ipcc_cmd_resp;
	    const uint8 *dp = (data + ICM_HDR_LEN);
	    CPRINT_VARIABLE_UNUSED(dp);
	    DEBUG_CPRINT(("OBC Time CNFG responce: %d\n",*dp));
	// obc_send_ipc_msg_pld(,,dp,len);
	    ipcc_cmd_resp.tm_rsp_id =TM_GET_MCU_EXT_MEM_INFO ;
	    ipcc_cmd_resp.tx_data_len = sizeof(ext_mem_info_s)+1;
	    ipcc_cmd_resp.tx_data=(uint8_t*)os_malloc(ipcc_cmd_resp.tx_data_len);
	    ipcc_cmd_resp.tx_data[0] = 1;
	    os_memcpy(&ipcc_cmd_resp.tx_data[1],dp,sizeof(ext_mem_info_s));
	    //ipcc_cmd_resp.tx_data_len = sizeof(ext_mem_info_s);
	    obc_pack_tm_data(&ipcc_cmd_resp);
	    status = ICM_OK;
	    return status;
}

/*This API decodes the response for file transfer initiation
 * whether successs or failure. Also decode the failure code send by PS
 */

int8 obc_ps_sband_firm_tftp_strt_res_dec(const uint8 *data, uint16 len)
{
	int8 status;
	const uint8 *dp = (data + ICM_HDR_LEN);

	uint8 tftp_start_sts = *dp;
	if(0 == tftp_start_sts)
	{
		DEBUG_CPRINT(("File transfer initiation success\n"));
	}
	else
	{
		DEBUG_CPRINT(("File transfer initiation failure\n"));
	}

	status = ICM_OK;
	return status;

}

/*This API decodes the list of firmware available firmware file sent by PS*/

int8 obc_ps_get_sband_firm_files_res_dec(const uint8 *data, uint16 len)
{

	int8 status, n;
	const uint8 *dp = (data + ICM_HDR_LEN);

	char file[30];
	n=*dp;

	DEBUG_CPRINT(("Number of SBAND firmware files is %d\n", n));
	dp+=1;
	for(int cntr = 1; cntr <= n; cntr++)
	{
	memcpy(&file,dp,sizeof(file));
	DEBUG_CPRINT(("Firmware file %d is %s\n",cntr,file));
	dp+=30;
	}

	status = ICM_OK;
	return status;

}

/*This API decodes the response for deletion of firmware files*/

int8 obc_ps_del_sband_firm_file_res_dec(const uint8 *data, uint16 len)
{

	int8 status;
	const uint8 *dp = (data + ICM_HDR_LEN);

	uint8 firm_del_sts = *dp;
	if(0 == firm_del_sts)
	{
		DEBUG_CPRINT(("Firmware file deletion success\n"));
	}
	else
	{
		DEBUG_CPRINT(("Firmware file deletion failure\n"));
	}

	status = ICM_OK;
	return status;

}

int8 obc_ps_curr_time_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    CPRINT_VARIABLE_UNUSED(dp);
    DEBUG_CPRINT(("OBC curr Time notify responce: %d\n",*dp));
    status = ICM_OK;
    return status;
}

int8 obc_ps_gnss_loc_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    CPRINT_VARIABLE_UNUSED(dp);
    DEBUG_CPRINT(("OBC gnss location notify responce: %d\n",*dp));
    status = ICM_OK;
    return status;
}

int8 obc_ps_gnss_tle_data_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    CPRINT_VARIABLE_UNUSED(dp);
    DEBUG_CPRINT(("OBC gnss TLE data notify responce: %d\n",*dp));
    status = ICM_OK;
    return status;
}

int8 obc_ps_gnss_compute_tle_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    os_itc_msg_handle_t ipc_msg;
    orbit_tle_t* orbit_tle;
    const uint8 *dp = (data + ICM_HDR_LEN);
    orbit_tle = os_malloc(sizeof(orbit_tle));
    os_memcpy((uint8_t*)orbit_tle,dp,sizeof(orbit_tle));
    DEBUG_CPRINT(("OBC gnss Compute TLE data  responce\n"));
    DEBUG_CPRINT(("Computed TLE smjaxs  : %lf\n",orbit_tle->smjaxs));
    DEBUG_CPRINT(("Computed TLE argp  : %lf\n",orbit_tle->argp));
    DEBUG_CPRINT(("Computed TLE ascn  : %lf\n",orbit_tle->ascn));
    DEBUG_CPRINT(("Computed TLE bstar  : %lf\n",orbit_tle->bstar));
    DEBUG_CPRINT(("Computed TLE ecc  : %lf\n",orbit_tle->ecc));

    ipc_msg.Msg_id = GPS_COMPUTE_TLE_RSP;
    ipc_msg.Msg_len = sizeof(orbit_tle);
    ipc_msg.pld.pld_ptr = (uint8_t*)orbit_tle;
    ipc_msg.src_entity =  OBC_IPCC_RECEIVE;
    os_itc_msg_send(&ipc_msg,GPS_TASK,1000);

    status = ICM_OK;
    return status;
}

/*********************************************************************************/
/************************* Response Encoder Functions ****************************/
/*********************************************************************************/

/*!
 * @brief This API encodes the default response for Interface Control Messsage
 * for which response encoder are not assigned.
 */
int8 icm_default_rsp_enc_hdlr(void)
{
    int8 status = ICM_RSP_ENC_HDLR_UNASIGN;
    DEBUG_CPRINT(("ICM Response Encoder handler not assigned for current CRRN ID\n"));
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * Target pointing request
 */
int8 ps_obc_trgt_pt_rsp_enc(uint8** data, uint16* len, uint8 rsp_sts)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_TRGT_POINT_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * GNNS location sharing request from PS
 */
int8 ps_obc_gnss_loc_rsp_enc(uint8** data, uint16* len, gps_loc_info *gli)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = sizeof(gps_loc_info);
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_GNSS_LOC_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,gli,data_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_get_curr_time_rsp_enc(uint8** data, uint16* len, uint32_t time_epoch)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 4;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_GET_CURR_TIME_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;

    os_memcpy(*data,&time_epoch,data_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_gnss_prd_loc_rsp_enc(uint8** data, uint16* len, uint8 sts)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_GNSS_PRD_LOC_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;

    os_memcpy(*data,&sts,data_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_gnss_tle_data_rsp_enc(uint8** data, uint16* len, gps_tle_data *tle)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = sizeof(gps_tle_data);
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_GNSS_TLE_DATA_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;

    os_memcpy(*data,tle,data_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_gnss_prd_tle_data_rsp_enc(uint8** data, uint16* len, uint8 sts)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_GNSS_PRD_TLE_DATA_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;

    os_memcpy(*data,&sts,data_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * PS keep alive request
 */
int8 ps_obc_keep_alive_rsp_enc(uint8** data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 0;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_KEEP_ALIVE_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    status = ICM_OK;
    return status;
}

int8 ps_obc_obc_app_id_list_rsp_enc(uint8** data, uint16* len,uint8* buff_data,uint8 buf_len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = buf_len;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_OBC_APP_ID_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    uint16* app_id_info_ptr =(uint16*)(buff_data+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;

    *data += hdr_len;
    os_memcpy(*data, buff_data, buf_len);
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_obc_hw_id_list_rsp_enc(uint8** data, uint16* len,uint8* buff_data,uint8 buf_len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = buf_len;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_OBC_HW_ID_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    uint16* hw_id_info_ptr =(uint16*)(buff_data+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
    *hw_id_info_ptr++ = 0x0;
    *hw_id_info_ptr++ = 0x1;
    *hw_id_info_ptr++ = 0x2;
    *hw_id_info_ptr++ = 0x3;
    *hw_id_info_ptr++ = 0x4;

    *data += hdr_len;
    os_memcpy(*data, buff_data, buf_len);
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_obc_app_qos_pri_list_rsp_enc(uint8** data, uint16* len,uint8* buff_data,uint8 buf_len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = buf_len;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_OBC_APP_QoS_PRI_LIST_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    uint8* app_id_pri_ptr =(buff_data+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_pri_ptr++ = 0x20;
    *app_id_pri_ptr++ = 0x01;
    *app_id_pri_ptr++ = 0x61;
    *app_id_pri_ptr++ = 0x81;
    *app_id_pri_ptr++ = 0x20;
    *app_id_pri_ptr++ = 0x02;
    *app_id_pri_ptr++ = 0x62;
    *app_id_pri_ptr++ = 0x82;
    *app_id_pri_ptr++ = 0x20;
    *app_id_pri_ptr++ = 0x03;
    *app_id_pri_ptr++ = 0x63;
    *app_id_pri_ptr++ = 0x83;
    *app_id_pri_ptr++ = 0x20;
    *app_id_pri_ptr++ = 0x04;
    *app_id_pri_ptr++ = 0x64;
    *app_id_pri_ptr++ = 0x84;
    *app_id_pri_ptr++ = 0x20;
    *app_id_pri_ptr++ = 0x05;
    *app_id_pri_ptr++ = 0x65;
    *app_id_pri_ptr++ = 0x85;

    *data += hdr_len;
    os_memcpy(*data, buff_data, buf_len);
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_schd_ps_pwr_on_rsp_enc(uint8** data, uint16* len,uint8 schld_res)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_SCHD_PS_PWR_ON_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);
    /* Encode data parameters */
    *data += hdr_len;
    **data = schld_res;
    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_pwr_on_rsp_enc(uint8** data, uint16* len,obc_radio_pwr_on* rpo)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 2;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_RADIO_PWR_ON_REQ;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);
    /* Encode data parameters */
    *data += hdr_len;
    os_memcpy(*data,rpo,sizeof(obc_radio_pwr_on));
    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_pwr_off_rsp_enc(uint8** data, uint16* len,uint8 pwr_off_rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_RADIO_PWR_OFF_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);
    /* Encode data parameters */
    *data += hdr_len;
    **data = pwr_off_rsp;
    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_rx_enbl_dsbl_rsp_enc(uint8** data, uint16* len,uint8 rx_enbl_dsbl_rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_RADIO_RX_ENBL_DSBL_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);
    /* Encode data parameters */
    *data += hdr_len;
    **data = rx_enbl_dsbl_rsp;
    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * alert request for specified orbit from PS
 */
int8 ps_obc_reg_orbit_trig_rsp_enc(uint8** data, uint16* len, uint8 reg_rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_REG_ORBIT_TRIG_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = reg_rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * ground station alert request from PS
 */
int8 ps_obc_reg_grnd_stn_ps_ntf_rsp_enc(uint8** data, uint16* len, uint8 reg_rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_REG_GRND_STN_PASS_NTF_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = reg_rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * power ON handshake notification from PS
 */
int8 ps_obc_pwr_on_hndske_ntf_rsp_enc(uint8** data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 0;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_PWR_ON_HNDSK_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * radio data transmission complete notification from PS
 */
int8 ps_obc_radio_data_tx_cplt_ntf_rsp_enc(uint8** data, uint16* len, uint8 rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_RADIO_DATA_TX_CPLT_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * SSD error notification from PS
 */
int8 ps_obc_ssd_err_ntf_rsp_enc(uint8** data, uint16* len, uint8 rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_SSD_ERR_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_ps_hw_err_recov_ntf_rsp_enc(uint8** data, uint16* len, uint8 rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_PS_HW_ERR_RECOV_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_ps_shutdown_ntf_rsp_enc(uint8** data, uint16* len, uint8 rsp_typ)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_PS_SHUTDOWN_NTF;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp_typ;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * PS hardware power on request from PS
 */
int8 ps_obc_ps_hw_pwr_on_rsp_enc(uint8** data, uint16* len, uint8 rsp, uint8 retry_tmr)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 2;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_PS_HW_PWR_ON_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp; *data += 1;
    **data = retry_tmr;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * PS hardware power off request from PS
 */
int8 ps_obc_ps_hw_pwr_off_rsp_enc(uint8** data, uint16* len, uint8 rsp)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = 1;
    *len = (hdr_len + data_len);

    unsigned int *hdr_data = (unsigned int*)os_malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = PS_OBC_PS_HW_PWR_OFF_CMD;
    hdr.data_len = data_len;

    *hdr_data = (hdr.crrn_type << CRRN_TYPE_POS \
            | hdr.crrn_id << CRRN_ID_POS \
            | hdr.data_len << CRRN_DATA_LEN_POS);

    /* Encode data parameters */
    *data += hdr_len;
    **data = rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}
