/****************************************************************************/
/* Copyright (c) 2007,许继集团有限公司                                      */
/* All rights reserved.                                                     */
/*                                                                          */
/*  模块描述：                                                              */
/** 客户端站点管理模块，提供站点管理结构各属性的读写
 *  @file  ac_srvmgs.h                                                      */
/*                                                                          */
/* 日期         作者    注释                                                */
/* 2008/01/31   ZYZ     从ac_srvm.c中分离出来                               */
/****************************************************************************/

#ifndef IEC61850_AC_SRVMGS_H
#define IEC61850_AC_SRVMGS_H

#include "glbtypes.h"
#include "mvl_defs.h"
#include "ai_obj.h"
#include "ac_sg.h"
#include "ac_reqm.h"
#include "mvl_acse.h"
#include "ac_acfg.h"
#include "ac_rpt.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 通道状态枚举值     
 */
typedef enum
{
    CHNL_STATE_UNCONNECTED,  /**< 通道未连接   */
    CHNL_STATE_CONNECTING,   /**< 通道正在连接 */
    CHNL_STATE_CONNECTED    /**< 通道已连接   */
}CHNL_STATE;

/**
 * 对象空间创建状态枚举值     
 */
typedef enum {
	CRE_STATE_UNCREATED,			/**< 未创建   */
	CRE_STATE_CREATING,				/**< 正在创建 */
	CRE_STATE_CREATED,				/**< 已创建   */
	CRE_STATE_CREATERR				/**< 创建出错 */
}CREATE_STATE;

/**
 * 数据刷新状态枚举值     
 */
typedef enum {
	REFR_STATE_UNREFRESHED,         /**< 未刷新   */
	REFR_STATE_REFRESHING,          /**< 正在刷新 */
	REFR_STATE_REFRESHED,           /**< 已刷新   */
	REFR_STATE_REFRESHERR           /**< 刷新出错 */
}REFRESH_STATE;

typedef struct
{
    CHNL_STATE chnl_state;
    MVL_NET_INFO *net_info;
    ST_CHAR dib_name[MAX_IDENT_LEN+1];
    ST_DOUBLE next_time;
	ST_BOOLEAN keep_con;
}AC_CHANNEL_CTRL;

typedef struct
{
    AC_CHANNEL_CTRL chnl_a;
    AC_CHANNEL_CTRL chnl_b;
    AC_CHANNEL active_chnl;
    // CONNECT_STATE con_state;
}AC_CONNECT_CTRL;


/**
  * 报告解析过程中使用的报告的数据集和报告的信息
  * 应用程序在刷新对象空间后初始化
*/
typedef struct 
{
	ST_CHAR rpt_id[MAX_IDENT_LEN+1]; /**< RPTID*/
	AI_DS_CTRL *ds;                  /**< 数据集指针*/
	RUNTIME_TYPE *rt;                /**< includebit的RUNTIME_TYPE指针*/
	ST_INT includebit_TYPEID;        /**< 传送了那些成员 BIT*/
	ST_INT old_sqnum;                /**< 已经接收到的报告SQNUM*/
	ST_INT rcb_id;                   /**< 报告控制块的ID*/
//	ST_BOOLEAN enable;               /**< 报告控制块使能标志*/
	EntryID_TDEF entryID;           /**< 备份的ENTRYID*/
	ST_BOOLEAN entryid_enable;      /**< 要不要判断ENTRYID*/
}AC_RPT_INFO;

/**
  * 报告解析过程中使用的报告的数据集和报告的信息，解析过程中使用的临时缓存指针
  * 应用程序在刷新对象空间后初始化
*/
typedef struct 
{
	AC_RPT_INFO *rpt_info;           /**< RPT信息数组*/
	ST_INT rpt_num;                  /**< 报告个数*/
	ST_VOID *data;                   /**< 解析报告时用的临时缓存*/
	ST_BOOLEAN init_flag;            /**< 是否初始化标志*/
}AC_IED_RPT_CTRL;
/**
 * 保存报告控制块刷新信息   
 */               
typedef struct ac_rcb_ref_info
{
	ST_INT           ld_num;
	ST_BOOLEAN       is_br;
	ST_INT			 id_br;
	ST_INT           id_lln0;
} AC_RCB_REF_INFO;
/**
 * 站点管理数据结构，一个结构实例对应一个站点     
 */
