/**
 * @file td_common.h
 *
 * @brief This file contains function prototypes and data definitions that
 * helps to create and unpack a TD frame
 *
 * @copyright Copyright 2023 Antaris, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef TD_LIB_H_
#define TD_LIB_H_

#include "tc_tm_lib_common.h"

#ifdef __cplusplus
extern "C" {
#endif
/**@}*/
/**\name C standard macros */
#ifndef NULL
#ifdef __cplusplus
#define NULL                            (0)
#else
#define NULL                            ((void *) 0)
#endif
#endif

/// Limits definitions
#define TD_ID_MAX               (255)    ///< Td id maximum limit

/// encrypt/decrypt and authentication related definitions
#define TD_CTRL_CRYPT_BIT      (0x20)   ///< encrypt/decrypt bit
#define TD_CTRL_CRYPT_POS      (0x5)    ///< encrypt/decrypt bit position
#define TD_CTRL_AUTH_BIT       (0x10)   ///< encrypt/decrypt bit
#define TD_CTRL_AUTH_POS       (0x4)    ///< encrypt/decrypt bit position
#define TD_KEY                 ("tele_data_secret_key") ///< key used for hmac
                                                          /// calculation

/// Corelation id related definitions
#define TD_CTRL_CO_ID_BIT       (0x40) ///< Notification/ Response bit
#define TD_CTRL_CO_ID_POS       (0x6)  ///< Notification/ Response bit position

/*************************** Data structures *********************************/
/**
 * @brief tele data frame structure definition
 *
 */
typedef struct td_frame
{
    uint8   sof1;                  /*!< Start of Frame indicator 1*/
    uint8   sof2;                  /*!< Start of Frame indicator 2*/
    uint8   td_ctrl;               /*!< Tele-data control */
    uint32  time_stamp;            /*!< Time stamp value */
    uint16  seq_no;                /*!< Sequence number */
    uint16  sat_id;                /*!< Satellite id */
    uint8   qos;                   /*!< Quality Of Service */
    uint16  sa_id;                 /*!< Souce Application id */
    uint16  da_id;                 /*!< Destination Application id */
    uint8   rm_id;                 /*!< Radio Module id */
    uint8  td_id;                  /*!< Tele-data id */
    uint16  td_co_id;              /*!< correlation id */
    uint16  td_len;                /*!< Tele-data data length */
    uint8*  td_data;               /*!< Tele-data data */
    uint8*  keys;                  /*!< Encryption-decryption keys */
    uint16  sec_cfg;               /*!< Sec configuration */
    uint16  mac_cfg;               /*!< Mac configuration */
    uint8   crc_8;                 /*!< CRC value */
    uint8*  cmac_hmac;             /*!< CMAC/HMAC value */
    uint8   eof;                   /*!< End of Frame indicator */
}s_td_frame;

/**
 * @brief function pointer to trigger function
 */

typedef   int (*td_trgr_ptr)(s_td_frame *);


/**
 * @brief structure that holds the tc id and it's corresponding trigger
 *        function pointer
 */
typedef struct td_terminator
{
    uint8  td_id;                    /*!< Tele-data id  */
    td_trgr_ptr  td_func[TD_ID_MAX]; /*!< Array of pointer to tc id handlers */
}s_td_terminator;

/**
 * @brief structure that holds routing table information. The values stored in
 *        this structure varies based on the comm protocol used.
 */
typedef struct td_rout_table
{
    uint32 port;                   /*!< Port number or slave register address*/
    uint32 addr;                   /*!< IP address or master address */
}s_td_rout_table;

/**
 * @brief structure that holds routing table information.
 */
typedef struct td_fwd
{
    s_td_rout_table rout_table;   /*!< Routing table of type s_td_rout_table */
}s_td_fwd;

/**
 * @brief Control field info structure for teledata
 */
