
#include "Deployment.h"
#include <stdarg.h>

const static UINT32  gCrcTable[256] =
{
	0x00000000U,0x04c11db7U,0x09823b6eU,0x0d4326d9U,0x130476dcU,0x17c56b6bU,
	0x1a864db2U,0x1e475005U,0x2608edb8U,0x22c9f00fU,0x2f8ad6d6U,0x2b4bcb61U,
	0x350c9b64U,0x31cd86d3U,0x3c8ea00aU,0x384fbdbdU,0x4c11db70U,0x48d0c6c7U,
	0x4593e01eU,0x4152fda9U,0x5f15adacU,0x5bd4b01bU,0x569796c2U,0x52568b75U,
	0x6a1936c8U,0x6ed82b7fU,0x639b0da6U,0x675a1011U,0x791d4014U,0x7ddc5da3U,
	0x709f7b7aU,0x745e66cdU,0x9823b6e0U,0x9ce2ab57U,0x91a18d8eU,0x95609039U,
	0x8b27c03cU,0x8fe6dd8bU,0x82a5fb52U,0x8664e6e5U,0xbe2b5b58U,0xbaea46efU,
	0xb7a96036U,0xb3687d81U,0xad2f2d84U,0xa9ee3033U,0xa4ad16eaU,0xa06c0b5dU,
	0xd4326d90U,0xd0f37027U,0xddb056feU,0xd9714b49U,0xc7361b4cU,0xc3f706fbU,
	0xceb42022U,0xca753d95U,0xf23a8028U,0xf6fb9d9fU,0xfbb8bb46U,0xff79a6f1U,
	0xe13ef6f4U,0xe5ffeb43U,0xe8bccd9aU,0xec7dd02dU,0x34867077U,0x30476dc0U,
	0x3d044b19U,0x39c556aeU,0x278206abU,0x23431b1cU,0x2e003dc5U,0x2ac12072U,
	0x128e9dcfU,0x164f8078U,0x1b0ca6a1U,0x1fcdbb16U,0x018aeb13U,0x054bf6a4U,
	0x0808d07dU,0x0cc9cdcaU,0x7897ab07U,0x7c56b6b0U,0x71159069U,0x75d48ddeU,
	0x6b93dddbU,0x6f52c06cU,0x6211e6b5U,0x66d0fb02U,0x5e9f46bfU,0x5a5e5b08U,
	0x571d7dd1U,0x53dc6066U,0x4d9b3063U,0x495a2dd4U,0x44190b0dU,0x40d816baU,
	0xaca5c697U,0xa864db20U,0xa527fdf9U,0xa1e6e04eU,0xbfa1b04bU,0xbb60adfcU,
	0xb6238b25U,0xb2e29692U,0x8aad2b2fU,0x8e6c3698U,0x832f1041U,0x87ee0df6U,
	0x99a95df3U,0x9d684044U,0x902b669dU,0x94ea7b2aU,0xe0b41de7U,0xe4750050U,
	0xe9362689U,0xedf73b3eU,0xf3b06b3bU,0xf771768cU,0xfa325055U,0xfef34de2U,
	0xc6bcf05fU,0xc27dede8U,0xcf3ecb31U,0xcbffd686U,0xd5b88683U,0xd1799b34U,
	0xdc3abdedU,0xd8fba05aU,0x690ce0eeU,0x6dcdfd59U,0x608edb80U,0x644fc637U,
	0x7a089632U,0x7ec98b85U,0x738aad5cU,0x774bb0ebU,0x4f040d56U,0x4bc510e1U,
	0x46863638U,0x42472b8fU,0x5c007b8aU,0x58c1663dU,0x558240e4U,0x51435d53U,
	0x251d3b9eU,0x21dc2629U,0x2c9f00f0U,0x285e1d47U,0x36194d42U,0x32d850f5U,
	0x3f9b762cU,0x3b5a6b9bU,0x0315d626U,0x07d4cb91U,0x0a97ed48U,0x0e56f0ffU,
	0x1011a0faU,0x14d0bd4dU,0x19939b94U,0x1d528623U,0xf12f560eU,0xf5ee4bb9U,
	0xf8ad6d60U,0xfc6c70d7U,0xe22b20d2U,0xe6ea3d65U,0xeba91bbcU,0xef68060bU,
	0xd727bbb6U,0xd3e6a601U,0xdea580d8U,0xda649d6fU,0xc423cd6aU,0xc0e2d0ddU,
	0xcda1f604U,0xc960ebb3U,0xbd3e8d7eU,0xb9ff90c9U,0xb4bcb610U,0xb07daba7U,
	0xae3afba2U,0xaafbe615U,0xa7b8c0ccU,0xa379dd7bU,0x9b3660c6U,0x9ff77d71U,
	0x92b45ba8U,0x9675461fU,0x8832161aU,0x8cf30badU,0x81b02d74U,0x857130c3U,
	0x5d8a9099U,0x594b8d2eU,0x5408abf7U,0x50c9b640U,0x4e8ee645U,0x4a4ffbf2U,
	0x470cdd2bU,0x43cdc09cU,0x7b827d21U,0x7f436096U,0x7200464fU,0x76c15bf8U,
	0x68860bfdU,0x6c47164aU,0x61043093U,0x65c52d24U,0x119b4be9U,0x155a565eU,
	0x18197087U,0x1cd86d30U,0x029f3d35U,0x065e2082U,0x0b1d065bU,0x0fdc1becU,
	0x3793a651U,0x3352bbe6U,0x3e119d3fU,0x3ad08088U,0x2497d08dU,0x2056cd3aU,
	0x2d15ebe3U,0x29d4f654U,0xc5a92679U,0xc1683bceU,0xcc2b1d17U,0xc8ea00a0U,
	0xd6ad50a5U,0xd26c4d12U,0xdf2f6bcbU,0xdbee767cU,0xe3a1cbc1U,0xe760d676U,
	0xea23f0afU,0xeee2ed18U,0xf0a5bd1dU,0xf464a0aaU,0xf9278673U,0xfde69bc4U,
	0x89b8fd09U,0x8d79e0beU,0x803ac667U,0x84fbdbd0U,0x9abc8bd5U,0x9e7d9662U,
	0x933eb0bbU,0x97ffad0cU,0xafb010b1U,0xab710d06U,0xa6322bdfU,0xa2f33668U,
	0xbcb4666dU,0xb8757bdaU,0xb5365d03U,0xb1f740b4U
};
/** 静态全局变量--需跟随 */
static EXIT_OP_STRUCT gExitOpInfo = {0u}; 

