/******************************************************************************
版权所有：	
文件名称：	IECComm.h
文件版本：	01.01
创建作者：	xxxxxx
创建日期：	2012-03-28
功能说明：	应用系统初始化
其它说明：
修改记录：
*/

#ifndef IECCOMM_H
#define IECCOMM_H
/*------------------------------- 头文件 --------------------------------------
*/


/*------------------------------- 宏定义 --------------------------------------
*/
#define IEC_BUF_LEN			256
#define MAX_SOE_PER_FRAME 	16

#define IEC_RECV_BUF_SIZE	1024 // 主要考虑加解密需要的空间


#define FILE_SEGMENT_BYTES     200  //文件传送时，段的字节数

enum
{
	IEC101_CHN=0,
	IEC103_CHN,
	IEC104_CHN,    	//一般通道
	IEC104_WAVE, 	//录波通道
	IEC_MODBUS_CHN, // modbus 主站规约
	IEC_FAULT_CHN, 	//  状态板通信
	IEC_HMI_CHN,
	IEC_MODBUS_M
};

enum
{
	MASTER_MODBUS=0x13,
	MASTER_101=0x23,
	MASTER_103=0x33,
	MASTER_MSG=0x43,
	MASTER_GPRS=0x53,
	MASTER_104=0x63,
	MASTER_MAINTAIN=0X73,
	MASTER_NUM
};

// COT
#define IEC_COT_SPONT		3 	 // 突发(自发)
#define IEC_COT_INIT		4 	 // 初始化
#define IEC_COT_REQ			5 	 // 请求
#define IEC_COT_ACT			6 	 // 激活
#define IEC_COT_ACTCON		7 	 // 激活确认
#define IEC_COT_DEACT		8 	 // 停止激活
#define IEC_COT_DEACTCON 	9 	 // 停止激活确认
#define IEC_COT_ACTTERM		10 	 // 激活终止
#define IEC_COT_UN_TI		44 	 // 未知的类型标识
#define IEC_COT_UN_COT		45 	 // 未知的传送原因
#define IEC_COT_UN_CA		46 	 // 未知的应用服务数据单元公共地址
#define IEC_COT_UN_OA		47 	 // 未知的信息对象地址
#define IEC_COT_UN_DEACT	49 	 // 停止激活终止

#define IEC_COT_T			0X80 // 试验位:0=未试验,  1=试验
#define IEC_COT_PN			0X40 // 确认位:0=肯定确认,1=否定确认

// QOI
#define IEC_QOI_CALL_ALL_GROUP	20 //总召唤
#define IEC_QOI_CALL_YX_BEGIN	21 //第 1 组
#define IEC_QOI_CALL_YX_END	 	28 //第 8 组
#define IEC_QOI_CALL_YC_BEGIN	29 //第 9 组
#define IEC_QOI_CALL_YC_END		36 //第 16 组

// 默认起始点号
#define IEC_YX_OFFSET			0x0001  //遥信起始地址
#define IEC_YC_OFFSET			0x4001  //遥测起始地址
#define IEC_YK_OFFSET			0x6001  //遥控起始地址
#define IEC_PULSE_OFFSET		0x6401  //电度起始地址

// 带选择的类型标识
extern u8 g_ti_select[];
extern u8 TI_SELECT_NUM;

//佛山局要求遥参定义
#define FOS_PAR_READ_ONE 		102 	//单个读定值
#define FOS_PAR_SET_ONE 		48		//单个定值设置
#define FOS_PAR_READ_MUL 		108		//多个读定值
#define FOS_PAR_SET_MUL			55		//多个定值设置

//自定义扩展遥参
#define FOS_PAR_READ_ONE_EXT 		90 	//单个读定值
#define FOS_PAR_SET_ONE_EXT 		91		//单个定值设置
#define FOS_PAR_READ_MUL_EXT 		92		//多个读定值
#define FOS_PAR_SET_MUL_EXT			93		//多个定值设置



#define FOS_PAR_STATR_ADDR 		0X5001	//遥参起始地址
#if defined GD_AREA_SHANWEI || defined GD_AREA_ZHONGSHAN_2020 || defined GD_AREA_ZHONGSHAN_2020_ZC || defined GD_AREA_ZHONGSHAN
	#define FOS_PAR_SW_NUM 			130		//遥参单回路开关遥参数量
#elif defined GD_AREA_ECZD_MAOMING
	#define FOS_PAR_SW_NUM 			180		//遥参单回路开关遥参数量
#elif defined GD_AREA_MEIZHOU_FTU || defined GD_AREA_MEIZHOU_2021
	#define FOS_PAR_SW_NUM 			110		//遥参单回路开关遥参数量
