#include "es_intf_ctrl_msg.h"
#include "file_transfer.h"


//#define GET_ES_CRRN_ID(x)  ((ES_ICM_CRRN_ID_MAX - x) - 1)

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

/*!
 * @brief Global variables declarations for storing decoded response
 */
extern uint16 rsp_enc_id;
extern uint16 ps_evnt_trig;
extern uint16 tc_id_var;
extern uint32 xband_data[50];
extern uint16 xband_data_len;

uint16 ps_vm_id;
icm_ps_pwr_off_info_s ppoi;
icm_pld_hw_pwr_off_info_s phpoi;
icm_vm_pwr_off_info_s poi;
icm_gs_pass_info_s gpi;
uint8 obc_pwr_ste;
uint8 obc_alive_alert_ntf;
uint8 radio_mod_id;
uint8 obc_frim_updt_state;
obc_rst_recv_updt rru;
uint8 recovered_hardware_id;

uint8 trgt_pt_rsp_val;
uint8 reg_orbit_trig_rsp_val;
uint8 reg_grnd_stn_ps_ntf_rsp_val;
uint8 ps_hw_pwr_on_rsp_val;
uint8 ps_hw_pwr_off_rsp_val;
uint8 pwr_on_schd_rsp_val;
icm_gnss_loc_info_s gli;
obc_radio_pwr_on rpo;
obc_get_curr_time gct;
uint16 *obc_hw_id_list_ptr,*obc_app_id_list_ptr;
uint8 *obc_app_qos_pri_ptr;
char tty_rsp[1000];

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

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Target point request
 */
int8 es_obc_trgt_point_req_enc(uint8** data, uint16* len, icm_trgt_pt_req_s *tpr)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 17;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    hdr.crrn_id = ES_OBC_TRGT_POINT_REQ;
    hdr.data_len = data_len;
printf("CRRN ID%d\n", hdr.crrn_id);
printf("CRRN type%d\n", hdr.crrn_type);
printf("CRRN len%d\n", hdr.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 = tpr->pld_hw_id; *data += 1;
    memcpy(*data,&tpr->lat,4); *data += 4;
    memcpy(*data,&tpr->longit,4); *data += 4;
    memcpy(*data,&tpr->alt,4); *data += 4;
    **data = tpr->act_tmr_min; *data += 1;
    **data = tpr->act_tmr_sec; *data += 1;
    memcpy(*data,&tpr->act_tmr_ms,2);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;

}
#if 0
/*!
 * @brief This API encodes the Interface Control Messsage for
 * alert registration for orbit parameters
 */
int8 ps_obc_reg_orbit_trig_cmd_enc(uint8** data, uint16* len, icm_reg_orbt_trig_s *rot)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 17;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    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 = rot->pld_hw_id; *data += 1;
    memcpy(*data,&rot->lat,4); *data += 4;
    memcpy(*data,&rot->longit,4); *data += 4;
    memcpy(*data,&rot->alt,4); *data += 4;
    **data = rot->alrt_tmr_min; *data += 1;
    **data = rot->alrt_tmr_sec; *data += 1;
    memcpy(*data,&rot->alrt_tmr_ms,2);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_get_curr_time_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * GNNS location request
 */
int8 ps_obc_gnss_loc_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS keep alive request to OBC
 */
int8 ps_obc_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    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_schd_ps_pwr_on_req_enc(uint8** data, uint16* len,schd_ps_pwr_on_req* sprq)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 4;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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;
    memcpy(*data,sprq,sizeof(schd_ps_pwr_on_req));
    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_pwr_on_req_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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;
    **data = radio_id;
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_obc_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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);


    status = ICM_OK;
    return status;
}

int8 ps_obc_obc_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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);


    status = ICM_OK;
    return status;
}


int8 ps_obc_radio_pwr_off_cmd_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    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 = radio_id;
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_radio_rx_enbl_dsbl_cmd_enc(uint8** data, uint16* len,radio_rx_enbl_dsbl* radio_info)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 2;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    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;
    memcpy(*data,radio_info,sizeof(radio_rx_enbl_dsbl));
    *data = (uint8*)hdr_data;
    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * alert registration for ground station pass notification
 */
int8 ps_obc_reg_grnd_stn_pass_ntf_cmd_enc(uint8** data, uint16* len, icm_reg_grnd_stn_ps_ntf_s *rgspn)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 7;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    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 = rgspn->pld_hw_id; *data += 1;
    **data = rgspn->grnd_stn_id; *data += 1;
    **data = rgspn->alrt_tmr_min; *data += 1;
    **data = rgspn->alrt_tmr_sec; *data += 1;
    memcpy(*data,&rgspn->alrt_tmr_ms,2); *data += 2;
    **data = rgspn->purpose;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * Radio module TX enable disable control command
 */
int8 ps_obc_radio_tx_enbl_dsbl_cmd_enc(uint8** data, uint16* len, uint8 rad_mod, uint8 tx_ctrl)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 2;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    hdr.crrn_id = PS_OBC_RADIO_TX_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 = rad_mod; *data += 1;
    **data = tx_ctrl;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}


/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS node state update notification
 */
int8 ps_obc_ste_updt_ntf_enc(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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_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 = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS power on handshake notification
 */
int8 ps_obc_pwr_on_hndsh_ntf_enc(uint8** data, uint16* len)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 4;
    uint32 ps_magic_val = 0;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    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);

    /* Encode data parameters */
    *data += hdr_len;
    ps_magic_val = ES_MAGIC_VAL;
    memcpy(*data, &ps_magic_val, 4);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS keep alive notification
 */
