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

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

#define IECLINK_CHN_BEGIN_RS	0X80

#define IECLINK_RECVBUF_MAX  	250  	// 
#define FILE_SEND_FRAME_LENTH 220   //每帧报文传输的文件字节数

enum
{
	IECLINK_YK_SND=0,	// 主站下发
	IECLINK_YK_ACK,		// 级联子站应答
	IECLINK_YK_END,		// 级联子站结束
	IECLINK_YK_NUM,
};

#define IECLINK_CALLLNK			(0x49)				// 请求链路状态
#define IECLINK_CALLRST			(0x40)				// 复位远方链路
#define IECLINK_CALLONE       		(0x4A)				// 请求一级数据
#define IECLINK_CALLTWO       	(0x4B)				// 请求二级数据

#define IECLINK_ECHOLNK       	(0x0B)				// 请求二级数据
#define IECLINK_ECHOAPP       (0x00)				// 请求二级数据

#ifdef	RCD_STRAN_M
enum
{
	RFILE_ACTIVE=0,
	RFILE_ACK,
};


#define IECLINK_RCD		177
#define RCD_DIR			"app/COMTRADE/"

typedef struct	newrcd_m_struct
{	
	u8	 filename[64];
	u16  addr;
}newrcd_m_struct;

#define NEWRCD_COUNT_M	64			/*队列大小*/	
#define NEWRCD_SIZE_M		sizeof(newrcd_m_struct)


#define RCD_MAX_BUF_M		NEWRCD_COUNT_M*NEWRCD_SIZE_M
typedef struct newrcd_queque_m
{	
	QTYPE	queue;
	u8	 data[RCD_MAX_BUF_M];
}newrcd_queque_m;

#endif


typedef struct LINK_YKDATA
{
	u8 	ti;		// 类型标识
	u8 	cot;	// 传送原因
	u8 	v;		// 值
	u8 	rev;	// 保留
}LINK_YKDATA;

typedef struct LINKYK
{
	u16 cp_m;	// 主通讯点
	u16 cp_s;	// 从通讯点
	u16 chnl;     //通道
	bool    	flag[IECLINK_YK_NUM];  // 有遥控数据要下发
	LINK_YKDATA data[IECLINK_YK_NUM];	
}LINKYK_DEF;
typedef struct LINK_PARDATA
{
	u8 	ti;		// 类型标识
	u8 	cot;	// 传送原因
	//u8 	v;		// 值
	u8  vsq;
	u8 	len;
	u8 	ti_m;//
	u8 	buf[256];	// 转发缓存
}LINK_PARDATA;

typedef struct LINKPAR
{
	u16 cp_m;	// 主通讯点
	u16 cp_s;	// 从通讯点
	u16 chnl;     //通道
	WORD parNum;	//
	bool    	flag[IECLINK_YK_NUM];  // 有遥控数据要下发
	LINK_PARDATA data[IECLINK_YK_NUM];	
}LINKPAR_DEF;

#ifdef YPARA_LINK
enum
{
	read_set=0,		/*读定值*/
	modify_set,		/*修改定值*/
	settion_swht,	/*切换定值区*/
};

enum
{
	YP_SEL=1,		
	YP_EXE,
	YP_CANCEL,
	YP_SEL_RETURN,
	YP_SEL_FAULT,
	YP_EXE_RETURN,		
	YP_EXE_FAULT,		
	YP_CANCEL_RETURN,		
	YP_CANCEL_FAULT,	
};
	
typedef struct
{
	u8 tag;
	u8 size;
	u8 value[32];
}iec_val_struct;

typedef struct 
{
	u16 cp_m;		// 主通讯点
	u16 cp_s;		// 从通讯点
	union
	{
		iec_val_struct val_iec;		/*iec格式*/				
	};	
}msg_ypara_base_struct;

typedef struct 
{	
	u8 type;
	u8 cmd;
	u16 section_p;	/*定值区*/
	
	u16 num;
	msg_ypara_base_struct base_data[50];
}msg_ypara_data_struct;