typedef struct td_ctrl
{
    uint8 source_dest : 1;    /*!< Source Destination identifier */
    uint8 tx_mode     : 1;    /*!< Transmit or re-transmit mode */
    uint8 comm_mode   : 2;    /*!< cast modes */
    uint8 auth        : 1;    /*!< Authenticated/Unautheticated */
    uint8 encrypt     : 1;    /*!< Unencrypted/Encrypted */
    uint8 td_msg_typ  : 1;    /*!< Notification/Response */
    uint8 reserved    : 1;    /*!< Reserved */
}s_td_ctrl;

/**
 * @brief Utility data type to populate s_td_ctrl structure
 */
typedef union
{
    s_td_ctrl ctrl;          /*!< s_td_ctrl structure instance */
    uint8 byte;              /*!< 8 bit utility variable  */
}s_td_ctrl_util;

/**
 * @brief This API initializes the s_td_frame by setting all the values of it's
 *        memebers to zero.
 *
 * @param[in] td_orig     : Structure instance of s_td_frame.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_init(s_td_frame *td_orig);

/**
 * @brief This API stores the start of frame passed in sof1 and sof2 value to
 * to the sof1 and sof2 members of passed in s_td_frame type struct.
 *
 * @param[in] td_orig     : Structure instance of s_td_frame.
 * @param[in] sof1         : Start Of Frame 1(sof1) value.
 * @param[in] sof2         : Start Of Frame 2(sof2) value.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_sof(s_td_frame *td_orig, uint8 sof1, uint8 sof2);

/**
 * @brief This API stores the passed in td_ctrl value to the td_ctrl member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig     : Structure instance of s_td_frame.
 * @param[in] td_ctrl     : td_ctrl value.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_td_ctrl(s_td_frame *td_orig, uint8 td_ctrl);

/**
 * @brief This API stores the passed in seq_no_in value to the seq_no member
 * of passed in s_td_frame type struct and also updates the global seq_no.
 *
 * @param[in] td_orig     : Structure instance of s_td_frame.
 * @param[in] seq_no_in   : Sequence number.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_seq_no(s_td_frame* td_orig, uint16 seq_no_in);

/**
 * @brief This API stores the passed in sat_id value to the sat_id member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] sat_id     : Satellite Id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_sat_id(s_td_frame* td_orig, uint16 sat_id);

/**
 * @brief This API stores the passed in priority value to the qos member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] priority   : Quality Of Service value.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_qos(s_td_frame* td_orig, uint8 priority);

/**
 * @brief This API stores the passed in sa_id value to the sa_id member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] sa_id      : Source Application Id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_sa_id(s_td_frame* td_orig, uint16 sa_id);

/**
 * @brief This API stores the passed in da_id value to the da_id member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] da_id      : Destination Application Id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_da_id(s_td_frame* td_orig, uint16 da_id);

/**
 * @brief This API stores the passed in rm_id value to the rm_id member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] rm_id      : Radio Module Id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_rm_id(s_td_frame* td_orig, uint8 rm_id);

/**
 * @brief This API stores the passed in td_id value to the td_id member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] td_id      : Teledata Id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_td_id(s_td_frame* td_orig, uint8 td_id);

/**
 * @brief This API stores the passed in co_id value to the td_co_id member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] co_id      : Correlation Id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_co_id(s_td_frame* td_orig, uint16 co_id);

/**
 * @brief This API stores the passed in td_len value to the td_len member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] td_len      : Teledata Length.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_td_len(s_td_frame* td_orig, uint16 td_len);

/**
 * @brief This API stores the passed in data to the td_data member of
 *         the passed in s_td_frame type struct. The size of data copied is
 *         equal to td_len. So td_orig_cfg_td_len api needs to be called
 *         first before calling this api.
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] data       : Pointer to the data that needs to be copied.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_td_data(s_td_frame* td_orig, uint8 *data);

/**
 * @brief This API stores the passed in crc_8 value to the crc_8 member of
 *         the passed in s_td_frame type struct
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] crc_8      : crc8 value.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_crc_8(s_td_frame* td_orig, uint8 crc_8);

/**
 * @brief This API stores the passed in hmac to the hmac member of
 *         the passed in s_td_frame type struct. The size of data copied is
 *         equal to size input value.
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 * @param[in] hmac       : Pointer to the computed hmac.
 * @param[in] size       : size of hmac that needs to be copied
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR or other values ->
 *          Error.
 */