/** 静态全局变量--无需跟随 */
static EXIT_OP_FIRST_REQ_STRUCT gFirstFReqInfo = {0u};
static EXIT_OP_SEC_REQ_STRUCT gSecondReqInfo = {0u};


static void ParseExitOpFirstRequst(const UINT8* dataBuf, UINT32 startIndex);    /* 解析首次退出运营请求 */
static void ParseExitOpSecondRequst(const UINT8* dataBuf, UINT32 startIndex);    /* 解析再次退出运营请求 */
static UINT16 PackExitOpFirstReply(UINT8* dataBuf,UINT16 maxLen);         /** 组包首次退出运营确认 */
static UINT16 PackExitOpSecondReply(UINT8* dataBuf,UINT16 maxLen);        /** 组包再次退出运营确认 */
static void ResetInitParam(void);    /** 重置参数*/
static UINT32 CRC32_AIM(UINT8 *pData, UINT16 wDataLen);    /** AIM 使用的CRC32计算函数 */
static void AIMPrinf(UINT8 Level,const char* lpszFormat, ...);         /* 调试打印 */
static UINT8 Deploy_FirstReqHandle(void); /*首次退出运营处理*/
static UINT8 Deploy_SecondReqHandle(void); /*再次退出运营处理*/
static UINT8 Deploy_CheckBoardID(UINT8 boardID_in);/*输入板卡ID与本地板卡ID一致x性检查*/
 /**
  * @brief AIM 使用的CRC32计算函数
  * @param[in] const UINT8* dataBuf,输入报文起始地址
  * @param[in] UINT16 wDataLen,长度
  * @param[out] 无
  * @return UINT32 CRC值
  * @note 无
  */
static UINT32 CRC32_AIM(UINT8 *pData, UINT16 wDataLen)
{
    UINT32 dwCrc = 0;
    UINT16 wCycle = 0;

    /*循环计算CRC32*/
    for(wCycle = (UINT8)0; wCycle < wDataLen; wCycle++)
    {
        dwCrc = (dwCrc << 8) ^ gCrcTable[ (dwCrc >> 24) ^ pData[wCycle]  ] ;
    }

    /*返回计算结果*/
    return dwCrc;
}


/**
 * @brief 调试打印函数
 * @param[in] const UINT8* dataBuf,输入报文起始地址
 * @param[in] UINT16 wDataLen,长度
 * @param[out] 无
 * @return UINT32 CRC值
 * @note 无
 */