int8 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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = 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
 * PS radio data transmission complete notification
 */
int8 ps_obc_radio_data_tx_cplt_ntf_enc(uint8** data, uint16* len, uint8 radio_mod_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    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 = radio_mod_id;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS notification of SSD error to OBC
 */
int8 ps_obc_ssd_err_ntf_enc(uint8** data, uint16* len, s_ssd_err_info *ssd_err_info)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 2;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    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 = ssd_err_info->err_type; *data += 1;
    **data = ssd_err_info->sect_id;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS notification of PS Firmware update status
 */
int8 ps_obc_ps_firmware_updt_ntf_enc(uint8** data, uint16* len, uint8 fm_updt_sts)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 1;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_PS_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 = fm_updt_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS notification of Playload Hardware Firmware update status
 */
int8 ps_obc_pld_hw_firmware_updt_ntf_enc(uint8** data, uint16* len, uint8 fm_updt_sts, uint16 hw_id)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 3;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_PLD_HW_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;
    memcpy(*data,&hw_id,2);
    *data += 2;
    **data = fm_updt_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS notification of Playload Virtual Machine Firmware update status
 */
int8 ps_obc_vm_firmware_updt_ntf_enc(uint8** data, uint16* len, uint8 fm_updt_sts, uint16 vm_id)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 3;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_VM_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;
    memcpy(*data,&vm_id,2);
    *data += 2;
    **data = fm_updt_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS reset and recovery status update notification
 */
int8 ps_obc_ps_rst_rcv_ntf_enc(uint8** data, uint16* len, uint8 rcv_ste, uint8 rst_type)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 2;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_PS_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;
    **data = rcv_ste; *data += 1;
    **data = rst_type;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS APP ID list notification to OBC
 */
int8 ps_obc_ps_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_PS_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;
    memcpy(*data, app_id_info_buff, buf_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS HW ID list notification to OBC
 */
int8 ps_obc_ps_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    hdr.crrn_id = PS_OBC_PS_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;
    memcpy(*data, hw_id_info_buff, buf_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}
int8 ps_obc_obc_app_qos_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_REQ;
    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);

    status = ICM_OK;
    return status;
}