#else
	#define FOS_PAR_SW_NUM 			50		//遥参单回路开关遥参数量
#endif

/*------------------------------ 类型结构 -------------------------------------
*/
#ifdef GEN_QUEUE

#define KEEP_QUEUE	0
#define	OVER_QUEUE	1

typedef struct QTYPE 	/* 定义队列指针类型QTYPE*/
{
	s32 count;      /*数量*/		
	s32 front;      /*读指针*/
	s32 rear;       /*写指针*/
	s32 maxsize;    /*缓存区最大大小*/		
	s32	s_size;     /*单个元素大小*/
	u8* data;     /*缓存区指针*/
}QTYPE;

enum
{
	RCD_PRINT=0,
	PARA_PRINT,
};



s32 queue_init(QTYPE *queque, s32 maxsize,void *data,s32 s_size);
s32 get_queue_count(QTYPE *queue);
s32 add_data_queque(QTYPE *queue,u8 *data, u8 op_type);
s32 get_data_queque(QTYPE *queue,u8 *data);
s32 print_queque(QTYPE *queue,u8 type);
s32 check_data_queque(QTYPE *queue,u8 *data);
void del_data_queue(QTYPE *queue);
#endif

#define SET_UP_TYPE	179

#ifdef RCD_STRAN_S
#define RCD_TYPE	177		/*自定义查询录波类型标识*/
#define NEWRCD_COUNT	64	
#define NEWRCD_SIZE		64

#define RCD_MAX_BUF		NEWRCD_COUNT*NEWRCD_SIZE
typedef struct newrcd_queque
{	
	QTYPE	queue;
	u8	 data[RCD_MAX_BUF];
}newrcd_queque;
void iec_commadd_rcd(char *filename);
#endif


typedef struct  SERIAL_COMM_STRUCT
{
	// 规约结构体的地址
	u8    	*ptBuf;			

	// 发送
	u8   	sendbuf[256];	// 第一个字节为发送长度,最大帧长为255
#ifdef FUNC_ENCRY_IN_ONE_SERIAL
	u8 enc_sendbuf[256];
#endif
	u8		nSendCnt;
	bool  	bSend;
	uint32_t 	us0_send;

	u8   extsendbuf[1024];
	
#ifdef FUNC_ENCRY_IN_ONE_SERIAL
	u8   extsendbuf_1[1024];
	u8   extsendbuf_2[1024];
	u8   extsendbuf_3[1024];
	bool bextsend_1;
	u16  extsendcnt_1;
	u16  extsendlen_1;
	bool bextsend_2;
	u16  extsendcnt_2;
	u16  extsendlen_2;
	bool bextsend_3;
	u16  extsendcnt_3;
	u16  extsendlen_3;
#endif
	u16  extsendcnt;
	u16  extsendlen;
	bool bextsend;

	// 接收
	bool			b_recv_reset;
	uint32_t 	us0_recv;
	uint32_t	us_recv_timeout;
}SERIAL_COMM;


// 接收BUF，用于接收主站一帧完整报文
typedef struct iec_rbuf
{
	u16		sts;		// 接收状态
	u16		len; 		// 接收报文中的长度信息
	u16		cnt;		// 接收数据计数
	
	u8		sum;		// 校验和
	u8		chn;		// 接收通道，统计计数用
	u8		*buf;

}iec_rbuf_t;




// 发送BUF的最大帧数，需考虑以下问题
// 1、不允许出现BUF满的情况
// 2、主站总召时，会带有ACK,所有只需考虑一次总召情况，目前假设一次总召小于24帧
// 3、系统K值，目前限定小于48
// 4、主动上送SOE或遥测每次都不会超过32帧(最大情况是上电时，E2PROM中的所有事件都需要发送)
// 5、修改此值，注意同时修改发送BUF的指针位数
#define  IEC_TBUF_NUM      	256		// 共有多少个buf
#define  IEC_TBUF_LEN  		256		// 每个buf长度

//规约发送缓冲头
typedef struct iec_tbuf_head
{	
	u16 frm_attr;		// 帧属性
	u16 soe_tail_send;	// 本帧中最后SOE的索引
	
	u16 tb_SendNum; 	// 为了方便和104序号进行比较，其值也为待发送帧的序号
	u32 us0;
}iec_tbuf_head_t;


