/*
 * IEC103Type.h
 */

#ifndef IEC103TYPE_H_
#define IEC103TYPE_H_

//#include "ostype.h"
#include "lib60870_common.h"

typedef enum 
{
    CS103_TYPE_S = 0,       /*CS103 从*/
    CS103_TYPE_M,           /*CS103 主*/
}CS103_Type;

enum ASDU_TYPE
{
	ASDU_1 = 0x01,
	ASDU_2 = 0x02,
	ASDU_10 = 0x0A,
	ASDU_40 = 0x28,
	ASDU_41 = 0x29,
	ASDU_42 = 0x2A,
	ASDU_43 = 0x2B,
	ASDU_44 = 0x2C,
	ASDU_45 = 0x2D,
	ASDU_46 = 0x2E,
	ASDU_50 = 0x32,
};

enum CMD_SEND
{
	CMD_RESET_CON = 1,
	CMD_RESET_NUM,
	CMD_RESET_TIMESTAMP,            //对时
	CMD_RESET_EVENT,                //复归命令
	CMD_SETTING_DOWNLOAD,           //定值下载
	CMD_SETTING_MODIFY,             //定值修改
	CMD_YK,							//遥控功能
	CMD_GET_ALL,
	CMD_GET_DATA_LV1,               //获取一级数据
	CMD_GET_DATA_LV2,               //获取二级数据
	CMD_GET_SINGLE_SETTING_VALUE,   //获取单个条目值
	CMD_GENERAL_READ_YX_GROUP_VALUE,
	CMD_GENERAL_READ_YC_GROUP_VALUE,
};

//标志位在报文中的位置
#define CODE_POSI     4        //控制域
#define TYP_POSI      6        //类型标识
#define VSQ_POSI      7        //可变结构限定词
#define COT_POSI      8        //传送原因
#define ADDR_POSI     9        //设备地址
#define FUN_POSI      10       //功能类型
#define INF_POSI      11       //信息序号
#define RII_POSI      12       //返回信息标识符
#define DPI_POSI      12       //双点信息
#define RET_POSI      13       //相对时间   表示装置启动到该元件动作的相对时间，毫秒
#define FAN_POSI      15       //故障序号
#define ASDU_1_TIMESTAMP  13   //ASDU1中四字节时间起始位置
#define ASDU_2_TIMESTAMP  17   //ASDU2中四字节时间起始位置
#define GROUP_POSI        14   //组号
#define TNTRY_POSI        15   //条目号
#define KOD_POSI          16   //描述的类别
#define GDD_POSI          17   //通用分类数据描述
#define GID_POSI          20   //通用分类标识数据
#define NGD_POSI          13   //通用分类数据集数目



#define START_10H 0x10    //固定长度报文启动字符
#define START_68H 0x68    //可变长度报文启动字符
#define END_16H   0x16    //结束字符
#define FCB_1     0x20    //帧计数位
#define FCV_1     0x10    //帧计数有效位
#define ACD_1     0x20    //有一级数据上送
#define PRA_1     0x40    //启动报文位　主到从
#define KOD_1     0x01    //描述类别  1为实际值

//功能码定义
#define FNA_S2C_RESET_CON    0   //复位通信功能码
#define FNA_S2C_RESET_NUM    7   //复位帧计数位功能码
#define FNA_S2C_POSTDATA_3   3   //传送数据（发送/确认帧）
#define FNA_S2C_POSTDATA_4   4   //传送数据（发送/无回答帧）
#define FNA_S2C_GETDATA_LV1  10  //召唤一级数据功能码
#define FNA_S2C_GETDATA_LV2  11  //召唤二级数据功能码

//ASDU号定义
#define ASDU6_TIMESTAMP  6      // 对时
#define ASDU7_GETALL     7      // 总召唤，遥信
#define ASDU20_RESET     20     // 复归
#define ASDU21_GETGROUP  21     // 总召唤，要测
#define ASDU10_SETTING   10     // 定值
#define ASDU20_RESET     20     // 复归
#define ASDU21_GETGROUP  21     // 总召唤，遥测
#define ASDU60  		 60     // 遥控