static void AIMPrinf(UINT8 Level, const char* lpszFormat, ...)
{
	va_list para;
	static CHAR tmpPrintBuf[65535u] = { '\0' };

	(void)CommonMemSet(tmpPrintBuf, 65535u, 0u, 65535u);
	if ((Level < AIM_LOG_LEVEL) && (NULL != gExitOpInfo.pfun))
	{
		va_start(para, lpszFormat);
		(void)vsnprintf(tmpPrintBuf, 65535u, lpszFormat, para);
		va_end(para);

		gExitOpInfo.pfun("%s", tmpPrintBuf);
	}
}

 /**
  * @brief 解析首次退出运营请求
  * @param[in] const UINT8* dataBuf,输入报文起始地址
  * @param[in] UINT32 startIndex,解析起始地址
  * @param[out] 无
  * @return 无
  * @note 无
  */
 static void ParseExitOpFirstRequst(const UINT8* dataBuf, UINT32 startIndex)
 {
	UINT32 errorcode = 0u;
	UINT32 msgstartIndex = startIndex;
	UINT32 exitOpCmdIndex = 0u;
	UINT32 index = startIndex;
	UINT32 tempCrc32 = 0u;
	UINT8 checkBoardid = 0u;
	
	if (NULL == dataBuf)
	{
		errorcode += 0x80000000u;
	}
	else
	{
		/** 帧类型 */
		index += 1u;
		exitOpCmdIndex = index;  /* 设置命令信息起始地址 */

		/** 板卡类型 */
		gFirstFReqInfo.boardType = dataBuf[index];
		index += 1u;

		/** 板卡ID */
		gFirstFReqInfo.chanelID = dataBuf[index];
		index += 1u;

		/** 时间戳 */
		gFirstFReqInfo.firstRequstTime = LongFromChar(&dataBuf[index]);
		index += 4u;

		/** 退出运营命令 */
		gFirstFReqInfo.exitOpCmd = dataBuf[index];
		index += 1u;

		checkBoardid = Deploy_CheckBoardID(gFirstFReqInfo.chanelID);
		if ((0x01u != gFirstFReqInfo.boardType) || (0x55U != checkBoardid))
		{
			errorcode += 0x01000000u;
		}
		else
		{
			if (0xaau == gFirstFReqInfo.exitOpCmd)
			{
				/** 退出运营命令CRC */
				gFirstFReqInfo.exitOpCmdCrc = LongFromChar(&dataBuf[index]);
				index += 4u;

				/** 计算退出运营命令CRC */
				tempCrc32 = CRC32_AIM(&dataBuf[exitOpCmdIndex], (UINT16)(index - 4u - exitOpCmdIndex));

				if (tempCrc32 == gFirstFReqInfo.exitOpCmdCrc)
				{
					/** 不处理*/
				}
				else
				{
					gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_1;
					AIMPrinf(AIM_LOG_FATAL, "opFirstCRC error: recv:%x, calc:%x,\n", gFirstFReqInfo.exitOpCmdCrc, tempCrc32);
				}

				/** 信息帧CRC */
				gFirstFReqInfo.msgCrc = LongFromChar(&dataBuf[index]);
				index += 4u;

				/** 计算信息帧CRC */
				tempCrc32 = CRC32_AIM(&dataBuf[msgstartIndex], (UINT16)(index - 4u - msgstartIndex));

				if (tempCrc32 == gFirstFReqInfo.msgCrc)
				{
					/** 不处理*/
				}
				else
				{
					gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_1;
					AIMPrinf(AIM_LOG_FATAL, "msgFirstCRC error: recv:%x, calc:%x.\n", gFirstFReqInfo.msgCrc, tempCrc32);
				}

				gFirstFReqInfo.refreshFlag = MSG_REFRESH;
			}
			else
			{
				errorcode += 0x40000000u;
			}
		}
	}

	if (0u == errorcode)
	{
		/** 处理正确，无需处理,此处需要调用打印打印错误*/
	}
	else
	{		
		(void)CommonMemSet(&gFirstFReqInfo, (UINT32)sizeof(EXIT_OP_FIRST_REQ_STRUCT),0u, (UINT32)sizeof(EXIT_OP_FIRST_REQ_STRUCT));
	}
 }


  /**
  * @brief 解析再次退出运营请求
  * @param[in] const UINT8* dataBuf,输入报文起始地址
  * @param[in] UINT32 startIndex,解析起始地址
  * @param[out] 无
  * @return 无
  * @note 无
  */
 static void ParseExitOpSecondRequst(const UINT8* dataBuf, UINT32 startIndex)
 {
	UINT32 errorcode = 0u;
	UINT32 msgstartIndex = startIndex;
	UINT32 exitOpCmdIndex = 0u;
	UINT32 index = startIndex;
	UINT32 tempCrc32 = 0u;
	UINT8 checkBoardid = 0u;

	if (NULL == dataBuf)
	{
		errorcode += 0x80000000u;
	}
	else
	{
		/** 帧类型 */
		index += 1u;
		exitOpCmdIndex = index;  /* 设置命令信息起始地址 */

		/** 板卡类型 */
		gSecondReqInfo.boardType = dataBuf[index];
		index += 1u;

		/** 板卡ID */
		gSecondReqInfo.chanelID = dataBuf[index];
		index += 1u;

		/** 时间戳 */
		gSecondReqInfo.secondRequstTime = LongFromChar(&dataBuf[index]);
		index += 4u;

		/** 首次确认信息中的时间戳 */
		gSecondReqInfo.firstReplyTime = LongFromChar(&dataBuf[index]);
		index += 4u;

		/** 退出运营命令 */
		gSecondReqInfo.exitOpCmd = dataBuf[index];
		index += 1u;

		checkBoardid = Deploy_CheckBoardID(gSecondReqInfo.chanelID);
		if ((0x01u != gSecondReqInfo.boardType) || (0x55U != checkBoardid))
		{
			errorcode += 0x01000000u;
		}
		else
		{
			if (0xaau == gSecondReqInfo.exitOpCmd)
			{
				/** 退出运营命令CRC */
				gSecondReqInfo.exitOpCmdCrc = LongFromChar(&dataBuf[index]);
				index += 4u;

				/** 计算退出运营命令CRC */
				tempCrc32 = CRC32_AIM(&dataBuf[exitOpCmdIndex], (UINT16)(index - 4u - exitOpCmdIndex));

				if (tempCrc32 == gSecondReqInfo.exitOpCmdCrc)
				{
					/** 不处理*/
				}
				else
				{
					gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_1;
					AIMPrinf(AIM_LOG_FATAL, "opSecCRC error: recv:%x, calc:%x,\n", gSecondReqInfo.exitOpCmdCrc, tempCrc32);
				}

				/** 信息帧CRC */
				gSecondReqInfo.msgCrc = LongFromChar(&dataBuf[index]);
				index += 4u;

				/** 计算信息帧CRC */
				tempCrc32 = CRC32_AIM(&dataBuf[msgstartIndex], (UINT16)(index - 4u - msgstartIndex));

				if (tempCrc32 == gSecondReqInfo.msgCrc)
				{
					/** 不处理 */
				}
				else
				{
					gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_1;
					AIMPrinf(AIM_LOG_FATAL, "msgSecCRC error: recv:%x, calc:%x.\n", gSecondReqInfo.msgCrc, tempCrc32);
				}

				gSecondReqInfo.refreshFlag = MSG_REFRESH;
			}
			else
			{
				errorcode += 0x40000000u;
			}
		}
	}

	if (0u == errorcode)
	{
		/** 处理正确，无需处理,此处需要调用打印打印错误*/
	}
	else
	{		
		(void)CommonMemSet(&gFirstFReqInfo, (UINT32)sizeof(EXIT_OP_FIRST_REQ_STRUCT),0u, (UINT32)sizeof(EXIT_OP_FIRST_REQ_STRUCT));
		(void)CommonMemSet(&gSecondReqInfo, (UINT32)sizeof(EXIT_OP_SEC_REQ_STRUCT), 0u, (UINT32)sizeof(EXIT_OP_SEC_REQ_STRUCT));
	}
 }

 /**
  * @brief 组包发送首次退出运营确认
  * @param[in] UINT8* dataBuf, 发送报文起始地址
  * @param[in] UINT16 maxLen, 发送报文最大长度
  * @param[out] 无
  * @return 0 处理失败；非0 成功
  * @note 无
  */
  static UINT16 PackExitOpFirstReply(UINT8* dataBuf,UINT16 maxLen)
  {
	UINT16 ret = 0u;
	UINT8 tmpBuff[500u] = {0u};   /** 事先保证此缓存空间足够*/
	UINT16 index = 0u;
	UINT32 tempCrc32 = 0u;

	if (NULL == dataBuf)
	{
		/** 入口参数错误 */
	}
	else
	{
		/** 预留两字节长度 */
		index += 2u;

		/** 帧类型 */
		tmpBuff[index] = EXIT_OP_FIRST_REPLY;
		index += 1u;

		/** 板卡类型 */
		tmpBuff[index] = gExitOpInfo.boardType;
		index += 1u;

		/** 板卡id */
		tmpBuff[index] = gExitOpInfo.chanelID;
		index += 1u;

		/** 时间戳 */
		(void)LongToChar(gExitOpInfo.ReplytTime,&tmpBuff[index]);
		index += 4u;

		/** 首次请求信息中的时间戳 */
		(void)LongToChar(gExitOpInfo.recvLastRequestTimestamp,&tmpBuff[index]);
		index += 4u;

		/** 授权状态 */
		tmpBuff[index] = gExitOpInfo.opStatus;
		index += 1u;

		/** 授权失败原因 */
		tmpBuff[index] = gExitOpInfo.opReason;
		index += 1u;

		/** 退出运营命令确认CRC */
		tempCrc32 = CRC32_AIM(&tmpBuff[3u], index - 3u);
		(void)LongToChar(tempCrc32,&tmpBuff[index]);
		index += 4u;

		/** 信息帧CRC */
		tempCrc32 = CRC32_AIM(&tmpBuff[2u], index - 2u);
		(void)LongToChar(tempCrc32,&tmpBuff[index]);
		index += 4u;

		/** 填写信息长度 */
		(void)ShortToChar(index - 2u,&tmpBuff[0u]);

		if (index <= maxLen)
		{
			ret = index;
			(void)CommonMemCpy(dataBuf,maxLen,tmpBuff,index);
		}
		else
		{
			/** 不处理 */
		}
	}
	return ret;
  }

  /**
  * @brief 组包发送再次退出运营确认
  * @param[in] UINT8* dataBuf, 发送报文起始地址
  * @param[in] UINT16 maxLen, 发送报文最大长度
  * @param[out] 无
  * @return 0 处理失败；非0 成功
  * @note 无
  */
  static UINT16 PackExitOpSecondReply(UINT8* dataBuf,UINT16 maxLen)
  {
	UINT16 ret = 0u;
	UINT8 tmpBuff[500u] = {0u};   /** 事先保证此缓存空间足够*/
	UINT16 index = 0u;
	UINT32 tempCrc32 = 0u;

	if (NULL == dataBuf)
	{
		/** 入口参数错误 */
	}
	else
	{
		/** 预留两字节长度 */
		index += 2u;

		/** 帧类型 */
		tmpBuff[index] = EXIT_OP_SECOND_REPLY;
		index += 1u;

		/** 板卡类型 */
		tmpBuff[index] = gExitOpInfo.boardType;
		index += 1u;

		/** 板卡id */
		tmpBuff[index] = gExitOpInfo.chanelID;
		index += 1u;

		/** 时间戳 */
		(void)LongToChar(gExitOpInfo.ReplytTime,&tmpBuff[index]);
		index += 4u;

		/** 再次请求信息中的时间戳 */
		(void)LongToChar(gExitOpInfo.recvLastRequestTimestamp,&tmpBuff[index]);
		index += 4u;

		/** 授权状态 */
		tmpBuff[index] = gExitOpInfo.opStatus;
		index += 1u;

		/** 授权失败原因 */
		tmpBuff[index] = gExitOpInfo.opReason;
		index += 1u;

		/** 退出运营命令确认CRC */
		tempCrc32 = CRC32_AIM(&tmpBuff[3u], index - 3u);
		(void)LongToChar(tempCrc32,&tmpBuff[index]);
		index += 4u;

		/** 信息帧CRC */
		tempCrc32 = CRC32_AIM(&tmpBuff[2u], index - 2u);
		(void)LongToChar(tempCrc32,&tmpBuff[index]);
		index += 4u;

		/** 填写信息长度 */
		(void)ShortToChar(index - 2u,&tmpBuff[0u]);

		if (index <= maxLen)
		{	
			ret = index;
			(void)CommonMemCpy(dataBuf,maxLen,tmpBuff,index);
		}
		else
		{
			/** 不处理 */
		}
	}
	return ret;
  }

  /**
   * @brief 重置参数
   * @param[in] 无
   * @param[out] 无
   * @return 无
   * @note 无
   */
  static void ResetInitParam(void)
  {
	  gExitOpInfo.inputMsgType = EXIT_OP_DEFAULT;
	  gExitOpInfo.outputMsgType = EXIT_OP_DEFAULT;

	  gExitOpInfo.boardType = 0u;
	  gExitOpInfo.chanelID = 0u;

	  gExitOpInfo.recvLastRequestTimestamp = 0u;
	  gExitOpInfo.ReplytTime = 0u;

	  gExitOpInfo.curTimeout = 0u;

	  gExitOpInfo.opStatus = FORBID_EXIT_OP_STATUS;
	  gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_0;
  }