int8 ps_obc_ps_hw_err_recov_ntf_enc (uint8 **data, uint16* len, uint16 recovered_hardware_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    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;
    memcpy(*data,&recovered_hardware_id,2);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 ps_obc_ps_shutdown_ntf_enc (uint8 **data, uint16* len, ps_shutdown_ntf* psd)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = 4, data_len = 4;
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_NTF;
    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;

    memcpy(data,&psd,sizeof(ps_shutdown_ntf));

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS Hardware power on command
 */
int8 ps_obc_ps_hw_pwr_on_cmd_enc(uint8** data, uint16* len, uint16 hw_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    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;
    memcpy(*data,&hw_id,2);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the Interface Control Messsage for
 * PS Hardware power off command
 */
int8 ps_obc_ps_hw_pwr_off_cmd_enc(uint8** data, uint16* len, uint16 hw_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_CMD;
    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;
    memcpy(*data,&hw_id,2);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}
#endif

/*********************************************************************************/
/************** Command, Request, Notification Decoder Functions *****************/
/*********************************************************************************/

/*!
 * @brief This API maps the decoder handler of 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;
    }
    icm_data_dec_fn[OBC_ES_PWR_OFF_CMD] = obc_es_pwr_off_cmd_dec;
    /* Decoder handler mapping */
    icm_data_dec_fn[ES_OBC_TRGT_POINT_REQ] = es_obc_trgt_pt_rsp_dec;
#if 0
    icm_data_dec_fn[OBC_PS_PWR_OFF_CMD] = obc_ps_pwr_off_cmd_dec;
    icm_data_dec_fn[OBC_PS_PLD_HW_PWR_OFF_CMD] = obc_ps_pld_hw_pwr_off_cmd_dec;
    icm_data_dec_fn[OBC_PS_VM_PWR_OFF_CMD] = obc_ps_vm_pwr_off_cmd_dec;
    icm_data_dec_fn[OBC_PS_VM_PWR_ON_CMD] = obc_ps_vm_pwr_on_cmd_dec;
    icm_data_dec_fn[OBC_PS_TC_TM_MSG_CMD] = obc_ps_tc_tm_msg_cmd_dec;
    icm_data_dec_fn[OBC_PS_FTP_MSG_CMD] = obc_ps_ftp_msg_cmd_dec;
    icm_data_dec_fn[OBC_PS_KEEP_ALIVE_REQ] = obc_ps_keep_alive_req_dec;
    icm_data_dec_fn[OBC_PS_PS_APP_ID_LIST_REQ] = obc_ps_ps_app_id_list_req_dec;
    icm_data_dec_fn[OBC_PS_PS_APP_PRI_LIST_REQ] = obc_ps_ps_app_pri_list_req_dec;
    icm_data_dec_fn[OBC_PS_PS_HW_ID_LIST_REQ] = obc_ps_ps_hw_id_list_req_dec;
    icm_data_dec_fn[OBC_PS_PS_HW_PRI_LIST_REQ] = obc_ps_ps_hw_pri_list_req_dec;
    icm_data_dec_fn[OBC_PS_GS_PASS_NTF] = obc_ps_gs_pass_ntf_dec;
    icm_data_dec_fn[OBC_PS_STATE_UPDT_NTF] = obc_ps_ste_updt_ntf_dec;
    icm_data_dec_fn[OBC_PS_RADIO_PWR_ON_NTF] = obc_ps_radio_pwr_on_ntf_dec;
    icm_data_dec_fn[OBC_PS_RADIO_PWR_OFF_NTF] = obc_ps_radio_pwr_off_ntf_dec;
    icm_data_dec_fn[OBC_PS_OBC_KEEP_ALIVE_NTF] = obc_ps_obc_keep_alive_ntf_dec;
    icm_data_dec_fn[OBC_PS_OBC_APP_ID_LIST_NTF] = obc_ps_obc_app_id_list_ntf_dec;
    icm_data_dec_fn[OBC_PS_OBC_HW_ID_LIST_NTF] = obc_ps_obc_hw_id_list_ntf_dec;
    icm_data_dec_fn[OBC_PS_OBC_HW_ERR_RECOV_NTF] = obc_ps_obc_hw_err_recov_ntf_dec;
    icm_data_dec_fn[OBC_PS_OBC_FIRM_UPDT_NTF] = obc_ps_obc_frim_updt_ntf_dec;
    icm_data_dec_fn[OBC_PS_OBC_RST_RECV_UPDT_NTF] = obc_ps_obc_rst_recv_updt_ntf_dec;
    icm_data_dec_fn[OBC_PS_STAGED_TC_CMD] = obc_ps_staged_tc_cmd_dec;
    icm_data_dec_fn[OBC_PS_XBAND_CMD] = obc_ps_xband_cmd_dec;	
    icm_data_dec_fn[OBC_PS_TEMP_INFO] = obc_ps_get_temp_info_dec;	
    icm_data_dec_fn[OBC_PS_TIME_INFO] = obc_ps_get_time_info_dec;	
    icm_data_dec_fn[OBC_PS_CHIP_INFO] = obc_ps_get_chip_info_dec;	
    icm_data_dec_fn[OBC_PS_EXT_MEM] = obc_ps_get_ext_mem_dec;		

    icm_data_dec_fn[PS_OBC_TRGT_POINT_REQ] = ps_obc_trgt_pt_rsp_dec;
    icm_data_dec_fn[PS_OBC_GNSS_LOC_REQ] = ps_obc_gnss_loc_rsp_dec;
    icm_data_dec_fn[PS_OBC_KEEP_ALIVE_REQ] = ps_obc_keep_alive_rsp_dec;
    icm_data_dec_fn[PS_OBC_RADIO_PWR_ON_REQ] = ps_obc_radio_pwr_on_rsp_dec;
    icm_data_dec_fn[PS_OBC_SCHD_PS_PWR_ON_REQ] = ps_obc_schd_ps_pwr_on_rsp_dec;
    icm_data_dec_fn[PS_OBC_GET_CURR_TIME_REQ] = ps_obc_get_curr_time_rsp_dec;
    icm_data_dec_fn[PS_OBC_RADIO_PWR_OFF_CMD] = ps_obc_radio_pwr_off_rsp_dec;
    icm_data_dec_fn[PS_OBC_RADIO_RX_ENBL_DSBL_CMD] = ps_obc_radio_rx_enbl_dsbl_rsp_dec;
    icm_data_dec_fn[PS_OBC_REG_ORBIT_TRIG_CMD] = ps_obc_reg_orbit_trig_rsp_dec;
    icm_data_dec_fn[PS_OBC_REG_GRND_STN_PASS_NTF_CMD] = ps_obc_reg_grnd_stn_ps_ntf_rsp_dec;
    icm_data_dec_fn[PS_OBC_PWR_ON_HNDSK_NTF] = ps_obc_pwr_on_hndsk_ntf_rsp_dec;
    icm_data_dec_fn[PS_OBC_RADIO_DATA_TX_CPLT_NTF] = ps_obc_radio_data_tx_cplt_ntf_rsp_dec;
    icm_data_dec_fn[PS_OBC_SSD_ERR_NTF] = ps_obc_ssd_err_ntf_rsp_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_ERR_RECOV_NTF] = ps_obc_ps_hw_err_recov_ntf_rsp_dec;
    icm_data_dec_fn[PS_OBC_PS_SHUTDOWN_NTF] = ps_obc_ps_shutdown_ntf_rsp_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_PWR_ON_CMD] = ps_obc_ps_hw_pwr_on_rsp_dec;
    icm_data_dec_fn[PS_OBC_PS_HW_PWR_OFF_CMD] = ps_obc_ps_hw_pwr_off_rsp_dec;
    icm_data_dec_fn[PS_OBC_OBC_APP_ID_LIST_REQ] = ps_obc_obc_app_id_list_rsp_dec;
    icm_data_dec_fn[PS_OBC_OBC_HW_ID_LIST_REQ] = ps_obc_obc_hw_id_list_rsp_dec;
    icm_data_dec_fn[PS_OBC_OBC_APP_QoS_PRI_LIST_REQ] = ps_obc_obc_app_qos_pri_list_rsp_dec;

    icm_data_dec_fn[OBC_PS_SIMU_PS_PWR_ON_CMD] = obc_ps_simu_ps_pwr_on_cmd_dec;
#endif

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the CRRN ID of the received response
 */
