/****************************************************************************/
/* Copyright (c) 2007,许继集团有限公司                                      */
/* All rights reserved.                                                     */
/*                                                                          */
/*  模块描述：                                                              */
/** 提供解析报告数据服务的接口
 *  @file  ac_rpt.c                                                      
 *  @author yh  huiy@xjgc.com												*/
/*                                                                          */
/* 日期         作者    注释                                                */
/* 2009/04/07   DJF     重构报告解析流程，改用缓存机制过滤双网报告          */
/* 2007/07/16   YH      创建文件                                            */
/****************************************************************************/
#ifndef IEC61850_RPT2_INCLUDED
#define IEC61850_RPT2_INCLUDED

#include "glbtypes.h"
#include "ai_obj.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 *	报告传送原因，为应用层方便，把掩码形式的传送原因变成枚举型，
 *  如果报告中同时同时出现多个触发选项，则上送优先级高的选项，优先级依次为DCHG、QCHG、DUPD、GI、INTGPD
 */
typedef enum 
{
	RPT_REASON_UNKNOWN,
	RPT_REASON_DCHG,
	RPT_REASON_QCHG,
	RPT_REASON_DUPD,
	RPT_REASON_INTGPD,
	RPT_REASON_GI
} AC_REPORT_REASON;

/** 
 * 报告触发选项定义，和本地数据格式的trgop值一致，长度为一个字节
 */
#define     TRG_RESERVED  0x80
#define     TRG_DCHG  0x40
#define     TRG_QCHG  0x20
#define     TRG_DUPD  0x10
#define     TRG_INTGRD  0x08
#define     TRG_GI  0x04
#define     TRG_UNKNOWN 0x02

/** 
 * OPTFLDS值定义
 */
#define		OPT_RESERVED  0x80
#define		OPT_SEQNUM  0x40
#define		OPT_REPORT_TIME_STAMP  0x20
#define		OPT_REASON_FOR_INCLUSION  0x10
#define		OPT_DATA_SET_NAME  0x08
#define		OPT_DATA_REFERENCE  0x04
#define		OPT_BUFFER_OVERFLOW  0x02
#define		OPT_ENTRYID  0x01
#define		OPT_CONF_REVISION  0x8000
#define		OPT_SEGMENTATION  0x4000
#define     OPT_UNKNOWN 0x2000

/**
 * 报告数据集中的一个对象的信息，初始化时建立，解析报告时用到这些信息。
 */
typedef struct  
{
	ST_CHAR *data_ptr;	/**< 指向对象空间中的值 */
	ST_CHAR *data;		/**< 存放从报告中解析出来的值 */
	ST_INT data_size;	/**< 值占有的空间大小 */
	ST_TIMESTAMP *t;	/**< 指向data中的t */
	RUNTIME_TYPE *rt;   /**< 对象的rt，用于解析报告中的数据 */
	AI_OBJ_VAL obj_val; /**< 对象的objVal，其中的每个prim的指针指向对象空间中对象的值 */
}AC_RPT_ENTRYDATA;

//缓存entrydata的条数
#define RPT_ENTRYDATA_BUF_NUM  50

typedef struct  
{
	AI_OBJ_ID obj_id;
	ST_TIMESTAMP t;
}AC_ENTRYDATA_BUF_UNIT;

typedef struct  
{
	AC_ENTRYDATA_BUF_UNIT units[RPT_ENTRYDATA_BUF_NUM];
	ST_INT index;
}AC_ENTRYDATA_BUF;

/**
 * 报告解析过程中使用的报告的数据集和报告的信息
 * 应用程序在刷新对象空间后初始化
*/
typedef struct 
{
	ST_BOOLEAN			init_ok;				/**< 初始化完成标志 */
	ST_CHAR				rptID[MAX_IDENT_LEN+1];	/**< RPTID*/
	ST_INT				rcb_id;					/**< 报告控制块的ID*/
	ST_CHAR				dsRef[MAX_REFERENCE_LENGTH + 1]; /**< 数据集成员参引 */
	AI_DS_CTRL			*ds;					/**< 数据集指针*/
	ST_INT				entry_num;				/**< 数据集对象个数 */
	AC_RPT_ENTRYDATA	*entry_datas;			/**< 数据集成员信息*/
	ST_UCHAR			*includebit;			/**< 报告中包含的数据集成员的掩码，初始化时申请内存 */
	RUNTIME_TYPE		*includebit_rt;			/**< includebit的RUNTIME_TYPE指针*/
	ST_INT				includebit_TYPEID;		/**< includebit的typeid*/
	AC_ENTRYDATA_BUF	entry_buf;				/**< 报告缓冲区，用于过滤双网报告*/
}AC_RCB_INFO;

/**
  * 报告解析过程中使用的报告的数据集和报告的信息，解析过程中使用的临时缓存指针
  * 应用程序在刷新对象空间后初始化
*/
typedef struct 
{
	AC_RCB_INFO *rcb_info;           /**< 报告控制块信息数组*/
	ST_INT rcb_num;                  /**< 报告控制块个数*/
	ST_BOOLEAN init_flag;            /**< 是否初始化*/
}AC_IED_RCB_INFO;

/**
 * 控制报告恢复给应用层时用的结构
*/
typedef struct 
{
	ST_CHAR		obj_ref[MAX_REFERENCE_LENGTH + 1]; 
	ST_RET		result; 
	ST_INT8		add_cause;		
	ST_UINT8	ctrl_num;    /**< ctlNum值 */   	
}AC_CTLREPORT_CTRL;


/**
 * 终止化报告要用到的数据集信息。
 * @param  rcb_info  报告的数据集及报告ID，及报告解析过程中使用的临时缓存的内存的释放
 * @return ST_VOID  无
 */
ST_VOID ac_uninit_rpt(AC_IED_RCB_INFO *rcb_info);

/**
 * 初始化报告要用到的数据集信息
 * @param  ied		    srv指针
 * @param  rcb_info		报告块指针
 * @retval SD_FAILURE   失败
 * @retval SD_SUCCESS   成功
 */
ST_RET ac_init_rpt(AI_IED_CTRL *ied, AC_IED_RCB_INFO *rcb_info);            


extern ST_VOID (*u_ac_on_recv_report)(
		VISIBLE_STRING65_TDEF rptID, /**< 传出rptid，应用层可用来映射到特定用途，如故障报告*/
		ST_INT  obj_num,             /**< 对象个数*/
		AI_OBJ_VAL *obj_val,         /**< 对象数据，数组*/
		ST_BOOLEAN *val_chgs,        /**< 指示每个obj的值是否有变化，数组，本地写对象空间的接口要添加传出参数，指明数据是否发生变化*/
		AC_REPORT_REASON  *reasons,  /**< 指示报告上送原因*/
		ST_INT  srv_id);             /**< IEDID*/

extern ST_VOID (*u_ac_on_ctl_report)(
		AC_CTLREPORT_CTRL *ctl_rpt_ctrl,  /**< 控制报告结构指针*/
		ST_INT  srv_id);                  /**< IEDID*/


#ifdef __cplusplus
}
#endif

#endif
