/********************************************************
*
* 文 件 名： EnvelopeManageAPI.c
* 版权说明： 北京交控科技有限公司
* 创建时间： 2022-04-15
* 作    者： 联锁组
* 功能描述： 包络应用程序接口
* 修改记录：
*
********************************************************/
#include "EnvelopeManageAPI.h"
#include "EnvelopeManage.h"
#include "ELMDataPrepare.h"
#include "EnvelopeLogicProcess.h"
#include "../DataManage/DeviceDataManage.h"
#include "WholeLineScreenAPI.h"
#include "../AxisSort/AxisSort.h"

/*================================静态函数声明区==============================*/
static UINT8 elm_InitEnvelopeInOC(void);     /* 初始化OC集中区内的所有计轴为隐藏车包络 */
static s_TRAIN_ENVELOPE_ID CTTrainEnvelope;  /*CT列车包络*/
static s_TRAIN_ENVELOPE_ID SleepTrainEnvelope; /*休眠车包络信息 */
static s_TRAIN_ENVELOPE_ID FaultTrainEnvelope; /*故障车包络信息 */

/**
 * @brief 静态函数：初始化OC集中区内的所有计轴为隐藏车包络
 * @return CI_SUCCESS 上电初始化成功
 *         CI_ERROR   上电初始化失败
 * @note 无
 */
static UINT8 elm_InitEnvelopeInOC(void)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;                          /*函数返回值*/
	UINT8 funFlag = CI_ERROR;                      /*函数执行返回值*/
	UINT16 cycle = 0u;
	UINT32 errorCode = 0u;                         /*错误码*/
	UINT16 acCnt = 0u;                             /*OC范围内所有的计轴区段数量*/
	const UINT16 *pACIdbuff = NULL;        /** 计轴ID数值缓存 */

	/** 获取OC范围内所有的计轴区段数组 */
	acCnt = elm_PrepareACBuffIndexs(&pACIdbuff);

	if (0u == acCnt)
	{
		/** 查询失败，OC范围内不可能不存在计轴区段 */
		errorCode = errorCode + 0x08000000u;
	}
	else
	{
		/** 遍历OC集中区所有的计轴区段*/
		for (cycle = 0u; cycle < acCnt; cycle++)
		{
			/*- 在占用无其他包络的计轴上添加UKT包络 */
			funFlag = elm_AddUKTEnvelopeInAC(pACIdbuff[cycle]);
			ASSERT_BREAK(CI_ERROR == funFlag,errorCode,0x04000000u);
		}
	}

	/** 设置函数返回值*/
	ASSERT_SETRET(0u == errorCode,ret,CI_SUCCESS,CI_ERROR);	

	/** 函数返回*/
	return ret;		
}



/**
 * @brief 对外接口：列车包络管理模块上电初始化
 * @return CI_SUCCESS 上电初始化成功
 *         CI_ERROR   上电初始化失败
 * @note OC上电时
 */
UINT8 elm_Init(void)
{
	/*- 局部变量定义*/
	UINT8 ret = CI_ERROR;
	UINT32 errorCode = 0u;

	/** 初始列车占用的包络存储空间 */
	ret = elm_InitEnvelope();
	ASSER_ERROR(CI_ERROR == ret,errorCode,0x80000000u);

	/** 初始化计轴关联的包络映射表*/
	ret = elm_InitACRelEnvelopeMap();
	ASSER_ERROR(CI_ERROR == ret,errorCode,0x40000000u);

	/** 初始化列车关联的包络映射表*/
	ret = elm_InitTrainRelEnvelopeMap();
	ASSER_ERROR(CI_ERROR == ret,errorCode,0x20000000u);

	/** 初始化OC集中区内的所有计轴为隐藏车包络*/
	ret = elm_InitEnvelopeInOC();
	ASSER_ERROR(CI_ERROR == ret,errorCode,0x10000000u);

	/** 初始化计轴诊断*/
	ret = aam_Init();
	ASSER_ERROR(CI_ERROR == ret,errorCode,0x08000000u);

	/** 判读初始化是否执行成功*/
	if (0u == errorCode)
	{
		/** 设置包络可正常工作 */
		elm_SetELMWorkFlag(ELM_WORK_OK);
		ret = CI_SUCCESS;
	}
	else
	{
		/** 记录错误信息--打印规范暂定*/
		elm_SetELMWorkFlag(ELM_WORK_ERROR);
		ret = CI_ERROR;
	}

	return ret;
}


/**
 * @brief 对外接口：列车包络管理模块主入口函数
 * @param[in] 
 * @param[out]
 * @return 
 * @note 列车包络管理需要处理CT车包络、UT车包络及隐藏车包络
 *       隐藏车包络即计轴区段无通信车包络或者UT车包络，也无法判断为计轴器故障，则该计轴区段为隐藏车包络
 *       CT车包络即有通信列车安全位置形成的包络
 *       UT车包络即丢失通信车后的列车包络
 */