int8 ps_icm_crrn_id_dec(const uint8 *data, uint16 len)
{
    int8 status;
    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);
    printf("Type: %d, ID: %d, Len: %d\n",hdr.crrn_type, hdr.crrn_id, hdr.data_len);

    icm_data_dec_fn[hdr.crrn_id](data,len);
    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of messages for which
 * specific message decoder is not assigned
 */
int8 icm_default_data_dec(const uint8 *data, uint16 len)
{
    int8 status = ICM_DEC_HDLR_UNASIGN;
    printf("ICM Decoder handler not assigned for current CRRN ID\n");
    return status;
}
/*!
 * @brief This API handles the decoding of Interface control message of
 * ES shutdown command
 */
int8 obc_es_pwr_off_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ppoi.shut_tmr_min = *dp++;
    ppoi.shut_tmr_sec = *dp++;
    memcpy(&ppoi.shut_tmr_ms,dp,2); dp += 2;
    ppoi.shut_purpose = *dp;

    rsp_enc_id = OBC_ES_PWR_OFF_CMD;

    status = ICM_OK;
    return status;
}
#if 0
/*!
 * @brief This API handles the decoding of Interface control message of
 * PS shutdown command
 */
int8 obc_ps_pwr_off_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    ppoi.shut_tmr_min = *dp++;
    ppoi.shut_tmr_sec = *dp++;
    memcpy(&ppoi.shut_tmr_ms,dp,2); dp += 2;
    ppoi.shut_purpose = *dp;

    rsp_enc_id = OBC_PS_PWR_OFF_CMD;

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    ppoi.shut_tmr_min = *dp++;
    ppoi.shut_tmr_sec = *dp++;
    memcpy(&ppoi.shut_tmr_ms,dp,2); dp += 2;
    ppoi.shut_purpose = *dp;

    rsp_enc_id = OBC_PS_TEMP_INFO;

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    ppoi.shut_tmr_min = *dp++;
    ppoi.shut_tmr_sec = *dp++;
    memcpy(&ppoi.shut_tmr_ms,dp,2); dp += 2;
    ppoi.shut_purpose = *dp;

    rsp_enc_id = OBC_PS_TIME_INFO;

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    ppoi.shut_tmr_min = *dp++;
    ppoi.shut_tmr_sec = *dp++;
    memcpy(&ppoi.shut_tmr_ms,dp,2); dp += 2;
    ppoi.shut_purpose = *dp;

    rsp_enc_id = OBC_PS_CHIP_INFO;

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    ppoi.shut_tmr_min = *dp++;
    ppoi.shut_tmr_sec = *dp++;
    memcpy(&ppoi.shut_tmr_ms,dp,2); dp += 2;
    ppoi.shut_purpose = *dp;

    rsp_enc_id = OBC_PS_EXT_MEM;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * PS payload hardware power off command
 */
int8 obc_ps_pld_hw_pwr_off_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    memcpy(&phpoi.pld_hw_id,dp,2); dp+=2;
    phpoi.shut_tmr_min = *dp++;
    phpoi.shut_tmr_sec = *dp++;
    memcpy(&phpoi.shut_tmr_ms,dp,2); dp += 2;
    phpoi.shut_purpose = *dp;

    rsp_enc_id = OBC_PS_PLD_HW_PWR_OFF_CMD;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * PS payload Virtual Machine power off command
 */
int8 obc_ps_vm_pwr_off_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    memcpy(&poi,dp,sizeof(poi));
    printf("Received VM Power Off Command %hd\n",poi.vm_id);
    rsp_enc_id = OBC_PS_VM_PWR_OFF_CMD;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * PS payload Virtual Machine power on command
 */
int8 obc_ps_vm_pwr_on_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    memcpy(&ps_vm_id,dp,2);
    printf("Received VM Power ON Command %hd\n",ps_vm_id);

    rsp_enc_id = OBC_PS_VM_PWR_ON_CMD;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * TC_TM message from OBC to PS
 */