/** =============================================接口相关处理=============================== */

/**
 * @brief 退出运营模块初始化
 * @param[in] UINT16 cycleTime 当前子系统运行周期
 * @param[in] const p_DPrintf pfun 打印接口
 * @param[out]
 * @return 
 * @note 
 */
  extern void Deploy_Init(UINT16 cycleTime,const p_DPrintf pfun)
  {
/*退出运营处理*/

	  gExitOpInfo.inputMsgType = EXIT_OP_DEFAULT;
	  gExitOpInfo.outputMsgType = EXIT_OP_DEFAULT;

	  gExitOpInfo.boardType = 0u;
	  gExitOpInfo.chanelID = 0u;

	  gExitOpInfo.recvLastRequestTimestamp = 0u;
	  gExitOpInfo.ReplytTime = 0u;

	  if (0u != cycleTime)
	  {
		  gExitOpInfo.maxTimeout = (UINT16)(EXIT_OP_TIMEOUT / cycleTime);
	  }
	  else
	  {
		  gExitOpInfo.maxTimeout = 0u;
	  }

	  gExitOpInfo.curTimeout = 0u;
	  gExitOpInfo.innerTime = 0u;
	  gExitOpInfo.exitOperateStatus = STAY_OP_STATUS;

	  gExitOpInfo.opStatus = FORBID_EXIT_OP_STATUS;
	  gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_0;

	  /*打印先删除*/
	  if (NULL == pfun)
	  {
		  gExitOpInfo.pfun = NULL;
	  }
	  else
	  {
		  gExitOpInfo.pfun = pfun;
	  }
  }

 /**
 * @brief 输入解包处理
 * @param[in] const UINT8* dataBuf,输入报文起始地址
 * @param[in] UINT16 dataLength,输入报文长度
 * @param[in] UINT8 srcType,类型
 * @param[in] UINT8 srcId,ID
 * @param[out] 无
 * @return 0,解析失败
           1，解析成功
 * @note 报文信息为去除协议和协议适配层头
 */