void elm_MainProcess(void)
{
	UINT8 workFlag = ELM_WORK_ERROR;
	UINT8 funRtn = CI_ERROR;

	ELM_LOG_TIME(ELM_LOG_FATAL,"\n==================ElM Start at %d=======================",Get2oo2CurCycleNum());
	ELM_LOG(ELM_LOG_FATAL,"Process info:\n");

	/** 包络管理模块可正常处理标志位 */
	workFlag = elm_GetELMWorkFlag();

	/** 如果包络管理模块不可正常处理，包络模块重新初始化 */
	if (ELM_WORK_ERROR == workFlag)
	{
		ELM_LOG_LOC(ELM_LOG_ERROR,"Last perid ELM error,need to reset ELM.")
		/** 重新初始化包络 */
		funRtn = elm_Init();
	}
	else
	{
		/** 计轴故障模块诊断 */
		aam_MainProcess();

		/** 刷新相邻OC范围内的包络信息 */
		elm_RefreshNextOCEnvelope();

		/** UKT包络跟踪处理 */
		elm_UKTEnvelopeTrack();

		/** 全线免筛允许判断 */
		wls_MainProcess();

		/** 全线免筛处理 */
		elm_WLScreenProcess();

		/** CT车包络跟踪处理 */
		elm_CTEnvelopeTrack();

		/** UCT车包络跟踪处理 */
		elm_UCTEnvelopeTrack();

		/*列车位置监督状态处理（置于UCT处理之后，解决AG存在UCT包络无法清除BG列车监督问题）*/
		TrainPosMonitorProc();

		/*虚拟筛选标志监督和清除*/
		elm_VirScreenPassMonitor();

		/** 列车筛选 */
		elm_TrainScreen();

		/** 根据占用清除UKT包络 */
		elm_ProcessFreeAC();

		/** 包络安全防护*/
		elm_SafeProtectProcess();

		/** 刷新列车控制状态 */
		elm_RefreshTrainConstrolStatus();

		/** 包络管理模块可正常处理标志位 */
		workFlag = elm_GetELMWorkFlag();

		/** 如果包络管理模块不可正常处理，包络模块重新初始化 */
		if (ELM_WORK_ERROR == workFlag)
		{
			ELM_LOG_LOC(ELM_LOG_ERROR,"ELM error,need to reset ELM.")

			/** 重新初始化包络 */
			funRtn = elm_Init();
		}
		else
		{
			/** 处理正确，不处理*/
			funRtn = CI_SUCCESS;
		}
	}

	if (CI_SUCCESS == funRtn)
	{
		/** 所有处理成功，无需防护 */
	}
	else
	{
		/** 包络重置防护失败，宕机处理*/
		SetPlatOverFlag();
		ASSER_DEBUG(CI_ERROR == funRtn,ELM_LOG_LOC(ELM_LOG_ERROR,"Envelope reset error to shutdown."));
	}

	/** 维护信息打印*/
	elm_MaintenanceInfo();

	ELM_LOG_TIME(ELM_LOG_FATAL,"\n==================ElM END=======================")
}


/**
 * @brief 对外接口：通过计轴ID查找计轴区段上的包络信息
 * @param[in] UINT16 acID
 * @param[out] EnvelopeStruct envelopeInfo[] 计轴区段上的包络信息
 * @return 0 计轴区段上不存在包络
           非0且小于SECTION_REL_ENVELOPE_SUM_MAX 计轴区段上包络数量
		   SECTION_REL_ENVELOPE_SUM_MAX，函数执行错误
 * @note 无
 */
UINT8 elm_GetEnvelopeInAC(UINT16 acID,INOUT EnvelopeStruct envelopeInfo[SECTION_REL_ENVELOPE_SUM_MAX])
{

	return elm_CopyEnvelopeInAC(acID,envelopeInfo);
}

/**
 * @brief 对外接口：通过计轴数组ID查找计轴区段上的包络ID信息
 * @param[in] UINT16 acID
 * @param[out] UINT16 envelopeIDs[] 计轴区段上的包络信息
 * @return 0 计轴区段上不存在包络
           非0且小于SECTION_REL_ENVELOPE_SUM_MAX 计轴区段上包络数量
		   其他，非法返回，函数执行错误
 * @note 
 */
UINT8 elm_GetEnvelopeIDsInAC(UINT16 acID,INOUT UINT16 envelopeIDs[SECTION_REL_ENVELOPE_SUM_MAX])
{
	UINT8 ret = SECTION_REL_ENVELOPE_SUM_MAX;
	UINT16 tmpACIndex = 0u;
	
	/** 入口参数合法性校验*/
	if (NULL == envelopeIDs)
	{
		/** 入口参数错误*/
	}
	else
	{
		/** 通过计轴ID获取计轴索引 */
		tmpACIndex = elm_PrepareACIndex(acID);

		/** 获取计轴上的包络ID */
		ret = elm_GetACRelEnvelopeCnt(tmpACIndex,envelopeIDs);
	}

	return ret;	
}


/**
 * @brief 对外接口：获取线路所有的包络信息
 * @param[out] UINT16 envelopeID[ENVELOPE_SUM_MAX] 包络ID
 * @return 0 不存在包络
           0 ~ ENVELOPE_SUM_MAX-1 包络数量
		   ENVELOPE_SUM_MAX 非法
 * @note 
 */
UINT16 elm_GetAllEnvelope(OUT UINT16 envelopeID[ENVELOPE_SUM_MAX])
{
	/*- 局部变量定义 */
	UINT16 ret = ENVELOPE_SUM_MAX;
	UINT16 cycle = 0u;
	UINT16 envelopeCnt = 0u;
	UINT8 vaildFlag = ENVELOPE_UNEXIT;

	/** 判断入口参数是否正确 */
	if (NULL == envelopeID)
	{
		/** 入口函数错误 */
	}
	else
	{
		/** 遍历所有包络 */
		for (cycle = 1u;cycle < ENVELOPE_SUM_MAX; cycle++)
		{
			/** 获取空间使用标志*/
			vaildFlag = elm_IsEnvelopeExit(cycle);

			/** 判断包络是否有效 */
			if (ENVELOPE_EXIT == vaildFlag)
			{
				/** 缓存包络ID */
				envelopeID[envelopeCnt++] = cycle; 
			}
			else
			{
				/** 无需缓存*/
			}
		}

		/** 函数返回*/
		ret = envelopeCnt;
	}

	return ret;
}

