/******************************************************************************

版权所有 (C), 2013-2023, 科大智能电气有限公司

******************************************************************************
文 件 名   : ASDU.c
版 本 号   : V1.0
生成日期   : 2022年04月07日
最近修改   :
功能描述   : 101及104规约的公共部分ASUD域相关数据处理
函数列表   :
修改历史   :
1.日    期   : 2022年04月07日
修改内容   : 创建文件
*******************************************************************************/
/*************************************文件包含*********************************/
#include "Asdu.h"

/*公共地址*/
#define ASDU_getCA      IntBytes_GetFromBuf
#define ASDU_setCA      IntBytes_Pack2Buf

/*传输原因*/
#define ASDU_getCOT     IntBytes_GetFromBuf
#define ASDU_setCOT     IntBytes_Pack2Buf

/*信息体地址*/
#define ASDU_getIOA     IntBytes_GetFromBuf
#define ASDU_setIOA     IntBytes_Pack2Buf

/*归一化值*/
#define ASDU_getNVA     U16_GetFromBuf
#define ASDU_setNVA     U16_Pack2Buf

/*短浮点值*/
#define ASDU_getSTD754     Float_GetFromBuf
#define ASDU_setSTD754     Float_Pack2Buf

/*CP56Time2a*/
#define ASDU_getCP56Time2a     CP56Time2a_GetFromBuf
#define ASDU_setCP56Time2a     CP56Time2a_Pack2Buf

/*************************************外部接口函数*****************************/
/**
* @brief       规约ASDU域报文构建函数
* @param[in]   pstSelf-规约实体指针
* @param[out]  pucBuf -返回组帧报文
* @return      ASDU的长度
*/
unsigned short GB10x_EncodeAsdu(CS10xHandle_t pstSelf, unsigned char * pucBuf)
{
	unsigned short usInfoLen = 0;
	unsigned short usVsq = 0;
	pucBuf[usInfoLen++] = pstSelf->stAsduElem.usTypeID; //类型标识

	if(CONTINUE == pstSelf->stAsduElem.usSQ)
	{
		usVsq = (pstSelf->stAsduElem.usNum | 0x80); // VSQ
	}
	else
	{
		usVsq = pstSelf->stAsduElem.usNum;
	}

	pucBuf[usInfoLen++] = usVsq;

	if(pstSelf->stAppParameters.iSzOfCOT == 1)
	{
		usInfoLen += ASDU_setCOT(&pucBuf[usInfoLen], pstSelf->stAsduElem.usCot, pstSelf->stAppParameters.iSzOfCOT);
	}
	else
	{
		usInfoLen += ASDU_setCOT(&pucBuf[usInfoLen], (pstSelf->stAsduElem.usCot | (pstSelf->stAsduElem.usCotH << 8)), pstSelf->stAppParameters.iSzOfCOT);
	}

	usInfoLen += ASDU_setCA(&pucBuf[usInfoLen], pstSelf->stAsduElem.uiAddr, pstSelf->stAppParameters.iSzOfCA);
	usInfoLen += pstSelf->stAsduElem.usPayloadSize;
	return usInfoLen;
}

/**
* @brief    规约ASDU域报文解析函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
*             pusPayloadSize-信息对象长度
* @param[out] 无
* @return     无
*/
void DecodeAsduInfoObj(CS10x *pstSelf)
{
	unsigned short usTypeId = 0;
	unsigned short usReason = 0;
	usTypeId = pstSelf->stAsduElem.usTypeID;
	usReason = pstSelf->stAsduElem.usCot;

	if(DecodeASDUCheck(pstSelf, pstSelf->stAsduElem.pucPayload))//ASDU域校验
	{
		return;
	}

	switch(usTypeId)
	{
		case M_EI_NA: //初始化
			Do_InitEnd(pstSelf, usReason);
			break;

		case C_IC_NA: //总召
			Do_Summon(pstSelf, usReason);
			break;

		case C_CI_NA: //电能量总召
			Do_DdSummon(pstSelf, usReason);
			break;

		case C_CS_NA: //对时
			Do_SetTime(pstSelf, usReason);
			break;

		case C_RP_NA: //复位
			Do_Reset_Process(pstSelf, usReason);
			break;

		case C_TS_NA: //测试
			Do_DataTest(pstSelf, usReason);
			break;

		case C_CD_NA:  //延时获得命令-南网
			Do_ObtainDelay(pstSelf, usReason);
			break;

		case C_RS_NA_NANWANG:  //读参数命令-南网
			Do_ParamRead_NanWang(pstSelf, usReason);
			break;

		case C_SP_NA: //参数预置/固化-南网（类型标识 55）
			Do_ParamWrite_Nanwang(pstSelf, usReason);
			break;

		case P_ME_NC: //参数预置-南网（类型标识 112）
			Do_ParamPreset_NanWang(pstSelf, usReason);
			break;

		case P_AC_NA: //参数固化-南网（类型标识 113）
			DoParamSolidify_NanWang(pstSelf, usReason);
			break;

		case F_FR_NA: //文件
			Do_FilePro(pstSelf, usReason);
			break;

		case C_SR_NA: //切换定值区
			Do_ChgConst(pstSelf, usReason);
			break;

		case C_RR_NA: //读当前定值区
			Do_ReadConst(pstSelf, usReason);
			break;

		case C_RS_NA: //读取当前定值区参数
			Do_ParamPreread(pstSelf, usReason);
			break;

		case C_WS_NA: //下设当前定值区参数
			Do_ParamPreset(pstSelf, usReason);
			break;

		case M_SP_NA: // YX
		case M_DP_NA: // YX
			Do_Yx(pstSelf, usReason);
			break;

		case M_ME_NA: // YC
		case M_ME_NB: // YC
		case M_ME_NC: // YC
			Do_Yc(pstSelf, usReason);
			break;

		case M_IT_NB: //电度数据不带时标
			Do_DdNoTime(pstSelf, usReason);
			break;

		case M_IT_TC: //电度数据带时标
			Do_DdWithTime(pstSelf, usReason);
			break;

		case C_SC_NA: // YK
		case C_DC_NA: // YK
			Do_YKPro(pstSelf, usReason);
			break;

		case M_FT_NA: //故障事件
			Do_FaultEvent(pstSelf);
			break;

		case M_DP_TB: // SOE
		case M_SP_TB: // SOE
			Do_SOE(pstSelf);
			break;

		case F_SR_NA:
			Do_Update(pstSelf, usReason);
			break;

		default:
			Do_Anomaly(pstSelf, COT_E_TYPE); //未知ID
			break;
	}
}