extern UINT8 Deploy_ParseAIMInputInfo(const UINT8* dataBuf, UINT16 dataLength, UINT8 srcType,UINT8 srcId)
{
	UINT8 ret = 0u;
	UINT32 msgLen = 0;
	UINT16 msgIndex = 0u;
	UINT16 srcDev = 0u;
	UINT32 checkCrc = 0u;
	UINT8 msgType = EXIT_OP_DEFAULT;

	srcDev += srcType;
	srcDev = (UINT16)(srcDev << 8u) + srcId;

	if ((NULL == dataBuf) || (DEVICE_TYPE_AIM != srcDev))
	{
		/** 入口参数错误*/
	}
	else
	{
		/** 获取信息长度*/
		msgLen = (UINT32)ShortFromChar(dataBuf);
		msgIndex += 2u;

		if ((2u < dataLength) && ((msgLen + 2U) == dataLength))
		{
			msgType = dataBuf[msgIndex];
			AIMPrinf(AIM_LOG_FATAL, "msgType:%x,\n", msgType);

			switch (msgType)
			{
				case EXIT_OP_FIRST_REQUEST:
					AIMPrinf(AIM_LOG_FATAL, "ParseExitOpFirstRequst,\n");
					ParseExitOpFirstRequst(&dataBuf[msgIndex],0u);
					ret = 1u;
					break;
				case EXIT_OP_SECOND_REQUEST:
					AIMPrinf(AIM_LOG_FATAL, "ParseExitOpSecondRequst,\n");
					ParseExitOpSecondRequst(&dataBuf[msgIndex],0u);
					ret = 1u;
					break;
				default:
					; /*类型错误不处理*/
					break;
			}
		}
		else
		{
			/** 长度不对 */
		}
	}
	return ret;
}