/**
* 功能：通信车、休眠车、故障车列车包络分类更新存储
* 输入参数： 无
* 全局变量：static s_TRAIN_ENVELOPE_ID CTTrainEnvelope;  CT列车包络
* static s_TRAIN_ENVELOPE_ID SleepTrainEnvelope;  休眠车包络信息
* static s_TRAIN_ENVELOPE_ID FaultTrainEnvelope; 休眠车包络信息 *
* fan 2024.06.12
*/
void UpdateTrainEnvelope(void)
{
	/*- 局部变量定义 */
	UINT16 cycle = 0u;
	UINT16 dwCTEnvlpCnt = 0U;
	UINT16 dwFaultTrainEnvlpCnt = 0U;
	UINT16 dwSleepTrainEnvlpCnt = 0U;
	UINT8 vaildFlag = ENVELOPE_UNEXIT;
	const EnvelopeStruct* PTempEnvelope = NULL;
	UINT8 chLocalId = 0u;
	UINT16 wOrgnTioc = 0u;
	UINT16 wTmpTioc = 0u;
	UINT16 wTmpLinkId = 0U;
	UINT16 wOrgnLinkId = 0u;
	UINT8 chSleepState = 0u;

	/*清空存储的包络信息*/
	CTTrainEnvelope.ELNum = 0U;
	SleepTrainEnvelope.ELNum = 0U;
	FaultTrainEnvelope.ELNum = 0U;
	(void)CommonMemSet(CTTrainEnvelope.TrainEnveLopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX), 0U, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX));
	(void)CommonMemSet(SleepTrainEnvelope.TrainEnveLopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX), 0U, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX));
	(void)CommonMemSet(FaultTrainEnvelope.TrainEnveLopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX), 0U, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX));

	chLocalId = GetSystemParaLocalCiId();
	/*遍历所有包络 */
	for (cycle = 1u; cycle < ENVELOPE_SUM_MAX; cycle++)
	{
		/** 获取空间使用标志*/
		vaildFlag = elm_IsEnvelopeExit(cycle);

		/** 判断包络是否有效 */
		if (ENVELOPE_EXIT == vaildFlag)
		{
			/* 分类缓存包络ID */
			PTempEnvelope = elm_GetEnvelopeInfoPtr(cycle);
			if (NULL != PTempEnvelope)
			{
				wTmpLinkId = PTempEnvelope->endPos.Lnk;
				wOrgnLinkId = PTempEnvelope->startPos.Lnk;


				wTmpTioc = GetLinkManageTiocById(wTmpLinkId);
				wOrgnTioc = GetLinkManageTiocById(wOrgnLinkId);

				chSleepState = GetTrainSleepState(PTempEnvelope->trainID[0]);
				if ((wTmpTioc == chLocalId) && (wOrgnTioc == chLocalId))
				{
					if ((TYPE_CT_ENVELOPE == PTempEnvelope->envelopeType)
						&& (TRAIN_SLEEP_YES == chSleepState))
					{
						SleepTrainEnvelope.TrainEnveLopeID[dwSleepTrainEnvlpCnt++] = cycle;
					}
					else if (TYPE_CT_ENVELOPE == PTempEnvelope->envelopeType)
					{
						CTTrainEnvelope.TrainEnveLopeID[dwCTEnvlpCnt++] = cycle;
					}
					else
					{
						/*非通信车均按照故障车发送*/
						FaultTrainEnvelope.TrainEnveLopeID[dwFaultTrainEnvlpCnt++] = cycle;
					}				
				}
				else
				{
					; /*不处理*/
				}
			}
		}
		else
		{
			; /** 无需缓存*/
		}
	}
	/*记录包络数量*/
	CTTrainEnvelope.ELNum = dwCTEnvlpCnt;
	SleepTrainEnvelope.ELNum = dwSleepTrainEnvlpCnt;
	FaultTrainEnvelope.ELNum = dwFaultTrainEnvlpCnt;
}

/**
* 功能：获取通信车包络
* @param[out] UINT16 envelopeID[ENVELOPE_SUM_MAX] 包络ID
* 全局变量：static s_TRAIN_ENVELOPE_ID CTTrainEnvelope;  CT列车包络
* 返回值： 0 ~ ENVELOPE_SUM_MAX-1 包络数量 ENVELOPE_SUM_MAX 非法
* fan 2024.06.12
*/
UINT16 elm_GetCTEnvelope(OUT UINT16 envelopeID[ENVELOPE_SUM_MAX])
{
	UINT16 ret = ENVELOPE_SUM_MAX;
	if (NULL != envelopeID)
	{
		ret = CTTrainEnvelope.ELNum;
		(void)CommonMemCpy(envelopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX), (const)CTTrainEnvelope.TrainEnveLopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX));
	}
	else
	{
		; /*入参非法*/
	}
	return ret;
}

/**
* 功能：获取休眠车包络
* @param[out] UINT16 envelopeID[ENVELOPE_SUM_MAX] 包络ID
* 全局变量：static s_TRAIN_ENVELOPE_ID SleepTrainEnvelope;  CT列车包络
* 返回值： 0 ~ ENVELOPE_SUM_MAX-1 包络数量 ENVELOPE_SUM_MAX 非法
* fan 2024.06.12
*/
UINT16 elm_GetSleepEnvelope(OUT UINT16 envelopeID[ENVELOPE_SUM_MAX])
{
	UINT16 ret = ENVELOPE_SUM_MAX;
	if (NULL != envelopeID)
	{
		ret = SleepTrainEnvelope.ELNum;
		(void)CommonMemCpy(envelopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX), (const)SleepTrainEnvelope.TrainEnveLopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX));
	}
	else
	{
		; /*入参非法*/
	}
	return ret;
}

/**
* 功能：获取故障车包络
* @param[out] UINT16 envelopeID[ENVELOPE_SUM_MAX] 包络ID
* 全局变量：static s_TRAIN_ENVELOPE_ID FaultTrainEnvelope;  CT列车包络
* 返回值： 0 ~ ENVELOPE_SUM_MAX-1 包络数量 ENVELOPE_SUM_MAX 非法
* fan 2024.06.12
*/
UINT16 elm_GetFaultEnvelope(OUT UINT16 envelopeID[ENVELOPE_SUM_MAX])
{
	UINT16 ret = ENVELOPE_SUM_MAX;
	if (NULL != envelopeID)
	{
		ret = FaultTrainEnvelope.ELNum;
		(void)CommonMemCpy(envelopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX), (const)FaultTrainEnvelope.TrainEnveLopeID, (UINT32)(sizeof(UINT16)*ENVELOPE_SUM_MAX));
	}
	else
	{
		; /*入参非法*/
	}
	return ret;
}

/**
 * @brief 对外接口：通过ID获取包络信息
 * @param[in] UINT16 envelopeID 包络ID
 * @return 非空 查询正确，包络信息
           NULL 查询错误
 * @note 
 */
const EnvelopeStruct* elm_GetEnvelopeInfoByID(UINT16 envelopeID)
{
	return elm_GetEnvelopeInfoPtr(envelopeID);
}


/**
 * @brief 对外接口：通过列车ID获取关联的包络ID
 * @param[in] UINT16 trainID 列车ID
 * @return 非空 查询正确，包络信息
           NULL 查询错误
 * @note 注：只返回CT包络
 */
const EnvelopeStruct* elm_GetEnvelopeInfoByTrainID(UINT16 trainID)
{
	const EnvelopeStruct* ret = NULL;
	UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/
	UINT16 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/

	/** 通过列车ID获取列车关联的包络ID*/
	relEnvelopeCnt = elm_GetRelELIdByTrainIDAndType(TYPE_CT_ENVELOPE,trainID,relEnvelopeID);
	
	if (1u == relEnvelopeCnt)
	{
		ret = elm_GetEnvelopeInfoPtr(relEnvelopeID[0u]);
	}
	else
	{
		/** 不处理 */
	}
	return ret;
}