typedef struct ac_server_management
{
	ST_INT           srv_id;
	ST_CHAR          srv_name[MAX_IDENT_LEN+1];  /**< 装置名称，由SCD配置文件解析得到 */

	AI_IED_CTRL      *ied;
	CREATE_STATE     cre_state;           /**< 对象空间创建状态    */ 

	
	AC_RCB_REF_INFO  a_rcb_ref_info;
	AC_RCB_REF_INFO  b_rcb_ref_info;
	REFRESH_STATE    refr_state;          /**< 站点数据刷新状态    */

	AC_IED_SG_CTRL   sg_ctrl;             /**< 定值管理信息        */
	AC_IED_RCB_INFO  rcb_info;			  /**< 报告管理信息        */
	AC_REQ_CTRL      *req_list;           /**< 异步请求链表        */
	AC_CONNECT_CTRL  con_ctrl;            /**< 站点网络状态结构    */
	AI_IED_CFG		 *ied_cfg;            /**< ied配置             */
} AC_SERVER_MANAGEMENT;                   

/**
 * 取得站点个数接口
 * @return  ST_INT 返回站点个数
 */
ST_INT ac_get_srvm_num();

/**
 * 获取站点重连标志位状态，该状态在初始化时默认为TRUE
 * @param   srv_id          服务器ID
 * @param   chnl            通道号
 * @retval  连接标志
 */
ST_BOOLEAN ac_get_srvm_chnlKeepCon(ST_INT srv_id, AC_CHANNEL chnl);
/**
 * 设置站点重连标志位状态，该状态在初始化时默认为TRUE
 * @param   srv_id          服务器ID，为-1时，认为设置所有服务器站点
 * @param   keep_con        保持连接标志，SD_TRUE,保持连接，SD_FALSE,不保持连接
 * @param   chnl            通道号
 * @retval  SD_SUCCESS      设置成功
 * @retval  SD_FAILURE      设置失败
 */
ST_RET ac_set_srvm_chnlKeepCon(ST_INT srv_id, ST_BOOLEAN keep_con, AC_CHANNEL chnl);

/**
 * 通过装置ID获取一个站点
 * @param   srv_id                   服务器ID
 * @retval  AC_SERVER_MANAGEMENT*    指向服务器结构的指针，失败返回NULL
 */
AC_SERVER_MANAGEMENT * ac_get_srvm_node(ST_INT srv_id);

/**
 * 通过服务器ID获取站点的对象空间创建状态
 * @param   srv_id          服务器ID
 * @param   create_state    保存返回状态值的指针
 * @retval  SD_SUCCESS      获取成功
 * @retval  SD_FAILURE      获取失败
 */
ST_RET ac_get_srvm_createState(ST_INT srv_id, CREATE_STATE *create_state);

/**
 * 设置站点的对象空间创建状态
 * @param   srv_id          服务器ID
 * @param   create_state    状态值
 * @retval  SD_SUCCESS      设置成功
 * @retval  SD_FAILURE      设置失败
 */
ST_RET ac_set_srvm_createState(ST_INT srv_id, CREATE_STATE create_state);

/**
 * 通过服务器ID获取站点的数据刷新状态
 * @param   srv_id          服务器ID
 * @param   refr_state      保存返回状态值的指针
 * @retval  SD_SUCCESS      获取成功
 * @retval  SD_FAILURE      获取失败
 */
ST_RET ac_get_srvm_refrState(ST_INT srv_id, REFRESH_STATE *refr_state);

/**
 * 设置站点的数据刷新状态
 * @param   srv_id          服务器ID
 * @param   refr_state      状态值
 * @retval  SD_SUCCESS      设置成功
 * @retval  SD_FAILURE      设置失败
 */
ST_RET ac_set_srvm_refrState(ST_INT srv_id, REFRESH_STATE refr_state);

/**
 * 通过站点的ID获得站点的名称
 * @param   srv_id          服务器ID
 * @retval  ST_CHAR *       成功返回站点的名称，失败返回NULL
 */
ST_CHAR * ac_get_srvm_name(ST_INT srv_id);

/**
 * 通过站点的名称获得站点的ID,如果没有找到，返回－1
 * @param   srv_name        服务器名称
 * @retval  ST_INT          成功返回站点的ID，失败返回－1
 */
ST_INT ac_get_srvm_srvId(ST_CHAR *srv_name);

/**
 * 通过站点的ID获得装置对应的客户端对象空间IED对象
 * @param   srv_id          服务器ID
 * @retval  AI_IED_CTRL *  成功返回装置对应的客户端对象空间ied对象，失败返回NULL
 */
AI_IED_CTRL * ac_get_srvm_ied(ST_INT srv_id);

/**
 * 通过站点的ID设置装置对应的客户端对象空间ied对象
 * @param   srv_id          服务器ID
 * @param   ied             服务器对象空间结构
 * @retval  SD_SUCCESS， SD_FAILURE
 */
ST_RET ac_set_srvm_ied(ST_INT srv_id, AI_IED_CTRL *ied);
/**
 * 通过站点的ID获得和装置连接的主通道的net_info
 * @param   srv_id          服务器ID
 * @retval  MVL_NET_INFO *  返回和装置连接的通道MVL_NET_INFO对象，断开时返回NULL
 */