int8 td_orig_cfg_hmac(s_td_frame* td_orig, uint8 *hmac, size_t size);

/**
 * @brief This API stores the passed in eof value to the eof member of the
 *        passed in s_td_frame type struct
 *
 * @param[in] td_orig     : Structure instance of s_td_frame.
 * @param[in] eof         : End Of Frame (eof) value.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_cfg_eof(s_td_frame *td_orig, uint8 eof);

/**
 * @brief This API calculates the crc for the passed in input_str
 *         for the input size and stores the crc value to the val parameter
 *         equal to size input value.
 *
 * @param[in] input_str : Input buffer for which the crc needs to be calculated
 * @param[out] val      : Pointer to the computed crc.
 * @param[in] size      : size of the input buffer
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR or other values ->
 *         Error.
 */
int8 td_orig_compute_crc(const uint8 *input_str, uint8* val, size_t size);

/**
 * @brief This API calculates the hmac with the key and key size
 *         for the passed in buffer of size "datasize" and store
 *         the computed hmac value to the out parameter
 *
 * @param[in] td_orig : Input buffer for which the hmac needs to be calculated
 * @param[in] key     : Key used for the calculation of the hmac
 * @param[in] keysize : size of the input key
 * @param[in] datasize : size of the input buffer
 * @param[out] out    : Pointer to the computed hmac.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR or other values ->
 *         Error.
 */
size_t td_orig_compute_hmac(s_td_frame* td_orig, const uint8* key,\
                             const uint32 keysize, const uint32 datasize,\
                                                              void* out);

/**
 * @brief This API resets the sequence number to one
 *
 * @return No return value as it is a void api
 */
void td_orig_reset_seq_no(void);

/**
 * @brief This API resets the timestamp to zero
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_reset_time_stamp(s_td_frame* td_orig);

/**
 * @brief This API copies the passed in encryption related parameters to the
 *        local structure. The parameters are utilised from the local structure
 *        during the encryption operation in td_pack() api
 *
 * @param[in] param    : Structure instance of s_crypt_params.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_orig_select_encryption(s_crypt_params *param);

/**
 * @brief This API encrypts the passed in buffer of size "length" based on the
 *        input encryption "param" and stores the encrypted buffer to the
 *        "output" parameter
 *
 * @param[in] param   : Structure instance of s_crypt_params.
 * @param[in] buf     : Input buffer to be encrypted
 * @param[in] length  : size of the input buffer
 * @param[out] output : Pointer to the encrypted buffer.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR or any other value ->
 *         Error.
 */
int32 td_orig_encrypt_data(s_crypt_params *param, const uint8 *buf,\
                                       int32 length, uint8 *output);

/**
 * @brief This API decrypts the passed in buffer of size "length" based on the
 *        input decryption "param" and stores the decrypted buffer to the
 *        "output" parameter
 *
 * @param[in] param   : Structure instance of s_crypt_params.
 * @param[in] buf     : Input buffer to be decrypted
 * @param[in] length  : size of the input buffer
 * @param[out] output : Pointer to the decrypted buffer.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR or any other value ->
 *          Error.
 */
int32 td_orig_decrypt_data(s_crypt_params *param, const uint8 *buf,\
                                      size_t length, uint8 *output);

/**
 * @brief This API stores the route_param with it's da_id by inserting
 *  the new node to the end of the linear linked list. If the head
 *  node is not nulland the new node is null, the route_param will
 *  be stored with the head node
 *
 * @param[in] td_fwd_head   : head node.
 * @param[in] new_node   : Pointer to new node
 * @param[in] da_id   : destination application id
 * @param[out] route_param  : Pointer to the routing parameters
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR
 *         TC_TM_LIB_SEARCH_ERROR -> Error.
 */
