#ifndef UDS_TYPES_H_
#define UDS_TYPES_H_

#include <stdint.h>

typedef uint8_t uds_bool_t;
typedef uint8_t uds_u8_t;
typedef uint16_t uds_u16_t;
typedef uint32_t uds_u32_t;
typedef int32_t uds_s32_t;
typedef uint8_t uds_sid_t;
typedef uint8_t uds_subfunc_t;
typedef uint32_t uds_channel_t;

#define uds_true ((uds_bool_t)1)
#define uds_false ((uds_bool_t)0)

#define UDS_SESSION_DEFAULT 0x1U
#define UDS_SESSION_PROGRAMMING 0x2U
#define UDS_SESSION_EXTENDED_DIAGNOSTIC 0x4U
#define UDS_SESSION_SAFETY_SYSTEM 0x8U
#define UDS_SESSION_5 0x10U
#define UDS_SESSION_6 0x20U
#define UDS_SESSION_7 0x40U
#define UDS_SESSION_8 0x80U
#define UDS_SESSION_9 0x100U
#define UDS_SESSION_10 0x200U
#define UDS_SESSION_11 0x400U
#define UDS_SESSION_12 0x800U
#define UDS_SESSION_13 0x1000U
#define UDS_SESSION_14 0x2000U
#define UDS_SESSION_15 0x4000U
#define UDS_SESSION_16 0x8000U
#define UDS_SESSION_17 0x10000U
#define UDS_SESSION_18 0x20000U
#define UDS_SESSION_19 0x40000U
#define UDS_SESSION_20 0x80000U
#define UDS_SESSION_21 0x100000U
#define UDS_SESSION_22 0x200000U
#define UDS_SESSION_23 0x400000U
#define UDS_SESSION_24 0x800000U
#define UDS_SESSION_25 0x1000000U
#define UDS_SESSION_26 0x2000000U
#define UDS_SESSION_27 0x4000000U
#define UDS_SESSION_28 0x8000000U
#define UDS_SESSION_29 0x10000000U
#define UDS_SESSION_30 0x20000000U
#define UDS_SESSION_31 0x40000000U
#define UDS_SESSION_32 0x80000000U
#define UDS_SESSION_ALL 0xFFFFFFFFU



#define UDS_SECURITY_LEVEL_NULL 0x1U
#define UDS_SECURITY_LEVEL_L1 0x2U
#define UDS_SECURITY_LEVEL_L2 0x4U
#define UDS_SECURITY_LEVEL_L3 0x8U
#define UDS_SECURITY_LEVEL_L4 0x10U
#define UDS_SECURITY_LEVEL_L5 0x20U
#define UDS_SECURITY_LEVEL_L6 0x40U
#define UDS_SECURITY_LEVEL_L7 0x80U
#define UDS_SECURITY_LEVEL_L8 0x100U
#define UDS_SECURITY_LEVEL_L9 0x200U
#define UDS_SECURITY_LEVEL_L10 0x400U
#define UDS_SECURITY_LEVEL_L11 0x800U
#define UDS_SECURITY_LEVEL_L12 0x1000U
#define UDS_SECURITY_LEVEL_L13 0x2000U
#define UDS_SECURITY_LEVEL_L14 0x4000U
#define UDS_SECURITY_LEVEL_L15 0x8000U
#define UDS_SECURITY_LEVEL_L16 0x10000U
#define UDS_SECURITY_LEVEL_L17 0x20000U
#define UDS_SECURITY_LEVEL_L18 0x40000U
#define UDS_SECURITY_LEVEL_L19 0x80000U
#define UDS_SECURITY_LEVEL_L20 0x100000U
#define UDS_SECURITY_LEVEL_L21 0x200000U
#define UDS_SECURITY_LEVEL_L22 0x400000U
#define UDS_SECURITY_LEVEL_L23 0x800000U
#define UDS_SECURITY_LEVEL_L24 0x1000000U
#define UDS_SECURITY_LEVEL_L25 0x2000000U
#define UDS_SECURITY_LEVEL_L26 0x4000000U
#define UDS_SECURITY_LEVEL_L27 0x8000000U
#define UDS_SECURITY_LEVEL_L28 0x10000000U
#define UDS_SECURITY_LEVEL_L29 0x20000000U
#define UDS_SECURITY_LEVEL_L30 0x40000000U
#define UDS_SECURITY_LEVEL_L31 0x80000000U
#define UDS_SECURITY_LEVEL_ALL 0xFFFFFFFFU