MVL_NET_INFO * ac_get_srvm_netInfo(ST_INT srv_id);
/**
 * 通过站点的ID获得对应通道的net_info
 * @param   srv_id          服务器ID
 * @param   chnl            通道号
 * @retval  MVL_NET_INFO *  返回和装置连接的通道MVL_NET_INFO对象，断开时返回NULL
 */
MVL_NET_INFO * ac_get_srvm_chnlNetInfo(ST_INT srv_id, AC_CHANNEL chnl);

/**
 * 设置装置的通道chnl的net_info
 * @param   srv_id          服务器ID
 * @param   net_info        装置连接通道
 * @param   chnl            通道号
 * @retval  SD_SUCCESS      设置成功
 * @retval  SD_FAILURE      设置失败
 */
ST_RET ac_set_srvm_chnlNetInfo(ST_INT srv_id, MVL_NET_INFO *net_info, AC_CHANNEL chnl);

/**
 * 通过srv_id获取定值管理信息结构的地址
 * @param   srv_id             服务器ID
 * @retval  AC_IED_SG_CTRL*    定值管理信息结构的指针，失败返回NULL
 */
AC_IED_SG_CTRL *ac_get_srvm_sgCtrl(ST_INT  srv_id);


/**
 * 通过ID获取报告相关的信息 。
 * @param   srv_id          SRVID
 * @return  AC_IED_RCB_INFO 报告块的指针
 */
AC_IED_RCB_INFO *ac_get_srvm_iedRcbInfo(ST_INT srv_id);

/**
 * 读取通道状态
 * @param   srv_id          服务器ID
 * @param   chnla_state     保存返回的A通道状态
 * @param   chnlb_state     保存返回的A通道状态
 * @param   active_chnl     活动通道
 * @retval  SD_SUCCESS      成功
 * @retval  SD_FAILURE      失败
 */
ST_RET ac_get_srvm_chnlState(ST_INT srv_id, CHNL_STATE *chnla_state, CHNL_STATE *chnlb_state, AC_CHANNEL *active_chnl);

/**
 * 设置某一通道状态,chnl为通道号state为通道状态
 * @param   srv_id          服务器ID
 * @param   state           通道状态
 * @param   chnl			通道号
 * @retval  SD_SUCCESS      成功
 * @retval  SD_FAILURE      失败
 */
ST_RET  ac_set_srvm_chnlState(ST_INT srv_id, CHNL_STATE state, AC_CHANNEL chnl);

/**
 * 设置主通道为chnl
 * @param   srv_id          服务器ID
 * @param   chnl			通道号
 * @retval  SD_SUCCESS      成功
 * @retval  SD_FAILURE      失败
 */
ST_RET ac_set_srvm_activeChnl(ST_INT srv_id, AC_CHANNEL chnl);

/**
 * 获取当前主通道
 * @param   srv_id          服务器ID
 * @retval  当前主通道
 */
AC_CHANNEL ac_get_srvm_activeChnl(ST_INT srv_id);

/**
 * 设置通道重连时间
 * @param   srv_id          服务器ID
 * @param   chnl			通道号
 * @param   next_time		重连时间
 * @retval  SD_SUCCESS      成功
 * @retval  SD_FAILURE      失败
 */
ST_RET  ac_set_srvm_chnlNextTime(ST_INT srv_id, AC_CHANNEL chnl, ST_DOUBLE next_time);

/**
 * 获取特殊iedconfig
 * @param   srv_id          服务器ID
 * @retval  iedconfig
 */
AI_IED_CFG *ac_get_srvm_iedConfig(ST_INT srv_id);
/**
 * 获取通道chnlDibName
 * @param   srv_id          服务器ID
 * @param   chnl			通道号
 * @retval  chnlDibName
 */
ST_CHAR *ac_get_srvm_chnlDibName(ST_INT srv_id, AC_CHANNEL chnl);

/**
 * 一次取出一个完整的状态，防止在取的过程中被其他线程修改剩下未取到的状态值
 * @param   srv_id          服务器ID
 * @param   con_ctrl        网络信息结构
 * @param   cre_state       保存对象空间创建状态指针
 * @param   refr_state      保存数据刷新状态指针
 * @retval  SD_SUCCESS      取值成功
 * @retval  SD_FAILURE      取值失败
 */
ST_RET  ac_get_srvm_wholeState(ST_INT   srv_id,
							   AC_CONNECT_CTRL  *con_ctrl, 
							   CREATE_STATE   *cre_state,
							   REFRESH_STATE  *refr_state);

#ifdef __cplusplus
}
#endif
#endif