/**
* @brief    规约ASDU域报文组帧函数
* @param[in]  pstSelf-规约实体指针
* @param[out] 无
* @return     数据长度
*/
unsigned short EncodeAsdu(CS10x *pstSelf)
{
	unsigned short usLength = 0;
	pstSelf->stSendBuf.usWritePtr = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->pucPayload = &pstSelf->stSendBuf.pBuf[GetPayloadOffset(pstSelf)];
	pstAsdus->usPayloadSize = 0;
	pstAsdus->uiAddr = pstSelf->stAppParameters.iPublicAddr;

	switch(pstSelf->byTaskFlagId)
	{
		case TSKID_SummonResponse:  //总召
			usLength = CS10x_Send_Summon(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_SummonYx:
			usLength = CS10x_Send_SummonYx(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_SendCOS:
			usLength = CS10x_Send_COS(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_SendSOE:
			usLength = CS10x_Send_SOE(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_SummonYc:
			usLength = CS10x_Send_SummonYc(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_YcDisturb:       //遥测扰动
			usLength = CS10x_Send_ChangeYc(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_DdSummon:        //电能量召唤
			usLength = CS10x_Send_DdSummon(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_DdData:          //发送电能量数据
			usLength = CS10x_Send_DdSummon_Data(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]); //电度总召数据
			break;

		case TSKID_DdTimeData:      //带时标电能量突发上送
			usLength = CS10x_Send_TimeDd_Data(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_TimeSyn:         //时间同步
			usLength = CS10x_Send_SynTime(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ResetProcess:    //复位
			usLength = CS10x_Send_ResetProcess(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_DataTest:        //测试帧
			usLength = CS10x_Send_DataTest(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_InitFinish:      //初始化完成
			usLength = CS10x_Send_InitEnd(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_FaultSoe:        //故障事件
			usLength = CS10x_Send_FaultEvent(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_FilePro: //文件
			usLength = CS10x_Send_FilePro(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ChgConst: //切换定值区
			usLength = CS10x_Send_ChgConst(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ReadConst: //读当前定值区
			usLength = CS10x_Send_ReadConst(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamPreread: //读取当前定值区参数
			usLength = CS10x_Send_ParamPreread(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamPrewrite: //下设当前定值区参数
			usLength = CS10x_Send_ParamPreset(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_YkProcess: // YK
			usLength = CS10x_Send_Yk(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_UpdateExe:
			usLength = CS10x_Send_Update(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_Anomaly: //异常帧回复发送
			usLength = CS10x_Send_Anomaly(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ObtainDelay:           /*延时获得命令-南网规约*/
			usLength = CS10x_Send_ObtainDelay(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamRead_NanWang:      /*读参数命令-南网规约*/
			usLength = CS10x_Send_ParamRead_NanWang(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamReadResponse_NanWang:    /*读参数上传命令-南网规约*/
			usLength = CS10x_Send_ParamRdResponse_NanWang(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamPreset_NanWang:/*参数预置命令-南网规约*/
			usLength = CS10x_Send_ParamPreset_NanWang(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamSolidify_NanWang: /*参数固化命令-南网规约*/
			usLength = CS10x_Send_ParamSolidify_NanWang(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		case TSKID_ParamWrite_NanWang: //预置/固化定值区参数-南网（类型标识 55）
			usLength = CS10x_Send_ParamWrite_Nanwang(pstSelf, pstSelf->uiaTaskParam[pstSelf->byTaskFlagId]);
			break;

		default:
			break;
	}

	return usLength;
}

/**
* @brief    104/101规约解析后处理
* @param[in]  pstSelf-规约实体指针
* @param[out] 无
* @return     无
*/
void DoAckFrame(CS10x *pstSelf)
{
	pstSelf->usFileNoneAckNum = 0;  /* 101规约无确认帧清零*/
	// CheckUpdate_DiturbYcEvent(pstSelf);
	// CheckUpdate_SoeEvent(pstSelf);
	return;
}

/***************************************内部函数*******************************/
/**
* @brief      ASDU域报文校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @param[out] 无
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeASDUCheck(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned char  ucRet    = 0;//返回校验结果;
	unsigned short usTypeId = pstSelf->stAsduElem.usTypeID;

	switch(usTypeId)
	{
		case M_EI_NA: //初始化
			ucRet = DecodeCheck_M_EI_NA(pstSelf, pucPayload);
			break;

		case C_IC_NA: //总召
			ucRet = DecodeCheck_C_IC_NA(pstSelf, pucPayload);
			break;

		case C_CI_NA: //电能量总召
			ucRet = DecodeCheck_C_CI_NA(pstSelf, pucPayload);
			break;

		case C_CS_NA: //对时
			ucRet = DecodeCheck_C_CS_NA(pstSelf, pucPayload);
			break;

		case C_RP_NA: //复位
			ucRet = DecodeCheck_C_RP_NA(pstSelf, pucPayload);
			break;

		case C_TS_NA: //测试
			ucRet = DecodeCheck_C_TS_NA(pstSelf, pucPayload);
			break;

		case F_FR_NA: //文件
			ucRet = DecodeCheck_F_FR_NA(pstSelf, pucPayload);
			break;

		case C_SR_NA: //切换定值区
			ucRet = DecodeCheck_C_SR_NA(pstSelf, pucPayload);
			break;

		case C_RR_NA: //读当前定值区
			ucRet = DecodeCheck_C_RR_NA(pstSelf, pucPayload);
			break;

		case C_RS_NA: //读取当前定值区参数
			ucRet = DecodeCheck_C_RS_NA(pstSelf);
			break;

		case C_WS_NA: //下设当前定值区参数
			ucRet = DecodeCheck_C_WS_NA(pstSelf);
			break;

		case M_SP_NA: // YX
		case M_DP_NA: // YX
			ucRet = DecodeCheck_M_SPDP_NA(pstSelf);
			break;

		case M_ME_NA: // YC
		case M_ME_NB: // YC
		case M_ME_NC: // YC
			ucRet = DecodeCheck_M_ME_NANBNC(pstSelf);
			break;

		case M_IT_NB: //电度数据不带时标
			ucRet = DecodeCheck_M_IT_NB(pstSelf);
			break;

		case M_IT_TC: //电度数据带时标
			ucRet = DecodeCheck_M_IT_TC(pstSelf);
			break;

		case C_SC_NA: // YK
		case C_DC_NA: // YK
			ucRet = DecodeCheck_C_SCDC_NA(pstSelf);
			break;

		case M_FT_NA: //故障事件
			ucRet = DecodeCheck_M_FT_NA(pstSelf);
			break;

		case M_DP_TB: // SOE
		case M_SP_TB: // SOE
			ucRet =  DecodeCheck_M_DPSP_TB(pstSelf);
			break;

		case F_SR_NA:
			ucRet = DecodeCheck_F_SR_NA(pstSelf);
			break;

		case C_CD_NA:  //延时获得命令-南网
			ucRet = DecodeCheck_C_CD_NA(pstSelf, pucPayload);
			break;

		case C_RS_NA_NANWANG:  //读参数命令-南网
			ucRet = DecodeCheck_C_RS_NA_NANWANG(pstSelf);
			break;

		case P_ME_NC: //参数预置-南网 （类型标识 112）
			ucRet = DecodeCheck_C_WS_NA_YZ(pstSelf);
			break;

		case P_AC_NA: //参数固化-南网
			ucRet = DecodeCheck_C_WS_NA_GH(pstSelf, pucPayload);
			break;

		case C_SP_NA: //参数预置/固化-南网（类型标识 55）
			ucRet = DecodeCheck_C_SP_NA(pstSelf);
			break;

		default:
			Do_Anomaly(pstSelf, COT_E_TYPE); //未知ID
			break;
	}

	return ucRet;
}

/**
* @brief      初始化校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_EI_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_INIT)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      总召校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_IC_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_ACTTERM)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      电能量总召校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_CI_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_ACTTERM)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      对时校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_CS_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_REQ && usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_ACTTERM)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      复位校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_RP_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      测试校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_TS_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      文件校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_F_FR_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	//放松条件 传输原因暂时也不判断 主站收传输原因5和6  从站收传输原因6和7
	return 0;
}

/**
* @brief      切换定值区校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_SR_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      读当前定值区校验函数
* @param[in]  pstSelf-规约实体指针
*             pucPayload-信息对象起始指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_RR_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      读取当前定值区参数校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_RS_NA(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      下设当前定值区参数校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_WS_NA(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_DEACT && usReason != COT_DEACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      YX校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_SPDP_NA(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_INTROGEN && usReason != COT_SPONT)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      YC校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_ME_NANBNC(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_INTROGEN && usReason != COT_SPONT && usReason != COT_PERCYC)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      电度数据不带时标校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_IT_NB(CS10x *pstSelf)
{
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	return 0;
}

/**
* @brief      电度数据带时标校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_IT_TC(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_SPONT)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      YK校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_SCDC_NA(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	unsigned int uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[0], pstSelf->stAppParameters.iSzOfIOA);

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(uiInfoAddr < 0x6001 || uiInfoAddr > 0x60FF)
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if((usReason & 0x3F) != COT_ACT && (usReason & 0x3F) != COT_ACTCON && (usReason & 0x3F) != COT_DEACT && (usReason & 0x3F) != COT_DEACTCON && (usReason & 0x3F) != COT_ACTTERM)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      故障事件校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_FT_NA(CS10x *pstSelf)
{
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	return 0;
}

/**
* @brief      SOE校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_M_DPSP_TB(CS10x *pstSelf)
{
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	return 0;
}

/**
* @brief      //延时获得命令-南网
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_CD_NA(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_SPONT && usReason != COT_ACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      读参数-南网
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_RS_NA_NANWANG(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_DEACT)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      参数预置-南网
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_WS_NA_YZ(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_DEACT && usReason != COT_DEACTCON && usReason != COT_INTROGEN && usReason != COT_REQ)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      参数固化-南网
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_WS_NA_GH(CS10x *pstSelf, unsigned char *pucPayload)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(ASDU_getIOA(pucPayload, pstSelf->stAppParameters.iSzOfIOA))
	{
		Do_Anomaly(pstSelf, COT_E_IADDR);//信息体地址错误
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_DEACT)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}


/**
* @brief      参数预置/固化-南网（类型标识 55）
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_C_SP_NA(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTCON && usReason != COT_DEACT && usReason != COT_DEACTCON)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief      软件升级校验函数
* @param[in]  pstSelf-规约实体指针
* @return     0 校验成功       1 校验失败
*/
unsigned char DecodeCheck_F_SR_NA(CS10x *pstSelf)
{
	unsigned short usReason  = pstSelf->stAsduElem.usCot; //传送原因
	unsigned int uiPubAddr = pstSelf->stAsduElem.uiAddr;//公共地址

	if((uiPubAddr != pstSelf->stAppParameters.iPublicAddr) && (uiPubAddr != 65535) && (uiPubAddr != 255))
	{
		Do_Anomaly(pstSelf, COT_E_CADDR); //公共地址异常
		return 1;
	}

	if(usReason != COT_ACT && usReason != COT_ACTTERM && usReason != COT_DEACT)
	{
		Do_Anomaly(pstSelf, COT_E_REASON); //未知传输原因
		return 1;
	}

	return 0;
}

/**
* @brief    异常帧处理接口函数
* @param[in]  pstSelf-规约实体指针
* @param[in]  usReason-传输原因即异常类型
* @param[out] 无
* @return     无
*/
void Do_Anomaly(CS10x *pstSelf, unsigned short usReason)
{
	if(pstSelf->stSendBakBuf.pBuf)
	{
		memcpy(pstSelf->stSendBakBuf.pBuf, pstSelf->stAsduElem.pucPayload, pstSelf->stAsduElem.usPayloadSize); //备份的ASDU域数据
		pstSelf->stSendBakBuf.usWritePtr = pstSelf->stAsduElem.usPayloadSize;
	}

	SetSendTask(pstSelf, TSKID_Anomaly, usReason, pstSelf->stAsduElem.usTypeID);  /*将相关ti用作参数传入，用于异常发送*/
	return;
}

/**
* @brief    异常回复帧组帧函数
* @param[in]  pstSelf-规约实体指针
* @param[in]  uiParam-传输原因
* @param[out] 无
* @return     ASDU数据长度
*/
unsigned short CS10x_Send_Anomaly(CS10x *pstSelf, unsigned int uiParam)
{
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = (unsigned short)uiParam;      /* cot */
	pstAsdus->usTypeID  = uiParam >> 16;     /* ti  */

	if(pstSelf->stSendBakBuf.pBuf)
	{
		memcpy(pstAsdus->pucPayload, pstSelf->stSendBakBuf.pBuf, pstSelf->stSendBakBuf.usWritePtr); //取出备份的ASDU域数据
		pstAsdus->usPayloadSize += pstSelf->stSendBakBuf.usWritePtr;
	}
	else
	{
		pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = 0;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief    时间同步接收处理函数 包括收到对时命令、收到对时命令的回复命令、收到请求命令
* @param[in]  pstSelf-规约实体
* @param[in]  usReason--传输原因即异常类型
* @param[out] 无
* @return     无
*/
void Do_SetTime(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char ucRetuen = 0;
	unsigned short usLen = 0;
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	__CP56Time2a stCp56Time;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_REQ == usReason)  //请求/被请求
	{
		SetSendTask(pstSelf, TSKID_TimeSyn, COT_REQ, 0);
	}

	if(COT_ACT == usReason)     //激活
	{
		ASDU_getCP56Time2a(&pstAsduInfo->pucPayload[usLen], &stCp56Time);

		if(pstSelf->pfnSetTime)
		{
			ucRetuen = pstSelf->pfnSetTime(&stCp56Time);
		}

		if(0 == ucRetuen) //检查时间
		{
			SetSendTask(pstSelf, TSKID_TimeSyn, COT_PN | COT_ACTCON, 0);
		}
		else
		{
			SetSendTask(pstSelf, TSKID_TimeSyn, COT_ACTCON, 0);
		}
	}
	else if(COT_ACTCON == usReason)  //激活确认
	{
		;
	}
	else if(COT_ACTTERM == usReason)  //激活终止
	{
		;
	}

	return;
}


/**
* @brief 时钟同步发送处理函数，应包含向下对时及回复对时帧
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParamusReason-传输原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_SynTime(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason        = (unsigned short)uiParam;
	unsigned short usSynType       = (unsigned short)(uiParam >> 16);
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_CS_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;
	__CP56Time2a stCp56Time;
	pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

	if(COT_REQ == (usReason & 0x3F))  //请求/被请求
	{
		if(usSynType)  //请求
		{
			pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], NULL);
		}
		else //被请求
		{
			if(pstSelf->pfnGetTime)
			{
				pstSelf->pfnGetTime(&stCp56Time);
			}

			pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stCp56Time);
		}
	}
	else if(COT_ACT == (usReason & 0x3F))  //激活
	{
		if(pstSelf->pfnGetTime)
		{
			pstSelf->pfnGetTime(&stCp56Time);
		}

		pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stCp56Time);
	}
	else if(COT_ACTCON == (usReason & 0x3F))  //激活确认
	{
		if(pstSelf->pfnGetTime)
		{
			pstSelf->pfnGetTime(&stCp56Time);
		}

		pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stCp56Time);
	}
	else if(COT_ACTTERM == (usReason & 0x3F))  //激活终止
	{
		;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 总召接收处理函数
*
* @param[in] pstSelf -规约实体
* @param[in] usReason --传输原因即异常类型
*/
void Do_Summon(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen = 0;
	unsigned short usQoi = 0;
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_ACT == usReason)  //激活
	{
		usQoi = pstAsduInfo->pucPayload[usLen++];
		SetSendTask(pstSelf, TSKID_SummonResponse, COT_ACTCON, usQoi);
	}
	else if(COT_ACTCON == usReason)  //激活确认
	{
		;
	}
	else if(COT_ACTTERM == usReason)  //激活终止
	{
		/*需要对时优先则开始启动对时，对时结束时启动总招*/
		if(0 == pstSelf->ucFirstAct)
		{
			pstSelf->ucFirstAct = 1;
			SetSendTask(pstSelf, TSKID_TimeSyn, COT_ACT, 0);
		}
	}

	return;
}


/**
* @brief 总召发送处理函数
*
* @param[in] pstSelf -规约实体
* @param[in] uiParam -传送原因
* @return
*/
unsigned short CS10x_Send_Summon(CS10x *pstSelf, unsigned int uiParam)
{
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_IC_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = (unsigned short)uiParam;
	unsigned short usReason        = pstAsdus->usCot;
	unsigned char  ucQoi           = (unsigned char)(uiParam >> 16);
	pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

	if(COT_ACT == usReason)  //激活 主站发
	{
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = QOI;
	}
	else if(COT_ACTCON == usReason || COT_ACTTERM == usReason)  //激活确认及激活终止 从站发
	{
		if(COT_ACTCON == usReason)
		{
			SetSendTask(pstSelf, TSKID_SummonYx, COT_INTROGEN, ucQoi);
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucQoi;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 升级发送处理函数
*
* @param[in] pstSelf -规约实体
* @param[in] usReason -传送原因
* @return
*/
void Do_Update(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucCtype = 0;
	unsigned short usLen   = 0;
	ASDU_Element *pAsduInfo = &pstSelf->stAsduElem;
	usLen += pstSelf->stAppParameters.iSzOfIOA;
	ucCtype = pAsduInfo->pucPayload[usLen++];

	if(pstSelf->pfnUpdateProc)
	{
		pstSelf->pfnUpdateProc(usReason, ucCtype, pstSelf->pUsrData);
	}

	if(COT_ACT == usReason)  //激活
	{
		SetSendTask(pstSelf, TSKID_UpdateExe, COT_ACTCON, ucCtype);
	}
	else if(COT_ACTTERM == usReason)  //激活终止
	{
		SetSendTask(pstSelf, TSKID_UpdateExe, COT_DEACTCON, ucCtype);
	}
	else if(COT_DEACT == usReason)  //停止激活
	{
		SetSendTask(pstSelf, TSKID_UpdateExe, COT_DEACTCON, ucCtype);
	}

	return;
}

/**
* @brief 升级发送处理函数
*
* @param[in] pstSelf -规约实体
* @param[in] uiParam -传送原因
* @return
*/
unsigned short CS10x_Send_Update(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usInfoLen     = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID = F_SR_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 0;
	pstAsdus->usCot     = (unsigned short)uiParam;
	usInfoLen = ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], 0, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->usPayloadSize += usInfoLen;
	pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = (unsigned char)(uiParam >> 16);//Qoi
	return pstAsdus->usPayloadSize;
}

/**
* @brief 电能量总召接收处理函数
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
* @return
*/
void Do_DdSummon(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen = 0;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_ACT == usReason)  //从站 解析电能量召唤命令
	{
		SetSendTask(pstSelf, TSKID_DdSummon, COT_ACTCON, 0);
	}
	else if(COT_ACTCON == usReason || COT_ACTTERM == usReason)  //主站
	{
		;
	}

	return;
}


/**
* @brief 电能量发送处理函数，应包含主站发送召唤命令，从站发送电能量回复报文
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_DdSummon(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_CI_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;
	pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

	if(COT_ACT == usReason)  //主站发
	{
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = QCC;
	}
	else if(COT_ACTCON == usReason || COT_ACTTERM == usReason)  //从站发
	{
		if(COT_ACTCON == usReason)
		{
			SetSendTask(pstSelf, TSKID_DdData, COT_REQCOGCN, 0); //到发送电能量数据中
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = QCC;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 不带时标电能量接收处理函数
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_DdNoTime(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen              = 0;
	unsigned short usDdBeginNo        = 0;
	unsigned short usDdNUm            = pstSelf->stAsduElem.usNum;
	TimeDd_Info stDdInfo   = {0};
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;

	if(CONTINUE == pstSelf->stAsduElem.usSQ)
	{
		usDdBeginNo = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
		usLen += pstSelf->stAppParameters.iSzOfIOA;

		for(unsigned short i = 0; i < usDdNUm; i++)
		{
			stDdInfo.uiInfoAddr = usDdBeginNo;
			stDdInfo.fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
			usLen += 4;
			usLen++;    /*品质描述符*/

			if(NULL != pstSelf->pfnSetDdValue)
			{
				pstSelf->pfnSetDdValue(&stDdInfo, pstSelf->pUsrData);
			}

			usDdBeginNo++;
		}
	}
	else
	{
		for(unsigned short i = 0; i < usDdNUm; i++)
		{
			stDdInfo.uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;
			stDdInfo.fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
			usLen += 4;
			usLen++;    /*品质描述符*/

			if(NULL != pstSelf->pfnSetDdValue)
			{
				pstSelf->pfnSetDdValue(&stDdInfo, pstSelf->pUsrData);
			}
		}
	}
}

/**
* @brief 带时标的电能量数据接收处理
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_DdWithTime(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen              = 0;
	unsigned short usDdBeginNo        = 0;
	unsigned short usDdNUm            = pstSelf->stAsduElem.usNum;
	TimeDd_Info stDdInfo   = {0};
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;

	if(CONTINUE == pstSelf->stAsduElem.usSQ)
	{
		usDdBeginNo = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
		usLen += pstSelf->stAppParameters.iSzOfIOA;

		for(unsigned short i = 0; i < usDdNUm; i++)
		{
			stDdInfo.uiInfoAddr = usDdBeginNo;
			stDdInfo.fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
			usLen += 4;
			usLen++;    /*品质描述符*/
			ASDU_getCP56Time2a(&pstAsduInfo->pucPayload[usLen], &stDdInfo.stCTime);
			usLen += 7;

			if(COT_SPONT == usReason && NULL != pstSelf->pfnAddTimeDdu)
			{
				pstSelf->pfnAddTimeDdu(&stDdInfo, pstSelf->pUsrData);
			}

			if(NULL != pstSelf->pfnSetDdValue)
			{
				pstSelf->pfnSetDdValue(&stDdInfo, pstSelf->pUsrData);
			}

			usDdBeginNo++;
		}
	}
	else
	{
		for(unsigned short i = 0; i < usDdNUm; i++)
		{
			stDdInfo.uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;
			stDdInfo.fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
			usLen += 4;
			usLen++;    /*品质描述符*/
			ASDU_getCP56Time2a(&pstAsduInfo->pucPayload[usLen], &stDdInfo.stCTime);
			usLen += 7;

			if(COT_SPONT == usReason && NULL != pstSelf->pfnAddTimeDdu)
			{
				pstSelf->pfnAddTimeDdu(&stDdInfo, pstSelf->pUsrData);
			}

			if(NULL != pstSelf->pfnSetDdValue)
			{
				pstSelf->pfnSetDdValue(&stDdInfo, pstSelf->pUsrData);
			}
		}
	}
}

/**
* @brief 发送电能量函数(响应主站电能量总召)
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return Asdu数据长度
*/
unsigned short CS10x_Send_DdSummon_Data(CS10x *pstSelf, unsigned int uiParam)
{
	const unsigned char c_ucPerSize1 = pstSelf->stAppParameters.iSzOfIOA + 5; /*不带时标：当前长度1 = 电能量对象地址长度 + 电能量对象长度（数值+品质描述词）*/
	const unsigned char c_ucPerSize2 = c_ucPerSize1 + 7;                    /*带时标：当前长度2 = 电能量对象地址长度 + 电能量对象长度（数值+品质描述词） + CP56Time2a长度*/
	unsigned short usDdSendTotal     = 0;       //不带时标总数量
	unsigned short usDdTimeSendTotal = 0;       //带时标总数量
	unsigned short usSendTotal       = 0;       //剩余发送总数量
	unsigned short usDdSendCnt       = 0;       //当前发送数量
	unsigned int uiEndInforAddr    = 0;       //组内信息体地址尾部 暂时不用 =起始+数量
	unsigned short usReason = (unsigned short)uiParam;
	ASDU_Element *pstAsdus   = &pstSelf->stAsduElem;
	pstAsdus->usTypeID    = M_IT_NB;
	pstAsdus->usSQ        = 0;
	pstAsdus->usNum       = 0;
	pstAsdus->usCot       = usReason;   //响应总召
	TimeDd_Info stDdInfo  = {0};

	if(NULL == pstSelf->pfnGetDdCountByGroup)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetDdValueByGroup)
	{
		return 0;
	}

	usDdSendTotal     = pstSelf->pfnGetDdCountByGroup(pstSelf->usDdType, pstSelf->pUsrData, &pstSelf->uiDdConstInfo, &uiEndInforAddr, 0);
	usDdTimeSendTotal = pstSelf->pfnGetDdCountByGroup(pstSelf->usDdType, pstSelf->pUsrData, &pstSelf->uiDdConstInfo, &uiEndInforAddr, 1);

	if(usDdSendTotal  + usDdTimeSendTotal <= pstSelf->usDdSendNum)
	{
		return 0;
	}

	if(usDdSendTotal > pstSelf->usDdSendNum)                //判断不带时标电度是否已发送完
	{
		pstSelf->usDdSummonSetup = 0;                       //执行不带时标电度处理
		usSendTotal = usDdSendTotal - pstSelf->usDdSendNum; //不带时标剩余电度个数
	}
	else
	{
		pstSelf->usDdSummonSetup = 1;                       //执行带时标电度处理
		usSendTotal = usDdTimeSendTotal - (pstSelf->usDdSendNum - usDdSendTotal); //带时标剩余电度个数
	}

	if(pstSelf->usDdSummonSetup)       //带时标且电度非实时（15分钟冻结、日冻结、潮流反向冻结）
	{
		pstAsdus->usTypeID = M_IT_TC; //在EncodeAsdu函数中已置为M_IT_NB，带时标时更新为M_IT_TC
	}

	if(0 == pstSelf->usDdSummonSetup)
	{
		for(unsigned short i = 0; i < usSendTotal; i++)
		{
			if(c_ucPerSize1 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
			{
				if(pstSelf->pfnGetDdValueByGroup(pstSelf->usDdType, pstSelf->usDdSendNum + i, &stDdInfo, pstSelf->pUsrData, 0))
				{
					pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stDdInfo.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
					pstAsdus->usPayloadSize += ASDU_setSTD754(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stDdInfo.fVal);
					pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = 0; //品质描述词QDS
					pstAsdus->usNum++;
					usDdSendCnt ++;
				}
				else
				{
					break;
				}
			}
			else
			{
				break;
			}
		}
	}
	else
	{
		if(usDdTimeSendTotal)
		{
			for(unsigned short i = 0; i < usSendTotal; i++)
			{
				if(c_ucPerSize2 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
				{
					if(pstSelf->pfnGetDdValueByGroup(pstSelf->usDdType, pstSelf->usDdSendNum - usDdSendTotal + i, &stDdInfo, pstSelf->pUsrData, 1))
					{
						pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stDdInfo.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
						pstAsdus->usPayloadSize += ASDU_setSTD754(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stDdInfo.fVal);
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = 0; //品质描述词QDS
						pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stDdInfo.stCTime);
						pstAsdus->usNum++;
						usDdSendCnt ++;
					}
					else
					{
						break;
					}
				}
				else
				{
					break;
				}
			}
		}
	}

	pstSelf->usDdSendNum += usDdSendCnt;                        //更新已发送电度数量

	if(pstSelf->usDdSendNum == usDdTimeSendTotal + usDdSendTotal) //电度数据发送完
	{
		pstSelf->usDdSendNum = 0;
		SetSendTask(pstSelf, TSKID_DdSummon, COT_ACTTERM, 0);   //电能量总召结束
	}
	else
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, 0);
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 带时标电能量发送接口（突发上送）
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_TimeDd_Data(CS10x *pstSelf, unsigned int uiParam)
{
	const unsigned char c_ucPerSize = pstSelf->stAppParameters.iSzOfIOA + 5 + 7; /*当前长度 = 电能量对象地址长度 + 电能量对象长度（数值+品质描述词） + CP56Time2a长度*/
	unsigned short usTimeDduTotal  = 0;        //需要发送总数量
	unsigned short usContinue      = 0;
	unsigned short usReason        = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = M_IT_TC;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 0;
	pstAsdus->usCot     = usReason; //突变
	TimeDd_Info stDdInfo = {0};

	if(NULL == pstSelf->pfnGetTimeDdu_SendNum)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetTimeDdu)
	{
		return 0;
	}

	usTimeDduTotal = pstSelf->pfnGetTimeDdu_SendNum(pstSelf->pUsrData);

	if(usTimeDduTotal == pstSelf->usDduSendNoAckNum)
	{
		return 0;
	}

	usTimeDduTotal -= pstSelf->usDduSendNoAckNum;

	for(unsigned short i = 0; i < usTimeDduTotal; i++)
	{
		if(c_ucPerSize + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
		{
			if(pstSelf->pfnGetTimeDdu(&stDdInfo, pstSelf->pUsrData, pstSelf->usDduSendNoAckNum))
			{
				pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stDdInfo.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				pstAsdus->usPayloadSize += ASDU_setSTD754(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stDdInfo.fVal);
				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = 0; //品质描述词QDS
				pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stDdInfo.stCTime);
				usContinue = 0;
				pstAsdus->usNum++;
			}
			else
			{
				usContinue = 1;
				break;
			}
		}
		else
		{
			usContinue = 1;
			break;
		}

		pstSelf->usDduSendNoAckNum++;
	}

	if(usContinue)
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, 0);
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 复位进程接收处理
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_Reset_Process(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen = 0;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_ACT == usReason)  //从站收
	{
		SetSendTask(pstSelf, TSKID_ResetProcess, COT_ACTCON, 0);

		if(NULL != pstSelf->pfnWrite_ResetCOI)
		{
			pstSelf->pfnWrite_ResetCOI(COI_2); //复位原因为远方复位
		}

		pstSelf->usResetDelay = 5000;//传入重启接口（规约重启）
	}
	else if(COT_ACTCON == usReason)  //主站收
	{
		;
	}

	return;
}

/**
* @brief //复位进程发送处理函数
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ResetProcess(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason        = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_RP_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;
	pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = QRP;
	return pstAsdus->usPayloadSize;
}

/**
* @brief //测试帧长帧解析
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_DataTest(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen = 0;
	unsigned short usFbp = 0;
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_ACT == usReason)  //从站收
	{
		usFbp = IEC_MAKEWORD(pstAsduInfo->pucPayload[usLen], pstAsduInfo->pucPayload[usLen + 1]);
		usLen += 2;
		SetSendTask(pstSelf, TSKID_DataTest, COT_ACTCON, usFbp);
	}
	else if(COT_ACTCON == usReason)  //主站收
	{
		;
	}

	return;
}

/**
* @brief //测试帧长帧发送
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_DataTest(CS10x *pstSelf, unsigned int uiParam)
{
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_TS_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = (unsigned short)uiParam;
	unsigned short usFbp           = (unsigned short)(uiParam >> 16);
	pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

	if(pstSelf->bFbpType)  //发送固定帧格式
	{
		pstAsdus->usPayloadSize += IntBytes_Pack2Buf(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], FBP, 2);
	}
	else
	{
		pstAsdus->usPayloadSize += IntBytes_Pack2Buf(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], usFbp, 2);
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief //解析初始化完成帧
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_InitEnd(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen = 0;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_INIT == usReason)
	{
		CS10x_M_Finish(pstSelf);
	}
}

/**
* @brief //发送初始化完成帧
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_InitEnd(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned char   ucCoi          = 0;
	unsigned short  usReason       = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = M_EI_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;

	if(COT_INIT == usReason)
	{
		pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

		if(NULL != pstSelf->pfnRead_ResetCOI)
		{
			ucCoi = pstSelf->pfnRead_ResetCOI(); //复位原因为远方复位
		}

		if(ucCoi <= COI_2)
		{
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucCoi;
		}
		else
		{
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = COI_0;
		}
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief //遥信报文解析 包括总召回复连续遥信帧及COS帧  单点及双点
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_Yx(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen       = 0;//信息体下标
	unsigned short usi         = 0;//循环变量
	unsigned short usYxNUm     = 0;//信息对象个数
	unsigned int uiYxBeginNo = 0;//信息体地址应为4个字节
	Yx_Info stYxInfo;
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	usYxNUm = pstSelf->stAsduElem.usNum;

	if(COT_INTROGEN == usReason || COT_SPONT == usReason)  //响应总召及突发
	{
		if(CONTINUE == pstSelf->stAsduElem.usSQ)  //点号连续
		{
			//解析首个信息体地址
			uiYxBeginNo = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;

			for(usi = 0; usi < usYxNUm; usi++)
			{
				stYxInfo.uiInfoAddr = uiYxBeginNo;
				stYxInfo.ucStatus = pstAsduInfo->pucPayload[usLen++];

				if(NULL != pstSelf->pfnGetYxPotPro)
				{
					stYxInfo.ucStateType = pstSelf->pfnGetYxPotPro(pstSelf->pUsrData, stYxInfo.uiInfoAddr);

					if(!stYxInfo.ucStateType && M_DP_NA == pstAsduInfo->usTypeID)
					{
						stYxInfo.ucStatus -= 1;
					}
				}

				if(NULL != pstSelf->pfnSetStatus)
				{
					pstSelf->pfnSetStatus(&stYxInfo, pstSelf->pUsrData);
				}

				uiYxBeginNo++;
			}
		}
		else if(DISCONTINUE == pstSelf->stAsduElem.usSQ)  //点号不连续
		{
			for(usi = 0; usi < usYxNUm; usi++)
			{
				//信息体地址
				uiYxBeginNo = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
				usLen += pstSelf->stAppParameters.iSzOfIOA;
				stYxInfo.uiInfoAddr = uiYxBeginNo;
				stYxInfo.ucStatus = pstAsduInfo->pucPayload[usLen++];

				if(NULL != pstSelf->pfnGetYxPotPro)
				{
					stYxInfo.ucStateType = pstSelf->pfnGetYxPotPro(pstSelf->pUsrData, stYxInfo.uiInfoAddr);

					if(!stYxInfo.ucStateType && M_DP_NA == pstAsduInfo->usTypeID)
					{
						stYxInfo.ucStatus -= 1;
					}
				}

				if(NULL != pstSelf->pfnSetStatus)
				{
					pstSelf->pfnSetStatus(&stYxInfo, pstSelf->pUsrData);
				}
			}
		}
	}

	return;
}

/**
* @brief 响应总召的遥信报文组帧，默认连续
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_SummonYx(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usi            = 0;//循环变量
	unsigned short usQoi          = 0;//召唤限定词
	unsigned short usReason       = 0;
	unsigned short usYxSendCnt    = MAX_Yx_CNT; //最大127
	unsigned short usYxAllCnt     = 0;
	unsigned int uiEndInforAddr = 0; //组内信息体地址尾部 暂时不用 = 起始+数量
	unsigned char  ucStateType    = 0;
	Yx_Info stYxInfoData = {0};
	ASDU_Element *pstAsdus  = &pstSelf->stAsduElem;
	usQoi                = (unsigned short)(uiParam >> 16);
	usReason             = (unsigned short)uiParam;

	if(NULL == pstSelf->pfnGetYxCountByGroup)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetYxStatusByGroup)
	{
		return 0;
	}

	usYxAllCnt = pstSelf->pfnGetYxCountByGroup(usQoi, pstSelf->pUsrData, &pstSelf->uiYxConstInfo, &uiEndInforAddr);

	if(usYxAllCnt <= pstSelf->usYxSendNum)
	{
		pstSelf->usYxSendNum = 0;
		SetSendTask(pstSelf, TSKID_SummonYc, COT_INTROGEN, usQoi);
		return 0;
	}

	if(usYxAllCnt - pstSelf->usYxSendNum <= usYxSendCnt)
	{
		usYxSendCnt = usYxAllCnt - pstSelf->usYxSendNum;
	}

	/****填充总召遥信****/
	pstAsdus->usTypeID = GetTaskTItype(pstSelf, DATATYPE_YX);//无用可删除?
	pstAsdus->usSQ     = CONTINUE;
	pstAsdus->usCot    = usReason; //响应总召
	pstAsdus->usNum    = 0;

	if(0 != pstSelf->pfnGetYxStatusByGroup(usQoi, pstSelf->usYxSendNum, &stYxInfoData, pstSelf->pUsrData)) // 区分单双点遥信 分开上送
	{
		if(stYxInfoData.ucStateType)
		{
			pstAsdus->usTypeID = M_DP_NA;
			ucStateType = stYxInfoData.ucStateType;
		}
		else
		{
			pstAsdus->usTypeID = M_SP_NA;
			ucStateType = stYxInfoData.ucStateType;
		}
	}
	else
	{
		return 0;
	}

	pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], pstSelf->uiYxConstInfo + pstSelf->usYxSendNum, pstSelf->stAppParameters.iSzOfIOA);

	for(usi = 0; usi < usYxSendCnt; usi++)
	{
		memset(&stYxInfoData, 0, sizeof(Yx_Info));

		if(0 != pstSelf->pfnGetYxStatusByGroup(usQoi, pstSelf->usYxSendNum + usi, &stYxInfoData, pstSelf->pUsrData))
		{
			if(ucStateType != stYxInfoData.ucStateType)
			{
				break;
			}

			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stYxInfoData.ucStatus;
			pstAsdus->usNum ++;
		}
		else
		{
			break;
		}
	}

	pstSelf->usYxSendNum += pstAsdus->usNum;

	if(pstSelf->usYxSendNum < usYxAllCnt)
	{
		SetSendTask(pstSelf, TSKID_SummonYx, usReason, usQoi);
	}
	else
	{
		pstSelf->usYxSendNum = 0;
		SetSendTask(pstSelf, TSKID_SummonYc, COT_INTROGEN, usQoi);
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 发送COS组帧函数
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_COS(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usi             = 0;//循环变量
	unsigned short usReason        = 0;
	unsigned short usCosAllCnt     = 0;
	unsigned short usEncodeInfoLen = 0;//已组帧的信息体长度
	unsigned char  ucStateType     = 0;
	unsigned char ucValid          = 0;
	SOE_Info stSoeInfo  = {0};
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	usReason = (unsigned short)uiParam;

	if(NULL == pstSelf->pfnGetSOE)
	{
		return 0;
	}

	usCosAllCnt = pstSelf->usSoeSendNum;

	if(usCosAllCnt <= pstSelf->usCosSendNoAckNum)  //总数量不大于待确认数量
	{
		return 0;
	}

	usCosAllCnt = usCosAllCnt - pstSelf->usCosSendNoAckNum; //总待发送数量
	/****填充COS****/
	pstAsdus->usTypeID = GetTaskTItype(pstSelf, DATATYPE_YX);
	pstAsdus->usSQ     = DISCONTINUE;
	pstAsdus->usNum    = 0;
	pstAsdus->usCot    = usReason; //突变
	memset(&stSoeInfo, 0, sizeof(SOE_Info));

	for(usi = 0; usi < usCosAllCnt; usi++)
	{
		memset(&stSoeInfo, 0, sizeof(SOE_Info));

		if(pstSelf->pfnGetSOE(&stSoeInfo, pstSelf->pUsrData, pstSelf->usCosSendNoAckNum))
		{
			if(ucValid == 0)
			{
				if(stSoeInfo.ucStateType)//Cos根据Soe点Type类型分帧处理
				{
					pstAsdus->usTypeID = M_DP_NA;
					ucStateType = stSoeInfo.ucStateType;
				}
				else
				{
					pstAsdus->usTypeID = M_SP_NA;
					ucStateType = stSoeInfo.ucStateType;
				}

				ucValid = 1;
			}

			if(ucStateType != stSoeInfo.ucStateType)
			{
				break;
			}

			usEncodeInfoLen = pstAsdus->usPayloadSize + pstSelf->stAppParameters.iSzOfIOA + 1;//已组帧+地址+元素长度

			if(usEncodeInfoLen <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
			{
				//信息体地址
				pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stSoeInfo.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				//信息体元素
				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stSoeInfo.ucStatus;
				pstAsdus->usNum++;
			}
			else
			{
				break;
			}
		}

		pstSelf->usCosSendNoAckNum++;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 遥测报文解析
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_Yc(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen       = 0;//信息体下标
	unsigned short usi         = 0;//循环变量
	unsigned short usYcNUm     = 0;//信息对象个数
	unsigned int uiYcBeginNo = 0;//信息体地址
	Yc_Info stYcInfo = {0};
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	usYcNUm = pstSelf->stAsduElem.usNum;

	if(COT_INTROGEN == usReason || COT_SPONT == usReason || COT_PERCYC == usReason)
	{
		if(CONTINUE == pstSelf->stAsduElem.usSQ)
		{
			//解析首个信息体地址
			uiYcBeginNo = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;

			for(usi = 0; usi < usYcNUm; usi++)
			{
				stYcInfo.uiInfoAddr = uiYcBeginNo;

				if(M_ME_NC == pstSelf->stAsduElem.usTypeID)  //浮点型
				{
					stYcInfo.fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
					usLen += 4;
				}
				else
				{
					stYcInfo.fVal = (float)ASDU_getNVA(&pstAsduInfo->pucPayload[usLen]);
					usLen += 2;
				}

				usLen++;    /*品质描述词*/

				if(NULL != pstSelf->pfnSetValue)
				{
					pstSelf->pfnSetValue(&stYcInfo, pstSelf->pUsrData);
				}

				if((COT_SPONT == usReason || COT_PERCYC == usReason) && NULL != pstSelf->pfnAddDiYcVal)
				{
					pstSelf->pfnAddDiYcVal(&stYcInfo, pstSelf->pUsrData);
				}

				uiYcBeginNo++;
			}
		}
		else if(DISCONTINUE == pstSelf->stAsduElem.usSQ)
		{
			for(usi = 0; usi < usYcNUm; usi++)
			{
				//信息体地址
				uiYcBeginNo = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
				usLen += pstSelf->stAppParameters.iSzOfIOA;
				stYcInfo.uiInfoAddr = uiYcBeginNo;

				if(M_ME_NC == pstSelf->stAsduElem.usTypeID)  //浮点型
				{
					stYcInfo.fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
					usLen += 4;
				}
				else
				{
					stYcInfo.fVal = (float)ASDU_getNVA(&pstAsduInfo->pucPayload[usLen]);
					usLen += 2;
				}

				usLen++;    /*品质描述词*/

				if(NULL != pstSelf->pfnSetValue)
				{
					pstSelf->pfnSetValue(&stYcInfo, pstSelf->pUsrData);
				}

				if((COT_SPONT == usReason || COT_PERCYC == usReason) && NULL != pstSelf->pfnAddDiYcVal)
				{
					pstSelf->pfnAddDiYcVal(&stYcInfo, pstSelf->pUsrData);
				}
			}
		}
	}

	return;
}

/**
* @brief 总召遥测帧组帧函数
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_SummonYc(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usi            = 0;//循环变量
	unsigned short usQoi          = 0;//召唤限定词
	unsigned short usReason       = 0;
	unsigned short usYcSendCnt    = 0;
	unsigned short usYcAllCnt     = 0;
	unsigned short usEncodeInfoLen = 0; //已组帧的信息体长度
	unsigned int uiEndInforAddr = 0; //组内信息体地址尾部 暂时不用 =起始+数量
	unsigned short usContinue     = 0;
	Yc_Info stYcInfoData = {0};
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	usQoi    = (unsigned short)(uiParam >> 16);
	usReason = (unsigned short)uiParam;

	if(NULL == pstSelf->pfnGetYcCountByGroup)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetYcValueByGroup)
	{
		return 0;
	}

	usYcAllCnt = pstSelf->pfnGetYcCountByGroup(usQoi, pstSelf->pUsrData, &pstSelf->uiYcConstInfo, &uiEndInforAddr);

	if(usYcAllCnt <= pstSelf->usYcSendNum)
	{
		pstSelf->usYcSendNum = 0;
		SetSendTask(pstSelf, TSKID_SummonResponse, COT_ACTTERM, usQoi);
		return 0;
	}

	usYcAllCnt -= pstSelf->usYcSendNum;
	/****填充总召遥测****/
	pstAsdus->usTypeID = GetTaskTItype(pstSelf, DATATYPE_YC);
	pstAsdus->usSQ     = CONTINUE;
	pstAsdus->usCot    = COT_INTROGEN; //响应总召
	pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], pstSelf->uiYcConstInfo + pstSelf->usYcSendNum, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->usNum = 0;

	for(usi = 0; usi < usYcAllCnt; usi++)
	{
		if(0 != pstSelf->pfnGetYcValueByGroup(usQoi, pstSelf->usYcSendNum + usi, &stYcInfoData, pstSelf->pUsrData))
		{
			usEncodeInfoLen = (M_ME_NA == pstAsdus->usTypeID || M_ME_NB == pstAsdus->usTypeID) ? 2 : 4; //遥测值长度
			usEncodeInfoLen += 1;//品质描述词 QDS长度
			usEncodeInfoLen += pstAsdus->usPayloadSize;//已组帧的信息体长度

			//填充遥测值
			if(usEncodeInfoLen <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
			{
				usContinue = 0;

				if(M_ME_NA == pstAsdus->usTypeID || M_ME_NB == pstAsdus->usTypeID)
				{
					//归一化值 NVA
					pstAsdus->usPayloadSize += ASDU_setNVA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], (unsigned short)stYcInfoData.fVal);
				}
				else
				{
					//IEEE STD745 短浮点数
					pstAsdus->usPayloadSize += ASDU_setSTD754(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stYcInfoData.fVal);
				}

				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stYcInfoData.ucQds;// QDS
				pstAsdus->usNum++;
			}
			else
			{
				usContinue = 1;
				break;
			}
		}

		usYcSendCnt++;
	}

	pstSelf->usYcSendNum += usYcSendCnt;

	if(usContinue)
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, usQoi);
	}
	else
	{
		pstSelf->usYcSendNum = 0;
		SetSendTask(pstSelf, TSKID_SummonResponse, COT_ACTTERM, usQoi);
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 变化遥测组帧函数
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ChangeYc(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned char   ucPerSize   = 0;                       // 当前固定长度
	unsigned char   ucLen       = 0;                       // 遥测值长度
	unsigned short  usYcAllCnt  = 0;
	unsigned short  usContinue  = 0;
	unsigned short  usReason    = (unsigned short)uiParam;
	unsigned short  usQoi       = (unsigned short)(uiParam >> 16);
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem; // 数据与实体关联
	pstAsdus->usSQ   = DISCONTINUE;              // 表示信息体地址 不连续
	pstAsdus->usCot  = usReason;                 // 突发回复
	pstAsdus->usNum  = 0;                        // 遥测突变的数量  数值需要判断
	Yc_Info stYcInfoData = {0};
	pstAsdus->usTypeID = GetTaskTItype(pstSelf, DATATYPE_YC);

	if(NULL == pstSelf->pfnGetDiturbYc_SendNum)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetDiturbYc)  // 从数据表中无遥测数据 则返回
	{
		return 0;
	}

	if(NULL == pstSelf->pfnUpdata_DiturbYc_Pout)  // 更新数据池出入指针
	{
		return 0;
	}

	ucLen = (M_ME_NA == pstAsdus->usTypeID || M_ME_NB == pstAsdus->usTypeID) ? 2 : 4;
	ucPerSize = pstSelf->stAppParameters.iSzOfIOA + ucLen + 1;         // 当前长度 = 电能量对象地址长度 + 遥测值长度 + 品质描述词长度
	usYcAllCnt = pstSelf->pfnGetDiturbYc_SendNum(pstSelf->pUsrData);       // 待发送的扰动遥测数据的数量
	pstSelf->usDisTurbYcSendNum = 0;

	for(unsigned short i = 0; i < usYcAllCnt; i++)
	{
		if(0 != pstSelf->pfnGetDiturbYc(&stYcInfoData, pstSelf->pUsrData, pstSelf->usDisTurbYcSendNum))  // 从数据表中取遥测数据
		{
			if(ucPerSize + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
			{
				pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stYcInfoData.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);

				if(ucLen == 4)
				{
					pstAsdus->usPayloadSize += ASDU_setSTD754(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stYcInfoData.fVal);
				}
				else
				{
					pstAsdus->usPayloadSize += ASDU_setNVA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], (unsigned short)stYcInfoData.fVal);
				}

				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stYcInfoData.ucQds;//品质描述词QDS
				usContinue = 0;
				pstAsdus->usNum++;
			}
			else
			{
				usContinue = 1;
				break;
			}
		}

		pstSelf->usDisTurbYcSendNum++;
	}

	if(usContinue)
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, usQoi);
	}

	pstSelf->pfnUpdata_DiturbYc_Pout(pstSelf->pUsrData, pstSelf->usDisTurbYcSendNum); //更新扰动数据池的出指针偏移量
	return pstAsdus->usPayloadSize;
}

/**
* @brief 遥控从站报文解析
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_YkSlavePro(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucYkType = 0; //遥控类型 选择-执行
	unsigned char  ucState  = 0; //开关状态
	unsigned short usLen    = 0; //信息体地址长度
	unsigned int uiYkAddr = 0; //信息体地址
	Yk_Info stInfo = {0};   //对外提供的遥控信息
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem; //接收的部分ASDU数据 待解析
	ASDU_CMD_T unYkTypeState; //遥控 类型和状态
	//从站解析遥控数据
	uiYkAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);//地址
	usLen += pstSelf->stAppParameters.iSzOfIOA;   //信息体地址位数
	unYkTypeState.ucBits = pstAsduInfo->pucPayload[usLen];

	//遥控数据更新至大规约结构体中用于组帧
	if(C_DC_NA == pstSelf->stAsduElem.usTypeID)    //双点遥控处理遥信
	{
		pstSelf->usYkType = YK_TYPE_C_DC; // 1双点遥控
		ucYkType = unYkTypeState.DCO.ucSE;
		ucState = unYkTypeState.DCO.ucDCS;

		if(ucState == 0 || ucState == 3) //遥信状态0 3不被允许
		{
			return;
		}
	}
	else if(C_SC_NA == pstSelf->stAsduElem.usTypeID)
	{
		pstSelf->usYkType = YK_TYPE_C_SC; // 0单点遥控
		ucYkType = unYkTypeState.SCO.ucSE;
		ucState = unYkTypeState.SCO.ucSCS;
	}
	else //遥控类型标识错误则返回
	{
		return;
	}

	pstSelf->ucSE = ucYkType;
	pstSelf->ucQu = ucState;
	pstSelf->ulYkAddr = uiYkAddr;
	/*遥控信息更至内部结构体中用于规约外数据处理*/
	stInfo.uiInfoAddr = uiYkAddr; // 信息体地址
	stInfo.ucStatus = ucState;    //遥控状态 开合
	stInfo.ucStateType = pstSelf->usYkType ; //单点0 双点1

	if(COT_ACT == (usReason & 0x3F))
	{
		stInfo.ucYkType = ucYkType;  //遥控类型 1 选择  0执行
	}
	else if(COT_DEACT == (usReason & 0x3F))
	{
		stInfo.ucYkType = 2;  //遥控类型 1 选择  0执行 2撤销
	}
	else
	{
		SetSendTask(pstSelf, TSKID_YkProcess, COT_E_REASON, pstSelf->usYkType);
		return;  //传输原因异常不处理
	}

	/*遥控数据外部接口处理*/
	if(NULL == pstSelf->pfnSetYkInfor)
	{
		if(COT_ACT == (usReason & 0x3F))
		{
			SetSendTask(pstSelf, TSKID_YkProcess, COT_PN | COT_ACTCON, pstSelf->usYkType);
		}
		else if(COT_DEACT == (usReason & 0x3F))
		{
			SetSendTask(pstSelf, TSKID_YkProcess, COT_PN | COT_DEACTCON, pstSelf->usYkType);
		}

		return;
	}

	/*遥控操作校验*/
	if(pstSelf->pfnFcYkVerify)
	{
		if(0 == pstSelf->pfnFcYkVerify(pstSelf->pUsrData))
		{
			if(COT_ACT == (usReason & 0x3F))
			{
				SetSendTask(pstSelf, TSKID_YkProcess, COT_PN | COT_ACTCON, pstSelf->usYkType);
			}
			else if(COT_DEACT == (usReason & 0x3F))
			{
				SetSendTask(pstSelf, TSKID_YkProcess, COT_PN | COT_DEACTCON, pstSelf->usYkType);
			}

			return;
		}
	}

	if(NULL != pstSelf->pfnSetYkInfor)
	{
		pstSelf->pfnSetYkInfor(&stInfo, pstSelf->pUsrData); //规约外执行遥控任务接口
	}
}

/**
* @brief 遥控主站报文解析
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_YkMasterPro(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucYkType = 0;  //遥控类型 选择-执行
	unsigned char  ucState  = 0;  //开关状态（不管单双点）
	unsigned short usLen    = 0;  //信息体地址长度
	unsigned int uiYkAddr = 0;  //信息体地址
	ASDU_CMD_T unYkTypeState; //遥控 类型和状态
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem; //接收的部分ASDU数据 待解析
	//主站 激活确认 停止激活确认 激活结束
	uiYkAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);//地址
	usLen += pstSelf->stAppParameters.iSzOfIOA;   //信息体地址位数
	unYkTypeState.ucBits = pstAsduInfo->pucPayload[usLen];

	//遥控数据更新至大规约结构体中
	if(C_DC_NA == pstSelf->stAsduElem.usTypeID)    //双点遥控处理遥信
	{
		pstSelf->usYkType = YK_TYPE_C_DC; // 1 双点遥控
		ucYkType = unYkTypeState.DCO.ucSE;
		ucState = unYkTypeState.DCO.ucDCS;

		if(ucState == 0 || ucState == 3) //遥信状态0 3不被允许
		{
			return;
		}
	}
	else if(C_SC_NA == pstSelf->stAsduElem.usTypeID)
	{
		pstSelf->usYkType = YK_TYPE_C_SC; // 0 单点遥控
		ucYkType = unYkTypeState.SCO.ucSE;
		ucState = unYkTypeState.SCO.ucSCS;
	}
	else
	{
		return;
	}

	pstSelf->ucSE = ucYkType;
	pstSelf->ucQu = ucState;
	pstSelf->ulYkAddr = uiYkAddr;
}

/**
* @brief 遥控从站发送报文组帧
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_YkSlave(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason = 0;
	unsigned short usTiType = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;;
	ASDU_CMD_T unYkTypeState; //遥控 类型和状态
	//使用大结构体参数组帧
	usReason = (unsigned short)uiParam;
	usTiType = (unsigned short)(uiParam >> 16);
	pstAsdus->usSQ = 0;
	pstAsdus->usNum = 1;
	pstAsdus->usCot = usReason;
	unYkTypeState.QOS.ucSE = pstSelf->ucSE;
	unYkTypeState.QOS.ucQL = pstSelf->ucQu;

	if(0 == usTiType)
	{
		pstAsdus->usTypeID = C_SC_NA;
	}
	else
	{
		pstAsdus->usTypeID = C_DC_NA;
	}

	pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], pstSelf->ulYkAddr, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = unYkTypeState.ucBits ;

	/*执行成功确认  停止激活确认*/
	if((COT_ACTCON == (usReason & 0x3F) && (0 == pstSelf->ucSE))
	        ||  COT_DEACTCON == (usReason & 0x3F) || COT_PN == (COT_PN & usReason))
	{
		if(pstSelf->ucYKEndFrame)
		{
			SetSendTask(pstSelf, TSKID_YkProcess, COT_ACTTERM, usTiType);  //激活结束帧置位
		}
	}
	else if(COT_ACTTERM == (usReason & 0x3F))
	{
		/*遥控结束，清空遥控状态信息*/
		pstSelf->ulYkAddr = 0;
		pstSelf->ucSE = 0;
		pstSelf->ucQu = 0;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 遥控主站发送报文组帧
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_YkMaster(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason = 0;
	unsigned short usTiType = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;;
	ASDU_CMD_T unYkTypeState; //遥控 类型和状态
	//使用大结构体参数组帧
	usReason = (unsigned short)uiParam;
	usTiType = (unsigned short)(uiParam >> 16);
	unYkTypeState.QOS.ucSE = pstSelf->ucSE;
	unYkTypeState.QOS.ucQL = pstSelf->ucQu;
	pstAsdus->usSQ = 0;
	pstAsdus->usNum = 1;
	pstAsdus->usCot = usReason;

	if(0 == usTiType)
	{
		pstAsdus->usTypeID = C_SC_NA;
	}
	else
	{
		pstAsdus->usTypeID = C_DC_NA;
	}

	pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], pstSelf->ulYkAddr, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = unYkTypeState.ucBits;

	/*激活6  停止激活8*/
	if(COT_ACT == (usReason & 0x3F))
	{
	}
	else if(COT_DEACT == (usReason & 0x3F))
	{
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 遥控报文解析
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_YKPro(CS10x *pstSelf, unsigned short usReason)
{
	CS10x_Type stType = pstSelf->eCS10x_Type;

	//从站解析
	if(CS101_TYPE_S == stType || CS104_TYPE_S == stType)
	{
		Do_YkSlavePro(pstSelf, usReason);
	}

	//主站解析
	if(CS101_TYPE_M == stType || CS104_TYPE_M == stType)
	{
		Do_YkMasterPro(pstSelf, usReason);
	}
}

/**
* @brief 遥控发送报文组帧
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_Yk(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usLen = 0;
	CS10x_Type stType = pstSelf->eCS10x_Type;

	//从站组帧
	if(CS101_TYPE_S == stType || CS104_TYPE_S == stType)
	{
		usLen = CS10x_Send_YkSlave(pstSelf, uiParam);
	}

	//主站组帧
	if(CS101_TYPE_M == stType || CS104_TYPE_M == stType)
	{
		usLen = CS10x_Send_YkMaster(pstSelf, uiParam);
	}

	return usLen;
}

/**
* @brief SOE报文解析函数
*
* @param[in] pstSelf 规约实体
*/
void Do_SOE(CS10x *pstSelf)
{
	unsigned short usLen   = 0;//信息体下标
	unsigned short usYxNUm = 0;//信息对象个数
	SOE_Info stSoeInfo     = {0};
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;

	if(CONTINUE == pstSelf->stAsduElem.usSQ)  // SOE点号连续
	{
		;
	}
	else if(DISCONTINUE == pstSelf->stAsduElem.usSQ)  // SOE点表不连续
	{
		usYxNUm = pstSelf->stAsduElem.usNum;

		for(unsigned short i = 0; i < usYxNUm; i++)
		{
			//信息体地址
			stSoeInfo.uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;
			stSoeInfo.ucStatus = pstAsduInfo->pucPayload[usLen++];

			if(NULL != pstSelf->pfnGetYxPotPro)
			{
				stSoeInfo.ucStateType = pstSelf->pfnGetYxPotPro(pstSelf->pUsrData, stSoeInfo.uiInfoAddr);

				if(!stSoeInfo.ucStateType && M_DP_TB == pstAsduInfo->usTypeID)
				{
					stSoeInfo.ucStatus -= 1;
				}
			}

			//获取时标
			ASDU_getCP56Time2a(&pstAsduInfo->pucPayload[usLen], &stSoeInfo.stCTime);
			usLen += 7;

			if(NULL != pstSelf->pfnAddSOE)
			{
				pstSelf->pfnAddSOE(&stSoeInfo, pstSelf->pUsrData);
			}

			if(stSoeInfo.uiInfoAddr == pstSelf->usWaveInfoAddr && stSoeInfo.ucStatus)
			{
				SetSendTask(pstSelf, TSKID_DirReqByFile, 0, 0);
			}
		}
	}
}

/**
* @brief SOE发送组帧函数
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_SOE(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usSoeSendTotal  = 0;//需要发送总数量
	unsigned short usEncodeInfoLen = 0;//已组帧的信息体长度
	unsigned short usSoeAllCnt     = 0;
	unsigned short usReason        = 0;
	unsigned char  ucStateType     = 0;
	unsigned char  ucValid         = 0;
	SOE_Info stSoeInfo  = {0};
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	usReason = (unsigned short)uiParam;

	if(NULL == pstSelf->pfnGetSOE_SendNum)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetSOE)
	{
		return 0;
	}

	usSoeSendTotal = pstSelf->usSoeSendNum;

	if(usSoeSendTotal == pstSelf->usSoeSendNoAckNum)
	{
		return 0;
	}

	usSoeAllCnt = usSoeSendTotal - pstSelf->usSoeSendNoAckNum;
	/****填充SOE****/
	pstAsdus->usTypeID = GetTaskTItype(pstSelf, DATATYPE_YXT);//无用可删除?
	pstAsdus->usSQ     = 0;
	pstAsdus->usNum    = 0;
	pstAsdus->usCot    = usReason; //突变
	memset(&stSoeInfo, 0, sizeof(SOE_Info));

	for(unsigned short i = 0; i < usSoeAllCnt; i++)
	{
		if(pstSelf->pfnGetSOE(&stSoeInfo, pstSelf->pUsrData, pstSelf->usSoeSendNoAckNum))
		{
			if(ucValid == 0)
			{
				if(stSoeInfo.ucStateType)                   //SOE 根据TypeID分针
				{
					pstAsdus->usTypeID = M_DP_TB;
					ucStateType = stSoeInfo.ucStateType;
				}
				else
				{
					pstAsdus->usTypeID = M_SP_TB;
					ucStateType = stSoeInfo.ucStateType;
				}

				ucValid = 1;
			}

			if(ucStateType != stSoeInfo.ucStateType)
			{
				break;
			}

			usEncodeInfoLen = pstAsdus->usPayloadSize + pstSelf->stAppParameters.iSzOfIOA + 1 + sizeof(__CP56Time2a);//已组帧+地址+元素+时标长度

			if(usEncodeInfoLen <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
			{
				//信息体地址
				pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stSoeInfo.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				//信息体元素
				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stSoeInfo.ucStatus;
				//时标
				pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stSoeInfo.stCTime);
				pstAsdus->usNum++;
			}
			else
			{
				break;
			}
		}

		pstSelf->usSoeSendNoAckNum++;

		if(pstSelf->usSoeSendNoAckNum >= pstSelf->usCosSendNoAckNum)
		{
			break;
		}
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief //故障事件报文解析
*
* @paramp[in] pstSelf 规约实体
*/
void Do_FaultEvent(CS10x *pstSelf)
{
	unsigned short i = 0;
	unsigned short usType = 0;
	unsigned short usLen  = 0;
	FAULT_EVENT_Info stFaultInfo = {0};
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	stFaultInfo.usSoeNum = pstAsduInfo->pucPayload[usLen++];
	usType = pstAsduInfo->pucPayload[usLen++];

	if(stFaultInfo.usSoeNum > MAX_FAULT_EVENT_SOE_SIZE)
	{
		stFaultInfo.usSoeNum = MAX_FAULT_EVENT_SOE_SIZE;
	}

	for(i = 0; i < stFaultInfo.usSoeNum; i++)
	{
		if(((pstSelf->usFaultEnable == 0 || pstSelf->usFaultEnable == 1) && pstSelf->stAppParameters.iSzOfIOA == 2)
		        || (pstSelf->usFaultEnable == 2))
		{
			stFaultInfo.staSoe[i].uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], 2);
		}
		else if(((pstSelf->usFaultEnable == 0 || pstSelf->usFaultEnable == 1) && pstSelf->stAppParameters.iSzOfIOA == 3)
		        || (pstSelf->usFaultEnable == 3))
		{
			stFaultInfo.staSoe[i].uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], 3);
		}
		else
		{
			return;
		}

		usLen += pstSelf->stAppParameters.iSzOfIOA;
		stFaultInfo.staSoe[i].ucStatus = pstAsduInfo->pucPayload[usLen++];

		if(NULL != pstSelf->pfnGetYxPotPro)
		{
			stFaultInfo.staSoe[i].ucStateType = pstSelf->pfnGetYxPotPro(pstSelf->pUsrData, stFaultInfo.staSoe[i].uiInfoAddr);

			if(!stFaultInfo.staSoe[i].ucStateType && M_DP_TB == pstAsduInfo->usTypeID)
			{
				stFaultInfo.staSoe[i].ucStatus -= 1;
			}
		}

		ASDU_getCP56Time2a(&pstAsduInfo->pucPayload[usLen], &stFaultInfo.staSoe[i].stCTime);
		usLen += 7;
	}

	stFaultInfo.usYcNum = pstAsduInfo->pucPayload[usLen++];
	usType = pstAsduInfo->pucPayload[usLen++];

	if(stFaultInfo.usYcNum > MAX_FAULT_EVENT_SOE_SIZE)
	{
		stFaultInfo.usYcNum = MAX_FAULT_EVENT_YC_SIZE;
	}

	for(unsigned short i = 0; i < stFaultInfo.usYcNum; i++)
	{
		stFaultInfo.staYc[i].uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
		usLen += pstSelf->stAppParameters.iSzOfIOA;

		if(M_ME_NC == usType)  //测量值-短浮点数
		{
			stFaultInfo.staYc[i].fVal = ASDU_getSTD754(&pstAsduInfo->pucPayload[usLen]);
			usLen += 4;
		}
		else
		{
			stFaultInfo.staYc[i].fVal = (float)ASDU_getNVA(&pstAsduInfo->pucPayload[usLen]);
			usLen += 2;
		}
	}

	if(NULL != pstSelf->pfnAddEvent)
	{
		pstSelf->pfnAddEvent(&stFaultInfo, pstSelf->pUsrData);
	}
}

/**
* @brief //故障事件发送报文组帧
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_FaultEvent(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usType           = 0;
	unsigned short usEventSendTotal = 0;                     //需要发送总数量
	FAULT_EVENT_Info stEventInfo = {0};
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = M_FT_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 0;
	pstAsdus->usCot     = (unsigned short)uiParam;           //突变

	if(!pstSelf->usFaultEnable)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetEvent_SendNum)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetFaultEvent)
	{
		return 0;
	}

	usEventSendTotal = pstSelf->pfnGetEvent_SendNum(pstSelf->pUsrData);

	if(usEventSendTotal == pstSelf->usEventSendNoAckNum)
	{
		return 0;
	}

	if(pstSelf->pfnGetFaultEvent(&stEventInfo, pstSelf->pUsrData, pstSelf->usEventSendNoAckNum))
	{
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stEventInfo.usSoeNum;
		usType = GetTaskTItype(pstSelf, DATATYPE_YXT);
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usType;

		for(unsigned short i = 0; i < stEventInfo.usSoeNum; i++)
		{
			if(pstSelf->usFaultEnable == 2 || (pstSelf->usFaultEnable == 1 && pstSelf->stAppParameters.iSzOfIOA == 2))
			{
				pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stEventInfo.staSoe[i].uiInfoAddr, 2);
			}
			else if(pstSelf->usFaultEnable == 3 || (pstSelf->usFaultEnable == 1 && pstSelf->stAppParameters.iSzOfIOA == 3))
			{
				pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stEventInfo.staSoe[i].uiInfoAddr, 3);
			}
			else
			{
				return 0;
			}

			if(0 == stEventInfo.staSoe[i].ucStateType && M_DP_TB == usType)
			{
				stEventInfo.staSoe[i].ucStatus += 1;
			}

			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stEventInfo.staSoe[i].ucStatus;
			pstAsdus->usPayloadSize += ASDU_setCP56Time2a(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &stEventInfo.staSoe[i].stCTime);
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stEventInfo.usYcNum;
		usType = GetTaskTItype(pstSelf, DATATYPE_YC);
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usType;

		for(unsigned short i = 0; i < stEventInfo.usYcNum; i++)
		{
			pstAsdus->usPayloadSize += ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stEventInfo.staYc[i].uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);

			if(M_ME_NC == usType)
			{
				pstAsdus->usPayloadSize += ASDU_setSTD754(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stEventInfo.staYc[i].fVal);
			}
			else
			{
				pstAsdus->usPayloadSize += ASDU_setNVA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], (unsigned short)stEventInfo.staYc[i].fVal);
			}
		}

		pstSelf->usEventSendNoAckNum++;
	}
	else
	{
		return 0;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief //规约从模式,  接收主站数据
*
* @param[in] pstSelf 规约实体
* @param[in] usType 操作标识
* @param[in] pucBuf 数据缓存
* @return
*/
void Do_FilePro_Slave(CS10x *pstSelf, unsigned char ucType, unsigned char *pucBuf, unsigned short usFileDateLen)
{
	switch(ucType)
	{
		//读文件
		case FILE_ST_RD_DIR:                //文件目录召唤 slave
			Revc_ReadFS_CallDir_S(pstSelf, pucBuf, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_ACT:           //读文件激活   slave
			Revc_ReadFS_SelectFile_S(pstSelf, pucBuf, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_DATA_RESPONE:  //读文件数据传输确认 slave
			Revc_ReadFS_AckFileSeg_S(pstSelf, pucBuf, &pstSelf->stRdSet);
			break;

		//写文件
		case FILE_ST_WR_FILE_ACT:           //写文件激活 slave
			Recv_WriteFS_SelectFile_S(pstSelf, pucBuf, &pstSelf->stWdSet);
			break;

		case FILE_ST_WR_FILE_DATA:              //写文件数据传输 slave
			Recv_WriteFS_DownFileSeg_S(pstSelf, pucBuf, &pstSelf->stWdSet, usFileDateLen);
			break;

		default:
			//文件操作标识错误或报文解析错误
			break;
	}
}

/**
* @brief //规约主模式, 接收对下设备数据
*
* @param[in] pstSelf 规约实体
* @param[in] usType 操作标识
* @param[in] pucBuf 数据缓存
* @return
*/
void Do_FilePro_Master(CS10x *pstSelf, unsigned char ucType, unsigned char *pucBuf)
{
	switch(ucType)
	{
		//读文件
		case FILE_ST_RD_DIR_RESPONE:        //目录召唤确认 master
			Revc_ReadFS_AckCallDir_M(pstSelf, pucBuf, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_ACT_RESPONE:   //读文件激活确认 master
			Revc_ReadFS_AckSelectFile_M(pstSelf, pucBuf, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_DATA:          //读文件数据传输 master
			Revc_ReadFS_CallFileSeg_M(pstSelf, pucBuf, &pstSelf->stRdSet);
			break;

		//写文件
		case FILE_ST_WR_FILE_ACT_RESPONE:       //写文件激活确认 master
			Recv_WriteFS_AckSelectFile_M(pstSelf, pucBuf, &pstSelf->stWdSet);
			break;

		case FILE_ST_WR_FILE_DATA_RESPONE:      //写文件数据传输确认 master
			Recv_WriteFS_AckDownFileSeg_M(pstSelf, pucBuf, &pstSelf->stWdSet);
			break;

		default:
			//文件操作标识错误或报文解析错误
			break;
	}
}


/**
* @brief //解析文件报文 包括目录及文件
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_FilePro(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen  = 0;
	unsigned short ucType = 0;
	CS10x_Type stCS10x_Type = pstSelf->eCS10x_Type;
	ASDU_Element *pAsduInfo    = &pstSelf->stAsduElem;
	unsigned char *pucPayload          = &pAsduInfo->pucPayload[0];
	usLen += pstSelf->stAppParameters.iSzOfIOA;
	// usVSQ = pstSelf->stAsduElem.usSQ | pstSelf->stAsduElem.usNum;
	/*if(usVSQ) //放松条件 传输原因暂时也不判断 主站收传输原因5和6  从站收传输原因6和7
	{
	return;
	}*/
	usLen++;                            //跳过附加数据包类型      02表示文件传输 其他为备用
	ucType = pucPayload[usLen++]; //操作标识

	if(stCS10x_Type == CS101_TYPE_S || stCS10x_Type == CS104_TYPE_S)
	{
		Do_FilePro_Slave(pstSelf, ucType, &pucPayload[usLen], pstSelf->stAsduElem.usPayloadSize - pstSelf->stAppParameters.iSzOfIOA - 2); /*减信息体地址长度 数据包类型 操作标识104 -5  101 -4*/
	}
	else if(stCS10x_Type == CS101_TYPE_M || stCS10x_Type == CS104_TYPE_M)
	{
		Do_FilePro_Master(pstSelf, ucType, &pucPayload[usLen]);
	}
	else
	{
		//主动模式设置错误
	}
}

/**
* @brief 比对录波文件差异
*
* @param[in] pstSelf 规约实体
*/
void CheckFileDiff(CS10x *pstSelf)
{
#if 0
	IEC_FILE_STU *pstFile = NULL;
	pstFile = &pstSelf->pstFileStu;
	// IEC_FILE_STU stWaveFileSt_L;

	for(unsigned short i = 0; i < pstFile->usFileNum; i++)
	{
		// IEC_PRINT("%s, %s \n\r",pstFile->caDirName,pstFile->staFileInfoSet[i].caFileName);
		if(false == pstSelf->pfnSearchFileName(pstFile->caDirName, pstFile->staFileInfoSet[i].caFileName, pstSelf->pUsrData))
		{
			memcpy(pstFile->stTransFileInfo.caFileName, pstFile->staFileInfoSet[i].caFileName, pstFile->staFileInfoSet[i].usFileNameLen);
			pstFile->stTransFileInfo.usFileNameLen = pstFile->staFileInfoSet[i].usFileNameLen;
			SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_RD_FILE_ACT, 0);
			return;
		}
	}

	pstFile->unStatus = FILE_ST_IDLE;
#endif
	return;
}


unsigned short CS10x_Send_FilePro_Master(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus)
{
	unsigned short usMsgSize = 0;

	switch(usFileProType)
	{
		case FILE_ST_RD_DIR:                //召唤目录
			usMsgSize = Send_ReadFS_CallDir_M(pstSelf, usFileProType, pstAsdus, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_ACT:           //读文件激活
			usMsgSize = Send_ReadFS_SelectFile_M(pstSelf, usFileProType, pstAsdus, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_DATA_RESPONE:  //读文件数据传输确认
			usMsgSize = Send_ReadFS_AckFileSeg_M(pstSelf, usFileProType, pstAsdus, &pstSelf->stRdSet);
			break;

		case FILE_ST_WR_FILE_ACT:           //写文件激活
			usMsgSize = Send_WriteFS_SelectFile_M(pstSelf, usFileProType, pstAsdus, &pstSelf->stWdSet);
			break;

		case FILE_ST_WR_FILE_DATA:          //写文件数据传输
			usMsgSize = Send_WriteFS_DownFileSeg_M(pstSelf, usFileProType, pstAsdus, &pstSelf->stWdSet);
			break;

		default:
			break;
	}

	return usMsgSize;
}


unsigned short CS10x_Send_FilePro_Slave(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus)
{
	unsigned short usMsgSize = 0;

	switch(usFileProType)
	{
		case FILE_ST_RD_DIR_RESPONE:        //召唤目录响应
			usMsgSize = Send_ReadFS_AckCallDir_S(pstSelf, usFileProType, pstAsdus, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_ACT_RESPONE:   //读文件激活确认
			usMsgSize = Send_ReadFS_AckSelectFile_S(pstSelf, usFileProType, pstAsdus, &pstSelf->stRdSet);
			break;

		case FILE_ST_RD_FILE_DATA:          //读文件数据传输
			usMsgSize = Send_ReadFS_CallFileSeg_S(pstSelf, usFileProType, pstAsdus, &pstSelf->stRdSet);

			/*101规约无确认文件传输功能*/
			if(pstSelf->eCS10x_Type == CS101_TYPE_S && usMsgSize > 0 && pstSelf->ucFileAckType == 1)
			{
				pstSelf->ucFileTransFrame = 1;   /* 正在进行文件传输*/
				pstSelf->usFileNoneAckNum++;        /* 未确认传输帧累加*/
			}

			break;

		case FILE_ST_WR_FILE_ACT_RESPONE:   //写文件激活确认
			usMsgSize = Send_WriteFS_AckSelectFile_S(pstSelf, usFileProType, pstAsdus, &pstSelf->stWdSet);
			break;

		case FILE_ST_WR_FILE_DATA_RESPONE:  //写文件数据传输确认
			usMsgSize = Send_WriteFS_AckDownFileSeg_S(pstSelf, usFileProType, pstAsdus, &pstSelf->stWdSet);
			break;

		default:
			break;
	}

	return usMsgSize;
}

/**
* @brief //文件操作发送接口函数
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_FilePro(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usFileProType       = (unsigned short)uiParam;
	CS10x_Type stCS10x_Type = pstSelf->eCS10x_Type;;
	ASDU_Element *pstAsdus     = &pstSelf->stAsduElem;
	pstAsdus->usTypeID = F_FR_NA;
	pstAsdus->usSQ          = 0;

	if(pstSelf->ucReadFileVSQ)
	{
		pstAsdus->usNum = 1; //解决部分部分主站无法识别VSQ=0的情况
	}
	else
	{
		pstAsdus->usNum = 0; // vsq=0;  1表示无效
	}

	if(stCS10x_Type == CS101_TYPE_S || stCS10x_Type == CS104_TYPE_S)
	{
		return CS10x_Send_FilePro_Slave(pstSelf, usFileProType, pstAsdus);
	}
	else if(stCS10x_Type == CS101_TYPE_M || stCS10x_Type == CS104_TYPE_M)
	{
		return CS10x_Send_FilePro_Master(pstSelf, usFileProType, pstAsdus);
	}
	else
	{
		//主动模式设置错误
	}

	return 0;
}


/**
* @brief 接收切换定值区命令接口
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传输原因
*/
void Do_ChgConst(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usArea = 0;
	unsigned short usLen  = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	usLen += pstSelf->stAppParameters.iSzOfIOA;

	if(COT_ACT == usReason)  //从站收
	{
		usArea = IEC_MAKEWORD(pstAsdus->pucPayload[usLen], pstAsdus->pucPayload[usLen + 1]);

		if(NULL == pstSelf->pfnSetParamArea)
		{
			return;
		}

		pstSelf->pfnSetParamArea(usArea, pstSelf->pUsrData);
		SetSendTask(pstSelf, TSKID_ChgConst, COT_ACTCON, 0);
	}
	else if(COT_ACTCON == usReason)
	{
		usArea = IEC_MAKEWORD(pstAsdus->pucPayload[usLen], pstAsdus->pucPayload[usLen + 1]);
		/*添加主模式读取成功返回函数*/
	}
}

/**
* @brief 切换定值区命令发送接口
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ChgConst(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usArea          = 0;
	unsigned short usInfoLen       = 0;
	unsigned short usReason        = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_SR_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;
	usInfoLen = ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], 0, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->usPayloadSize += usInfoLen;

	if(COT_ACT == usReason)  //激活
	{
		if(pstSelf->pfnGetParamArea)
		{
			usArea = pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData);
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
	}
	else if(COT_ACTCON == usReason)  //激活确认
	{
		if(pstSelf->pfnGetParamArea)
		{
			usArea = pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData);
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 读定值区接收接口
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_ReadConst(CS10x *pstSelf, unsigned short usReason)
{
	if(COT_ACT == usReason)  //从站收
	{
		SetSendTask(pstSelf, TSKID_ReadConst, COT_ACTCON, 0);
	}
	else if(COT_ACTCON == usReason)
	{
	}
}

/**
* @brief 读参数定值区发送接口
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return Asdu数据长度
*/
unsigned short CS10x_Send_ReadConst(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usArea          = 0;
	unsigned short usInfoLen       = 0;
	unsigned short usReason        = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_RR_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;
	usInfoLen = ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], 0, pstSelf->stAppParameters.iSzOfIOA);
	pstAsdus->usPayloadSize += usInfoLen;

	if(COT_ACT == usReason)  //激活
	{
	}
	else if(COT_ACTCON == usReason)  //激活确认
	{
		if(pstSelf->pfnGetParamArea)
		{
			usArea = pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData);
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
			usArea = pstSelf->pfnGetParamArea(MINPARAMAREA, pstSelf->pUsrData);
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
			usArea = pstSelf->pfnGetParamArea(MAXPARAMAREA, pstSelf->pUsrData);
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
		}
		else
		{
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usArea >> 8;
		}
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 参数定值读取接收接口
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_ParamPreread(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucPi        = 0;
	unsigned short usLen       = 0;
	unsigned short usParamArea = 0;
	unsigned int uiInfoAddr  = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	IECPARAM_T stIecParam = {0};
	usParamArea = IEC_MAKEWORD(pstAsdus->pucPayload[usLen], pstAsdus->pucPayload[usLen + 1]);
	usLen += 2;

	/*判断定值区*/
	if(pstSelf->pfnGetParamArea && usParamArea == pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData))
	{
	}

	if(COT_ACT == usReason)  //从站收
	{
		/*读取后不允许固化，公用缓冲区*/
		pstSelf->ucPmPresetFlag = 0;
		pstSelf->uiPmPresetTimeout = 0;

		if(pstAsdus->usNum)
		{
			for(unsigned short i = 0; i < pstAsdus->usNum; i++)
			{
				uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
				usLen += pstSelf->stAppParameters.iSzOfIOA;
				stIecParam.uiInfoAddr = uiInfoAddr;

				if(pstSelf->pfnAddIECParam)
				{
					pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
				}

				pstSelf->ucParamFlag = 1;     /*追加缓存*/
			}
		}
		else
		{
			if(pstSelf->pfnAddIECParam)
			{
				/*读取所有参数*/
				pstSelf->pfnAddIECParam(1, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
			}
		}

		//        pstSelf->ucParamFlag = 0;     /*104多帧一起时可能存在问题，采用追加的方式实现，在响应完成后清零*/
		if(pstSelf->pfnRunReadIECParam)
		{
			pstSelf->pfnRunReadIECParam(pstSelf->pUsrData);
		}
	}
	else if(COT_ACTCON == usReason)
	{
		/*作为主站时，暂时不添加*/
		ucPi = pstAsdus->pucPayload[usLen++];

		for(unsigned short i = 0; i < pstAsdus->usNum; i++)
		{
			uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;
			stIecParam.uiInfoAddr = uiInfoAddr;
			stIecParam.ucType = pstAsdus->pucPayload[usLen++];
			stIecParam.ucLen = pstAsdus->pucPayload[usLen++];

			if(CheckParamTagAndLen(stIecParam.ucType, stIecParam.ucLen) == false)
			{
				return;
			}

			if(stIecParam.ucLen)
			{
				memcpy(stIecParam.unVal.caBuf, &pstAsdus->pucPayload[usLen], stIecParam.ucLen);
				usLen += stIecParam.ucLen;
			}

			/*添加通知参数接收函数*/
		}

		if((ucPi & PARAM_CONT_1) == 0)  //无后续帧，置任务状态
		{
			/*通知接收完成*/
		}
	}
}

/**
* @brief 参数定值读取发送接口
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return Asdu数据长度
*/
unsigned short CS10x_Send_ParamPreread(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned char  ucTxNum         = 0;/*本次发送个数*/
	unsigned short usArea          = 0;
	unsigned short usContinue      = 0;
	unsigned short usTotalNum      = 0;/*缓冲数据个数*/
	unsigned short usReason        = (unsigned short)uiParam;
	IECPARAM_T stIecParam = {0};
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_RS_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usCot     = usReason;

	if(pstSelf->pfnGetParamArea)
	{
		usArea = pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData);
	}

	pstAsdus->pucPayload[pstAsdus->usPayloadSize ++] = IEC_LOBYTE(usArea);//当前定值区号：低
	pstAsdus->pucPayload[pstAsdus->usPayloadSize ++] = IEC_HIBYTE(usArea);//当前定值区号：高

	if(NULL == pstSelf->pfnGetParamCount)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetParamInfoByIndx)
	{
		return 0;
	}

	if(COT_ACT == usReason)  //激活
	{
		usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData); //获取总数量

		for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
		{
			if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
			{
				if(pstSelf->stAppParameters.iSzOfIOA + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
				{
					ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
					pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
					ucTxNum++;
					usContinue = 0;
				}
				else
				{
					usContinue = 1;
					break;
				}
			}

			pstSelf->usParamSendNum++;
		}

		if(!ucTxNum)
		{
			return 0;
		}
	}
	else if(COT_ACTCON == usReason)
	{
		usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData); //获取总数量
		pstAsdus->usPayloadSize++;                                                                             //是否后续帧及数据帧数量后面填充

		for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
		{
			if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
			{
				if(pstSelf->stAppParameters.iSzOfIOA + 2 + stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
				{
					ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
					pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
					pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stIecParam.ucType;
					pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stIecParam.ucLen;
					memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);/*复制当前参数值*/
					pstAsdus->usPayloadSize += stIecParam.ucLen;
					ucTxNum++;
					usContinue = 0;
				}
				else
				{
					usContinue = 1;
					break;
				}
			}

			pstSelf->usParamSendNum++;                             /*参数发送个数*/
		}

		if(usContinue)
		{
			pstAsdus->pucPayload[2] = PARAM_CONT_1;              /*PI参数特征表示为1：有后续*/
		}
		else
		{
			pstAsdus->pucPayload[2] = 0;                          /*PI参数特征表示为1：无后续*/
		}
	}

	if(usContinue == 0)
	{
		pstSelf->usParamSendNum = 0;
		pstSelf->ucParamFlag = 0;           /*无后续帧时，不进行追加，其他条件下可以进行参数追加，解决连帧问题*/
	}
	else
	{
		SetSendTask(pstSelf, TSKID_ParamPreread, usReason, 0);     /*继续执行发送任务*/
	}

	pstAsdus->usNum = ucTxNum;                            /*VSQ赋值*/
	return pstAsdus->usPayloadSize;
}

/**
* @brief 参数定值写接口接收处理接口（参数预置、固化、取消）
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_ParamPreset(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucPi            = 0;
	unsigned short usi             = 0;
	unsigned short usArea          = 0;
	unsigned short usLen           = 0;
	unsigned int uiInfoAddr      = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	IECPARAM_T stIecParam = {0};
	usArea = IEC_MAKEWORD(pstAsdus->pucPayload[usLen], pstAsdus->pucPayload[usLen + 1]);

	if(pstSelf->pfnGetParamArea && usArea == pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData))
	{
	}

	usLen += 2;
	ucPi = pstAsdus->pucPayload[usLen++];

	if(COT_ACT == usReason)  //从站收
	{
		if(ucPi & PARAM_SE_1)  //参数预置
		{
			pstSelf->ucPmPresetFlag = 1;
			pstSelf->uiPmPresetTimeout = 180000;    /*最长固化时间*/

			if(pstAsdus->usNum == 0)
			{
				return;
			}

			/*首次预置时，清除发送序号*/
			if(pstSelf->ucParamFlag == 0)
			{
				pstSelf->usParamSendNum = 0;
			}

			for(usi = 0; usi < pstAsdus->usNum; usi++)
			{
				uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
				usLen += pstSelf->stAppParameters.iSzOfIOA;
				stIecParam.uiInfoAddr = uiInfoAddr;
				stIecParam.ucType = pstAsdus->pucPayload[usLen++];
				stIecParam.ucLen = pstAsdus->pucPayload[usLen++];

				if(CheckParamTagAndLen(stIecParam.ucType, stIecParam.ucLen) == false)
				{
					return;
				}

				if(stIecParam.ucLen)
				{
					memcpy(stIecParam.unVal.caBuf, &pstAsdus->pucPayload[usLen], stIecParam.ucLen);
					usLen += stIecParam.ucLen;
				}

				if(NULL != pstSelf->pfnAddIECParam)
				{
					pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMWT, &stIecParam, pstSelf->pUsrData);
				}

				pstSelf->ucParamFlag = 1;
			}

			pstSelf->uiPreSetContCount = 10000; /* 10S无参数预置则判定为参数预置结束 */

			/*配置参数时无后续帧则之间认定无后续，否则使用超时+固化参数进行状态更新*/
			if(pstSelf->ucPreSetContType == 0)
			{
				/*一帧参数小于5个时，自动认定为最后一帧数据，主要用于山东一体化运维不固化*/
				if(pstAsdus->usNum < 5 || (ucPi & PARAM_CONT_1) == PARAM_CONT_0)
				{
					pstSelf->ucParamFlag = 0;
				}
			}

			SetSendTask(pstSelf, TSKID_ParamPrewrite, COT_ACTCON, PARAM_SE_1);
		}
		else
		{
			pstSelf->ucParamFlag = 0;      /*重置首次添加标识*/
			unsigned char ucFlag = 0;

			if(pstSelf->ucPreSetContType)
			{
				pstSelf->usParamSendNum = 0;
			}

			if(0 == (ucPi & PARAM_CR_1))  // VSQ 为0，参数固化
			{
				/*预置后才允许固化*/
				if(pstSelf->ucPmPresetFlag && pstSelf->pfnRunWriteIECParam)
				{
					ucFlag = pstSelf->pfnRunWriteIECParam(pstSelf->pUsrData);
				}
			}

			if(ucFlag)
			{
				SetSendTask(pstSelf, TSKID_ParamPrewrite, COT_ACTCON, 0);       /*预置成功*/
			}
			else
			{
				SetSendTask(pstSelf, TSKID_ParamPrewrite, COT_PN | COT_ACTCON, 0);    /*预置失败，终止命令*/
			}

			pstSelf->ucPmPresetFlag = 0;
			pstSelf->uiPmPresetTimeout = 0;
		}
	}
	else if(COT_ACTCON == usReason)
	{
		if(ucPi & PARAM_SE_1)  //参数预置
		{
		}
		else
		{
			if(ucPi & PARAM_CR_1)  //取消预置
			{
			}
			else //参数固化
			{
			}
		}

		return; //  收到预置命令
	}
	else if(COT_DEACT == usReason)
	{
		pstSelf->ucPmPresetFlag = 0;
		pstSelf->uiPmPresetTimeout = 0;
		pstSelf->ucParamFlag = 0;

		if((ucPi & (PARAM_SE_1 | PARAM_CR_1)) == PARAM_CR_1)
		{
			SetSendTask(pstSelf, TSKID_ParamPrewrite, COT_DEACTCON, PARAM_CR_1);
		}

		return;
	}
	else if(COT_DEACTCON == usReason)
	{
		/*停止激活确认*/
	}
}

/**
* @brief 参数定值写接口发送组包处理
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ParamPreset(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned char  ucCont     = 0;
	unsigned char  ucPi       = 0;
	unsigned char  ucTxNum    = 0;
	unsigned short usTotalNum = 0;
	unsigned short usi        = 0;
	unsigned short usArea     = 0;
	unsigned short usReason   = (unsigned short)uiParam;
	unsigned short usPi       = (unsigned short)(uiParam >> 16);           /*参数*/
	IECPARAM_T stIecParam = {0};
	ASDU_Element *pstAsdus =  &pstSelf->stAsduElem;
	pstAsdus->usTypeID = C_WS_NA;
	pstAsdus->usSQ = 0;
	pstAsdus->usNum = 0;
	pstAsdus->usCot = usReason;

	if(pstSelf->pfnGetParamArea)
	{
		usArea = pstSelf->pfnGetParamArea(CURPARAMAREA, pstSelf->pUsrData);
	}

	pstAsdus->pucPayload[pstAsdus->usPayloadSize ++] = IEC_LOBYTE(usArea);
	pstAsdus->pucPayload[pstAsdus->usPayloadSize ++] = IEC_HIBYTE(usArea);

	if(NULL == pstSelf->pfnGetParamInfoByIndx)
	{
		return 0;
	}

	if(COT_ACT == usReason)
	{
		if(PARAM_SE_1 & usPi)  //对子设备进行参数预置
		{
			ucPi = PARAM_SE_1;
			pstAsdus->usPayloadSize++; // PI标识位置

			if(NULL == pstSelf->pfnGetParamCount)
			{
				return 0;
			}

			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData); //获取总数量

			for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
			{
				if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, usi, &stIecParam, pstSelf->pUsrData))
				{
					if(pstSelf->stAppParameters.iSzOfIOA + 2 + stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
					{
						ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
						pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stIecParam.ucType;
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stIecParam.ucLen;
						memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);
						pstAsdus->usPayloadSize += stIecParam.ucLen;
						ucTxNum++;
						ucCont = 0;

						if(pstSelf->ucParamFlag == 1)
						{
							ucCont = 1;
						}
					}
					else
					{
						ucCont = 1;
					}
				}

				pstSelf->usParamSendNum++;
			}

			if(ucCont)
			{
				ucPi |= PARAM_CONT_1;
				SetSendTask(pstSelf, pstSelf->byTaskFlagId, COT_ACT, PARAM_SE_1);
			}

			if(ucCont == 0 || pstSelf->usParamSendNum == usTotalNum)
			{
				pstSelf->usParamSendNum = 0;
			}

			pstAsdus->usNum = ucTxNum;
			pstAsdus->pucPayload[2] = ucPi;
		}
		else
		{
			if(PARAM_CR_1 & usPi)  //取消预置
			{
				ucPi |= PARAM_CR_1;
				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucPi;
			}
			else //参数固化
			{
				ucPi = 0;
				pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucPi;
			}
		}
	}
	else if(COT_ACTCON == usReason || (COT_PN | COT_ACTCON) == usReason)  //回复主站参数预置数据
	{
		if(PARAM_SE_1 == usPi)
		{
			ucPi = PARAM_SE_1;
			pstAsdus->usPayloadSize++;
			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

			for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
			{
				if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, usi, &stIecParam, pstSelf->pUsrData))
				{
					if(pstSelf->stAppParameters.iSzOfIOA + 2 + stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
					{
						ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
						pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stIecParam.ucType;
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stIecParam.ucLen;
						memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);
						pstAsdus->usPayloadSize += stIecParam.ucLen;
						ucTxNum++;
						ucCont = 0;
					}
					else
					{
						ucCont = 1;
						break;
					}
				}

				pstSelf->usParamSendNum++;
			}

			/*缓存中无数据，不进行后续发送*/
			if(ucCont)
			{
				ucPi |= PARAM_CONT_1;
				SetSendTask(pstSelf, pstSelf->byTaskFlagId, COT_ACTCON, PARAM_SE_1);
			}

			/*主方向有后续，本帧返回带后续帧*/
			if(pstSelf->ucParamFlag == 1 && pstSelf->ucPreSetContType == 0)
			{
				ucPi |= PARAM_CONT_1;
			}

			/*主方向无后续帧且发送完成时，清除*/
			if(pstSelf->ucParamFlag == 0 && (ucCont == 0 || pstSelf->usParamSendNum == usTotalNum))
			{
				pstSelf->usParamSendNum = 0;
			}

			pstAsdus->usNum = ucTxNum;
			pstAsdus->pucPayload[2] = ucPi;
		}
		else
		{
			ucPi = 0;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucPi;
		}
	}
	else if(COT_DEACT == usReason)
	{
		;
	}
	else if(COT_DEACTCON == usReason)
	{
		if((usPi & (PARAM_SE_1 | PARAM_CR_1)) == PARAM_CR_1)  //取消预置
		{
			ucPi |= PARAM_CR_1;
			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucPi;
		}
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief Set the 101/104 Asdu Payload site
*
* @param[in] pstSelf 规约实体
* @return 组包长度
*/
unsigned short GetPayloadOffset(CS10x *pstSelf)
{
	unsigned short usPos = 0;

	if(CS101_TYPE_S == pstSelf->eCS10x_Type || CS101_TYPE_M == pstSelf->eCS10x_Type)
	{
		usPos = 5 + pstSelf->stAppParameters.iSzOfLinkAddr + pstSelf->stAppParameters.iSzOfCA + pstSelf->stAppParameters.iSzOfCOT + 2;
	}
	else
	{
		usPos = APCI_LEN + 2 + pstSelf->stAppParameters.iSzOfCA + pstSelf->stAppParameters.iSzOfCOT;
	}

	return usPos;
}

/**
* @brief Get the Asdu Info object
*
* @param[in] pstSelf 规约实体
**           pucPayload-信息对象起始指针
*            pusPayloadSize-信息对象长度
*/
unsigned short DecodeAsduMember(CS10x *pstSelf, unsigned char * pucAsdu, unsigned short usAsduSz)
{
	unsigned short usLen = 0;
	pstSelf->stAsduElem.usTypeID = pucAsdu[usLen++];
	pstSelf->stAsduElem.usSQ = pucAsdu[usLen] >> 7;
	pstSelf->stAsduElem.usNum = pucAsdu[usLen++] & 0x7F;

	if(1 == pstSelf->stAppParameters.iSzOfCOT)
	{
		pstSelf->stAsduElem.usCot = pucAsdu[usLen];
		usLen += 1;
	}
	else
	{
		pstSelf->stAsduElem.usCot = IEC_MAKEWORD(pucAsdu[usLen], pucAsdu[usLen + 1]);
		pstSelf->stAsduElem.usCotH = pucAsdu[usLen + 1];
		usLen += 2;
	}

	pstSelf->stAsduElem.usCot = pstSelf->stAsduElem.usCot & 0xFF;   /*仅处理低字节数据，不处理高字节数据*/

	if(1 == pstSelf->stAppParameters.iSzOfCA)  //公共地址字节数
	{
		pstSelf->stAsduElem.uiAddr = pucAsdu[usLen++];
	}
	else
	{
		pstSelf->stAsduElem.uiAddr = IEC_MAKEWORD(pucAsdu[usLen], pucAsdu[usLen + 1]);
		usLen += 2;
	}

	pstSelf->stAsduElem.pucPayload = pucAsdu + usLen;       // ASDU信息体起始指针
	pstSelf->stAsduElem.usPayloadSize = usAsduSz - usLen;   // ASDU域长度
	return usLen;
}

/**
* @brief Get the Task TI type object
*
* @param[in] pstSelf 规约实体
* @param[in] usDataType
* @return usTiType数据TI类型
*/
unsigned short GetTaskTItype(CS10x *pstSelf, unsigned short usDataType)
{
	unsigned short usTiType = 0;

	if(DATATYPE_YC == usDataType)
	{
		switch(pstSelf->usYcType)
		{
			case YC_TYPE_ME_NA:
				usTiType = M_ME_NA;
				break;

			case YC_TYPE_ME_NB:
				usTiType = M_ME_NB;
				break;

			case YC_TYPE_ME_NC:
				usTiType = M_ME_NC;
				break;

			default:
				usTiType = M_ME_NA;
				break;
		}
	}
	else if(DATATYPE_YX == usDataType)
	{
		switch(pstSelf->usYxType)
		{
			case YX_TYPE_M_SP:
				usTiType = M_SP_NA;
				break;

			case YX_TYPE_M_DP:
				usTiType = M_DP_NA;
				break;

			default:
				usTiType = M_SP_NA;
				break;
		}
	}
	else if(DATATYPE_YXT == usDataType)
	{
		switch(pstSelf->usYxType)
		{
			case YX_TYPE_M_SP:
				usTiType = M_SP_TB;
				break;

			case YX_TYPE_M_DP:
				usTiType = M_DP_TB;
				break;

			default:
				usTiType = M_SP_TB;
				break;
		}
	}

	return usTiType;
}

/**********************文件传输扩展接口************************/

/**
* @brief 召唤目录===>接收
* @param[in]  pstSelf  规约实体
* @param[in]  pucBuf   数据缓存
* @param[out] pstRdSet 文件信息及传输状态
* @return
*/
void Revc_ReadFS_CallDir_S(CS10x *pstSelf, unsigned char *pucBuf, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usLen = 0;
	memset(pstRdSet, 0x00, sizeof(tFILEDIR_RD_SET));
	pstSelf->ucTransStatus = FILE_ST_RD_DIR_RESPONE; //文件目录召唤响应
	memcpy(&pstRdSet->uiId, &pucBuf[usLen], 4);
	usLen += 4; //目录ID 4字节
	//文件名
	pstRdSet->ucDirLen = pucBuf[usLen++];
	memcpy(pstRdSet->caDirName, &pucBuf[usLen], pstRdSet->ucDirLen);
	usLen += pstRdSet->ucDirLen;
	//召唤目录条件
	pstRdSet->ucCallFlag = pucBuf[usLen++];
	CP56Time2a_GetFromBuf(&pucBuf[usLen], &pstRdSet->stStartTime);
	usLen += 7;
	CP56Time2a_GetFromBuf(&pucBuf[usLen], &pstRdSet->stEndTime);

	//查询目录下文件数量
	if(NULL != pstSelf->pfnGetNumDirFile)
	{
		pstRdSet->usFrmNum = pstSelf->pfnGetNumDirFile(pstRdSet);
	}

	SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_RD_DIR_RESPONE, 0);
}

/**
* @brief 召唤目录确认===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf     数据缓存
* @param[out] pstRdSet 文件信息及传输状态
* @return
*/
static tDIR_FILE_INFO s_stDirFileSet[DIRFILE_SET_NUM];  //所有主设备共用
void Revc_ReadFS_AckCallDir_M(CS10x *pstSelf, unsigned char *pucBuf, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usLen = 0;
	tDIR_FILE_INFO  *pstDirFileInfo;
	pstSelf->ucTransStatus = FILE_ST_RD_DIR_RESPONE;
	pstRdSet->usFrmNum = 0;

	if(0 == pucBuf[usLen++])  // 0-成功；1-失败
	{
		usLen += 4;                                  //目录ID 4字节
		pstRdSet->ucFollow = pucBuf[usLen++];   //后续标志
		pstRdSet->usFrmNum = pucBuf[usLen++];   //本帧文件数量

		for(unsigned short i = 0; i < pstRdSet->usFrmNum; i++)
		{
			pstDirFileInfo = &s_stDirFileSet[i];
			pstDirFileInfo->stFileName.ucFileLen = pucBuf[usLen++];
			memcpy(pstDirFileInfo->stFileName.caFileName, &pucBuf[usLen], pstDirFileInfo->stFileName.ucFileLen);
			usLen += pstDirFileInfo->stFileName.ucFileLen;
			pstDirFileInfo->ucAttri = pucBuf[usLen++]; //属性
			memcpy(&pstDirFileInfo->uiFileSize, &pucBuf[usLen], 4);
			usLen += 4;
			CP56Time2a_GetFromBuf(&pucBuf[usLen], &pstDirFileInfo->stTimeStamp);
			usLen += 7;
			pstRdSet->usCurNum++;

			if(pstRdSet->usCurNum >= DIRFILE_SET_NUM)
			{
				pstRdSet->usCurNum = DIRFILE_SET_NUM;
				break;
			}
		}

		if(0 == pstRdSet->ucFollow || DIRFILE_SET_NUM == pstRdSet->usCurNum)  //无后续帧 数据结束,判断是否需要
		{
			pstSelf->ucTransStatus = FILE_ST_IDLE;
			pstSelf->uiTransTimerCur = 0;
		}

		if(pstRdSet->usFrmNum > 0)
		{
			if(pstSelf->pfnDealDirRecvFinish != NULL)
			{
				pstSelf->pfnDealDirRecvFinish(s_stDirFileSet, pstRdSet->usFrmNum, pstRdSet->ucFollow);
			}
		}
	}
}

/**
* @brief 读文件激活===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf     数据缓存
* @param[out] pstRdSet 文件信息及传输状态
* @return
*/
void Revc_ReadFS_SelectFile_S(CS10x *pstSelf, unsigned char *pucBuf, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usLen = 0;
	tDIR_FILE_INFO stDirFileInfo = {0};

	if(pstSelf->ucTransStatus < FILE_ST_RD_DIR_RESPONE)
	{
		return;
	}

	pstSelf->ucTransStatus = FILE_ST_RD_FILE_ACT; //读文件激活
	pstRdSet->ucFileLen = pucBuf[usLen++];
	memcpy(pstRdSet->caFileName, &pucBuf[usLen], pstRdSet->ucFileLen);

	if(NULL != pstSelf->pfnGetProDirFile)
	{
		pstSelf->pfnGetProDirFile(pstRdSet, &stDirFileInfo, PROT_FILE_OBJ, 0, pstSelf->pvFileReadParam);
	}

	pstRdSet->uiTotalSize = stDirFileInfo.uiFileSize; //给读文件数据传输用
	pstRdSet->uiOffSetSize = 0;             //读文件激活将文件偏移量复位
	SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_RD_FILE_ACT_RESPONE, 0);
}

/**
* @brief 读文件激活确认===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstRdSet 文件信息及传输状态
* @return
*/
void Revc_ReadFS_AckSelectFile_M(CS10x *pstSelf, unsigned char *pucBuf, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usLen = 0;
	tFILE_NAME  stFileName;
	memset(&stFileName, 0x00, sizeof(tFILE_NAME));

	if(pstSelf->ucTransStatus < FILE_ST_RD_FILE_ACT)
	{
		return;
	}

	pstSelf->ucTransStatus = FILE_ST_RD_FILE_ACT_RESPONE;

	if(0 == pucBuf[usLen++])  // 0-成功；1-失败
	{
		memset(&stFileName, 0, sizeof(tFILE_NAME));
		stFileName.ucFileLen = pucBuf[usLen++]; //文件名长度
		memcpy(stFileName.caFileName, &pucBuf[usLen], stFileName.ucFileLen);
		usLen += stFileName.ucFileLen + 4; //跳过文件标识

		if(pstRdSet->ucFileLen == stFileName.ucFileLen &&
		        0 == strcmp(pstRdSet->caFileName, stFileName.caFileName))
		{
			memcpy(&pstRdSet->uiTotalSize, &pucBuf[usLen], 4);
			usLen += 4;
			pstSelf->uiTransTimerCur = 0;
		}
	}
}

/**
* @brief 读文件数据传输===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstRdSet 文件信息及传输状态
* @return
*/
void Revc_ReadFS_CallFileSeg_M(CS10x *pstSelf, unsigned char *pucBuf, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usLen = 0;
	unsigned char ucChecksum = 0;
	unsigned char ucDataLen = 0;
	ASDU_Element *pstAsduInfo;
	pstAsduInfo = &pstSelf->stAsduElem;

	if(pstSelf->ucTransStatus < FILE_ST_RD_FILE_ACT_RESPONE)
	{
		return;
	}

	pstSelf->ucTransStatus = FILE_ST_RD_FILE_DATA;
	usLen += 4; //文件标识
	memcpy(&pstRdSet->uiOffSetSize, &pucBuf[usLen], 4);
	usLen += 4;                                  //文件传输偏移
	pstRdSet->ucFollow = pucBuf[usLen++]; //有无后续 1字节
	ucDataLen = pstAsduInfo->usPayloadSize - usLen - 6;
	ucChecksum = checksum_8(&pucBuf[usLen], ucDataLen);

	if(ucChecksum == pstAsduInfo->pucPayload[pstAsduInfo->usPayloadSize - 1])
	{
		if(pstSelf->pfnWriteFile != NULL)
		{
			pstSelf->pfnWriteFile(pstRdSet, &pucBuf[usLen], ucDataLen, pstSelf->pUsrData);
		}
	}

	if(pstRdSet->ucFollow == 0)
	{
		SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_RD_FILE_DATA_RESPONE, 0);
		pstSelf->ucTransStatus = FILE_ST_IDLE; //文件传输完成
		pstSelf->uiTransTimerCur = 0;
	}
}


