#ifndef HART_LIB_H
#define HART_LIB_H

#include "hart_settings.h"
#include "../DustNetworks/dn_endianness.h"

//=========================== define ==========================================

#define HART_BURST0 0
#define HART_BURST1 1
#define HART_BURST2 2
#define HART_BURST3 3
#define HART_BURST_ALL             HART_BURST_NUM

#define HART_EVENT0 0
#define HART_EVENT1 1
#define HART_EVENT2 2
#define HART_EVENT3 3
#define HART_EVENT_ALL             HART_EVENT_NUM

#define HART_MAX_FRAME_LENGTH           128u // TODO change to actual value

// flage returned by hart_lib_cmd when answer must not be generated
#define HART_LIB_DO_NOT_ANSWER            (-1)
#define HART_LIB_BUF_OVF                  (-2)
#define HART_LIB_FSM_NOT_READY            (-3)

//==== response codes HCF_SPEC-307
#define HART_RC_SUCESS                 0 
// 1 NOT DEFINED                       
#define HART_RC_INVALID_SELECTION      2
#define HART_RC_PARAM_TOO_LARGE        3
#define HART_RC_PARAM_TOO_SMALL        4
#define HART_RC_TOO_FEW_DATA           5
#define HART_RC_DEVICE_SPECIFIC_ERR    6  // must return 'device malfunction' and 'more status availible' in status byte
#define HART_RC_WRITE_PROTECTED        7
#define HART_RC_MULTI_WARNING_8        8
#define HART_RC_MULTI_ERR_9            9
#define HART_RC_MULTI_ERR_10          10
#define HART_RC_MULTI_ERR_11          11
#define HART_RC_MULTI_ERR_12          12
#define HART_RC_MULTI_ERR_13          13
#define HART_RC_MULTI_WARNING_14      14
#define HART_RC_MULTI_ERR_15          15
#define HART_RC_ACCESS_RESTRICTED     16
#define HART_RC_INVALID_DEV_VAR       17
#define HART_RC_INVALID_UNITS         18
#define HART_RC_DEV_VAR_NOT_ALLOWED   19
#define HART_RC_INVALID_EXTD_CMD_NUM  20
#define HART_RC_INVALIS_IO_CARD_NUM   21
#define HART_RC_INVALID_CHAN_NUM      22
#define HART_RC_SUBDEV_RESP_ERR       23
// 24-27 NOT DEFINED                  
#define HART_RC_MULTI_ERR_28          28 
#define HART_RC_MULTI_ERR_29          29
#define HART_RC_MULTI_WARNING_30      30
#define HART_RC_MULTI_WARNING_31      31
#define HART_RC_BUSY                  32
#define HART_RC_DELAYED_RESP_INIT     33
#define HART_RC_DELAYED_RESP_RUNNING  34
#define HART_RC_DELAYED_RESP_DEAD     35
#define HART_RC_DELAYED_RESP_CONFLICT 36
// 37-59 NOT DEFINED
#define HART_RC_PAYLOAD_TOO_LONG      60
#define HART_RC_NO_BUFF_AVAILIBLE_61  61
#define HART_RC_NO_BUFF_AVAILIBLE_62  62
#define HART_RC_PRIORITY_TOO_LOW      63
#define HART_RC_CMD_NOT_IMPLEMENTED   64
#define HART_RC_MULTI_ERR_65          65
#define HART_RC_MULTI_ERR_66          66
#define HART_RC_MULTI_ERR_67          67
#define HART_RC_MULTI_ERR_68          68
#define HART_RC_MULTI_ERR_69          69
#define HART_RC_MULTI_ERR_70          70
#define HART_RC_MULTI_ERR_71          71
#define HART_RC_MULTI_ERR_72          72
// END, THE REST IS NOT DEFINED IN HCF_SPEC307

//=========================== typedef =========================================

typedef enum
{
    HART_MASTER_SECONDARY       = 0,
    HART_MASTER_PRIMARY         = 1,
		HART_MASTER_GATEWAY         = 2,
		HART_MASTER_NETWORK_MANAGER = 3
} hart_lib_master_t;

typedef struct
{
		uint8_t  cmdId[2];
		uint8_t  dataLen; // Len of HART payload
		uint8_t  data[HART_MAX_FRAME_LENGTH];// in format RC|HART_DATA
} hart_lib_wirelessCmd_t;

typedef struct
{
	  uint8_t                status;  // HART status and extended status
	  uint8_t                extStatus;
		hart_lib_wirelessCmd_t cmd;     // command field in format hart_lib_wirelessCmd_t
} hart_lib_wirelessPacket_t;

//=== callback signature
typedef void (*hart_lib_wirelessBurst_cbt) (void);

//=========================== prototypes ======================================

// returns polling address
uint8_t hart_lib_init(uint8_t *macAddr);

int16_t hart_lib_cmd(uint16_t cmdId, const uint8_t *in, uint8_t inLen, uint8_t *out, uint8_t outLen, hart_lib_master_t master);
uint8_t hart_lib_getStatus(hart_lib_master_t master);
uint8_t hart_lib_getExtendedStatus(void);
void    hart_lib_incCfgChangeCnt(void);


//==== publishing function
int16_t hart_lib_burst(uint8_t burstNum, hart_lib_wirelessPacket_t *out);
int8_t  hart_lib_burstEnable(uint8_t burstNum, hart_lib_wirelessBurst_cbt Cb , bool enable);
int8_t  hart_lib_burstGetPeriod(uint8_t burstNum, uint32_t* period_ms);

#endif