/**
 * @brief 对外接口：通过包络ID转换成接口组包需要的包络信息 
 * @param[in] UINT16 envelopeID 包络ID
 * @param[out] InfEnvelopeStruct *pInfEnvelope 转换的接口包络信息
 * @return CI_SUCCESS 获取成功
           CI_ERROR 获取失败
 * @note 如果接口获取失败，需要导向安全侧处理，通知所有列车切成感知行车
 */
UINT8 elm_ConvertEnvelopeInfo(UINT16 envelopeID,IN InfEnvelopeStruct *pInfEnvelope)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	const EnvelopeStruct* PTempEnvelope = NULL;

	/** 通过包络ID获取包络信息 */
	PTempEnvelope = elm_GetEnvelopeInfoPtr(envelopeID);

	/** 判读入口参数是否正确 */
	if ((NULL != PTempEnvelope) && (NULL != pInfEnvelope))
	{
		/*- 转换成接口信息 */
		pInfEnvelope->envelopeType = PTempEnvelope->envelopeType;
		pInfEnvelope->id = PTempEnvelope->id;
		pInfEnvelope->startPos = PTempEnvelope->startPos;
		pInfEnvelope->endPos = PTempEnvelope->endPos;
		pInfEnvelope->suspicHead = (0u != PTempEnvelope->headTrainID) ? (UINT8)CI_IVOC_HEAD_SCREEN_UNKNOW : (UINT8)CI_IVOC_HEAD_SCREEN_PASS;
		pInfEnvelope->suspicTail = (0u != PTempEnvelope->tailTrainID) ? (UINT8)CI_IVOC_TAIL_SCREEN_UNKNOW : (UINT8)CI_IVOC_TAIL_SCREEN_PASS;
		pInfEnvelope->trianCnt = PTempEnvelope->trianCnt;
		(void)CommonMemCpy(pInfEnvelope->trainID, (UINT32)sizeof(pInfEnvelope->trainID), PTempEnvelope->trainID, (UINT32)sizeof(PTempEnvelope->trainID));
		ret = CI_SUCCESS;
	}
	else
	{
		/** 入口参数错误 */
	}

	/** 函数返回 */
	return ret;
}


/**
 * @brief 对外接口：跟随包络管理模块数据
 * @param[out] UINT8 *pDataBuff 跟随数据的存储地址指针
 * @param[in] UINT32 curIndex 跟随数据的索引地址
 * @return 跟随数据的长度
 * @note 无
 */