//COT传送原因定义
//控制方向
#define COT_S2C_TIMESTAMP     8      //时间同步
#define COT_S2C_GETALL_START  9      //总查询(总召唤)的启动
#define COT_S2C_REMOTE  	  0x0c   //远方操作
#define COT_S2C_COMMON_ORDER  0x14   //一般命令
#define COT_S2C_GENERAL_WRITE 0x28   //通用分类写命令
#define COT_S2C_GENERAL_READ  0x2A   //通用分类读命令

//FUN定义
#define FUN_GLB 0xFF       //全局功能类型
#define FUN_GEN 0xFE       //通用分类服务功能类型


//INF定义
#define INF_RESET_ORDER   0x13  //复归命令，所有装置相同
#define INF_READ_GROUP    0xF1  //读一个组的全部条目的值或者属性
#define INF_READ_EBTRY    0xF4  //读一个条目的值或者属性
#define INF_CONFIRM_WRITE 0xF9  //带确认的写条目
#define INF_EXEC_WRITE    0xFA  //带执行的写条目

#define MAX_SIZE 1024


typedef struct {
	u8 fcb; // 桢记数位
	u8 fcv; // 桢记数有效位
} IEC103CodeS2C;

typedef union 
{
	u32 uValue;
	f32 fValue;
	u8 buf[4];
}UnionConvert4Byte;

typedef union 
{
	s16  value;
	u16 uValue;
	u8 buf[2];
}UnionConvert2Byte;

typedef struct
{
	//通用分类标识序号GIN
	u8 groupNo;    //组号
	u8 entryNo;    //条目号

	//描述的类别KOD
	u8 kod;        //1为实际值

	//通用分类数据描述GDD
	u8 datatype;   //数据类型
	u8 datasize;   //数据宽度
	u8 number:7,   //数目
			cont:1;     //后续状态位
}stDataUnit;     //通用分类数据单元


typedef struct
{
	u16 msec;              //毫秒
	u8  min:6,             //分钟
			 res1:1,		    //备用
		     iv:1;              //IV=0为有效  =1为无效
	u8  hour:7,            //小时
		     su:1;              //su夏时制标志
	u8  day:5,             //日
			 dayofweek:3;       //未采用
	u8  month:4,           //月
			 res2:4;            //备用
	u8  year:7,            //年
			 res3:1;            //备用
}stTime7Byte;



// 带品质描述词的被测量(MEA)
typedef struct {
	union {
		s16	mval:13,	// 带符号规一化定点数，最高位符合位，数据位占12位
				res:1,		// 备用位:未用(常为0)
				er:1,		// 差错位:0-有效，1-无效
				ov:1;		// 溢出位:0-无溢出，1-溢出

		s16   wVal;
	}mea;
}MEA;


/**
 * \brief GetLayerSt 获取链路层状态，检测是否满足发送条件
 * \param 
 *
 * \return 
 */
typedef s32 (*CS103_SendCb) (u8 *buf, u16 usLen, void *arg);

/**
 * \brief SetValue 规约更新应用数据
 * \param 
 *
 * \return 
 */
typedef s32 (*CS103_SetValue) (u8 ucFun, u8 ucInf, f32 fVal, void *pParam);

/**
 * \brief SetStatus 规约更新应用状态
 * \param 
 *
 * \return 
 */
typedef s32 (*CS103_SetStatus) (u8 ucFun, u8 ucInf, u8 ucSt, void *pParam);

/**
 * \brief AddSOE 规约添加SOE信息
 * \param 
 *
 * \return 
 */
typedef s32 (*CS103_AddSOE) (u8 ucFun, u8 ucInf, u8 ucSt, stTime7Byte *pTime, void *pParam);