typedef struct 
{	
	u8 type;
	u8 cmd;
	u16 section_p;	/*定值区*/
	
}msg_oper_setion_struct;


typedef struct 
{
	u8  sport;
	u8	dport;
	union
	{	
		u8 type;
		msg_ypara_data_struct ypara_msg;
		msg_oper_setion_struct setion_msg;
	};

/*组包区*/	
	u8  flag;
	//u8 	len;
	//u8 	buf[256];	/*转发缓存*/
}msg_data_struct;

#define PAR_COUNT_M	10			/*队列大小*/	
#define PAR_SIZE_M		sizeof(msg_data_struct)	/*1.6K*/
#define PAR_MAX_BUF_M		PAR_COUNT_M*PAR_SIZE_M
#define PAR_BUF_COUNT	200

typedef struct par_queque_m
{	
	QTYPE	queue;
	u8	 data[PAR_MAX_BUF_M];
}par_queque_m;

extern msg_data_struct temp_par;

void print_msg_base(msg_ypara_data_struct *msg);
int mananger_msg_ypara_s(msg_data_struct *msg,u8 sport,u8 dport);
int get_index_link(u16 link_ch,u16 link_cp);
int get_stbl_index_s(u16 parId);
#endif

typedef struct FILETEST
{
	bool bDir;
	bool bFile;
	bool bFileok;
	bool b104ack;
	u8    fnamelen;
	char filename[64];
	u32  filelenth;
	u32   fileid;
	u32   offset;
	struct file * 	handle;
	char * filebuf;
#ifdef RCD_STRAN_M
	u16 addr;
	u8 bTransing;	/*读文件中*/
#endif
	DWORD 	us0_file_trans;

	bool bwFile;
	bool bwTrans;
	bool bUpdateStart;
	bool bUpdateEnd;
	u32 woffset;
	u32 wfilelenth;
	u32 wId;
	char * wbuf;
	
}FILETEST_DEF;


typedef struct LNK_STATUS  // 101规约处理结构体
{
	u8		byRetryTimes;		//重发次数
	bool		bLinkOK;		// 连接建立
	bool		bMSend;			// 发送标志
	bool		bMRecvOK;		// 接收到确认报文
	bool		bMFCB;
	bool 	bMFCV;
	bool		bUsed;
	bool 	bRetryErr;

	bool    	bCallLnk;		// 请求链路状态
	bool    	bCallRst;		// 复位链路状态
	bool    	bCallAll;		// 总召
	bool    	bCallDD;		// 电度总召
	bool    	bCallOne;		// 召一级数据
	bool    	bSetTime;		// 时间同步
	bool        bDdValid;			// 电度有效标志
	bool        bEchoLnk;
	bool        bEchoApp;
	bool        brst;
	DWORD	dTInteral;
	DWORD	dTMWait;	//发送间隔	
	DWORD	dTCallAllTime;
	DWORD	dTSendTime; // 主站主动发送时的间隔
	// 从设备对时
	uint32_t us0_set_time;
#ifdef RCD_STRAN_M
	DWORD	dTRcdTime; // 录波查询间隔		
	bool	bRcd;	   // 查询录波使能

	bool	bRcding;	//	查询录波进行中
	DWORD	 dRcdingTime; //
#endif

#ifdef YPARA_LINK
	bool bSet_all;			/*读所有定值*/ 
	bool section_all;
	DWORD	dSetTime;		/*所有定值间隔*/
#endif
}LNK_STATUS;

typedef struct IEC_SLAVE  // 101规约处理结构体
{
	WORD  addr;		//装置地址
	bool     bDdValid;         // 有电度值 ，需进行电度总召
	LNK_STATUS tlnksave;
}IEC_SLAVE;