int8 obc_ps_tc_tm_msg_cmd_dec(const uint8 *data, uint16 len)
{

    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint16 *ptr_2b = NULL;
    icm_tc_pld_info_s tc_pld_info;

    /* Decode data */
    ptr_2b = (uint16 *)dp;
    tc_pld_info.tc_id = *ptr_2b; dp += 2;

    tc_pld_info.src_id = *dp++;
    tc_pld_info.dst_id = *dp++;
    ptr_2b = (uint16 *) dp;
    tc_pld_info.tc_pld_len = *ptr_2b; dp += 2;

    tc_pld_info.tc_pld_buff = malloc(tc_pld_info.tc_pld_len);
    memcpy(tc_pld_info.tc_pld_buff,dp,tc_pld_info.tc_pld_len);
    printf("TC ID is %d\n",tc_pld_info.tc_id);
    printf("SRC ID is %d\n",tc_pld_info.src_id);
    printf("DST ID is %d\n",tc_pld_info.dst_id);
    printf("TC PLD Len is %d\n",tc_pld_info.tc_pld_len);
    printf("TC PLD is %d %d\n",tc_pld_info.tc_pld_buff[0], tc_pld_info.tc_pld_buff[1]);


    switch(tc_pld_info.tc_id)
    {
        case TC_TTY_START:
            {
                //respective PS Controller handler need to be implemented

                //Pack response
                tc_id_var = TM_TTY_START;
                rsp_enc_id = OBC_PS_TC_TM_MSG_CMD;
            }
            break;

        case TC_TTY_END:
            {
                //respective PS Controller handler need to be implemented

                //Pack response
                tc_id_var = TM_TTY_END;
                rsp_enc_id = OBC_PS_TC_TM_MSG_CMD;
            }
            break;

        case TC_TTY_DEBUG:
            {
                ps_tty_execute((char*)tc_pld_info.tc_pld_buff,tc_pld_info.tc_pld_len,tty_rsp);
                tc_id_var = TM_TTY_DEBUG;
                rsp_enc_id = OBC_PS_TC_TM_MSG_CMD;
            }
            break;

        case TC_XBAND:
            {
                printf("X-Band command received ");

                int i = 0;

                for(i=0;i<tc_pld_info.tc_pld_len;i++)
                {
                    printf("%u ",tc_pld_info.tc_pld_buff[i]);
                }
            }
            break;

        default:
            {
                printf("Invalid TC ID received %d\n",tc_pld_info.tc_id);
            }
    }

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * FTP TC_TM message from OBC to PS
 */
int8 obc_ps_ftp_msg_cmd_dec(const uint8 *data, uint16 len)
{

    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint16 *ptr_2b = NULL;
    icm_tc_pld_info_s tc_pld_info;

    /* Decode data */
    ptr_2b = (uint16 *)dp;
    tc_pld_info.tc_id = *ptr_2b; dp += 2;

    tc_pld_info.src_id = *dp++;
    tc_pld_info.dst_id = *dp++;
    ptr_2b = (uint16 *) dp;
    tc_pld_info.tc_pld_len = *ptr_2b; dp += 2;

    tc_pld_info.tc_pld_buff = malloc(tc_pld_info.tc_pld_len);
    memcpy(tc_pld_info.tc_pld_buff,dp,tc_pld_info.tc_pld_len);
    printf("TC ID is %d\n",tc_pld_info.tc_id);
    printf("SRC ID is %d\n",tc_pld_info.src_id);
    printf("DST ID is %d\n",tc_pld_info.dst_id);
    printf("TC PLD Len is %d\n",tc_pld_info.tc_pld_len);
    printf("TC PLD is %d %d\n",tc_pld_info.tc_pld_buff[0], tc_pld_info.tc_pld_buff[1]);


    switch(tc_pld_info.tc_id)
    {

        case TC_FTCI:
        case TC_FTFCI:
        case TC_FTSR:
        case TC_FTDS:
        case TC_FTDB:

            //printf("FTM Rcvd %d\n",tc_pld_info.tc_id);
            ft_payload_parser(tc_pld_info.tc_id,tc_pld_info.dst_id,tc_pld_info.tc_pld_buff,tc_pld_info.tc_pld_len);
            break;

        default:
            {
                printf("FTP Invalid TC ID received %d\n",tc_pld_info.tc_id);
            }
    }

    status = ICM_OK;
    return status;
}

uint8_t ps_tty_execute(char* tty_data,uint32_t data_len,char* tty_rsp)
{
    FILE *fptr;
    fptr = popen(tty_data,"r");
    fread(tty_rsp,1000,1,fptr);
    pclose(fptr);
    /* Execute shell command */
    return 0;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * PS Keep alive request
 */
int8 obc_ps_keep_alive_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

    rsp_enc_id = OBC_PS_KEEP_ALIVE_REQ;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * PS APP ID list request
 */
int8 obc_ps_ps_app_id_list_req_dec(const uint8 *data, uint16 len)
{
    int8 status;

    rsp_enc_id = OBC_PS_PS_APP_ID_LIST_REQ;

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_app_pri_list_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    rsp_enc_id = OBC_PS_PS_APP_PRI_LIST_REQ;

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_id_list_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    rsp_enc_id = OBC_PS_PS_HW_ID_LIST_REQ;

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_pri_list_req_dec(const uint8 *data, uint16 len)
{
    int8 status;
    rsp_enc_id = OBC_PS_PS_HW_PRI_LIST_REQ;

    status = ICM_OK;
    return status;
}
/*!
 * @brief This API handles the decoding of Interface control message of
 * Ground station pass alert notification
 */
int8 obc_ps_gs_pass_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    gpi.rem_tmr_min = *dp++;
    gpi.rem_tmr_sec = *dp++;
    memcpy(&gpi.rem_tmr_ms,dp,2); dp += 2;
    gpi.radio_comm_intf_type = *dp;

    rsp_enc_id = OBC_PS_GS_PASS_NTF;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * OBC state update notification
 */
int8 obc_ps_ste_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    obc_pwr_ste = *dp;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * Radio power ON notification from OBC to PS
 */
int8 obc_ps_radio_pwr_on_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    radio_mod_id = *dp;

    rsp_enc_id = OBC_PS_RADIO_PWR_ON_NTF;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * Radio power OFF notification from OBC to PS
 */
int8 obc_ps_radio_pwr_off_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    radio_mod_id = *dp;

    rsp_enc_id = OBC_PS_RADIO_PWR_OFF_NTF;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * OBC alive notification alert to PS
 */
int8 obc_ps_obc_keep_alive_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;

    obc_alive_alert_ntf++;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * OBC notification on OBC APP ID list
 */
int8 obc_ps_obc_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;

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

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}
int8 obc_ps_obc_frim_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    obc_frim_updt_state = *dp;
    printf("OBC_Frimware update state %d\n",obc_frim_updt_state);
    rsp_enc_id = OBC_PS_OBC_FIRM_UPDT_NTF;

    status = ICM_OK;
    return status;
}

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

    uint32 *pld = (uint32 *)dp;

    memcpy(xband_data,pld, 20);
    xband_data[4] |= 0x40000000;
    //xband_data[4] |= 0x80000000;
    //xband_data[4] |= 0xC0000000;

    xband_data_len = 20;

    switch(xband_data[4] & 0x0F)
    {
        case 0:
            {

                xband_data[4] |= 0x40000000 ;
                printf("Set IDLE command");
                uint32 x_data[5] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x60000000};
                xband_data_len = sizeof(x_data);
                memcpy(xband_data,x_data,xband_data_len);


            }
            break;
        case 1:
            {
                if(0x20000000 & xband_data[4])
                {
                    printf("Set device configuration\r\n");
                    xband_data[4] |= 0x40000000 ;
                }
                else
                {
                    printf("Get device configuration\r\n");

                    uint32 x_data[30] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x50000001,0x00000000,0x00000000,0x005a06e0,0x005a06e0,0x005a06e0,0x001f95f0,0x001f95f0,0x007d1f40,0x007d1f40,0x00000000,0x00000000,0x00b71b00,0x00b71b00,0x00000000,0x00000000,0x00b71b00,0x00b71b00,0x1db706e1,0x98c21cc2,0x59815414,0x00040000,0x025313c,0x02531239,0x00401c00,0x00000000};

                    xband_data_len = sizeof(x_data);
                    memcpy(xband_data,x_data,xband_data_len);

                }
            }
            break;
        case 2:
            {
                printf("Get feature command\r\n");


                uint32 x_data[9] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x50000002,0x03ff3f05,0xffffffc5,0x0040da00,0xffffffff};
                xband_data_len = sizeof(x_data);
                memcpy(xband_data,x_data,xband_data_len);

            }
            break;
        case 3:
            {
                printf("Get version info\r\n");

                uint32 x_data[21] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x50000003,0x54aaca6c,0x31555043,0x001a0000,0x30018e96,0x7b2cb712,0x41475046,0x00310000,0x30111097,0x1dacead0,0x50415753,0x006b0000,0x3007379f,0xffffffff,0xffffffff,0xffffffff,0xffffffff};

                xband_data_len = sizeof(x_data);
                memcpy(xband_data,x_data,xband_data_len);

            }
            break;
        case 4:
            {
                printf("Get house keep info\r\n");


                uint32 x_data[30] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x50000004,0x54aaca6c,0x00000000,0x3feecfc0,0x00000000,0x3ffd2170,0x00000000,0x3feece40,0x00000000,0x3ff00980,0x00000000,0x3ffd1e10,0x00000000,0x3ff5b790,0x002a2e21,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00000000,0x00400000,0x00400000,0x0006583e};

                xband_data_len = sizeof(x_data);
                memcpy(xband_data,x_data,xband_data_len);

            }
            break;
        case 5:
            {
                printf("Get xpa info \r\n");

                uint32 x_data[9] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x50000005,0x54aaca6c,0x00000000,0x3feecfc0,0x00000000};
                xband_data_len = sizeof(x_data);
                memcpy(xband_data,x_data,xband_data_len);

            }
            break;
        case 7:
            {
                printf("Set udp stream\r\n");
            }
            break;
        case 9:
            {
                if(0x20000000 & xband_data[4])
                {
                    printf("Set IP address command\r\n");
                    xband_data[4] |= 0x40000000 ;
                }
                else
                {
                    printf("Get IP address command\r\n");

                    uint32 x_data[6] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x50000009,0xc0a80164};
                    xband_data_len = sizeof(x_data);
                    memcpy(xband_data,x_data,xband_data_len);
                }

            }
            break;
        case 0x1b:
            {
                printf("Reset command\r\n");

                uint32 x_data[5] ={0xc9c694fb,0xdeac9b61,0x19ea8546,0x09c58891,0x609ae41b};
                xband_data_len = sizeof(x_data);
                memcpy(xband_data,x_data,xband_data_len);

            }
            break;
    }

    printf("\nOBC_XBAND command %x \n",pld[4]);
    rsp_enc_id = OBC_PS_XBAND_CMD;

    status = ICM_OK;
    return status;
}
int8 obc_ps_obc_rst_recv_updt_ntf_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    rru.reset_recovery_state = *dp++;
    rru.reset_type = *dp;
    printf("OBC_Reset_recovery_state %d reset_type %d\n",rru.reset_recovery_state,rru.reset_type);
    rsp_enc_id = OBC_PS_OBC_RST_RECV_UPDT_NTF;

    status = ICM_OK;
    return status;
}