// 104发送缓冲区,在K值有效的情况下，其作用如下 :
// 1、使用k值进行发送流量控制。
// 2、通过ACK对已发送的SOE进行确认。
// 3、发送帧确认超时检测
typedef struct iec_tbuf
{
	// buf指针，注意位数和MAX_104_FRAMES的对应关系
	volatile u8 	tb_head ; 
	volatile u8 	tb_tail_send;
	volatile u8 	tb_tail_ack;
	
	iec_tbuf_head_t tb_info[IEC_TBUF_NUM];
	u8 				tb_data[IEC_TBUF_NUM][IEC_TBUF_LEN];
}iec_tbuf_t;


typedef struct TRANSFILE_DEF {
	WORD	filename;
	WORD 	filelenth;
	WORD 	setctionnum;
	char   	*pdat;     // 节内容对应指针，传输完毕后需释放
	DWORD 	InfoAddr;		// 信息体地址，对应文件目录
	DWORD 	us0_file_trans;
	bool      	bFiletransing;
	bool        bSegtransing;
	DWORD  	transBytes;		//已传输的节的字节数
	DWORD  sectionlenth;
	BYTE      sectionchecksum;	//节校验和
	BYTE       filechecksum;			//文件传输时的文件校验和
	BYTE       transsection;
}TRANSFILE;


typedef struct  T_FILE_DEF {
	char       dirpath[64];
	DWORD	id;  // 文件标识
	DWORD 	filelenth; // 文件大小
	DWORD   offset;  //传输偏移
	DWORD 	us0_file_trans;
	char   	*pfilebuf;     // 内容对应指针，传输完毕后需释放
	bool      	bTransing; // 文件开始传输
	bool      	bdatTraned; //内容已启动传输,判超时使用

	DWORD  wId; //写文件ID
	DWORD  wfilelenth; //写文件长度
	DWORD  woffset;
	DWORD  us0_file_write;
	char       *writebuf;  // 写文件缓存指针
	bool       bdatwriting;  //
	BYTE       recvwrnum;
	BYTE      vsq;  //主站下发的 VSQ，在上送报文时返回
	char       wfilename[64];

	// 文件升级
	bool bUpdateStart;
	bool bUpdateCancel;
	bool bUpdateReset;
	DWORD  us0_updatereset;
	char  updatefilename[64];
	
}T_FILE;

//为了节省空间，单独申请写字符串的结构体数组，最大允许16个定值
#define RMT_STR_NUM	16

typedef struct RMT_SET_DAT_DEF
{
	WORD	di[RMT_SET_NUMBER];
	float 	val[RMT_SET_NUMBER];
	struct 	
	{
		WORD  di;
		char  str[32];
	}t_str[RMT_STR_NUM];
	DWORD  us0_preset; //预置参数
	bool        bpreset; //预置参数标志
	
}RMT_SET_DATA;


#define  RMT_FIXED_SET_NUM 14 // 固定定值

typedef struct RMT_SET_VAL
{
	WORD di;
	BYTE  type;
	BYTE  unit;
	BYTE  len;
	BYTE str[32];
}RMT_SET_VAL;

typedef struct RMT_FIXED_TABLE
{
	BYTE  num;
	RMT_SET_VAL set[RMT_FIXED_SET_NUM];
}RMT_FIXED_TABLE;

#define IEC_FAULT_FRAMELEN  (EXT_ARG_NUMBER*7+16)

typedef struct FAULT_PARA_BUF_DEF
{
	// buf指针，注意位数和MAX_104_FRAMES的对应关系
	volatile u8 	head 	 : 3; 
	volatile u8 	tail : 3;	
	u8 			data[8][IEC_FAULT_FRAMELEN];  // 参数报文遥信+13个遥测
}FAULT_PARA_BUF;

extern RMT_FIXED_TABLE g_fixedset;

typedef struct YT_BUF
{
	BYTE yc_data[256];
}YT_BUF;

extern DWORD dTpartime;
/****************参数变化队列***************/
typedef struct para_chg_single
{
	u8	group_type;  
	u16 setno;
	float val;	
	struct rtc_time_t  ct;
	
	u32 parId;	//通信点号信息		
}para_chg_single;

#define PARA_CHG_COUNT	1024			/*队列大小*/	
#define PARA_CHG_SIZE		sizeof(para_chg_single)
#define PARA_CHG_MAX_BUF		PARA_CHG_COUNT*PARA_CHG_SIZE
typedef struct para_chg_queque
{	
	QTYPE	queue;
	u8	 data[PARA_CHG_MAX_BUF];
}para_chg_queque;

extern para_chg_queque g_para_chg_queque[COMM_CHANNEL_NUM]; 
/****************参数变化队列***************/