int8 td_add_rout_table(node *td_fwd_head, node *new_node,\
                                    uint16 da_id, void* route_param);

/**
 * @brief This API copies the routing parameters to the route_param
 *        based on the td_orig->da_id. td_fwd_add_rout_table ()
 *        need to invoked first to configure the routing table with da_id.
 *
 * @param[in] td_orig   : Structure instance of s_td_frame.
 * @param[in] td_fwd_head   : head node.
 * @param[out] route_param  : Pointer to the routing parameters
 * @param[in] size  : size of the routing table
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_SEARCH_ERROR if No routing
 *   parameter found for the da_id or TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_route_pkt_hdrs(s_td_frame *td_orig, node *td_fwd_head,\
                                void* route_param, size_t size);

/**
 * @brief This API copies the routing parameters to the route_param
 *        based on the td_orig->da_id and td_orig->data to the data param
 *        of size td_orig->td_len. td_fwd_add_rout_table () need to invoked
 *        first to configure the routing table with da_id.
 *
 * @param[in] td_orig   : Structure instance of s_td_frame.
 * @param[in] td_fwd_head   : head node.
 * @param[out] route_param  : Pointer to the routing parameters
 * @param[in] size  : size of the routing table
 * @param[out] data  : Pointer to the copied data
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_SEARCH_ERROR if No 
 * routing parameter found for the da_id or TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_route_pkt(s_td_frame *td_orig, node *td_fwd_head,\
                              void* route_param, size_t size, uint8* data);

/**
 * @brief This API stores the start of frame (sof1 and sof2) from the sof
 * members of passed in s_td_frame type struct to passed in sof1
 * and sof2 pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] sof1       : Pointer to sof1 data.
 * @param[out] sof2       : Pointer to sof2 data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_sof(s_td_frame *td_term, uint8 *sof1, uint8 *sof2);

/**
 * @brief This API populates the members of td_ctrl input structure based on
 *         the td_term->td_ctrl value.
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] td_ctrl   : Structure instance of s_td_ctrl.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_td_ctrl(s_td_frame *td_term, s_td_ctrl *td_ctrl);

/**
 * @brief This API stores the sequence number (seq_no) from the seq_no
 *        member of passed in s_td_frame type struct to passed in seq_no
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] seq_no       : Pointer to seq_no data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_seq_no(s_td_frame *td_term, uint16 *seq_no);

/**
 * @brief This API stores the satellite id (sat_id) from the sat_id
 *        member of passed in s_td_frame type struct to passed in sat_id
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] sat_id       : Pointer to sat_id data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_sat_id(s_td_frame *td_term, uint16 *sat_id);

/**
 * @brief This API stores the quality of service (qos) from the qos
 *        member of passed in s_td_frame type struct to passed in qos
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] qos       : Pointer to qos data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_qos(s_td_frame *td_term, uint16 *qos);

/**
 * @brief This API stores the source application id (sa_id) from the sa_id
 *        member of passed in s_td_frame type struct to passed in sa_id
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] sa_id       : Pointer to sa_id data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_sa_id(s_td_frame *td_term, uint16 *sa_id);

/**
 * @brief This API stores the destination application id (da_id) from the da_id
 *        member of passed in s_td_frame type struct to passed in da_id
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] da_id       : Pointer to da_id data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_da_id(s_td_frame *td_term, uint16 *da_id);

/**
 * @brief This API stores the Radio module id (rm_id) from the rm_id
 *        member of passed in s_td_frame type struct to passed in rm_id
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] rm_id       : Pointer to rm_id data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_rm_id(s_td_frame *td_term, uint8 *rm_id);

/**
 * @brief This API stores the tele data id (td_id) from the td_id
 *        member of passed in s_td_frame type struct to passed in td_id
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] td_id       : Pointer to td_id data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_td_id(s_td_frame *td_term, uint8 *td_id);

/**
 * @brief This API stores the td_co_id (coorelation id)of passed in
 * s_td_frame type struct to passed in td_id value.
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] co_id     : Pointer to correlation id.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_co_id(s_td_frame *td_term, uint16 *co_id);

/**
 * @brief This API stores the tele data data length (td_len) from the td_len
 *        member of passed in s_td_frame type struct to passed in td_len
 *        pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] td_len    : Pointer to td_len data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_td_len(s_td_frame *td_term, uint16 *td_len);

/**
 * @brief This API stores the end of frame (eof) from the sof member of passed
 *        in s_td_frame type struct to passed in eof pointer
 *
 * @param[in] td_term    : Structure instance of s_td_frame.
 * @param[out] eof       : Pointer to eof data.
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_extract_eof(s_td_frame *td_term, uint8 *eof);

/**
 * @brief This API stores the teledata id (td_id) and the td_func function
 *        pointer to the td_term and keeps a local copy of it. The
 *        td_unpack_trigger api utilizes this to trigger td_func when ever it
 *        receives the corresponding td_id
 *
 * @param[in] td_term    : Structure instance of s_td_terminator.
 * @param[in] td_id      : tele data id
 * @param[in] td_func    : function pointer for the corresponding td_id
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_add_td_func(s_td_terminator* td_term, uint8 td_id,\
                                            td_trgr_ptr td_func);

/**
 * @brief This API removes the td_func function for the tele data id (td_id)
 *        from the local copy
 *
 * @param[in] td_term    : Structure instance of s_td_terminator.
 * @param[in] td_id      : tele data id
 *
 * @return Result of API execution status
 * @retval TC_TM_LIB_OK -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
int8 td_term_remove_td_func(s_td_terminator* td_term, uint8 td_id);

/**
 * @brief This API copies the structure data to the output buffer(dst). While 
 * copying it takes care of the extension bit for the required members.
 * Finally it computes CRC ,hmac and embeds those value to the final 
 * output buffer(dst).
 *
 * @param[out] dst     : pointer to the output buffer
 * @param[in] td_orig  : Structure instance of s_td_frame.
 *
 * @return Size of the output buffer if all operations are 
 *         success else failure code
 * @retval 0 or greater than zero-> success less than zero ->failure
 */