/**
* @brief 读文件数据传输确认===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstRdSet 文件信息及传输状态
* @return
*/
void Revc_ReadFS_AckFileSeg_S(CS10x *pstSelf, unsigned char *pucBuf, tFILEDIR_RD_SET *pstRdSet)
{
	if(pstSelf->ucTransStatus < FILE_ST_RD_FILE_DATA)
	{
		return;
	}

	pstSelf->ucTransStatus = FILE_ST_RD_FILE_DATA_RESPONE;
}

/**
* @brief 写文件激活===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstWdSet 文件信息及传输状态
* @return
*/
void Recv_WriteFS_SelectFile_S(CS10x *pstSelf, unsigned char *pucBuf, tFILE_WD_SET  *pstWdSet)
{
	unsigned short usLen = 0;
	pstSelf->ucTransStatus = FILE_ST_WR_FILE_ACT;
	memset(pstWdSet->ucFileName, 0, sizeof(tFILE_NAME));
	pstWdSet->ucFileLen = pucBuf[usLen++];
	memcpy(pstWdSet->ucFileName, &pucBuf[usLen], pstWdSet->ucFileLen);
	usLen += pstWdSet->ucFileLen;
	memcpy(&pstWdSet->uiFileId, &pucBuf[usLen], 4);
	usLen += 4; //文件ID
	memcpy(&pstWdSet->uiFileSize, &pucBuf[usLen], 4);
	usLen += 4; //文件大小
	pstWdSet->ucResult = 0;

	/*检测是否可以写入文件*/
	if(pstSelf->pfnWriteFileCheck)
	{
		pstWdSet->ucResult = pstSelf->pfnWriteFileCheck(pstWdSet, pstSelf->pvFileWrteParam, pstSelf->pUsrData);
	}

	SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_WR_FILE_ACT_RESPONE, 0);
	/*重置md5*/
	StartMD5(&pstSelf->stMd5_Ctx);
}