int8 obc_ps_staged_tc_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);
    uint32 staged_tc_id = 0;

    /* Decode data */
    memcpy(&staged_tc_id,dp,sizeof(uint32));
    printf("Received Staged TC ID %u\n",staged_tc_id);
    rsp_enc_id = OBC_PS_STAGED_TC_CMD;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API handles the decoding of Interface control message of
 * OBC notification on OBC HW ID list
 */
int8 obc_ps_obc_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;

    /* Decode data */
    num_hw = *dp;
    ptr = (uint16*)(dp+1);
    for(i=0; i< num_hw; i++)
    {
        hw_id = *ptr++;
        printf("HW ID is %x\n",hw_id);
    }

    /* Respective handler need to be updated here */

    status = ICM_OK;
    return status;
}

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

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

    /* Decode data */
    hw_id = *dp;

    printf("Recovered HW ID ERR RECOV is %d\n",hw_id);

    rsp_enc_id = OBC_PS_OBC_HW_ERR_RECOV_NTF;
    status = ICM_OK;
    return status;
}

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

/*!
 * @brief This API decodes the Interface Control Message of
 * target pointing response
 */
int8 ps_obc_trgt_pt_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    trgt_pt_rsp_val = *dp;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * GNSS location sharing response
 */
int8 ps_obc_gnss_loc_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    gli.status = *dp++;
    memcpy(&gli.lat,dp,4); dp += 4;
    memcpy(&gli.longit,dp,4); dp += 4;
    memcpy(&gli.alt,dp,4);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * Keep alive response from OBC
 */