/**
* @brief 首次退出运营处理
* @param[in] 无
* @param[out] 无
* @return 无
* @note 无
*/
static UINT8 Deploy_FirstReqHandle(void)
{
	UINT8 rtn = 0u;

	if (((EXIT_OP_DEFAULT == gExitOpInfo.inputMsgType) || (EXIT_OP_FIRST_REQUEST == gExitOpInfo.inputMsgType))
		&& (gExitOpInfo.recvLastRequestTimestamp != gFirstFReqInfo.firstRequstTime))
	{
		gExitOpInfo.inputMsgType = EXIT_OP_FIRST_REQUEST;
		gExitOpInfo.outputMsgType = EXIT_OP_FIRST_REPLY;
		gExitOpInfo.boardType = gFirstFReqInfo.boardType;
		gExitOpInfo.chanelID = gFirstFReqInfo.chanelID;
		gExitOpInfo.ReplytTime = gExitOpInfo.innerTime;
		gExitOpInfo.recvLastRequestTimestamp = gFirstFReqInfo.firstRequstTime;
		AIMPrinf(AIM_LOG_FATAL, "fisrt_opReason: %d,\n", gExitOpInfo.opReason);
		if (FORBID_EXIT_OP_REASON_0 == gExitOpInfo.opReason)
		{
			gExitOpInfo.opStatus = PERMIT_EXIT_OP_STATUS;
		}
		else
		{
			gExitOpInfo.opStatus = FORBID_EXIT_OP_STATUS;
		}

		if (PERMIT_EXIT_OP_STATUS == gExitOpInfo.opStatus)
		{
			/** 启动计时 */
			gExitOpInfo.curTimeout = 0u;
		}
		else
		{
			/** 终止计时,此周期不进行重置参数 */
			gExitOpInfo.curTimeout = gExitOpInfo.maxTimeout;
		}
	}
	else
	{
		/** 再次收到首次请求，走超时重置参数*/
		rtn = 0xffu;
	}

	return rtn;
}