typedef struct {
	void                *pUsrData;      /*用户自定义数据接口*/

	u16				usFirstNum;

	u16				usTaskID;
	VFLAGS         	stTaskFlags;
	
	IEC103CodeS2C	stIEC103CodeS2C;	/*103控制域主到从*/
    u8      	ucAddr; 				/*从站地址*/
    u8     		ucReSend_Num;     		/*重发次数*/
    u16     	usReSend_Gap;     		/*重发间隔*/
	u32        	ulSummon_Gap;    		/*总召间隔*/    //参数关联
    u32        	ulSyn_Gap;       		/*同步间隔*/    //参数关联
    // u32        	ulHeart_Gap;     		/*心跳间隔*/    //参数关联
    u32        	ulSend_Gap;      		/*数据发送间隔参数*/


	// u32        ulHeart_Tcn;       /* 心跳累计时间计数 */
    u32        	ulSummon_Tcn;      		/* 定时总招时间计数 */
    u32        	ulTimeSyn_Tcn;     		/* 定时对时时间计数 */

	u8      	usResend_Ncn;         /* 重发次数计数 */
    u16        	usResend_Tcn;         /* 重发间隔时间计数 */  

    BOOL    bIsResetConEnd;   	/*复位通信*/

    BOOL    bIsResetNumEnd;  	//复位帧计数位
	BOOL    bIsGetAllEnd;    	//总召唤

	u8      ucIDCount;

	u8      ucYcGroupNum;
	u8      ucYxGroupNum;

	u8      ucGroupNo;
	u8		ucEntryNo;

	u8		ucYkFun;
	u8		ucYkInf;
	u8		ucYkSE;
	u8		ucYkACT;
	u8		ucYkDCS;
	u8		ucYkQU;

	CS10x_Send_Cb           SendCb;      /*数据发送接口*/
	CS10x_GetTime           GetTime;     /*获取事件*/
	/*对外提供数据*/   
    CS103_SetValue      SetValue;              /*规约更新应用数据*/
    CS103_SetStatus     SetStatus;              /*规约更新应用状态*/
    CS103_AddSOE        AddSOE;                /*添加SOE信息*/

	struct VCommBuf     stRecvBuf;       /*接收数据缓冲区*/
    struct VCommBuf     stSendBuf;       /*发送数据缓冲区*/
}CS103;

/**
 * @brief 设置设备地址
 * 
 * @param self 
 * @param pstParam 
 */
void CS103_SetAddr(CS103 *self, u8 ucAddr);

/**
 * @brief 设置总召定时间隔关联
 * 
 * @param self 
 * @param pstParam 
 */
void CS103_SetSummonGap(CS103 *self, u32 ulGap);

/**
 * @brief 设置对时同步间隔关联
 * 
 * @param self 
 * @param pstParam 
 */
void CS103_SetSynTimeGap(CS103 *self, u32 ulGap);

/**
 * @brief 101规约重发间隔时间参数输入
 * @param self 
 * @param pstParam 
 */
void CS103_ResendGap(CS103 *self, u16 usGap);
/**
 * @brief 101规约重发次数参数输入
 * @param self 
 * @param pstParam 
 */
void CS103_ResendCnt(CS103 *self, u8 ucCnt);

/**
 * @brief 获取时间接口
 * 
 * @param self 
 * @param cb 
 */
void CS103_GetTimeHandler(CS103 *self, CS10x_GetTime cb);

/**
 * @brief 设置接收遥测接口
 * 
 * @param self 
 * @param cb 
 */
void CS103_SetValueHandler(CS103 *self, CS103_SetValue cb);

/**
 * @brief 设置接收遥信接口
 * 
 * @param self 
 * @param cb 
 */
void CS103_SetStatusHandler(CS103 *self, CS103_SetStatus cb);

/**
 * @brief 设置接收SOE处理函数
 * 
 * @param self 
 * @param cb 
 */
void CS103_AddSOEHandler(CS103 *self, CS103_AddSOE cb);

CS103 *CS103_Init(CS103_SendCb cb, void *arg, CS103_Type type);
void CS103_Destory(CS103 *self);
BOOL CS103_DoRecv(CS103 *self, u8 *pBuf, u16 usLen);
void CS103_TimerHandle(CS103 *self, u16 usGap);

#endif /* IEC103TYPE_H_ */