#ifdef FUNC_MORE_PRESET
	extern YT_BUF PresetData101[256];		//预置报文暂存区
	extern YT_BUF SetData101[256];			//固化报文暂存区
	extern int WrongCount101[256];			//预置/固化报文出错暂存区
	extern int g_CountPreset101, g_CountSet101;		//预置/固化/出错帧计数
	extern bool gb_101_yt;						//101遥调标志
	/*意义同上*/
	extern YT_BUF PresetData104[256];
	extern YT_BUF SetData104[256];
	extern int WrongCount104[256];
	extern int g_CountPreset104, g_CountSet104;
	extern bool gb_104_yt;						//104遥调标志
#endif

/*------------------------------ 变量声明 -------------------------------------
*/
extern SERIAL_COMM g_tRsComm[];
extern s8 UART_CHANNEL[];

extern bool byc_filter;	//遥测滤波，防止遥测没有稳定下来突发上送
extern bool g_bCommLed;
extern u32 g_comm_link_status;    	//通信连接状态，每个通道用一个bit表示
extern bool g_bCommStatus;

extern u8 g_arrIECBuf[];
extern int g_link_uart_chnl;		
extern u8 uart_test_begin;
extern u8 uart_test_flag[CFG_UART_NUM_MAX][2];
extern s8 g_hmi_chnl,g_auxhmi_chnl;

//定义预置/固化参数时用于比较的数组及变量
extern BYTE buf_forCompare[256];
extern int i_forCompare,j_forCompare;
extern bool bfirst_sel;


/*------------------------------ 函数声明 -------------------------------------
*/
#define RS_Send_Enable(x)
#define RS_Recv_Enable(x)
#define RS_Ena_Init(x)
void iec_ypara_chg_noty(void *pt,bool b104); 
void iec_ypara_chg_soe(void);



#ifdef YPARA_LINK
int get_ypara_linkch_write(void *pt,BYTE *pdat,BYTE vsq,bool b104);
int iec_setread_mananger(void *pt,BYTE *pdat,BYTE vsq,bool b104);
#endif

#ifdef YPARA_LINK_S
void set_para_flag(void);
#endif

void IEC_CommInit(void)  ;                 
void IECCommTask(void);

//int asdu_get_event(u8 ch,u16 head,u8* pcos,u8 *psoe,u16 *psoe_no,int baddr3,bool *bf,EVENT_STRUCT *ev,u16 *extarg,u8 *yxtype);
int asdu_get_event(u8 ch,u16 head,u8* pcos,u8 *psoe,u8* pcos1,u8 *psoe1,u16*psoe_sno,u16*psoe_dno,	int baddr3,bool *bf,EVENT_STRUCT *ev,u16 *extarg,u8 *yxtype,u8 *pcosnum,u8 *pcosnum1);
int asdu_get_event_104(u8 ch,u16 head,u8* pcos,u8 *psoe,u16 *psoe_no,int baddr3,bool *bf,EVENT_STRUCT *ev,u16 *extarg,u8 *yxtype);

int asdu_get_event_yc(BYTE *dat,int baddr3,u16 arg_index);

char * IEC_Getdir(DWORD di);
void  uart_isr(void);  
void uart_232_485_test(u8 *buf);
int  iec_setwrite(void *pt,BYTE *pdat,BYTE cot,BYTE vsq,bool b104);// dat从定值区号开始
int  iec_setread(void *pt,BYTE *pdat,BYTE vsq,bool b104) ;// dat从定值区号开始
bool readRunParId(WORD sw, WORD parId, BYTE *pbuf);
bool selectRunParId(WORD sw, WORD parId, BYTE *pbuf);
bool wirteRunParId(WORD sw, WORD parId, BYTE *pbuf,u8 ti);
int  iec_file_app(void *pt,BYTE *dat,BYTE cot,u8 framelen,bool b104) ;// dat  从信息对象开始
void  iec_readfile_send(void *pt,bool b104) ;//
void iec_freefile(T_FILE *ptfile);
int  iec_pro_update(void *pt,BYTE cot,BYTE ctype,bool b104) ;
void iec_printfixedset(void);
void  iec_init_fixedset(void *pt,RMT_FIXED_TABLE *pfixedset,bool b104);
void iec_GetMsgInfo(u8 *buf,int len,u8 *ti,u8 *cot,u8 *se,bool b101);
int  iec_findchardot(u8 *buf,u8 *str);
bool getCommStatus(void);
bool getIecLink101Status(void);
#ifdef CPU_FUXI
int uart_isr_thread_create(int ch);
#endif

#endif

/*------------------------------ 文件结束 -------------------------------------
*/