UINT32 elm_GetTransferData(OUT UINT8 *pDataBuff,UINT32 curIndex)
{
	/*- 局部变量定义 */
	UINT32 ret = curIndex;
	UINT32 copyIndex = curIndex;
	UINT16 cycle = 0u;
	UINT16 envelopeCnt = 0u;
	UINT32 envelopeCntIndex = 0u;
	UINT16 envelopeID[ENVELOPE_SUM_MAX] = {0u};
	const EnvelopeStruct *pEnvelope = NULL;
	UINT32 errorCode = 0u;
	UINT32 acRelEnvelpeCntIndex = 0u;
	UINT16 copyAcCnt = 0u;
	UINT16 trainRelEnvelopeCnt = 0u;
	UINT8 acRelEnvelpeCnt = 0u;
	UINT16 acRelenvelopeId[SECTION_REL_ENVELOPE_SUM_MAX] = {0u};
	const TrainMapStruct * relEnvelopePtr = NULL;

	if (NULL != pDataBuff)
	{
		/** 设置模块标识 */
		pDataBuff[copyIndex++] = (UINT8)'E';
		pDataBuff[copyIndex++] = (UINT8)'L';
		pDataBuff[copyIndex++] = (UINT8)'M';


		/** 获取模块是否可正常运行标志 */
		pDataBuff[copyIndex++] = elm_GetELMWorkFlag();

		/** 获取包络数量 */
		envelopeCnt = elm_GetAllEnvelope(envelopeID);
		envelopeCntIndex = copyIndex;
		copyIndex += 2u;

		for (cycle = 0u;cycle < envelopeCnt;cycle++)
		{
			/** 获取包络指针*/
			pEnvelope = elm_GetEnvelopeInfoPtr(envelopeID[cycle]);

			/** 判断指针是否为空 */
			ASSERT_BREAK(NULL == pEnvelope,errorCode,0x40000000u)

			/** 包络存在标识*/
			pDataBuff[copyIndex++] = pEnvelope->exitFlag;

			/** 包络类型 */
			pDataBuff[copyIndex++] = pEnvelope->envelopeType;

			/** 包络标识 */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16),&(pEnvelope->id), (UINT32)sizeof(UINT16));
			copyIndex += (UINT32)sizeof(UINT16);

			/** 包络前端列车ID */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16),&(pEnvelope->headTrainID), (UINT32)sizeof(UINT16));
			copyIndex += (UINT32)sizeof(UINT16);

			/** 包络后端列车ID */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16),&(pEnvelope->tailTrainID), (UINT32)sizeof(UINT16));
			copyIndex += (UINT32)sizeof(UINT16);
			
			/** 始端位置 */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(LOD_STRU),&(pEnvelope->startPos), (UINT32)sizeof(LOD_STRU));
			copyIndex += (UINT32) sizeof(LOD_STRU);

			/** 终端位置 */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(LOD_STRU),&(pEnvelope->endPos), (UINT32)sizeof(LOD_STRU));
			copyIndex += (UINT32)sizeof(LOD_STRU);

			/** 包络中包含的列车数量 */
			pDataBuff[copyIndex++] = pEnvelope->trianCnt;

			/** 包络中包含的列车ID */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)(sizeof(UINT16)*pEnvelope->trianCnt),&(pEnvelope->trainID[0]), (UINT32)(sizeof(UINT16)*pEnvelope->trianCnt));
			copyIndex += (UINT32)sizeof(UINT16)*pEnvelope->trianCnt;

			/** 包络中包含的列车激活端 */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)(sizeof(UINT8)*pEnvelope->trianCnt),&(pEnvelope->ACTPort[0]), (UINT32)(sizeof(UINT8)*pEnvelope->trianCnt));
			copyIndex += (UINT32)sizeof(UINT8)*pEnvelope->trianCnt;

			/** 包含的AC数量 */
			pDataBuff[copyIndex++] = pEnvelope->ACCnt;

			/** 包络中包含的列车ID */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)(sizeof(UINT16)*pEnvelope->ACCnt),&(pEnvelope->ACID[0]), (UINT32)(sizeof(UINT16)*pEnvelope->ACCnt));
			copyIndex += (UINT32)sizeof(UINT16)*pEnvelope->ACCnt;

			/** 包络UCT转UKT起始时间 */
			(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT32), &(pEnvelope->dwUCTToUKTStartCycNum), (UINT32)sizeof(UINT32));
			copyIndex += (UINT32)sizeof(UINT32);
		}

		/** 判断是否处理正确 */
		if (0u == errorCode)
		{
			/** 设置包络数量 */
			(void)CommonMemCpy(&pDataBuff[envelopeCntIndex], (UINT32)sizeof(UINT16), &envelopeCnt , (UINT32)sizeof(UINT16));

			/** 设置计轴映射包络表数量 */
			acRelEnvelpeCntIndex = copyIndex;
			copyIndex += 2u; 

			/** 拷贝计轴关联的包络映射表 */
			for (cycle = 1u; cycle < AXIS_SECTION_SUM_MAX;cycle++)
			{
				/** 通过计轴索引获取计轴关联的包络信息 */
				acRelEnvelpeCnt = elm_GetACRelEnvelopeCnt(cycle,acRelenvelopeId);

				/** 判断是否查询错误 */
				ASSERT_BREAK(SECTION_REL_ENVELOPE_SUM_MAX == acRelEnvelpeCnt,errorCode,0x20000000u)

				/** 判断计轴上关联的包络是否存在，如果不存在则不拷贝*/
				if (0u == acRelEnvelpeCnt)
				{
					/** 计轴不关联包络，不进行拷贝 */
				}
				else
				{
					/** 计轴索引 */
					(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16),&cycle, (UINT32)sizeof(UINT16));
					copyIndex += (UINT32)sizeof(UINT16);

					/** 计轴上的包络信息 */
					pDataBuff[copyIndex++] = acRelEnvelpeCnt;

					/** 计轴映射的包络ID */
					(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)(sizeof(UINT16)*acRelEnvelpeCnt),&acRelenvelopeId[0], (UINT32)(sizeof(UINT16)*acRelEnvelpeCnt));
					copyIndex += (UINT32)(sizeof(UINT16)*acRelEnvelpeCnt);

					/** 包络数量加1*/
					copyAcCnt++;
				}
			}

			/** 判断计轴映射表是否拷贝成功 */
			if (0u == errorCode)
			{
				/** 设置计轴映射表数量 */
				(void)CommonMemCpy(&pDataBuff[acRelEnvelpeCntIndex], (UINT32)sizeof(UINT16), &copyAcCnt , (UINT32)sizeof(UINT16));

				/** 设置列车映射包络表数量*/
				trainRelEnvelopeCnt = LINE_MAX_TRAIN;
				(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)sizeof(UINT16), &trainRelEnvelopeCnt , (UINT32)sizeof(UINT16));
				copyIndex += (UINT32)sizeof(UINT16);

				/** 拷贝列车关联的包络映射表 */
				for (cycle = 1u; cycle < LINE_MAX_TRAIN;cycle++)
				{
					/** 通过列车ID获取列车关联的包络 */
					relEnvelopePtr = elm_GetTrainRelEnvelopeMapPtr(cycle);
					ASSERT_BREAK(NULL == relEnvelopePtr,errorCode,0x10000000u);

					/** 拷贝列车关联的包络数量 */
					pDataBuff[copyIndex++] = relEnvelopePtr->envelopeCnt;

					/** 拷贝列车关联的包络信息 */
					(void)CommonMemCpy(&pDataBuff[copyIndex], (UINT32)(sizeof(UINT16) * relEnvelopePtr->envelopeCnt), &(relEnvelopePtr->envelopeId[0u]) , (UINT32)(sizeof(UINT16) * relEnvelopePtr->envelopeCnt));
					copyIndex += (UINT32)(sizeof(UINT16) * relEnvelopePtr->envelopeCnt);
				}

				if (cycle == LINE_MAX_TRAIN)
				{
					/** 拷贝计轴诊断索引*/
					copyIndex = aam_GetTransferData(pDataBuff,copyIndex);

					/** 设置返回值，即拷贝的数组索引值 */
					ret = copyIndex;
					ELM_LOG(ELM_LOG_FATAL,"info:ELM Transfer dataIndex:%d.dataLen:%d.\n",copyIndex,copyIndex - curIndex);
				}
				else
				{
					ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Transfer train id:%d rel envelope info error.",errorCode,cycle);
				}
			}
			else
			{
				ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Transfer acindex%d rel envelope info error.",errorCode,cycle);
			}
		}
		else
		{
			ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Transfer envelope info error.",errorCode);
		}
	}
	else
	{
		/** 入口参数不对，不进行拷贝，直接返回 */
		ASSER_ERROR(NULL == pDataBuff,errorCode,0x80000000u)
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Input info error.",errorCode);
	}
	return ret;
}

/**
 * @brief 对外接口：拷贝包络管理模块数据
 * @param[in] const UINT8 *pDatabuff 跟随数据的存储地址指针
 * @param[in] UINT32 curIndex 跟随数据的索引地址
 * @param[in] UINT32 len 跟随数据的长度
 * @return CI_ERROR 拷贝失败
           CI_SUCCESS 拷贝成功
 * @note 
 */