/*Represents UDS negative response codes (see ISO 14229-1:2013 §A.1 Negative response codes p.325).*/
typedef enum {
    UDS_NRC_PR = 0x00,
    UDS_NRC_GR = 0x10,
    UDS_NRC_SNS = 0x11,
    UDS_NRC_SFNS = 0x12,
    UDS_NRC_IMLOIF = 0x13,
    UDS_NRC_RTL = 0x14,
    UDS_NRC_BRR = 0x21,
    UDS_NRC_CNC = 0x22,
    UDS_NRC_RSE = 0x24,
    UDS_NRC_NRFSC = 0x25,
    UDS_NRC_FPEORA = 0x26,
    UDS_NRC_ROOR = 0x31,
    UDS_NRC_SAD = 0x33,
    UDS_NRC_AR = 0x34,
    UDS_NRC_IK = 0x35,
    UDS_NRC_ENOA = 0x36,
    UDS_NRC_RTDNE = 0x37,
    UDS_NRC_SDTR = 0x38,
    UDS_NRC_SDTNA = 0x39,
    UDS_NRC_SDTF = 0x3A,
    UDS_NRC_CVFITP = 0x50,
    UDS_NRC_CVFISIG = 0x51,
    UDS_NRC_CVFICOT = 0x52,
    UDS_NRC_CVFITE = 0x53,
    UDS_NRC_CVFIF = 0x54,
    UDS_NRC_CVFIC = 0x55,
    UDS_NRC_CVFISCP = 0x56,
    UDS_NRC_CVFICERT = 0x57,
    UDS_NRC_OVF = 0x58,
    UDS_NRC_CCF = 0x59,
    UDS_NRC_SARF = 0x5A,
    UDS_NRC_SKCDF = 0x5B,
    UDS_NRC_CDUF = 0x5C,
    UDS_NRC_DAF = 0x5D,
    UDS_NRC_UDNA = 0x70,
    UDS_NRC_TDS = 0x71,
    UDS_NRC_GPF = 0x72,
    UDS_NRC_WBSC = 0x73,
    UDS_NRC_RCRRP = 0x78,
    UDS_NRC_SFNSIAS = 0x7E,
    UDS_NRC_SNSIAS = 0x7F,
    UDS_NRC_RPMTH = 0x81,
    UDS_NRC_RPMTL = 0x82,
    UDS_NRC_EIR = 0x83,
    UDS_NRC_EINR = 0x84,
    UDS_NRC_ERTTL = 0x85,
    UDS_NRC_TEMPTH = 0x86,
    UDS_NRC_TEMPTL = 0x87,
    UDS_NRC_VSTH = 0x88,
    UDS_NRC_VSTL = 0x89,
    UDS_NRC_TPTH = 0x8A,
    UDS_NRC_TPTL = 0x8B,
    UDS_NRC_TRNIN = 0x8C,
    UDS_NRC_TRNIG = 0x8D,
    UDS_NRC_BSNC = 0x8F,
    UDS_NRC_SLNIP = 0x90,
    UDS_NRC_TCCL = 0x91,
    UDS_NRC_VTH = 0x92,
    UDS_NRC_VTL = 0x93,
} uds_nrc_t;

typedef enum
{
    UDS_IDLE  =  0x01u,       /**< Uds state idle */
    UDS_RECEIVING =  0x02u,   /**< Uds state receiving data */
    UDS_PROCESSING =  0x03u,  /**< Uds state processing data */
    UDS_SENDING   =  0x06u,   /**< Uds state sending response */
} uds_last_item_status_t;





typedef enum
{
    UDS_CANTP,  /**< Can tp */
    UDS_LINTP,  /**< Lin tp */
} uds_tp_t;
typedef struct
{
    uds_u32_t channel;                            /**< Uds channel */
    uds_u32_t channelId;                          /**< Channel id in cantp/lintp*/
    uds_u32_t sessionMode;                        /**< Active session*/
    uds_bool_t serverTimerEnable;                 /**< S3timer enable */
    uds_s32_t curServerTime;                      /**< Current server time */
    uds_u32_t secureLevel;                        /**< Current secure level */
    uds_last_item_status_t channelState;          /**< State of last data */
    uds_u16_t receivedDataLength;                 /**< Received data length */
    uds_u8_t *receivedData;                       /**< Received data */
    uds_u8_t *transmitData;                       /**< Dransmit data */
    uds_s32_t pendingDataIndex;                   /**< Pending data index in config */
    void *pendingParam;                           /**< Pending param */
    uds_u8_t pendingNum;                              
}uds_state_t;



typedef enum{
    UDS_OK = 0,                                /**< No error */
    UDS_PRE_TX_ERROR = 1,                      /**< Error of tx happened before transmit*/
    UDS_TX_ERROR = 2,                          /**< Error of tx happened in tp */
    UDS_RX_ERROR = 3,                          /**< Error of rx happened in tp */
}uds_error_t;

typedef struct uds_rule_config_t
{
    const uds_u8_t *rxData;                   /**< receive data */
    const uds_u8_t *rxMask;                   /**< receive data mask */
    uds_u8_t rxMatchLength;                   /**< data match length */
    uds_u32_t sessionMask;                    /**< supported sessions of the data */
    uds_u32_t secureLevelMask;                /**< supported secure level of the data */
    void (*callback)(uds_channel_t channel, uds_u8_t* data, uds_u16_t dataLength, void* param); /**< callback of the data */
} uds_rule_config_t;

typedef struct
{
    uds_u8_t channel;                                                     /**< Uds channel */
    uds_tp_t channelType;                                                 /**< Channel type*/
    uds_u32_t channelId;                                                  /**< Channel id in Tp layer*/
    uds_u32_t s3ServerTime;                                               /**< S3 server time */
    uds_u16_t bufferSize;                                                 /**< Buffer size */
    uds_u32_t ruleConfigNum;                                              /**< Rule config num */
    const uds_rule_config_t *ruleConfig;                                  /**< Rule config */
    void (*rxCallback)(uds_channel_t channel, uds_u8_t* data, uds_u16_t dataLength); /**< Rx callback */
    void (*errorCallback)(uds_channel_t channel,uds_error_t error);       /**< Error callback */
} uds_config_t;

#endif