int8 ps_obc_keep_alive_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    printf("Keep alive response obtained from OBC\n");

    /* Required PS controller handling need to be added here */

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    pwr_on_schd_rsp_val = *dp;

    printf("OBC Power on Schedule response %d\n",pwr_on_schd_rsp_val);

    status = ICM_OK;
    return status;
}
int8 ps_obc_radio_pwr_on_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    rpo.pwr_on_rsp = *dp++;
    rpo.pwr_on_retry_req_dur = *dp;

    printf("OBC radio Power on response %d retry dur %d\n",rpo.pwr_on_rsp,rpo.pwr_on_retry_req_dur);

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    memcpy(&gct,dp,sizeof(obc_get_curr_time));
    printf("OBC get time min %d hour %d mday %d mon %d year %d wday %d yday %d isday %d\n",gct.min,gct.hour,gct.mday,gct.mon,gct.year,gct.wday,gct.yday,gct.isday);

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    res = *dp++;

    printf("OBC radio Power off response %d\n",res);

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    res = *dp++;

    printf("OBC radio rx enable disabe response %d\n",res);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * alert registration response for orbit parameter
 */
int8 ps_obc_reg_orbit_trig_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    reg_orbit_trig_rsp_val = *dp;

    status = ICM_OK;
    return status;
}

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

    reg_grnd_stn_ps_ntf_rsp_val = *dp;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * response from OBC for handshake notification initiated by PS
 */
int8 ps_obc_pwr_on_hndsk_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;

    /* Required PS controller handling need to be added here */
    printf("OBC response for PS Power on handshake notification\n");

    /* Trigger next set of events */
    ps_evnt_trig = PS_OBC_PS_APP_ID_LIST_NTF;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * response from OBC for handshake notification initiated by PS
 */
int8 ps_obc_radio_data_tx_cplt_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint8 rsp_sts;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    rsp_sts = *dp;

    /* Required PS controller handling need to be added here */
    printf("OBC response for PS radio data tx complete notification is %d\n",rsp_sts);

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * response from OBC for SSD error notification initiated by PS
 */
int8 ps_obc_ssd_err_ntf_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    uint8 rsp_sts;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    rsp_sts = *dp;

    /* Required PS controller handling need to be added here */
    printf("OBC response for SSD error swtich notification is %d\n",rsp_sts);

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    rsp_sts = *dp;

    /* Required PS controller handling need to be added here */
    printf("OBC response for hardware error recovery notification is %d\n",rsp_sts);

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    rsp_sts = *dp;

    /* Required PS controller handling need to be added here */
    printf("OBC response for ps shutdown notification is %d\n",rsp_sts);

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    ps_hw_pwr_on_rsp_val = *dp;

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    ps_hw_pwr_off_rsp_val = *dp;

    status = ICM_OK;
    return status;
}

int8 ps_obc_obc_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, i;
    uint16* ptr;

    /* Decode data */
    num_app = *dp;
    printf("Response recevied total app id %d\n",*dp);
    ptr = (uint16*)(dp+1);
    for(i=0; i< num_app; i++)
    {
        app_id = *ptr++;
        printf("APP ID is %x\n",app_id);
        app_id = *ptr++;
        printf("Peer APP ID is %x\n",app_id);
    }

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    num_hw = *dp;
    printf("Response recevied total HW id %d\n",*dp);
    ptr = (uint16*)(dp+1);
    for(i=0; i< num_hw; i++)
    {
        hw_id = *ptr++;
        printf("HW ID is %x\n",hw_id);
    }

    status = ICM_OK;
    return status;
}

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

    /* Decode data */
    obc_app_qos_pri_ptr = malloc(temp_len);
    memcpy(obc_app_qos_pri_ptr,dp,temp_len);
    printf("Response recevied number of pri enteries %d\n",*obc_app_qos_pri_ptr++);
    int i=0;
    while(i < (temp_len-1))
    {
        printf("obc app id qos pri %x\n",*obc_app_qos_pri_ptr++);
        i++;
    }

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API decodes the Interface Control Message of
 * Simulation event trigger of OBC powering ON PS
 */
int8 obc_ps_simu_ps_pwr_on_cmd_dec(const uint8 *data, uint16 len)
{
    int8 status;

    /* Trigger next set of events */
    ps_evnt_trig = PS_OBC_PWR_ON_HNDSK_NTF;

    status = ICM_OK;
    return status;
}
#endif

/*!
 * @brief This API decodes the Interface Control Message of
 * target pointing response
 */