/**
* @brief 再次退出运营处理
* @param[in] 无
* @param[out] 无
* @return 无
* @note 无
*/
static UINT8 Deploy_SecondReqHandle(void)
{
	UINT8 rtn = 0u;

	if ((EXIT_OP_FIRST_REQUEST == gExitOpInfo.inputMsgType) &&
		(MSG_REFRESH == gSecondReqInfo.refreshFlag) &&
		(PERMIT_EXIT_OP_STATUS == gExitOpInfo.opStatus))
	{
		gExitOpInfo.inputMsgType = EXIT_OP_SECOND_REQUEST;

		if (FORBID_EXIT_OP_REASON_0 != gExitOpInfo.opReason)
		{
			gExitOpInfo.opStatus = FORBID_EXIT_OP_STATUS;
		}
		else
		{
			if ((gExitOpInfo.boardType == gSecondReqInfo.boardType) &&
				(gExitOpInfo.chanelID == gSecondReqInfo.chanelID))
			{
				if (gExitOpInfo.ReplytTime == gSecondReqInfo.firstReplyTime)
				{
					gExitOpInfo.opStatus = PERMIT_EXIT_OP_STATUS;
					gExitOpInfo.exitOperateStatus = EXIT_OP_STATUS;
				}
				else
				{
					gExitOpInfo.opStatus = FORBID_EXIT_OP_STATUS;
					gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_3;
				}
			}
			else
			{
				gExitOpInfo.opStatus = FORBID_EXIT_OP_STATUS;
				gExitOpInfo.opReason = FORBID_EXIT_OP_REASON_2;
			}
		}

		/** 更新时间戳 */
		gExitOpInfo.ReplytTime = gExitOpInfo.innerTime;
		gExitOpInfo.recvLastRequestTimestamp = gSecondReqInfo.secondRequstTime;

		gExitOpInfo.outputMsgType = EXIT_OP_SECOND_REPLY;

		AIMPrinf(AIM_LOG_FATAL, "Sec_opReason: %d.\n", gExitOpInfo.opReason);

		/** 终止计时,此周期不进行重置参数 */
		gExitOpInfo.curTimeout = gExitOpInfo.maxTimeout;
	}
	else
	{
		/** 先收到再次请求，走超时重置参数**/
		gExitOpInfo.curTimeout = gExitOpInfo.maxTimeout;
		rtn = 0xffu;
	}

	return rtn;
}



/**
 * @brief 退出运营处理
 * @param[in] 无
 * @param[out] 无
 * @return 无
 * @note 无
 */
extern void Deploy_ExitOperationHandle(void)
 {	
	UINT8 needTimeOutProcess = 0u;
	gExitOpInfo.innerTime++;
	gExitOpInfo.outputMsgType = EXIT_OP_DEFAULT;


	AIMPrinf(AIM_LOG_FATAL, "refreshFlag:%x-%x ,\n", gFirstFReqInfo.refreshFlag, gSecondReqInfo.refreshFlag);

	if (((MSG_REFRESH == gFirstFReqInfo.refreshFlag) && (MSG_REFRESH == gSecondReqInfo.refreshFlag)) ||
	    ((MSG_NO_REFRESH == gFirstFReqInfo.refreshFlag) && (MSG_NO_REFRESH == gSecondReqInfo.refreshFlag)))
	{
		needTimeOutProcess = 0xffu;
	}
	else if (MSG_REFRESH == gFirstFReqInfo.refreshFlag)
	{
		needTimeOutProcess = Deploy_FirstReqHandle();
	}
	else if (MSG_REFRESH == gSecondReqInfo.refreshFlag)
	{
		needTimeOutProcess = Deploy_SecondReqHandle();
	}
	else
	{
		needTimeOutProcess = 0xffu;
	}

	if (0xffU == needTimeOutProcess)
	{
		if (gExitOpInfo.curTimeout < gExitOpInfo.maxTimeout)
		{
			gExitOpInfo.curTimeout++;
		}
		else
		{
			/** 未启动计时，或者超时 */
			ResetInitParam();
		}
	}
	else
	{
		/** 无需处理 */
	}

	/* 打印内存存储 */
	AIMPrinf(AIM_LOG_FATAL, "AIM:Osta:%x,iType:%x,oType:%x,board:%d-%d,recvLastTime:%08x,rTime:%08x,timeout:%d-%d,innerTime:%d,Opsta:%x,opReason:%x,pfun:%x.\n",
		gExitOpInfo.exitOperateStatus, gExitOpInfo.inputMsgType, gExitOpInfo.outputMsgType, gExitOpInfo.boardType, gExitOpInfo.chanelID,
		gExitOpInfo.recvLastRequestTimestamp, gExitOpInfo.ReplytTime, gExitOpInfo.curTimeout, gExitOpInfo.maxTimeout, gExitOpInfo.innerTime,
		gExitOpInfo.opStatus, gExitOpInfo.opReason, gExitOpInfo.pfun);

	 /** 输入信息用完则清空 */
	(void)CommonMemSet(&gFirstFReqInfo, (UINT32)sizeof(EXIT_OP_FIRST_REQ_STRUCT),0u,  (UINT32)sizeof(EXIT_OP_FIRST_REQ_STRUCT));
	(void)CommonMemSet(&gSecondReqInfo, (UINT32)sizeof(EXIT_OP_SEC_REQ_STRUCT),0u,  (UINT32)sizeof(EXIT_OP_SEC_REQ_STRUCT));
	
 }



