/**
 * @file tc_tm_lib_common.h
 *
 * @brief This file contains function prototypes and types that is common for
 *        all tc tm and td modules
 *
 * @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 TC_TM_LIB_COMMON_H_
#define TC_TM_LIB_COMMON_H_

#include "exo_types.h"
#include <time.h>
#include <checksum.h>
#include <exo_osal_mem_management.h>

#ifdef __cplusplus
extern "C" {
#endif

#define EXT_BIT_MASK    (0x80)
#define EXT_BIT_POS     (0x7)

/// Error code definitions

#define TC_TM_LIB_OK                    (0)   ///< Success return value
#define TC_TM_LIB_NULL_PTR             (-1)   ///< Null pointer return value
#define TC_TM_LIB_CRC_ERROR            (-2)   ///< CRC value mismatch
#define TC_TM_LIB_HMAC_ERROR           (-3)   ///< hmac value mismatch
#define TC_TM_LIB_SEARCH_ERROR         (-4)   ///< search failure
#define TC_TM_LIB_CRYPT_UNSUPPORTED    (-5)   ///< Unsupported encryption type
#define TC_TM_LIB_SOF_EOF_ERROR        (-6)   ///< Frame identifier error
#define TC_TM_LIB_EOF_ERROR            (-7)   ///< EOF identifier error
#define TC_TM_MIN_LEN_ERROR            (-8)   ///< TC/TM len less than min len
#define TC_TM_FULL_PLD_NOT_PRSNT       (-9)   ///< TC/TM Full payload not present in the input data
#define TC_TM_MAX_LEN_ERROR            (-10)  ///< TC/TM length greater than max len

/// Start of Frame and End of Frame definitions
#define TC_TM_LIB_SOF1                (0xa5)  ///< Start of Frame Identifier 1
#define TC_TM_LIB_SOF2                (0xaa)  ///< Start of Frame Identifier 2
#define TC_TM_LIB_EOF                 (0xba)  ///< End of Frame Identifier

/// TC Maximum length
#define TC_MAX_LEN                    (2*1024)  ///< TC maximum data length
///< hash key size
#define SHA256_HASH_SIZE              (256 / 8)

/// Encryption decryption functionality codes

/** 
  * @brief  GPIO Bit SET and Bit RESET enumeration
  */
typedef enum
{
  CRYPT_AES_CFB8 = 0,                ///< AES-CFB8 encryption or decryption
  CRYPT_AES_CFB8128                  ///< AES-CFB128 encryption or decryption
}e_crypt_mode;

typedef struct
{
    uint8 iv[16];
    uint8 *key;
    size_t key_size;
    e_crypt_mode encrypt_mode;
}s_crypt_params;

/**
 * @brief Utility structure that helps in searching routing table
 */
typedef struct node_struct
{
    uint16 da_id;                 /*!< destination application id */
    void* route_param;            /*!< ptr to routing table */
    struct node_struct *nxt;      /*!< ptr that holds the addr of next node */
}node;

/**
 * @brief This API returns utc epoch time.
 *
 * @param[in] : void
 *
 * @return epoch time
 * @retval epoch time
 */
time_t get_utc_epoch(void);

/**
 * @brief Copies 1 or 2 bytes from the src buffer to dst depending on the
 *        src data. If data is greater than 127, the extension bit (7th bit)
 *        is set and 2 bytes of data is copied to the destination.
 *
 * @param[in] src   : Pointer to source data.
 * @param[out] dst  : Pointer to the destination
 * @param[in] size  : size of the source dara
 *
 * @return size of data copied to destination pointer
 * @retval greather than zero -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
uint16 set_extnd_val_16(const uint16 *src, uint8 *dst, size_t size);

/**
 * @brief Copies 1 or 2 bytes from the src buffer to dst depending on the
 *        src data extension bit. If the extension bit (7th bit) is set,
 *        2 bytes of data is copied to the destination else 1 byte is copied
 *
 * @param[in] src   : Pointer to source data.
 * @param[out] dst  : Pointer to the destination
 * @param[in] size  : size of the source dara
 *
 * @return size of data copied to destination pointer
 * @retval greather than zero -> Success / TC_TM_LIB_NULL_PTR -> Error.
 */
uint16 get_extnd_val_16(const uint8 *src, uint16 *dst, 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] data : 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 Computed hmac length
 * @retval greather than zero -> success / TC_TM_LIB_NULL_PTR  -> Error.
 */
size_t compute_hmac(const uint8* data, const uint8* key, const uint32 keysize,\
                                             const uint32 datasize, void* out);

/**
 * @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 Zero -> Success / TC_TM_LIB_NULL_PTR -> Input null pointer
 *         TC_TM_LIB_CRYPT_UNSUPPORTED-> If unsupported encryption
 *         method is selected.
 */
int32 aes_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.
 *
 * @retval Zero -> Success / TC_TM_LIB_NULL_PTR -> Input null pointer
 *         TC_TM_LIB_CRYPT_UNSUPPORTED-> If unsupported encryption
 *         method is selected.
 */
int32 aes_decrypt_data(s_crypt_params *param, const uint8 *buf, int32 length,\
                                                              uint8 *output);

#ifdef __cplusplus
}
#endif
#endif /* TC_TM_LIB_COMMON_H_ */