int8 es_obc_trgt_pt_rsp_dec(const uint8 *data, uint16 len)
{
    int8 status;
    const uint8 *dp = (data + ICM_HDR_LEN);

    /* Decode data */
    trgt_pt_rsp_val = *dp;

    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;
    printf("ICM Response Encoder handler not assigned for current CRRN ID\n");
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * ES shutdown command
 */
int8 obc_es_pwr_off_rsp_enc(uint8** data, uint16* len, uint8 shut_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    hdr.crrn_id = OBC_ES_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 = shut_rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}
#if 0
/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * PS shutdown command
 */
int8 obc_ps_pwr_off_rsp_enc(uint8** data, uint16* len, uint8 shut_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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 = shut_rsp;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * payload hardware power off command
 */
int8 obc_ps_pld_hw_pwr_off_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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;
    **data = rsp_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * payload Virtual Machine power off command
 */
int8 obc_ps_vm_pwr_off_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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;
    **data = rsp_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * payload Virtual Machine power on command
 */
int8 obc_ps_vm_pwr_on_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

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

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_get_temp_info_rsp_enc(uint8** data, uint16* len, uint8 temp_info_resp)
{ 
    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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

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

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_get_time_info_rsp_enc(uint8** data, uint16* len, ps_get_time_s *ps_get_time)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = sizeof(ps_get_time_s);
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    /* Encode data parameters */
    *data += hdr_len;
    memcpy(*data,ps_get_time,sizeof(ps_get_time_s));

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_get_chip_info_rsp_enc(uint8** data, uint16* len, ps_get_chip_info_s *ps_get_chip_info,ps_get_feature_s *ps_get_features)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = sizeof(ps_get_chip_info_s)+sizeof(ps_get_features);
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    /* Encode data parameters */
    *data += hdr_len;
    memcpy(*data,ps_get_chip_info,sizeof(ps_get_chip_info_s));
    memcpy(*data+sizeof(ps_get_chip_info_s),ps_get_features,sizeof(ps_get_feature_s));

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_get_ext_mem_rsp_enc(uint8** data, uint16* len, ps_get_ext_mem_s *ps_get_ext_mem)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = sizeof(ps_get_ext_mem_s);
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    /* Encode data parameters */
    *data += hdr_len;
    memcpy(*data,ps_get_ext_mem,sizeof(ps_get_ext_mem_s));

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}


/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * TC_TM data from PS to OBC
 */
int8 obc_ps_tc_tm_msg_rsp_enc(uint8** data, uint16* len, \
        icm_tm_pld_info_s *tm_pld_info)
{
    int8 status;
    icm_header_s hdr;
    uint16 hdr_len = ICM_HDR_LEN, data_len = (6+tm_pld_info->tm_pld_len);
    *len = (hdr_len + data_len);

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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;
    memcpy(*data,&tm_pld_info->tm_id,2); *data += 2;
    **data = tm_pld_info->src_id; *data += 1;
    **data = tm_pld_info->dst_id; *data += 1;
    **data = tm_pld_info->tm_pld_len; *data += 2;
    memcpy(*data,tm_pld_info->tm_pld_buff,tm_pld_info->tm_pld_len);

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * PS Keep alive response
 */
int8 obc_ps_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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 response for Interface Control Messsage of
 * ground station pass alert
 */
int8 obc_ps_gs_pass_ntf_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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 = rsp_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * Radio power ON notification
 */
int8 obc_ps_radio_pwr_on_ntf_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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 = rsp_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

/*!
 * @brief This API encodes the response for Interface Control Messsage of
 * Radio power OFF notification
 */
int8 obc_ps_radio_pwr_off_ntf_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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 = rsp_sts;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_obc_frim_updt_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    status = ICM_OK;
    return status;
}

int8 obc_ps_obc_rst_recv_updt_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    status = ICM_OK;
    return status;
}

int8 obc_ps_staged_tc_cmd_rsp_enc(uint8** data, uint16* len)
{
    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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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;
    **data = 0;

    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_obc_hw_err_recv_ntf_rsp_enc(uint8** data, uint16* len,uint8 res)
{
    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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    *data += hdr_len;
    **data = res;
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_app_id_list_req_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    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++ = 0x88;
    *app_id_info_ptr++ = 0x2001;
    *app_id_info_ptr++ = 0x89;
    *app_id_info_ptr++ = 0x2002;
    *app_id_info_ptr++ = 0x8a;
    *app_id_info_ptr++ = 0x2003;
    *app_id_info_ptr++ = 0x8b;
    *app_id_info_ptr++ = 0x2004;
    *app_id_info_ptr++ = 0x8c;
    *app_id_info_ptr++ = 0x2005;

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

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_app_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    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;
    memcpy(*data, buff_data, buf_len);
    *data = (uint8*)hdr_data;

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    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++ = 0x4000;
    *hw_id_info_ptr++ = 0x4001;
    *hw_id_info_ptr++ = 0x4002;
    *hw_id_info_ptr++ = 0x4003;
    *hw_id_info_ptr++ = 0x4004;

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

    status = ICM_OK;
    return status;
}

int8 obc_ps_ps_hw_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*)malloc(*len);
    *data = (uint8*)hdr_data;

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

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

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

    status = ICM_OK;
    return status;
}

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

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

    /* Encode header information */
    hdr.crrn_type = CRRN_TYPE_RSP;
    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);

    *data += hdr_len;
    **data = 1;
    *data += sizeof(int8);

    memcpy(*data, buff_data, buf_len);
    *data = (uint8*)hdr_data;

    printf("\n[XBAND] data in ICD encode: %d\n",buf_len);

    for(int i =0;i<buf_len;i++)
    {
        printf("\t %x",buff_data[i] );
    }

    status = ICM_OK;
    return status;
}

#endif