/**
* @brief 写文件激活确认===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstWdSet 文件信息及传输状态
* @return
*/
void Recv_WriteFS_AckSelectFile_M(CS10x *pstSelf, unsigned char *pucBuf, tFILE_WD_SET *pstWdSet)
{
	unsigned short usLen = 0;
	tFILE_WD_SET stWdAck = {0}; //对下从设备响应的写文件激活确认

	if(pstSelf->ucTransStatus < FILE_ST_WR_FILE_ACT)
	{
		return;
	}

	memset(&stWdAck, 0x00, sizeof(tFILE_WD_SET));
	pstSelf->ucTransStatus = FILE_ST_WR_FILE_ACT_RESPONE;

	if(0 == pucBuf[usLen++])  // 0-成功；1-失败, //默认传输文件目录正确
	{
		stWdAck.ucFileLen = pucBuf[usLen++]; //文件名长度
		memcpy(stWdAck.ucFileName, &pucBuf[usLen], stWdAck.ucFileLen);
		usLen += stWdAck.ucFileLen;
		memcpy(&stWdAck.uiFileId, &pucBuf[usLen], 4);
		usLen += 4; //文件标识
		memcpy(&stWdAck.uiFileSize, &pucBuf[usLen], 4);
		usLen += 4;

		//
		if(pstWdSet->ucFileLen == stWdAck.ucFileLen && (0 == strcmp(pstWdSet->ucFileName, stWdAck.ucFileName)) &&
		        pstWdSet->uiFileId == stWdAck.uiFileId && pstWdSet->uiFileSize == stWdAck.uiFileSize)
		{
			SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_WR_FILE_DATA, 0);
		}
		else
		{
			//从设备响应写文件激活, 与写文件激活信息不一致
		}
	}
}