/**
 * @brief 输出组包处理
 * @param[in] UINT16 maxLen,输出报文存储空间
 * @param[out] UINT8* dataBuf,输出报文起始地址
 * @return 0 处理失败；非0 成功
 * @note 
 */
extern UINT16 Deploy_PackToAIMInfo(UINT8* dataBuf,UINT16 maxLen)
 {
	UINT16 ret = 0u;

	switch(gExitOpInfo.outputMsgType)
	{	
		case EXIT_OP_FIRST_REPLY:
			ret = PackExitOpFirstReply(dataBuf,maxLen);
			break;
		case EXIT_OP_SECOND_REPLY:
			ret = PackExitOpSecondReply(dataBuf,maxLen);
			break;
		default:
			/*不处理*/
			break;
	}

	return ret;
 }


 /**
 * @brief 拷贝跟随数据
 * @param[out] UINT8 *pDataBuff 跟随数据的存储地址指针
 * @param[in] UINT32 curIndex 跟随数据的索引地址
 * @return 跟随数据的长度
 * @note 无
 */
extern UINT32 Deploy_GetTransferData(OUT UINT8 *pDataBuff,UINT32 curIndex)
{
	/*- 局部变量定义 */
	UINT32 ret = curIndex;
	UINT32 copyIndex = curIndex;

	if (NULL == pDataBuff)
	{
		/** 入口参数错误 */
	}
	else
	{
		/** 模块标识*/
		pDataBuff[copyIndex++] = (UINT8)'D';
		pDataBuff[copyIndex++] = (UINT8)'e';
		pDataBuff[copyIndex++] = (UINT8)'p';
		pDataBuff[copyIndex++] = (UINT8)'l';
		pDataBuff[copyIndex++] = (UINT8)'o';
		pDataBuff[copyIndex++] = (UINT8)'y';

		pDataBuff[copyIndex++] = gExitOpInfo.exitOperateStatus;

		ret = copyIndex;
	}
	
	return ret;
}

/**
 * @brief 设置跟随数据
 * @param[in] const UINT8 *pDatabuff 跟随数据的存储地址指针
 * @param[in] UINT32 curIndex 跟随数据的索引地址
 * @param[in] UINT32 len 跟随数据的长度
 * @return 截取数据索引
 * @note 
 */
extern UINT32 Deploy_SetTransferData(IN const UINT8 *pDatabuff,UINT32 curIndex)
{
	UINT32 ret = curIndex;
	UINT32 setIndex = curIndex;
	UINT8 modelFlag[6] = {0u};

	if (NULL == pDatabuff)
	{
		/** 入口参数错误 */
	}
	else
	{
		/** 模块标识 */
		modelFlag[0] = pDatabuff[setIndex++];
		modelFlag[1] = pDatabuff[setIndex++];
		modelFlag[2] = pDatabuff[setIndex++];
		modelFlag[3] = pDatabuff[setIndex++];
		modelFlag[4] = pDatabuff[setIndex++];
		modelFlag[5] = pDatabuff[setIndex++];

		if (((UINT8)'D' == modelFlag[0]) && ((UINT8)'e' == modelFlag[1]) && ((UINT8)'p' == modelFlag[2]) &&
		((UINT8)'l' == modelFlag[3]) && ((UINT8)'o' == modelFlag[4]) && ((UINT8)'y' == modelFlag[5]))
		{
			gExitOpInfo.exitOperateStatus = pDatabuff[setIndex++];

			ret = setIndex;
		}
		else
		{
			/** 跟随数据错误 */
		}
	}

	return ret;
}


 /**
  * @brief 获取退出运营状态
  * @param[in] 无
  * @param[out] 无
  * @return EXIT_OP_STATUS 退出运营；STAY_OP_STATUS 处于运营
  * @note 
  */
extern UINT8 Deploy_GetExitOperateStatus(void)
{
	return gExitOpInfo.exitOperateStatus;
}


/**
* @brief 输入板卡ID与本地板卡ID一致性检查
* @param[in] localboardID 板卡ID
* @param[out] 无
* @return 0x55一致且有效   0xaa输入无效或比较不一致
*/
static UINT8 Deploy_CheckBoardID(UINT8 boardID_in)
{
	UINT8 retval = 0xaaU;

	UINT8 localBoardId = 0U;
#if (kPLATFORM==kVXWORKS)
	localBoardId=MSCP_GetBoardID();
	if ((1U == localBoardId) && (0xA0U == boardID_in))
	{
		/*板卡A系*/
		retval = 0x55;
	}
	else if ((2U == localBoardId) && (0x0BU == boardID_in))
	{
		/*板卡B系*/
		retval = 0x55;
	}
	else
	{
		retval = 0xaa;
	}
#endif
	return retval;
}