int32 td_pack(uint8 *dst, s_td_frame *td_orig);

/**
 * @brief This API copies the structure data to the input buffer(dst) to the
 *        input structure. It also computes crc and hmac for the input buffer
 *        and compares it with the embedded values.
 *
 * @param[in] dst     : pointer to the input buffer
 * @param[out] td_orig  : Structure instance of s_td_frame.
 *
 * @return Size of the unpacked data if the crc and hmac checks are success 
 *         else failure code
 * @retval 0 or greater than zero-> success less than zero ->failure
 */
int32 td_unpack(const uint8 *dst, s_td_frame *td_orig);

/**
 * @brief This API copies the structure data to the input buffer(dst) to the
 *        input structure. It also computes crc and hmac for the input buffer
 *        and compares it with the embedded values. It also triggers the user
 *        function if the user function is mapped with the received
 *        td_orig->td_id with td_term_add_td_func() api
 *
 * @param[in] dst     : pointer to the input buffer
 * @param[out] td_orig  : Structure instance of s_td_frame.
 *
 * @return return status of the triggered function if the crc and hmac checks
 *          are success else failure code
 * @retval return status of the triggered function
 */
int8 td_unpack_trigger(const uint8 *dst, s_td_frame *td_orig);

/**
 * @brief This API triggers the user function if the user function is
 *        mapped with the received td_orig->td_id with 
 *        td_term_add_td_func() api
 *
 * @param[in] td_orig    : Structure instance of s_td_frame.
 *
 * @return return status of the triggered function. Returns null poiner If no
 *         trigger function is found returns or if the input is null pointer
 * @retval return status of the triggered function else TC_TM_LIB_NULL_PTR ->
 *           Error.
 */
int8 td_trgr_func(s_td_frame *td_orig);

#ifdef __cplusplus
}
#endif
#endif /*TD_LIB_H_ */