/**
* @brief 写文件数据传输===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstWdSet 文件信息及传输状态
* @return
*/
void Recv_WriteFS_DownFileSeg_S(CS10x *pstSelf, unsigned char *pucBuf, tFILE_WD_SET *pstWdSet, unsigned short usFileDateLen)
{
	unsigned char ucContinue   = 0;
	unsigned char ucChecksum   = 0;
	unsigned char ucDataLen    = 0;
	unsigned short usLen       = 0;
	unsigned int uiCurFileId = 0;
	pstSelf->ucTransStatus = FILE_ST_WR_FILE_DATA;
	//usLen = 0;
	memcpy(&uiCurFileId, &pucBuf[usLen], 4);
	usLen += 4; //文件标识

	if(uiCurFileId != pstWdSet->uiFileId)
	{
		pstWdSet->ucResult = WRITE_FILE_ERR_ID;
		SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_WR_FILE_DATA_RESPONE, 0);
		return;
	}

	memcpy(&pstWdSet->uiOffSetSize, &pucBuf[usLen], 4);
	usLen += 4;                   //文件标识
	ucContinue = pucBuf[usLen++]; //有无后续 1字节
	ucDataLen = usFileDateLen - usLen - 1 ;
	ucChecksum = checksum_8(&pucBuf[usLen], ucDataLen);

	if(ucChecksum == pucBuf[usLen + ucDataLen])
	{
		/*计算MD5*/
		EncodeMD5(&pstSelf->stMd5_Ctx, &pucBuf[usLen], ucDataLen);
		//            pstSelf->WriteFile(pstFile->caDirName, pstFile->stTransFileInfo.caFileName, pstFile->uiFileOffset, &pAsduInfo->pucPayload[usLen], ucDataLen, pstSelf->pUsrData);

		if(pstSelf->pfnWrite)
		{
			pstSelf->pfnWrite(pstWdSet->uiOffSetSize, &pucBuf[usLen], ucDataLen, pstSelf->pvFileWrteParam, pstSelf->pUsrData);
		}
	}
	else
	{
		//            pstFile->stTransFileInfo.ucAttr = WRITE_FILE_ERR_CHECK;
		pstWdSet->ucResult = WRITE_FILE_ERR_CHECK;
		SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_WR_FILE_DATA_RESPONE, 0);
		return;
	}

	if(ucContinue == 0)
	{
		/*MD5结果计算*/
		GetMD5(&pstSelf->stMd5_Ctx, pstSelf->ucaMd5_Result);

		if(pstSelf->pfnMd5ResultCb)
		{
			pstSelf->pfnMd5ResultCb(pstSelf->ucaMd5_Result);
		}

		SetSendTask(pstSelf, TSKID_FilePro, FILE_ST_WR_FILE_DATA_RESPONE, 0);

		if(pstSelf->pfnWriteFinish)
		{
			pstSelf->pfnWriteFinish(pstSelf->ucaMd5_Result, pstSelf->pvFileWrteParam, pstSelf->pUsrData);
		}

		pstWdSet->ucResult = WRITE_FILE_ERR_NONE;
	}
}