UINT32 elm_SetTransferData(IN const UINT8 *pDatabuff,UINT32 curIndex,UINT32 len)
{
	/*- 局部变量定义 */
	UINT32 ret = curIndex;
	UINT8 funRtn = CI_ERROR;
	UINT8 cycleELM = 0u;
	UINT32 setIndex = curIndex;
	UINT16 cycle = 0u;
	UINT16 envelopeCnt = 0u;
	EnvelopeStruct EnvelopeInfo = {0u}; 
	UINT32 errorCode = 0u;
	UINT16 copyAcCnt = 0u;
	UINT16 ACBuffIndex = 0u;
	UINT8 acRelEnvelpeCnt = 0u;
	UINT8 cycleEnvelpeId = 0u;
	UINT16 acRelenvelopeId = 0u;
	UINT16 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	UINT16 relEnvelopeID[TRAIN_IN_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/


	if ((NULL == pDatabuff) || (curIndex >= len))
	{
		/** 入口参数错误 */
		ASSER_ERROR(CI_ERROR == ret,errorCode,0x80000000u)
		ELM_LOG_LOC(ELM_LOG_ERROR,"errno:0x%08x info:Input info error,curindex:%d,len:%d.",errorCode,curIndex,len)
	}
	else
	{
		if ((UINT8)'E' == pDatabuff[setIndex])
		{
			setIndex++;
			if ((UINT8)'L' == pDatabuff[setIndex])
			{
				setIndex++;
				if ((UINT8)'M' == pDatabuff[setIndex])
				{
					setIndex++;
					/** 跟随ELM模块正常工作标志位 */
					elm_SetELMWorkFlag(pDatabuff[setIndex++]);

					/** 获取包络数量 */
					(void)CommonMemCpy(&envelopeCnt, (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
					setIndex += (UINT32)sizeof(UINT16);

					/** 先清空包络信息*/
					(void)elm_InitEnvelope();

					/** 跟随包络信息 */
					for (cycle = 0u; cycle < envelopeCnt; cycle++)
					{
						/** 清空缓存空间 */
						(void)CommonMemSet(&EnvelopeInfo, (UINT32)sizeof(EnvelopeStruct), 0, (UINT32)sizeof(EnvelopeStruct));

						/** 包络存在标识*/
						EnvelopeInfo.exitFlag = pDatabuff[setIndex++];

						/** 包络类型 */
						EnvelopeInfo.envelopeType = pDatabuff[setIndex++];

						/** 包络标识 */
						(void)CommonMemCpy(&(EnvelopeInfo.id), (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
						setIndex += (UINT32)sizeof(UINT16);

						/** 包络前端列车ID */
						(void)CommonMemCpy(&(EnvelopeInfo.headTrainID), (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
						setIndex += (UINT32)sizeof(UINT16);

						/** 包络后端列车ID */
						(void)CommonMemCpy(&(EnvelopeInfo.tailTrainID), (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
						setIndex += (UINT32)sizeof(UINT16);

						/** 始端位置 */
						(void)CommonMemCpy(&(EnvelopeInfo.startPos), (UINT32)sizeof(LOD_STRU), &pDatabuff[setIndex], (UINT32)sizeof(LOD_STRU));
						setIndex += (UINT32)sizeof(LOD_STRU);

						/** 终端位置 */
						(void)CommonMemCpy(&(EnvelopeInfo.endPos), (UINT32)sizeof(LOD_STRU), &pDatabuff[setIndex], (UINT32)sizeof(LOD_STRU));
						setIndex += (UINT32)sizeof(LOD_STRU);

						/** 包络中包含的列车数量 */
						EnvelopeInfo.trianCnt = pDatabuff[setIndex++];

						/** 包络中包含的列车ID */
						(void)CommonMemCpy(&(EnvelopeInfo.trainID[0]), (UINT32)(sizeof(UINT16)*EnvelopeInfo.trianCnt), &pDatabuff[setIndex], (UINT32)(sizeof(UINT16)*EnvelopeInfo.trianCnt));
						setIndex += (UINT32)(sizeof(UINT16)*EnvelopeInfo.trianCnt);

						/** 包络中包含的列车激活端 */
						(void)CommonMemCpy(&(EnvelopeInfo.ACTPort[0]), (UINT32)(sizeof(UINT8)*EnvelopeInfo.trianCnt), &pDatabuff[setIndex], (UINT32)(sizeof(UINT8)*EnvelopeInfo.trianCnt));
						setIndex += (UINT32)(sizeof(UINT8)*EnvelopeInfo.trianCnt);

						/** 包含的AC数量 */
						EnvelopeInfo.ACCnt = pDatabuff[setIndex++];

						/** 包络中包含的列车ID */
						(void)CommonMemCpy(&(EnvelopeInfo.ACID[0]), (UINT32)(sizeof(UINT16)*EnvelopeInfo.ACCnt), &pDatabuff[setIndex], (UINT32)(sizeof(UINT16)*EnvelopeInfo.ACCnt));
						setIndex += (UINT32)sizeof(UINT16)*EnvelopeInfo.ACCnt;

						/** 包络UCT转UKT起始时间 */
						(void)CommonMemCpy(&(EnvelopeInfo.dwUCTToUKTStartCycNum), (UINT32)sizeof(UINT32), &pDatabuff[setIndex], (UINT32)sizeof(UINT32));
						setIndex += (UINT32)sizeof(UINT32);
						
						/** 添加到包络缓存空间中 */
						funRtn = elm_SetEnvelopeByIndex(&EnvelopeInfo, EnvelopeInfo.id);

						/** 判断是否处理正确 */
						ASSERT_BREAK(CI_ERROR == funRtn, errorCode, 0x40000000u);
					}

					/** 判断跟随包络信息是否正确 */
					if (0u == errorCode)
					{
						/** 清空计轴关联包络映射表*/
						(void)elm_InitACRelEnvelopeMap();

						/** 获取跟随的计轴映射表数量 */
						(void)CommonMemCpy(&copyAcCnt, (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
						setIndex += 2u;

						/** 拷贝计轴关联的包络映射表 */
						for (cycle = 0u; cycle < copyAcCnt; cycle++)
						{
							/** 获取计轴数组索引 */
							(void)CommonMemCpy(&ACBuffIndex, (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
							setIndex += (UINT32)sizeof(UINT16);

							/** 获取计轴关联的包络个数 */
							acRelEnvelpeCnt = pDatabuff[setIndex++];

							/** 设置计轴关联的包络ID*/
							for (cycleEnvelpeId = 0u; cycleEnvelpeId < acRelEnvelpeCnt; cycleEnvelpeId++)
							{
								/** 获取包络ID */
								(void)CommonMemCpy(&acRelenvelopeId, (UINT32)sizeof(UINT16), &pDatabuff[setIndex], (UINT32)sizeof(UINT16));
								setIndex += (UINT32)sizeof(UINT16);

								/** 设置包络 */
								funRtn = elm_SetACRelEnvelopeMap(OP_ADD, ACBuffIndex, acRelenvelopeId);

								/** 判断是否处理正确 */
								ASSERT_BREAK(CI_ERROR == funRtn, errorCode, 0x40000000u);
							}

							/** 判断是否处理正确 */
							ASSERT_BREAK(cycleEnvelpeId != acRelEnvelpeCnt, errorCode, 0x20000000u);
						}

						/** 判读是否处理成功 */
						if (0u == errorCode)
						{
							/** 清空列车关联包络映射表*/
							(void)elm_InitTrainRelEnvelopeMap();

							/** 跳过2字节的列车数量 */
							setIndex += (UINT32)sizeof(UINT16);

							/** 设置列车关联的包络映射表 */
							for (cycle = 1; cycle < LINE_MAX_TRAIN; cycle++)
							{
								/** 清空缓存 */
								(void)CommonMemSet(&relEnvelopeID[0u], (UINT32)sizeof(relEnvelopeID), 0u, (UINT32)sizeof(relEnvelopeID));

								/** 获取列车关联的包络数量 */
								relEnvelopeCnt = pDatabuff[setIndex++];

								/** 获取列车关联的包络信息 */
								(void)CommonMemCpy(&relEnvelopeID[0u], (UINT32)(sizeof(UINT16) * relEnvelopeCnt), &pDatabuff[setIndex], (UINT32)(sizeof(UINT16) * relEnvelopeCnt));
								setIndex += (UINT32)sizeof(UINT16) * relEnvelopeCnt;

								/** 将列车序列添加到内存 */
								for (cycleELM = 0u; cycleELM < relEnvelopeCnt; cycleELM++)
								{
									funRtn = elm_SetTrainRelEnvelopeMap(OP_ADD, cycle, relEnvelopeID[cycleELM]);
									ASSERT_BREAK(CI_ERROR == funRtn, errorCode, 0x10000000u);
								}

								ASSERT_BREAK(relEnvelopeCnt != cycleELM, errorCode, 0x08000000u);
							}

							if (0u == errorCode)
							{
								/** 设置计轴诊断信息*/
								setIndex = aam_SetTransferData(pDatabuff, setIndex, len);

								/** 设置返回值 */
								ASSERT_SETRET(setIndex <= len, ret, setIndex, ret);
								ELM_LOG(ELM_LOG_FATAL, "info:ELM Set dataIndex%d.dataLen:%d.\n", setIndex, len);
							}
							else
							{
								/** 打印错误信息 */
								ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Set Train Rel Envelope Map info error.", errorCode);
							}

						}
						else
						{
							/** 打印错误信息 */
							ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Set ac Rel Envelope Map info error.", errorCode);
						}
					}
					else
					{
						/** 打印错误信息 */
						ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:Set envelope info error.", errorCode);
					}

				}
				else
				{
					/** 跟随数据类型错误 */
					ASSER_ERROR(CI_ERROR == ret, errorCode, 0x40000000u);
					ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:TransferData type:%c error.", errorCode, pDatabuff[curIndex]);
				}
			}
			else
			{
				/** 跟随数据类型错误 */
				ASSER_ERROR(CI_ERROR == ret, errorCode, 0x40000000u);
				ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:TransferData type:%c error.", errorCode, pDatabuff[curIndex]);
			}
		}
		else
		{
			/** 跟随数据类型错误 */
			ASSER_ERROR(CI_ERROR == ret, errorCode, 0x40000000u);
			ELM_LOG_LOC(ELM_LOG_ERROR, "errno:0x%08x info:TransferData type:%c error.", errorCode, pDatabuff[curIndex]);
		}
	}
	return ret;
}

/**
 * @brief 对外接口：根据已知条件创建包络
 * @param[in] UINT8 envelopeType 包络类型
 * @param[in] UINT16 TrainID 包络ID
 * @param[in] LOD_STRU startPoint 包络起始位置
 * @param[in] LOD_STRU endPoint 包络终止位置
 * @param[in] UINT16 headTrainID 包络前端列车ID
 * @param[in] UINT16 tailTrainID 包络后端列车ID
 * @param[out] EnvelopeStruct *pEnvelope 包络
 * @return CI_SUCCESS 包络创建正确，返回成功
 *         CI_ERROR   包络创建失败，返回失败
 * @note 
 */
UINT8 elm_BuildEnveLope(UINT8 envelopeType,UINT16 TrainID, LOD_STRU startPoint,LOD_STRU endPoint,UINT16 headTrainID,UINT16 tailTrainID, \
	INOUT EnvelopeStruct *pEnvelope)
{
	return elm_CreateEnveLope(envelopeType,TrainID,startPoint,endPoint,headTrainID,tailTrainID,pEnvelope);
}


/**
 * @brief 对外接口：查询基准包络前方最近的包络
 * @param[in] const EnvelopeStruct* pEnvelop 基准包络
 * @param[in] const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC] 待比较的包络
 * @param[in] UINT8 envelopeCnt 待比较的包络数量
 * @param[out] UINT16 *preEnvelope 包络前方id
 * @param[out] UINT16 *backEnvelope 包络后方id
 * @return CI_ERROR 查询失败
           CI_SUCCESS 查询成功
 * @note 无
 */
UINT8 elm_GetNearestBaseOnEnvelope(IN const EnvelopeStruct* pEnvelop, IN const UINT16 arEnvelopID[TRAIN_SUM_MAX_IN_OC], UINT8 envelopeCnt, OUT UINT16 *preEnvelope, OUT UINT16 *backEnvelope)
{
	UINT8 ret = CI_ERROR;
	UINT8 includeCnt = 0u;
	UINT16 includeELMid[TRAIN_SUM_MAX_IN_OC] = {0u};  /** 重合的包络id */
	UINT8 fuRtn = 0u;

	/** 调用底层函数 */
	fuRtn = elm_SearchNearestEnvelope(pEnvelop,arEnvelopID,envelopeCnt,preEnvelope,backEnvelope,&includeCnt,includeELMid);

	/** 设置函数返回值 */
	ASSERT_SETRET(CI_SUCCESS == fuRtn,ret,CI_SUCCESS,CI_ERROR);
	
	return ret;
}

/**
* @brief 对外接口：列车注销时清除对应包络
* @param[in] wId 列车ID
* @return 无
* @note 无
*/
void elm_LogoutDel(UINT16 wTrainId)
{
	UINT16 relEnvelopeCnt = TRAIN_REL_ENVELOPE_SUM_MAX;    /*列车关联的包络数量*/
	UINT16 relEnvelopeID[TRAIN_REL_ENVELOPE_SUM_MAX] = {0u};  /*列车关联的包络索引*/
	UINT8 funRet = 0u;
	UINT16 trainid = 0u;
	UINT8 headNeedScreen = NEED_SCREEN;
	UINT8 tailNeedScreen = NEED_SCREEN;
	const EnvelopeStruct* pEnvelop = NULL;
	UINT32 errorCode = 0u;

	if (LINE_MAX_TRAIN < wTrainId)
	{
		trainid = wTrainId & 0x00ffu;
	}
	else
	{
		trainid = wTrainId;
	}

	/** 获取包络信息 */
	relEnvelopeCnt = elm_GetRelELIdByTrainIDAndType(TYPE_CT_ENVELOPE,trainid,relEnvelopeID);
	pEnvelop = elm_GetEnvelopeInfoPtr(relEnvelopeID[0]);
	if ( NULL == pEnvelop)
	{
		/** 未存在该车包络，不处理*/
	}
	else
	{
		/** 删除切换车 */
		funRet = elm_ClearHanderOverEnvelope(pEnvelop,trainid);

		/** 下线车处理 */
		headNeedScreen = (LINE_MAX_TRAIN == pEnvelop->headTrainID) ? NEED_SCREEN : UNNEED_SCREEN;
		tailNeedScreen = (LINE_MAX_TRAIN == pEnvelop->tailTrainID) ? NEED_SCREEN : UNNEED_SCREEN;
		elm_JudgeTrainOffline(trainid,headNeedScreen,tailNeedScreen);

		if (CI_ERROR == funRet)
		{
			/** 删除CT包络，生成UKT包络 */
			funRet = elm_DeleteCTOrUCTEnvelope(relEnvelopeID[0]);
			ELM_LOG(ELM_LOG_ERROR,"errno:0x%08x info:clear train%d ELM error by Cancel.",errorCode,trainid);

			/** 判断是否处理成功 */
			if (CI_ERROR == funRet)
			{
				/** 设置包络管理模块处理错误 */
				ASSER_ERROR(CI_ERROR == funRet,errorCode,0x8000000u);
				ELM_LOG(ELM_LOG_ERROR,"errno:0x%08x info:clear train%d ELM error by Cancel need to retset ELM.",errorCode,trainid);
				elm_SetELMWorkFlag(ELM_WORK_ERROR);
			}
			else
			{
				/** 继续处理 */
			}			
		}
		else
		{
			/** 处理成功， 继续处理 */
		}
	}
}


/**
 * @brief 对外接口：获取列车关联的包络
 * @param[in] UINT16 wTrainId 列车ID
 * @param[out] UINT16 envelopeId[TRAIN_REL_ENVELOPE_SUM_MAX] 列车关联的包络
 * @return UINT8 
           TRAIN_REL_ENVELOPE_SUM_MAX 查询失败
		   0 ~ TRAIN_REL_ENVELOPE_SUM_MAX  查询成功
 * @note 无
 */
UINT8 elm_GetTrainRelELM(UINT16 wTrainId,OUT UINT16 envelopeId[TRAIN_REL_ENVELOPE_SUM_MAX])
{
	UINT8 ret = TRAIN_REL_ENVELOPE_SUM_MAX;

	/** 入口参数校验 */
	ASSERT_RET_VALUE(NULL == envelopeId,ret,0x80000000u);

	/** 获取包络信息 */
	ret = elm_GetRelELIdByTrainID(wTrainId,envelopeId);

	return ret;
}

/**
 * @brief 创建一个临时的UKT包络
 * @param[in] UINT16 acID 计轴ID
 *            UINT8 Dir 包络方向
 * @param[out] EnvelopeStruct* pEnvelope 创建的包络
 * @return 1 创建成功
 *         0 创建失败
 */
UINT8 elm_CreatTempUKTEnvelope(UINT16 acID, UINT8 Dir, EnvelopeStruct* pEnvelope)
{
	/*- 局部变量定义 */
	UINT8 ret = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT32 errorCode = 0u;
	ELM_AxisLocStruct AcLoc = { 0u };

	/** 入口参数校验 */
	ASSERT_RET_VALUE(((0U == acID) || (AXIS_SECTION_SUM_MAX < acID)), ret, 0x80000000u);
	ASSERT_RET_VALUE(NULL == pEnvelope, ret, 0x40000000u);
	ASSERT_RET_VALUE(((EMAP_SAME_DIR != Dir) && (EMAP_CONVER_DIR != Dir)), ret, 0x20000000u);

	/** 获取计轴位置 */
	funRtn = elm_PrepareACLoc(acID, Dir, &AcLoc);

	if (CI_ERROR == funRtn)
	{
		ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x10000000u);
		ELM_LOG(ELM_LOG_ERROR, "errno:0x%08x info:Get AC%d Loc error.\n", errorCode, acID);
	}
	else
	{
		/** 创建包络 */
		funRtn = elm_BuildEnveLope(TYPE_UKT_ENVELOPE, LINE_MAX_TRAIN, AcLoc.startPos, AcLoc.endPos, 0u, 0u, pEnvelope);
		ASSER_ERROR(CI_ERROR == funRtn, errorCode, 0x08000000u);
		ASSER_DEBUG(CI_ERROR == funRtn, ELM_LOG(ELM_LOG_ERROR, "errno:0x%08x info:AC%d Create temp envelope error.\n", errorCode, acID));
	}

	/** 设置返回值 */
	ASSERT_SETRET(0u == errorCode, ret, CI_SUCCESS, CI_ERROR)

	return ret;
}

/**
* @brief 获取包络相邻的包络
* @param[in] UINT16 envelopeId
* @param[out] UINT16 *preEnvelope 包络前方id
* @param[out] UINT16 *backEnvelope 包络后方id
* @return CI_ERROR 查询失败
CI_SUCCESS 查询成功
* @note
*   1、elm_GetNearestEnvelope 接口函数
*/
UINT8 elm_GetNearestEnvelopeApi(UINT16 envelopeId, OUT UINT16 *preEnvelope, OUT UINT16 *backEnvelope)
{
	return elm_GetNearestEnvelope(envelopeId, preEnvelope, backEnvelope);
}

/**
* @brief 获取包络是否完全属于本OC
* @param[in] const EnvelopeStruct* Ptemp
* @param[out] 无
* @return ELM_BELONG_OTHER 属于相邻OC
ELM_BELONG_OWNER 属于本OC
CI_ERROR，非法
* @note 无
*/
UINT8 elm_PrepareEnvelopeIsSelfApi(IN const EnvelopeStruct* ptemp)
{
	return elm_PrepareEnvelopeIsSelf(ptemp);
}