/********************************************************************
版权所有：	
文件版本： V1.00
文件名称： IEC104.h
生成日期： 2007年04月26日
作    者：xxxxxx
使用范围：

功    能： IEC104规约处理
更新信息：
更新日志1：
修改者:
修改日期:
修改内容:
修改原因:
*********************************************************************/
#ifndef IEC104_H_
#define IEC104_H_

#include "bspconfig.h"

#define IEC104_FIFO_SIZE		1024

// IEC104类型
#define IEC104_TYPE_NET		0	// 网络104
#define IEC104_TYPE_RS		1	// 串口104

// IEC104规约数据传输状态
#define IEC104_ST_STOPPED	1	// STOPPED状态，系统初始化、接收到STOPPED命令、连接断开，进入此状态。
#define IEC104_ST_STARTED 	2	// STARTED状态，接收到STARTED命令，进入此状态。
#define IEC104_ST_PENDING	3	// PENDING状态，在STARTED状态，接收到STOPPED命令，但还有未确认的I帧，进入此状态

// 帧类型定义
#define FRAME_I				0x00  // I帧
#define FRAME_S				0x01  // S帧
#define FRAME_U_SATRT 		0x07  // STARTED帧 
#define FRAME_U_SATRT_ACK 	0x0B  // STARTED帧 应答
#define FRAME_U_STOP		0x13  // STOPPED帧 
#define FRAME_U_STOP_ACK	0x23  // STOPPED帧 应答
#define FRAME_U_TEST		0x43  // TESTFR帧 
#define FRAME_U_TEST_ACK	0x83  // TESTFR帧 应答
#define FRAME_SM2			0xFF  // 加密帧

#define FRAME_I_COS			0X0100// COS帧
#define FRAME_I_SOE			0X0200// SOE帧
#define FRAME_I_PRIOR_HIGH	0X0400// 高优先级帧，例如突发COS、SOE
#define FRAME_I_PRIOR_LOW	0X0800// 低优先级帧，例如总召、组召的数据帧
#define FRAME_I_ENCRYPT		0X1000// 加密安全帧
#define FRAME_I_106			0X2000// 延时获取帧

typedef struct IEC104  // 104规约处理结构体
{
	// 通道属性
	BYTE        type;
	BYTE		chnl;		// 通道索引值，串口在前(0:(CFG_UART_NUM_MAX-1))，逻辑网络在后(CFG_UART_NUM_MAX:(CFG_UART_NUM_MAX+IEC104_TOTAL_SOCKETS-1)
	BYTE        cNetIndex;	// 对应网络接口的索引值，0表示网络0，1表示网络1
	u8			ip[4];
	
	// 连接计数
	u32   		LinkCountNet;	// TCP连接建立计数序号
	u32			LinkCountApp;	// 规约正在处理的连接
	u32			LinkCountRecv;	// 接收到的报文归属的连接

	// 规约状态
	int 		state;
	bool		bSendChange;
	DWORD 		DTSendChange;
	bool		bfirst_call;
	bool	bEchosecmd5 ;//文件校验MD5，错误信息返回标识

	// 序号记录
	Byte2WORD	SendNum;	//发送序列号，其值为待发送帧的序号
	Byte2WORD	RecvNum;	//接收序列号，期望对方下一帧的序号
	Byte2WORD	AckNum; 	//确认序列号，其值为对方期望的下一帧的序号
	WORD            AckRecvNum;  // 已确认的对方发送序列号

	// 计时
	uint32_t us0_yc;	// 遥测发送间隔计时
	uint32_t us0_sec;	// 秒定时器计时使用
	uint32_t secs;		// 连接建立持续时间
	uint32_t us0_client;		// 连接建立持续时间

	// 测试帧发送
	bool   		  bStartTest;
	uint32_t us0_test_wait;					
	uint32_t us0_test;
	bool               bClientStart;

	// 普通帧接收处理
	// 为了防止资源冲突，除了在主循环中，判有效后，可以相应修改bRecvOk外，
	// 其它变量只允许在接收线程或中断中修改，勿在其它地方修改。
	volatile bool   bRecvOk;
	BYTE		cTypeCounter;	/*接受帧类型	*/
	WORD		cRecvLenth; 	/* 接收到数据计数器*/
	WORD		cRecvCnt;		/*有效数据记数*/

	//加密帧接收处理(见普通帧接收处理说明)	
	volatile bool  bSM2Data; // 
	BYTE 	SM2L2;
	WORD 	csm2RecvCnt;			/*有效数据记数*/
	DWORD 	us0_SM2Over;	
	
	// 级联遥控
	u32  lnk_yk_send_flag;		// 级联遥控
	uint32_t us0_lnk_yk;	// 

	//级联遥参
	u32  lnk_par_send_flag;		// 级联遥参
	uint32_t us0_lnk_par;
	
	// 其它
	bool bRmtSM2;	//此标志表示加密遥控报文正在处理，期间不能主动上送SOE和遥测，否则有可能导致有些主站处理不正确
	bool bInitCOI;	// 初始化原因
	long yc_save[MAX_YC_NUMBER];
	
	// 发送接收缓存
	BYTE		arrRecvBuf[IEC_RECV_BUF_SIZE];
	BYTE		arrSendBuf[256];
	BYTE              extSendBuf[IEC_RECV_BUF_SIZE];
	iec_tbuf_t	TxBuf[2];  // 带优先级发送BUF，数字越小，优先级越高。
	iec_rbuf_t 	RxBuf;	   // 接收BUF，用于接收主站的一帧报文，目前只在加密报文用，以后应统一
	
	TRANSFILE   tfile; // 104标准文件传输
	T_FILE         tf;    // 国网规范文件传输
	
	RMT_SET_DATA	 tr;
	FAULT_PARA_BUF tfault;
#ifdef YPARA_LINK
	msg_data_struct msg_ypara_recv;

	msg_data_struct msg_ypara_send; /*临时组织区,防止堆栈过大*/
	uint32_t us0_msg_ypara;	// 
#endif

#ifdef YPARA_LINK_S
	bool para_updata_flag;
#endif


#ifdef RCD_STRAN_S
	newrcd_queque	rcd_qt; 	/*新产生录波文件名队列*/
#endif	

	BYTE  recv_fifo_buf[IEC104_FIFO_SIZE]; 
 	struct rt_fifo	recv_fifo;	
}IEC104_DEF;