/**
* @brief 写文件数据传输确认===>接收
*
* @param[in]  pstSelf   规约实体
* @param[in]  pucBuf    数据缓存
* @param[out] pstWdSet 文件信息及传输状态
* @return
*/
void Recv_WriteFS_AckDownFileSeg_M(CS10x *pstSelf, unsigned char *pucBuf, tFILE_WD_SET *pstWdSet)
{
	if(pstSelf->ucTransStatus < FILE_ST_WR_FILE_DATA)
	{
		return;
	}

	pstSelf->ucTransStatus = FILE_ST_WR_FILE_DATA_RESPONE;
	pstSelf->uiTransTimerCur = 0;
}

/**
* @brief 召唤目录<===发送
* @param[in]  pstSelf   规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstRdSet 文件信息及传输状态
* @return
*/
unsigned short Send_ReadFS_CallDir_M(CS10x *pstSelf, unsigned short usFileProType,  ASDU_Element *pstAsdus, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usInfoLen = 0;
	unsigned short *usPayloadSize;
	unsigned char *pucPayload;
	usPayloadSize = &pstAsdus->usPayloadSize;
	pucPayload = &pstAsdus->pucPayload[0];
	pstSelf->ucTransStatus = FILE_ST_RD_DIR; //读取目录
	pstSelf->uiTransTimerCur = 0;           //定时器
	pstAsdus->usCot = COT_REQ;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;      //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_RD_DIR; //操作标识
	(*usPayloadSize) += 4;
	pucPayload[(*usPayloadSize)++] = pstRdSet->ucDirLen; //目录ID
	memcpy(&pucPayload[(*usPayloadSize)], pstRdSet->caDirName, pstRdSet->ucDirLen);
	(*usPayloadSize) += pstRdSet->ucDirLen;
	pucPayload[(*usPayloadSize)++] = pstRdSet->ucCallFlag;// 召唤标志, 0: 读取目录下所有文件, 1: 目录下满足搜索时间段的文件
	(*usPayloadSize) += CP56Time2a_Pack2Buf(&pucPayload[(*usPayloadSize)], &pstRdSet->stStartTime);
	(*usPayloadSize) += CP56Time2a_Pack2Buf(&pucPayload[(*usPayloadSize)], &pstRdSet->stEndTime);
	return (*usPayloadSize);
}

/**
* @brief 召唤目录响应<===发送
* @param[in]  pstSelf   规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstRdSet 文件信息及传输状态
* @return
*/
unsigned short Send_ReadFS_AckCallDir_S(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned char  caBuf[256]          = {0};
	unsigned short usi                 = 0;
	unsigned short usInfoLen           = 0;
	unsigned short usContinue          = 0;
	unsigned short usIDataLen          = 0;
	unsigned short usAsduFileflg       = 0;
	unsigned short usFileSendNum_Local = 0;
	unsigned short usFileSendNum_Total = 0;
	unsigned short *usPayloadSize      = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload         = &pstAsdus->pucPayload[0];
	tDIR_FILE_INFO stDirFileInfo = {0};
	pstSelf->ucTransStatus = FILE_ST_RD_DIR_RESPONE; //开始回复文件目录状态
	pstAsdus->usCot = COT_REQ;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;              //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_RD_DIR_RESPONE; //操作标识
	pucPayload[(*usPayloadSize)++] = 0x00; //结果描述成功
	memcpy(&pucPayload[(*usPayloadSize)], &pstRdSet->uiId, 4); //目录ID
	(*usPayloadSize) += 4;
	usFileSendNum_Total = pstRdSet->usFrmNum - pstRdSet->usCurNum; //剩余待发送文件数量
	usAsduFileflg = (*usPayloadSize);
	(*usPayloadSize) += 2; //先跳过后续帧与本帧数量
	// pucPayload[(*usPayloadSize)++] = usContinue;   //有无后续
	// pucPayload[(*usPayloadSize)++] = usFileSendNum;   //本帧数量

	for(usi = 0; usi < usFileSendNum_Total; usi++)
	{
		memset(caBuf, 0, 256);
		usIDataLen = 0;

		if(NULL != pstSelf->pfnGetProDirFile)
		{
			pstSelf->pfnGetProDirFile(pstRdSet, &stDirFileInfo, PROT_DIR_OBJ, pstRdSet->usCurNum, pstSelf->pvFileReadParam);
		}

		caBuf[usIDataLen++] = stDirFileInfo.stFileName.ucFileLen;
		memcpy(&caBuf[usIDataLen], stDirFileInfo.stFileName.caFileName, stDirFileInfo.stFileName.ucFileLen);
		usIDataLen += stDirFileInfo.stFileName.ucFileLen;
		caBuf[usIDataLen++] = stDirFileInfo.ucAttri; //文件属性备用
		memcpy(&caBuf[usIDataLen], &stDirFileInfo.uiFileSize, 4);
		usIDataLen += 4;
		memcpy(&caBuf[usIDataLen], &stDirFileInfo.stTimeStamp, 7);
		usIDataLen += 7;

		if(usIDataLen + (*usPayloadSize) <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
		{
			memcpy(&pucPayload[(*usPayloadSize)], caBuf, usIDataLen);
			(*usPayloadSize) += usIDataLen;
			usContinue = 0;
			pstRdSet->usCurNum++;
			usFileSendNum_Local++;
		}
		else
		{
			usContinue = 1;
			break;
		}
	}

	pucPayload[usAsduFileflg] = usContinue;              //有无后续
	pucPayload[usAsduFileflg + 1] = usFileSendNum_Local; //本帧数量

	if(usContinue)
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, usFileProType, 0);
	}

	return (*usPayloadSize);
}


/**
* @brief 读文件激活<===发送
*
* @param[in]  pstSelf   规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstRdSet 文件信息及传输状态
* @return
*/
unsigned short Send_ReadFS_SelectFile_M(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usInfoLen      = 0;
	unsigned short *usPayloadSize;
	unsigned char *pucPayload;
	pstSelf->ucTransStatus = FILE_ST_RD_FILE_ACT;   //读文件激活
	pstSelf->uiTransTimerCur = 0;
	usPayloadSize = &pstAsdus->usPayloadSize;
	pucPayload = &pstAsdus->pucPayload[0];
	pstAsdus->usCot = COT_ACT;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;           //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_RD_FILE_ACT; //操作标识
	pucPayload[(*usPayloadSize)++] = pstRdSet->ucFileLen;
	memcpy(&pucPayload[(*usPayloadSize)], pstRdSet->caFileName, pstRdSet->ucFileLen);
	(*usPayloadSize) += pstRdSet->ucFileLen;
	return (*usPayloadSize);
}