typedef struct IECLINK  // 101规约处理结构体
{
	u8	chnl;
	u8	type;
	u8	nSendCnt;
	u8	sum;
	u8 	*sendbuf;
	u8  recvbuf[IEC_BUF_LEN];// 101规约，接收的报文，最大40个字节

	LNK_STATUS tlnk;
	bool		bData;
	// 帧接收
	u8	nTypeCounter;       // 帧接收状态
	u16	nRecvCounter;		// 接收数据计数
	u16	nRecvLenth;			// 接收到数据长度
	u16	nRecvCnt;           // 根据数据长度计数

	// 连接计数
	u32	LinkCount;	
	Byte2WORD	SendNum;	//发送序列号
	Byte2WORD	RecvNum;	//接收序列号
	Byte2WORD	AckNum; 	//确认序列号
	WORD            AckRecvNum;  // 已确认的对方发送序列号

	// 测试帧发送
	bool   		  bStartTest;
	bool    	bSendS;			// 需要发送S帧
	bool    	bTestAck;		// 子站的测试帧需要应答
	bool        bPH101;
	uint32_t us0_test_wait;					
	uint32_t us0_test;

	// 遥控发送标志
	// 每bits代表一个开关，bit0代表公共，一共1个公共和31个开关。
	DWORD dtpartime[SWITCH_NUM_EXT_PUB];
	u32 yk_send_flag;
	u32 par_send_flag;
#ifdef YPARA_LINK
	par_queque_m		par_queue;	 
	
	u8	sport;
	msg_data_struct temp_par;
#endif
	FILETEST_DEF tft;

	
#ifdef	RCD_STRAN_M	
	//FILETEST_DEF	tfile_m;
	newrcd_queque_m	rcd_m;
#endif

    bool b_lb_master;
	IEC_SLAVE tsla[32];  //最多支持32个子站
	BYTE slave_num;
	BYTE slave_current;
	WORD slave_addr;
	bool    bcfg;
	bool    b101Addr2Byte;// 101链路地址
	bool	   b101App2Byte;	// 101应用地址
	bool    b101Cot2Byte;	// 101传送原因
	DWORD retrytime;
	DWORD sendinteraltime;
	DWORD callalltime;         // 总召时间
	
}IECLINK_DEF;

#ifdef IEC_NOLINK_NO_CALLYX
typedef struct  IEC_LINK_STATE
{
	bool link_err;				//级联通讯异常
	bool link_flag;				//级联状态
	TIMERELAY tLinkBreak;		//级联计时
}IEC_LINK_REG;
extern IEC_LINK_REG g_link_comm;
#endif	




extern int 				g_link104_init_ok[CFG_LINK_104_NUM];
extern volatile int 	g_net_104link_data[CFG_LINK_104_NUM];
extern IECLINK_DEF g_link_104[CFG_LINK_104_NUM];

extern LINKYK_DEF g_lnk_yk[SWITCH_NUM_EXT_PUB];
extern LINKPAR_DEF g_link_par[SWITCH_NUM_EXT_PUB];
extern u8   g_link_par_cnt;      /*当前遥参游标*/
int get_index_setno(u8 	group_type,u16 setno);
void set_read_all(IECLINK_DEF *pt);


// 公共
void lnk_call_all(void);
void lnk_update_time_all(void);
int lnk_master_yk(struct do_table *pdt,u8 ti,u8 cot,u8 v);
int lnk_master_par(struct do_table *pdt,u8 ti,u8 cot,u8 v,BYTE *buf,u8 vsq);


// 101
void lnk_101_init(IECLINK_DEF *pt,u8 chnl,bool bPH);
void lnk_101_app(IECLINK_DEF *pt);
void lnk_101_recv(IECLINK_DEF *pt,u8 byRevData);


// 104
void lnk_104_init(int net);
void lnk_104_app (int net);
void lnk_104_recv(int net,u8 cRcvData) ;

int  lnk_info_printf(void);

void lnk_test_file_trans(IECLINK_DEF *pt);  // 测试文件传输函数
void lnk_test_file_frame(IECLINK_DEF *pt,u8 *pdat,u8 framelen) ;//  
void lnk_read_test_file(void);
void lnk_write_test_file(void);
void lnk_update_file_frame(IECLINK_DEF *pt,u8 ctype); //  
bool lnk_file_check_trans(IECLINK_DEF *pt);
int  getstrval(char *buf);
void lnk_rst_set(void);
#endif