union u_RsIEC
{
	struct IEC101 iec101;
	struct IEC104 iec104;
	struct IECLINK	ieclnk;
};


extern IEC104_DEF g_t104[IEC104_TOTAL_SOCKETS];

extern u8 get_par_link_data_dz(BYTE *out,BYTE *in,BYTE parNum,u8 ti);
extern bool get_par_ch_info(WORD parAddr,struct do_table *parTab);
extern int iec_add2frame_dz(BYTE *pbuf,RMT_SET_VAL *pset,bool b104);
extern void IEC101_link_par(IEC101_DEF *pt);

void IEC104_Init(void);
void IEC104_Init_RS(IEC104_DEF* pt,BYTE chnl);

void IEC104_App(IEC104_DEF *pt104);
int  IEC104_Ether_App(void);

void IEC104_Recv_Reset(IEC104_DEF *pt104);
int  IEC104_Recv(IEC104_DEF *pt104,BYTE cRcvData) ;
void  IEC104_Recv_Int(IEC104_DEF *pt,u8 byRevData); 


void IEC104_SM2Send(IEC104_DEF *pt104);
void IEC104_AddFrame(IEC104_DEF *pt104,BYTE *dat,int len,BYTE vsq,BYTE cot,BYTE type) ;// 
void IEC104_AddFrame_dz(IEC104_DEF *pt104,BYTE *dat,int len,BYTE vsq,BYTE cot ,BYTE type,bool addone);
void IEC104_SectionWrite(IEC104_DEF *pt104,u8 *ps);
void IEC104_SectionRead(IEC104_DEF *pt104);			// 读定值区
void IEC104_link_par(IEC104_DEF *pt104);


/***********************下面是104规约文件传输部分代码2016-8-10************************/

void  IEC104_SegmentContinue(IEC104_DEF *pt104);

void IEC104_File_Echo(IEC104_DEF *pt104,BYTE *dat); //dat 从报文的帧类型开始

void IEC104_File_Sure(IEC104_DEF *pt104,BYTE *dat) ;//dat 从报文的帧类型开始
void IEC104_FreeFile(IEC104_DEF *pt104);	
void IEC104_Echo_US(IEC104_DEF *pt104,BYTE frametype);


/****************endfile************************************/

#endif