/**
* @brief 读文件激活确认<===发送
*
* @param[in]  pstSelf   规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstRdSet 文件信息及传输状态
* @return
*/
unsigned short Send_ReadFS_AckSelectFile_S(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usInfoLen      = 0;
	unsigned short *usPayloadSize = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload    = &pstAsdus->pucPayload[0];
	pstSelf->ucTransStatus = FILE_ST_RD_FILE_ACT_RESPONE; //开始文件激活状态
	pstAsdus->usCot = COT_ACTCON;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;                   //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_RD_FILE_ACT_RESPONE; //操作标识
	pucPayload[(*usPayloadSize)++] = 0x00; //结果描述成功
	pucPayload[(*usPayloadSize)++] = pstRdSet->ucFileLen; //文件名长度
	memcpy(&pucPayload[(*usPayloadSize)], pstRdSet->caFileName, pstRdSet->ucFileLen);
	(*usPayloadSize) += pstRdSet->ucFileLen;
	memcpy(&pucPayload[(*usPayloadSize)], &pstRdSet->uiId, 4);
	(*usPayloadSize) += 4; //文件ID
	memcpy(&pucPayload[(*usPayloadSize)], &pstRdSet->uiTotalSize, 4);
	(*usPayloadSize) += 4; //文件大小
	SetSendTask(pstSelf, pstSelf->byTaskFlagId, FILE_ST_RD_FILE_DATA, 0);
	return (*usPayloadSize);
}


/**
* @brief 读文件数据传输<===发送
*
* @param[in]  pstSelf    规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstRdSet 文件信息及传输状态
* @return
*/
unsigned short Send_ReadFS_CallFileSeg_S(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned char  pucBuf[256]      = {0};
	unsigned short usInfoLen        = 0;
	unsigned short usFileSendLen    = 0;
	unsigned short usContinue       = 0;
	unsigned int uiMaxFileSendLen = 200;
	unsigned short *usPayloadSize   = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload      = &pstAsdus->pucPayload[0];
	pstSelf->ucTransStatus = FILE_ST_RD_FILE_DATA; //开始数据传输状态
	pstAsdus->usCot = COT_REQ;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;            //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_RD_FILE_DATA; //操作标识
	memcpy(&pucPayload[(*usPayloadSize)], &pstRdSet->uiId, 4);
	(*usPayloadSize) += 4; //文件ID
	memcpy(&pucPayload[(*usPayloadSize)], &pstRdSet->uiOffSetSize, 4);
	(*usPayloadSize) += 4;

	if(pstRdSet->uiOffSetSize > pstRdSet->uiTotalSize)
	{
		return 0;
	}

	if(NULL != pstSelf->pfnReadFile)
	{
		usFileSendLen = pstSelf->pfnReadFile(pstRdSet->uiOffSetSize, pucBuf, uiMaxFileSendLen, pstSelf->pvFileReadParam);
	}

	/*文件读取异常*/
	if(0 == usFileSendLen)
	{
		return 0;
	}

	if(pstRdSet->uiOffSetSize + usFileSendLen < pstRdSet->uiTotalSize)
	{
		usContinue = 1;
	}
	else
	{
		usContinue = 0;
		usFileSendLen = pstRdSet->uiTotalSize - pstRdSet->uiOffSetSize;
	}

	pucPayload[(*usPayloadSize)++] = usContinue;
	memcpy(&pucPayload[(*usPayloadSize)], pucBuf, usFileSendLen);
	(*usPayloadSize) += usFileSendLen;
	pucPayload[(*usPayloadSize)++] = checksum_8(pucBuf, usFileSendLen);
	pstRdSet->uiOffSetSize += usFileSendLen;

	if(usContinue)
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, FILE_ST_RD_FILE_DATA, 0);
	}

	return (*usPayloadSize);
}

/**
* @brief 读文件数据传输确认<===发送
*
* @param[in]  pstSelf    规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstRdSet 文件信息及传输状态
* @return
*/
unsigned short Send_ReadFS_AckFileSeg_M(CS10x *pstSelf, unsigned short usFileProType,  ASDU_Element *pstAsdus, tFILEDIR_RD_SET *pstRdSet)
{
	unsigned short usInfoLen = 0;
	unsigned short *usPayloadSize = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload    = &pstAsdus->pucPayload[0];
	pstAsdus->usCot = COT_REQ;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;                    //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_RD_FILE_DATA_RESPONE; //操作标识
	(*usPayloadSize) += 9;

	if(0 == strcmp(pstRdSet->caDirName, COMTRADE))    //仅仅COMTRADE才比对录波文件
	{
		CheckFileDiff(pstSelf);

		if(pstAsdus->usTypeID != 0xD2)
		{
			pstAsdus->usTypeID = 0xD2;
			pstAsdus->usCot = COT_REQ;
			usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
			(*usPayloadSize) += usInfoLen;
			pucPayload[(*usPayloadSize)++] = FILE_TRANS;                    //数据包类型文件传输
			pucPayload[(*usPayloadSize)++] = FILE_ST_RD_FILE_DATA_RESPONE; //操作标识
			(*usPayloadSize) += 9;
		}
	}
	else
	{
		pstSelf->ucTransStatus = FILE_ST_IDLE;
		pstSelf->uiTransTimerCur = 0;
	}

	return (*usPayloadSize);
}


/**
* @brief 写文件激活<===发送
*
* @param[in]  pstSelf    规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstWdSet 文件信息及传输状态
* @return
*/
unsigned short Send_WriteFS_SelectFile_M(CS10x *pstSelf, unsigned short usFileProType,  ASDU_Element *pstAsdus, tFILE_WD_SET    *pstWdSet)
{
	unsigned short usInfoLen = 0;
	unsigned short *usPayloadSize;
	unsigned char *pucPayload;
	pstSelf->ucTransStatus = FILE_ST_WR_FILE_ACT; //写文件激活
	pstSelf->uiTransTimerCur = 0;
	usPayloadSize = &pstAsdus->usPayloadSize;
	pucPayload = &pstAsdus->pucPayload[0];
	pstAsdus->usCot = COT_ACT;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;           //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_WR_FILE_ACT; //操作标识
	//pucPayload[(*usPayloadSize)++] = pstFileWdSet->ucResult; //??????????
	pucPayload[(*usPayloadSize)++] = pstWdSet->ucFileLen;
	memcpy(&pucPayload[(*usPayloadSize)], pstWdSet->ucFileName, pstWdSet->ucFileLen);
	(*usPayloadSize) += pstWdSet->ucFileLen;
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiFileId, 4);
	(*usPayloadSize) += 4; //文件ID
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiFileSize, 4);
	(*usPayloadSize) += 4;
	return (*usPayloadSize);
}


/**
* @brief 写文件激活确认<===发送
*
* @param[in]  pstSelf     规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstWdSet 文件信息及传输状态
* @return
*/
unsigned short Send_WriteFS_AckSelectFile_S(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus, tFILE_WD_SET  *pstWdSet)
{
	unsigned short usInfoLen      = 0;
	unsigned short *usPayloadSize = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload    = &pstAsdus->pucPayload[0];
	pstSelf->ucTransStatus = FILE_ST_WR_FILE_ACT_RESPONE; //开始数据传输状态
	pstAsdus->usCot = COT_ACTCON;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;                   //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_WR_FILE_ACT_RESPONE; //操作标识
	pucPayload[(*usPayloadSize)++] = pstWdSet->ucResult;                        //文件描述成功
	pucPayload[(*usPayloadSize)++] = pstWdSet->ucFileLen;
	memcpy(&pucPayload[(*usPayloadSize)], pstWdSet->ucFileName, pstWdSet->ucFileLen);
	(*usPayloadSize) += pstWdSet->ucFileLen;
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiFileId, 4);
	(*usPayloadSize) += 4;
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiFileSize, 4);
	(*usPayloadSize) += 4;
	return (*usPayloadSize);
}


/**
* @brief 写文件数据传输<===发送
*
* @param[in]  pstSelf     规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstWdSet 文件信息及传输状态
* @return
*/
unsigned short Send_WriteFS_DownFileSeg_M(CS10x *pstSelf, unsigned short usFileProType,  ASDU_Element *pstAsdus, tFILE_WD_SET   *pstWdSet)
{
	unsigned char  pucBuf[200]      = {0};
	unsigned char  ucContinue       = 0;
	unsigned char  ucChecksum       = 0;
	unsigned short usInfoLen        = 0;
	unsigned short usFileSendLen    = 0;
	unsigned int uiMaxFileSendLen = 200;
	unsigned short *usPayloadSize   = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload      = &pstAsdus->pucPayload[0];
	pstAsdus->usCot = COT_ACT;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;           //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_WR_FILE_DATA; //操作标识
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiFileId, 4);
	(*usPayloadSize) += 4;
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiOffSetSize, 4);
	(*usPayloadSize) += 4;

	if(pstWdSet->uiOffSetSize > pstWdSet->uiFileSize)
	{
		return 0;
	}

	//memcpy(pstSlaveFileStu->caDirName,pstFile->caDirName,IEC_FILE_NAME_SIZE);
	//memcpy(pstSlaveFileStu->caFileName,pstFile->stTransFileInfo.caFileName,IEC_FILE_NAME_SIZE);
	usFileSendLen = pstSelf->pfnReadFile(pstWdSet->uiOffSetSize, pucBuf, uiMaxFileSendLen, (void *)pstSelf->pvFileReadParam);

	if(pstWdSet->uiOffSetSize + usFileSendLen < pstWdSet->uiFileSize)
	{
		ucContinue = 1;
	}
	else
	{
		ucContinue = 0;
		usFileSendLen = pstWdSet->uiFileSize - pstWdSet->uiOffSetSize;
	}

	pucPayload[(*usPayloadSize)++] = ucContinue;
	memcpy(&pucPayload[(*usPayloadSize)], pucBuf, usFileSendLen);
	(*usPayloadSize) += usFileSendLen;
	ucChecksum = checksum_8(pucBuf, usFileSendLen);
	pucPayload[(*usPayloadSize)++] = ucChecksum;
	pstWdSet->uiOffSetSize += usFileSendLen;

	if(ucContinue)
	{
		SetSendTask(pstSelf, pstSelf->byTaskFlagId, usFileProType, 0);
	}
	else
	{
		pstWdSet->uiOffSetSize = 0;
	}

	pstSelf->uiTransTimerCur = 0;
	return (*usPayloadSize);
}


/**
* @brief 写文件数据传输确认<===发送
*
* @param[in]  pstSelf     规约实体
* @param[in]  usFileProType
* @param[out] pstAsdus
* @param[in]  pstWdSet 文件信息及传输状态
* @return
*/
unsigned short Send_WriteFS_AckDownFileSeg_S(CS10x *pstSelf, unsigned short usFileProType, ASDU_Element *pstAsdus, tFILE_WD_SET *pstWdSet)
{
	unsigned short usInfoLen      = 0;
	unsigned short *usPayloadSize = &pstAsdus->usPayloadSize;
	unsigned char  *pucPayload    = &pstAsdus->pucPayload[0];

	if(pstSelf->ucTransStatus < FILE_ST_WR_FILE_DATA)
	{
		return 0;
	}

	pstSelf->ucTransStatus = FILE_ST_WR_FILE_DATA_RESPONE; //开始数据传输状态
	pstAsdus->usCot = COT_REQ;
	usInfoLen = ASDU_setIOA(&pucPayload[(*usPayloadSize)], 0, pstSelf->stAppParameters.iSzOfIOA);
	(*usPayloadSize) += usInfoLen;
	pucPayload[(*usPayloadSize)++] = FILE_TRANS;                    //数据包类型文件传输
	pucPayload[(*usPayloadSize)++] = FILE_ST_WR_FILE_DATA_RESPONE; //操作标识
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiFileId, 4);
	(*usPayloadSize) += 4;
	memcpy(&pucPayload[(*usPayloadSize)], &pstWdSet->uiOffSetSize, 4);
	(*usPayloadSize) += 4;                                                 //数据段号
	pucPayload[(*usPayloadSize)++] = pstWdSet->ucResult; //写文件错误类型0-成功
	return (*usPayloadSize);
}

/**
* @brief  延时获得命令接收处理
* @param[in]  pstSelf-规约实体
* @param[in]  usReason--传输原因
* @param[out] 无
* @return     无
*/
void Do_ObtainDelay(CS10x *pstSelf, unsigned short usReason)
{
	if(COT_ACT == usReason)  //激活
	{
		SetSendTask(pstSelf, TSKID_ObtainDelay, COT_ACTCON, 0);
	}

	return;
}

/**
* @brief 延时获得命令发送处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParam   usReason-传输原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ObtainDelay(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason        = (unsigned short)uiParam;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_CD_NA;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = usReason;
	__CP56Time2a stCp56Time;
	pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

	if(COT_ACTCON == (usReason & 0x3F))  //激活确认
	{
		if(pstSelf->pfnGetTime)
		{
			pstSelf->pfnGetTime(&stCp56Time);
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stCp56Time.ucLMs;
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = stCp56Time.ucHMs;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 南网参数定值读取接收接口
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_ParamRead_NanWang(CS10x *pstSelf, unsigned short usReason)
{
	unsigned short usLen = 0;
	unsigned short usQoi = 0;
	unsigned int uiInfoAddr  = 0;
	IECPARAM_T stIecParam = {0};
	ASDU_Element *pstAsduInfo = &pstSelf->stAsduElem;
	usQoi = pstAsduInfo->pucPayload[pstSelf->stAsduElem.usPayloadSize - 1];

	if(COT_ACT == usReason && usQoi == 0x14)  //激活
	{
		/*读取后不允许固化，公用缓冲区*/
		pstSelf->ucPmPresetFlag = 0;
		pstSelf->uiPmPresetTimeout = 0;
		SetSendTask(pstSelf, TSKID_ParamRead_NanWang, COT_ACTCON, usQoi);

		if(pstSelf->pfnAddIECParam)
		{
			/*读取所有参数*/
			pstSelf->pfnAddIECParam(1, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
		}
	}
	else if(COT_ACT == usReason)
	{
		/*读取后不允许固化，公用缓冲区*/
		pstSelf->ucPmPresetFlag = 0;
		pstSelf->uiPmPresetTimeout = 0;

		if(pstAsduInfo->usNum)
		{
			if(pstAsduInfo->usSQ == 1)
			{
				pstSelf->ucPmPresetVsqFlag = 1;
				uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);

				for(unsigned short i = 0; i < pstAsduInfo->usNum; i++)
				{
					stIecParam.uiInfoAddr = uiInfoAddr;
					uiInfoAddr++;

					if(pstSelf->pfnAddIECParam)
					{
						pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
					}

					pstSelf->ucParamFlag = 1;     /*追加缓存*/
				}
			}
			else if(pstAsduInfo->usSQ == 0)
			{
				for(unsigned short i = 0; i < pstAsduInfo->usNum; i++)
				{
					uiInfoAddr = ASDU_getIOA(&pstAsduInfo->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
					usLen += pstSelf->stAppParameters.iSzOfIOA;
					usLen += 4;
					stIecParam.uiInfoAddr = uiInfoAddr;

					if(pstSelf->pfnAddIECParam)
					{
						pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
					}

					pstSelf->ucParamFlag = 1;     /*追加缓存*/
				}
			}
		}
		else
		{
			if(pstSelf->pfnAddIECParam)
			{
				/*读取所有参数*/
				pstSelf->pfnAddIECParam(1, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
			}
		}

		SetSendTask(pstSelf, TSKID_ParamRead_NanWang, COT_ACTCON, 0);
	}
}


/**
* @brief 南网读参数命令发送处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParamusReason-传输原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ParamRead_NanWang(CS10x *pstSelf, unsigned int uiParam)
{
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = C_RS_NA_NANWANG;
	pstAsdus->usSQ      = 0;
	pstAsdus->usNum     = 1;
	pstAsdus->usCot     = (unsigned short)uiParam;
	unsigned short usReason        = pstAsdus->usCot;
	unsigned char  ucQoi           = (unsigned char)(uiParam >> 16);
	unsigned char  ucTxNum         = 0;/*本次发送个数*/
	unsigned short usContinue      = 0;
	unsigned short usTotalNum      = 0;/*缓冲数据个数*/
	IECPARAM_T stIecParam = {0};

	if(pstSelf->ucPmPresetVsqFlag == 1)
	{
		pstSelf->ucPmPresetVsqFlag = 0;
		pstAsdus->usSQ      = 1;
	}

	if(NULL == pstSelf->pfnGetParamCount)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetParamInfoByIndx)
	{
		return 0;
	}

	if(COT_ACTCON == usReason || COT_ACTTERM == usReason)  //激活确认及激活终止 从站发
	{
		if(ucQoi == 0x14)
		{
			pstAsdus->usPayloadSize += ASDU_setIOA(pstAsdus->pucPayload, 0, pstSelf->stAppParameters.iSzOfIOA);

			if(COT_ACTCON == usReason)
			{
				SetSendTask(pstSelf, TSKID_ParamReadResponse_NanWang, COT_INTROGEN, 6);
			}

			pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucQoi;
		}
		else
		{
			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData); //获取总数量

			if(pstAsdus->usSQ)
			{
				pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, pstSelf->usParamSendNum, &stIecParam, pstSelf->pUsrData);
				ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;

				for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
					{
						if(stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
						{
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);/*复制当前参数值*/
							pstAsdus->usPayloadSize += stIecParam.ucLen;
							ucTxNum++;
							usContinue = 0;
						}
						else
						{
							usContinue = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;                             /*参数发送个数*/
				}
			}
			else
			{
				for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
					{
						if(pstSelf->stAppParameters.iSzOfIOA + stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
						{
							ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
							pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);/*复制当前参数值*/
							pstAsdus->usPayloadSize += stIecParam.ucLen;
							ucTxNum++;
							usContinue = 0;
						}
						else
						{
							usContinue = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;                             /*参数发送个数*/
				}
			}

			if(usContinue == 0)
			{
				pstSelf->usParamSendNum = 0;
				pstSelf->ucParamFlag = 0;           /*无后续帧时，不进行追加，其他条件下可以进行参数追加，解决连帧问题*/
			}
			else
			{
				SetSendTask(pstSelf, TSKID_ParamRead_NanWang, usReason, 0);     /*继续执行发送任务*/
			}

			pstAsdus->usNum = ucTxNum;                            /*VSQ赋值*/
			return pstAsdus->usPayloadSize;
		}
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 读参数传输命令发送处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParam-传输原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ParamRdResponse_NanWang(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned char  ucTxNum         = 0;/*本次发送个数*/
	unsigned short usContinue      = 0;
	unsigned short usTotalNum      = 0;/*缓冲数据个数*/
	unsigned short usReason        = (unsigned short)uiParam;
	unsigned char  ucQpm           = (unsigned char)(uiParam >> 16);
	IECPARAM_T stIecParam = {0};
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	pstAsdus->usTypeID  = P_ME_NC;
	pstAsdus->usSQ      = 1;
	pstAsdus->usCot     = usReason;

	if(NULL == pstSelf->pfnGetParamCount)
	{
		return 0;
	}

	if(NULL == pstSelf->pfnGetParamInfoByIndx)
	{
		return 0;
	}

	if(COT_INTROGEN == usReason && ucQpm == 0x06)
	{
		usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData); //获取总数量
		pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, pstSelf->usParamSendNum, &stIecParam, pstSelf->pUsrData);
		ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
		pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;

		for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
		{
			if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
			{
				if(stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen - 1)
				{
					memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);/*复制当前参数值*/
					pstAsdus->usPayloadSize += stIecParam.ucLen;
					ucTxNum++;
					usContinue = 0;
				}
				else
				{
					usContinue = 1;
					break;
				}
			}

			pstSelf->usParamSendNum++;                             /*参数发送个数*/
		}

		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = ucQpm;              /*PI参数特征表示为1：有后续*/
	}

	if(usContinue == 0)
	{
		pstSelf->usParamSendNum = 0;
		pstSelf->ucParamFlag = 0;           /*无后续帧时，不进行追加，其他条件下可以进行参数追加，解决连帧问题*/
		SetSendTask(pstSelf, TSKID_ParamRead_NanWang, COT_ACTTERM, 0x14);
	}
	else
	{
		SetSendTask(pstSelf, TSKID_ParamReadResponse_NanWang, usReason, ucQpm);     /*继续执行发送任务*/
	}

	pstAsdus->usNum = ucTxNum;                            /*VSQ赋值*/
	return pstAsdus->usPayloadSize;
}

/**
* @brief 南网参数预置命令接收处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParam-传输原因
* @return ASDU数据长度
*/
void Do_ParamPreset_NanWang(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucRet = 0;
	unsigned char  ucQpm            = 0;
	unsigned short usi             = 0;
	unsigned short usLen           = 0;
	unsigned int uiInfoAddr      = 0;
	unsigned char *pucMsgBuf = &pstSelf->ucDataBackBuf[0];
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	IECPARAM_T stIecParam = {0};
	ucQpm = pstAsdus->pucPayload[pstSelf->stAsduElem.usPayloadSize - 1];

	if((COT_ACT == usReason || COT_DEACT == usReason) && ucQpm == 0x09)  //从站收
	{
		if(COT_ACT == usReason)
		{
			pstSelf->ucPmPresetFlag = 1;
			pstSelf->uiPmPresetTimeout = 180000;
		}
		else if(COT_DEACT == usReason)
		{
			pstSelf->ucPmPresetFlag = 0;
			pstSelf->uiPmPresetTimeout = 0;
			pstSelf->ucParamFlag = 0;
		}

		if(pstAsdus->usNum == 0)
		{
			return;
		}

		/*首次预置时，清除发送序号*/
		if(pstSelf->ucParamFlag == 0)
		{
			pstSelf->usParamSendNum = 0;
		}

		stIecParam.ucType = TAG_TPYE_FLOAT;
		stIecParam.ucLen = 4;

		if(pstAsdus->usSQ)
		{
			pstSelf ->ucPmPresetVsqFlag = 1;
			uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
			usLen += pstSelf->stAppParameters.iSzOfIOA;

			for(usi = 0; usi < pstAsdus->usNum; usi++)
			{
				stIecParam.uiInfoAddr = uiInfoAddr;
				memcpy(stIecParam.unVal.caBuf, &pstAsdus->pucPayload[usLen], stIecParam.ucLen);
				usLen += stIecParam.ucLen;

				if(NULL != pstSelf->pfnAddIECParam)
				{
					ucRet = pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMWT, &stIecParam, pstSelf->pUsrData);

					if(ucRet == 0)
					{
						break;
					}
				}

				uiInfoAddr++;
				pstSelf->ucParamFlag = 1;
			}
		}
		else
		{
			for(usi = 0; usi < pstAsdus->usNum; usi++)
			{
				uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
				usLen += pstSelf->stAppParameters.iSzOfIOA;
				stIecParam.uiInfoAddr = uiInfoAddr;
				memcpy(stIecParam.unVal.caBuf, &pstAsdus->pucPayload[usLen], stIecParam.ucLen);
				usLen += stIecParam.ucLen;

				if(NULL != pstSelf->pfnAddIECParam)
				{
					ucRet = pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMWT, &stIecParam, pstSelf->pUsrData);

					if(ucRet == 0)
					{
						break;
					}
				}

				pstSelf->ucParamFlag = 1;
			}
		}

		if(ucRet == 1)
		{
			if(COT_ACT == usReason)
			{
				SetSendTask(pstSelf, TSKID_ParamPreset_NanWang, COT_ACTCON, ucQpm);
			}
			else if(COT_DEACT == usReason)
			{
				SetSendTask(pstSelf, TSKID_ParamPreset_NanWang, COT_DEACTCON, ucQpm);
			}
		}
		else
		{
			if(COT_ACT == usReason)
			{
				pstSelf->ucPmPresetFlag = 0;
				pstSelf->uiPmPresetTimeout = 0;
			}

			pstSelf->ucBackLen = pstSelf->stAsduElem.usPayloadSize;
			memcpy(pucMsgBuf, &pstAsdus->pucPayload[0], pstSelf->stAsduElem.usPayloadSize);
			SetSendTask(pstSelf, TSKID_ParamPreset_NanWang, COT_PN | COT_ACTCON, ucQpm);
		}
	}
}


/**
* @brief 南网参数预置命令/读参数上传发送处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParam-传输原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ParamPreset_NanWang(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned char  ucCont     = 0;
	unsigned char  ucTxNum    = 0;
	unsigned short usTotalNum = 0;
	unsigned short usi        = 0;
	unsigned short usReason   = (unsigned short)uiParam;
	unsigned short usQpm       = (unsigned short)(uiParam >> 16);           /*参数*/
	IECPARAM_T stIecParam = {0};
	ASDU_Element *pstAsdus =  &pstSelf->stAsduElem;
	pstAsdus->usTypeID = P_ME_NC;
	pstAsdus->usSQ = 0;
	pstAsdus->usNum = 0;
	pstAsdus->usCot = usReason;

	if(pstSelf ->ucPmPresetVsqFlag == 1)
	{
		pstSelf ->ucPmPresetVsqFlag = 0;
		pstAsdus->usSQ = 1;
	}
	else
	{
		pstAsdus->usSQ = 0;
	}

	if(NULL == pstSelf->pfnGetParamInfoByIndx)
	{
		return 0;
	}

	if(COT_ACTCON == usReason ||  COT_DEACTCON == usReason || COT_SPONT == usReason)  //回复主站参数预置数据
	{
		if(usQpm == 0x09)
		{
			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

			if(pstAsdus->usSQ)
			{
				pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, pstSelf->usParamSendNum, &stIecParam, pstSelf->pUsrData);
				ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;

				for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, usi, &stIecParam, pstSelf->pUsrData))
					{
						if(4 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen - 1)
						{
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
							pstAsdus->usPayloadSize += 4;
							ucTxNum++;
							ucCont = 0;
						}
						else
						{
							ucCont = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;
				}
			}
			else
			{
				for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, usi, &stIecParam, pstSelf->pUsrData))
					{
						if(pstSelf->stAppParameters.iSzOfIOA + 4 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen - 1)
						{
							ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
							pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
							pstAsdus->usPayloadSize += 4;
							ucTxNum++;
							ucCont = 0;
						}
						else
						{
							ucCont = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;
				}
			}
		}
		else if(COT_SPONT == usReason && usQpm == 0x06)
		{
			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

			for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
			{
				if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, usi, &stIecParam, pstSelf->pUsrData))
				{
					if(pstSelf->stAppParameters.iSzOfIOA + 4 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen - 1)
					{
						ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
						pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
						memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
						pstAsdus->usPayloadSize += 4;
						ucTxNum++;
						ucCont = 0;
					}
					else
					{
						ucCont = 1;
						break;
					}
				}

				pstSelf->usParamSendNum++;
			}
		}

		/*缓存中无数据，不进行后续发送*/
		if(ucCont)
		{
			SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, usQpm);
		}

		/*主方向无后续帧且发送完成时，清除pstSelf->ucParamFlag == 0 &&*/
		if((ucCont == 0 || pstSelf->usParamSendNum == usTotalNum))
		{
			pstSelf->usParamSendNum = 0;
			pstSelf->ucParamFlag = 0;
		}

		pstAsdus->usNum = ucTxNum;
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQpm;
	}
	else if((COT_PN | COT_ACTCON) == usReason)
	{
		if(pstAsdus->usSQ)
		{
			pstAsdus->usNum = (pstSelf->ucBackLen - pstSelf->stAppParameters.iSzOfIOA - 1) / 4;
		}
		else
		{
			pstAsdus->usNum = (pstSelf->ucBackLen - 1) / (pstSelf->stAppParameters.iSzOfIOA + 4);
		}

		memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], &pstSelf->ucDataBackBuf[0], pstSelf->ucBackLen);
		pstAsdus->usPayloadSize += pstSelf->ucBackLen;
		pstSelf->ucParamFlag = 0;
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 南网参数固化命令接收处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParam-传输原因
* @return ASDU数据长度
*/
void DoParamSolidify_NanWang(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucQpa            = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	ucQpa = pstAsdus->pucPayload[pstSelf->stAsduElem.usPayloadSize - 1];

	if(COT_ACT == usReason && ucQpa == 0x01)  //从站收
	{
		pstSelf->ucParamFlag = 0;      /*重置首次添加标识*/
		unsigned char ucFlag = 0;

		/*预置后才允许固化*/
		if(pstSelf->ucPmPresetFlag && pstSelf->pfnRunWriteIECParam)
		{
			ucFlag = pstSelf->pfnRunWriteIECParam(pstSelf->pUsrData);
		}

		if(ucFlag)
		{
			SetSendTask(pstSelf, TSKID_ParamSolidify_NanWang, COT_ACTCON, 0x01);       /*固化成功*/
		}
		else
		{
			SetSendTask(pstSelf, TSKID_ParamSolidify_NanWang, COT_PN | COT_ACTCON, 0x01);    /*固化失败，终止命令*/
		}

		pstSelf->ucPmPresetFlag = 0;
		pstSelf->uiPmPresetTimeout = 0;
	}
}

/**
* @brief 南网参数固化命令发送处理函数
*
* @param[in] pstSelf -规约实体指针
* @param[in] uiParam-传输原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ParamSolidify_NanWang(CS10x *pstSelf, unsigned int uiParam)
{
	unsigned short usReason   = (unsigned short)uiParam;
	unsigned short usQpa       = (unsigned short)(uiParam >> 16);
	ASDU_Element *pstAsdus =  &pstSelf->stAsduElem;
	pstAsdus->usTypeID = P_AC_NA;
	pstAsdus->usSQ = 0;
	pstAsdus->usNum = 1;
	pstAsdus->usCot = usReason;

	if(COT_ACTCON == usReason || (COT_PN | COT_ACTCON) == usReason)   //回复主站参数预置数据
	{
		ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], 0x00, pstSelf->stAppParameters.iSzOfIOA);
		pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
		pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQpa;

		if(usReason == COT_ACTCON)
		{
			SetSendTask(pstSelf, TSKID_ParamPreset_NanWang, COT_SPONT, 0x06);
		}
	}

	return pstAsdus->usPayloadSize;
}

/**
* @brief 参数定值写接口接收处理接口（参数预置、固化、取消）
*
* @param[in] pstSelf 规约实体
* @param[in] usReason 传送原因
*/
void Do_ParamWrite_Nanwang(CS10x *pstSelf, unsigned short usReason)
{
	unsigned char  ucQos            = 0;
	unsigned short usi             = 0;
	unsigned short usLen           = 0;
	unsigned int uiInfoAddr      = 0;
	unsigned char ucFlag = 0;
	unsigned short usTotalNum = 0;
	ASDU_Element *pstAsdus = &pstSelf->stAsduElem;
	IECPARAM_T stIecParam = {0};

	if(pstAsdus->usNum == 0)
	{
		return;
	}

	ucQos = pstAsdus->pucPayload[pstSelf->stAsduElem.usPayloadSize - 1];

	if(COT_ACT == usReason || COT_DEACT == usReason)  //从站收
	{
		if((ucQos & PARAM_SE_1) == PARAM_SE_1)  //参数预置
		{
			if(COT_ACT == usReason)
			{
				pstSelf->ucPmPresetFlag = 1;
				pstSelf->uiPmPresetTimeout = 180000;
			}
			else if(COT_DEACT == usReason)
			{
				pstSelf->ucPmPresetFlag = 0;
				pstSelf->uiPmPresetTimeout = 0;
				pstSelf->ucParamFlag = 0;
			}

			stIecParam.ucType = TAG_TPYE_FLOAT;
			stIecParam.ucLen = 4;

			/*首次预置时，清除发送序号*/
			if(pstSelf->ucParamFlag == 0)
			{
				pstSelf->usParamSendNum = 0;
			}

			if(pstAsdus -> usSQ)
			{
				pstSelf ->ucPmPresetVsqFlag = 1;
				uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
				usLen += pstSelf->stAppParameters.iSzOfIOA;

				for(usi = 0; usi < pstAsdus->usNum; usi++)
				{
					stIecParam.uiInfoAddr = uiInfoAddr;
					memcpy(stIecParam.unVal.caBuf, &pstAsdus->pucPayload[usLen], stIecParam.ucLen);
					usLen += stIecParam.ucLen;
					usLen ++;

					if(NULL != pstSelf->pfnAddIECParam)
					{
						pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMWT, &stIecParam, pstSelf->pUsrData);
					}

					pstSelf->ucParamFlag = 1;
					uiInfoAddr++;
				}
			}
			else
			{
				for(usi = 0; usi < pstAsdus->usNum; usi++)
				{
					uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
					usLen += pstSelf->stAppParameters.iSzOfIOA;
					stIecParam.uiInfoAddr = uiInfoAddr;
					memcpy(stIecParam.unVal.caBuf, &pstAsdus->pucPayload[usLen], stIecParam.ucLen);
					usLen += stIecParam.ucLen;
					usLen ++;

					if(NULL != pstSelf->pfnAddIECParam)
					{
						pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMWT, &stIecParam, pstSelf->pUsrData);
					}

					pstSelf->ucParamFlag = 1;
				}
			}

			if(COT_ACT == usReason)
			{
				SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_ACTCON, PARAM_SE_1);
			}
			else if(COT_DEACT == usReason)
			{
				SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_DEACTCON, PARAM_SE_1);
			}
		}
		else
		{
			stIecParam.ucType = TAG_TPYE_FLOAT;
			stIecParam.ucLen = 4;

			if(pstSelf->ucPmPresetFlag)
			{
				usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

				if(usTotalNum != pstAsdus->usNum)
				{
					return;
				}

				if(pstAsdus -> usSQ)
				{
					pstSelf ->ucPmPresetVsqFlag = 1;
					uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
					pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, 0, &stIecParam, pstSelf->pUsrData);

					if(uiInfoAddr != stIecParam.uiInfoAddr) //固化若分多帧发送，只处理最后一帧
					{
						return;
					}

					usLen += pstSelf->stAppParameters.iSzOfIOA;

					for(unsigned short i = 0; i < pstAsdus->usNum; i++)
					{
						if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, i, &stIecParam, pstSelf->pUsrData))
						{
							if(memcmp(&pstAsdus->pucPayload[usLen], stIecParam.unVal.caBuf, 4) != 0)
							{
								SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_PN | COT_ACTCON, 0);
								return;
							}

							usLen += 4;
							usLen ++;
						}
					}
				}
				else
				{
					for(unsigned short i = 0; i < pstAsdus->usNum; i++)
					{
						if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, i, &stIecParam, pstSelf->pUsrData))
						{
							uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);

							if(uiInfoAddr != stIecParam.uiInfoAddr)
							{
								return;
							}

							usLen += pstSelf->stAppParameters.iSzOfIOA;

							if(memcmp(&pstAsdus->pucPayload[usLen], stIecParam.unVal.caBuf, 4) != 0)
							{
								SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_PN | COT_ACTCON, 0);
								return;
							}

							usLen += 4;
							usLen ++;
						}
					}
				}

				if(pstSelf->pfnRunWriteIECParam)
				{
					ucFlag = pstSelf->pfnRunWriteIECParam(pstSelf->pUsrData);

					if(ucFlag)
					{
						SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_ACTCON, 0);       /*固化成功*/
					}
					else
					{
						SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_PN | COT_ACTCON, 0);    /*固化失败，终止命令*/
					}
				}

				pstSelf->uiPmPresetTimeout = 0;
			}
			else
			{
				stIecParam.ucType = TAG_TPYE_FLOAT;
				stIecParam.ucLen = 4;

				if(pstAsdus -> usSQ)
				{
					pstSelf ->ucPmPresetVsqFlag = 1;
					uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
					usLen += pstSelf->stAppParameters.iSzOfIOA;

					for(usi = 0; usi < pstAsdus->usNum; usi++)
					{
						stIecParam.uiInfoAddr = uiInfoAddr;
						usLen += stIecParam.ucLen;
						usLen ++;

						if(NULL != pstSelf->pfnAddIECParam)
						{
							pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
						}

						pstSelf->ucParamFlag = 1;
						uiInfoAddr++;
					}
				}
				else
				{
					for(usi = 0; usi < pstAsdus->usNum; usi++)
					{
						uiInfoAddr = ASDU_getIOA(&pstAsdus->pucPayload[usLen], pstSelf->stAppParameters.iSzOfIOA);
						usLen += pstSelf->stAppParameters.iSzOfIOA;
						stIecParam.uiInfoAddr = uiInfoAddr;
						usLen += stIecParam.ucLen;
						usLen ++;

						if(NULL != pstSelf->pfnAddIECParam)
						{
							pstSelf->pfnAddIECParam(0, pstSelf->ucParamFlag, IECPARAMRD, &stIecParam, pstSelf->pUsrData);
						}

						pstSelf->ucParamFlag = 1;
					}
				}

				SetSendTask(pstSelf, TSKID_ParamWrite_NanWang, COT_PN | COT_ACTCON, 0);    /*固化失败，终止命令*/
			}
		}
	}
}

/**
* @brief 参数定值写接口发送组包处理
*
* @param[in] pstSelf 规约实体
* @param[in] uiParam 传送原因
* @return ASDU数据长度
*/
unsigned short CS10x_Send_ParamWrite_Nanwang(CS10x * pstSelf, unsigned int uiParam)
{
	unsigned char  ucCont     = 0;
	unsigned char  ucTxNum    = 0;
	unsigned short usTotalNum = 0;
	unsigned short usi        = 0;
	unsigned short usReason   = (unsigned short)uiParam;
	unsigned short usQos       = (unsigned short)(uiParam >> 16);           /*参数*/
	IECPARAM_T stIecParam = {0};
	ASDU_Element *pstAsdus =  &pstSelf->stAsduElem;
	pstAsdus->usTypeID = C_SP_NA;

	if(pstSelf ->ucPmPresetVsqFlag == 1)
	{
		pstSelf ->ucPmPresetVsqFlag = 0;
		pstAsdus->usSQ = 1;
	}
	else
	{
		pstAsdus->usSQ = 0;
	}

	pstAsdus->usNum = 0;
	pstAsdus->usCot = usReason;

	if(NULL == pstSelf->pfnGetParamInfoByIndx)
	{
		return 0;
	}

	if(COT_ACTCON == usReason ||  COT_DEACTCON == usReason)   //回复主站参数预置数据
	{
		if(PARAM_SE_1 == usQos)
		{
			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

			if(pstAsdus->usSQ)
			{
				pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, pstSelf->usParamSendNum, &stIecParam, pstSelf->pUsrData);
				ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;

				for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, usi, &stIecParam, pstSelf->pUsrData))
					{
						if(5 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
						{
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
							pstAsdus->usPayloadSize += 4;
							pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQos;
							ucTxNum++;
							ucCont = 0;
						}
						else
						{
							ucCont = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;
				}
			}
			else
			{
				for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMWT, usi, &stIecParam, pstSelf->pUsrData))
					{
						if(pstSelf->stAppParameters.iSzOfIOA + 5 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
						{
							ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
							pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
							pstAsdus->usPayloadSize += 4;
							pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQos;
							ucTxNum++;
							ucCont = 0;
						}
						else
						{
							ucCont = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;
				}
			}
		}
		else if(PARAM_SE_0 == usQos)
		{
			usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

			if(pstAsdus->usSQ)
			{
				pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, pstSelf->usParamSendNum, &stIecParam, pstSelf->pUsrData);
				ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
				pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;

				for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, usi, &stIecParam, pstSelf->pUsrData))
					{
						if(5 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
						{
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
							pstAsdus->usPayloadSize += 4;
							pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQos;
							ucTxNum++;
							ucCont = 0;
						}
						else
						{
							ucCont = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;
				}
			}
			else
			{
				for(usi = pstSelf->usParamSendNum; usi < usTotalNum; usi++)
				{
					if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, usi, &stIecParam, pstSelf->pUsrData))
					{
						if(pstSelf->stAppParameters.iSzOfIOA + 5 + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
						{
							ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
							pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
							memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, 4);
							pstAsdus->usPayloadSize += 4;
							pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQos;
							ucTxNum++;
							ucCont = 0;
						}
						else
						{
							ucCont = 1;
							break;
						}
					}

					pstSelf->usParamSendNum++;
				}
			}
		}

		/*缓存中无数据，不进行后续发送*/
		if(ucCont)
		{
			SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, usQos);
		}

		/*主方向无后续帧且发送完成时，清除*/
		if(ucCont == 0 || (pstSelf->usParamSendNum == usTotalNum))
		{
			pstSelf->usParamSendNum = 0;
			pstSelf->ucParamFlag = 0;
		}
	}
	else if((COT_PN | COT_ACTCON) == usReason)
	{
		usTotalNum = pstSelf->pfnGetParamCount(pstSelf->pUsrData);

		if(pstAsdus->usSQ)
		{
			pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, pstSelf->usParamSendNum, &stIecParam, pstSelf->pUsrData);
			ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
			pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;

			for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
			{
				if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
				{
					if(1 + stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
					{
						memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);/*复制当前参数值*/
						pstAsdus->usPayloadSize += stIecParam.ucLen;
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQos;
						ucTxNum++;
						ucCont = 0;
					}
					else
					{
						ucCont = 1;
						break;
					}
				}

				pstSelf->usParamSendNum++;                             /*参数发送个数*/
			}
		}
		else
		{
			for(unsigned short i = pstSelf->usParamSendNum; i < usTotalNum; i++)
			{
				if(pstSelf->pfnGetParamInfoByIndx(IECPARAMRD, i, &stIecParam, pstSelf->pUsrData))
				{
					if(pstSelf->stAppParameters.iSzOfIOA + stIecParam.ucLen + pstAsdus->usPayloadSize <= pstSelf->stAppParameters.iMaxSzOfAsduLen)
					{
						ASDU_setIOA(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.uiInfoAddr, pstSelf->stAppParameters.iSzOfIOA);
						pstAsdus->usPayloadSize += pstSelf->stAppParameters.iSzOfIOA;
						memcpy(&pstAsdus->pucPayload[pstAsdus->usPayloadSize], stIecParam.unVal.caBuf, stIecParam.ucLen);/*复制当前参数值*/
						pstAsdus->usPayloadSize += stIecParam.ucLen;
						pstAsdus->pucPayload[pstAsdus->usPayloadSize++] = usQos;
						ucTxNum++;
						ucCont = 0;
					}
					else
					{
						ucCont = 1;
						break;
					}
				}

				pstSelf->usParamSendNum++;                             /*参数发送个数*/
			}
		}

		/*缓存中无数据，不进行后续发送*/
		if(ucCont)
		{
			SetSendTask(pstSelf, pstSelf->byTaskFlagId, usReason, 0);
		}

		/*主方向无后续帧且发送完成时，清除*/
		if(ucCont == 0 || pstSelf->usParamSendNum == usTotalNum)
		{
			pstSelf->usParamSendNum = 0;
			pstSelf->ucParamFlag = 0;
		}
	}

	pstAsdus->usNum = ucTxNum;
	return pstAsdus->usPayloadSize;
}