/****************************************************************************************************
* 文件名   :  APP_LinkManage.c
* 版权说明 :  交控科技股份有限公司
* 版本号   :  1.0
* 创建时间 :  2022.02.28
* 作者     :  TIOC组
* 功能描述 :  LINK数据管理源文件
* 使用注意 :
*
* 修改记录 :
*
**************************************************************************************************/
#include "LinkConfigDataManage.h"
#include "SwitchConfigDataManage.h"
#include "SwitchDataManage.h"
#include "CiSystemDefine.h"
#include "EnvelopeDefine.h"
#include "SectionStateProcess_define.h"
#include "AxisConfigDataManage.h"

LinkDataConfigStru g_szLinkConfigData[LINK_SUM_MAX] = { 0u };
UINT16 g_linkNum = 0u;

/**
* @brief 判断列车占压逻辑区段序列，是否需要判断逻辑区段道岔位置
* @param const UINT16 wLgcId 逻辑区段ID
* @param const str_Zone strZone 列车占压区域
* @return CI_ERROR:不需要检查道岔位置，CI_SUCCESS:需要检查
* @note
*/
static UINT8 IsLgcNeedCheckSwitchPos(const UINT16 wLgcId, const str_Zone strZone);

/**
* @brief GetLinkNum 获取LINK数量
* @param void
* @return 成功：LINK数量 失败 ：UINT16_MAX
*/
UINT16 GetLinkNum(void)
{
	UINT16 wRetVal = UINT16_MAX;

	if ((0u < g_linkNum) && (LINK_SUM_MAX > g_linkNum))
	{
		wRetVal = g_linkNum;
	}
	else
	{
		; /*失败*/
	}
	return wRetVal;
}

/**
* @brief GetLinkData 获取LINK数据
* @param void
* @return LINK数据
*/
LinkDataConfigStru * GetLinkData(void)
{
	return g_szLinkConfigData;
}

/**
* @brief GetLinkDataById 根据ID获取LINK数据
* @param linkId 编号
* @return LINK数据
*/
LinkDataConfigStru * GetLinkDataById(const UINT16 linkId)
{
	LinkDataConfigStru * rtnValue = NULL;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	
	if (UINT16_MAX != index)
	{
		rtnValue = &g_szLinkConfigData[index];
	}
	else
	{
		;
	}

	return rtnValue;
}

/**
* @brief GetLinkDataByIndex 根据索引获取LINK数据
* @param linkIndex 索引
* @return LINK数据
*/
LinkDataConfigStru * GetLinkDataByIndex(const UINT16 linkIndex)
{
	LinkDataConfigStru * rtnValue = NULL;

	if (linkIndex < LINK_SUM_MAX)
	{
		rtnValue = &g_szLinkConfigData[linkIndex];
	}
	else
	{
		; /*入参下标错误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkIndexById 根据编号获取索引
* @param linkId 编号
* @return LINK索引
*/
UINT16 GetLinkIndexById(const UINT16 linkId)
{
	UINT16 index = UINT16_MAX;

	if ((0u != linkId) && (LINK_SUM_MAX > linkId))
	{
		index = linkId;
	}
	else
	{
		;
	}

	return index;
}

/**
* @brief GetLinkLengthById 获取LINK长度
* @param linkId 编号
* @return LINK长度
*/
UINT32 GetLinkLengthById(const UINT16 linkId)
{
	UINT32 rtnValue = UINT32_MAX;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].dwLength;
	}
	else
	{
		; /*id 错误*/
	}

	if (0u == rtnValue)
	{
		rtnValue = UINT32_MAX;
	}

	return rtnValue;
}
#if 0
/**
* @brief GetLinkPointType 获取LINK端点类型
* @param linkId 编号
* @return LINK长度
*/
UINT8 GetLinkPointType(const UINT16 linkId,UINT8 * pOrgnPointType, UINT8 * pTmnlPointType)
{
	UINT8 rtnValue = CI_ERROR;
	UINT16 index = 0u;

	if ((NULL != pOrgnPointType) && (NULL != pTmnlPointType))
	{
		index = GetLinkIndexById(linkId);
		if (UINT16_MAX != index)
		{
			*pOrgnPointType = g_szLinkConfigData[index].wOrgnPointType;
			*pTmnlPointType = g_szLinkConfigData[index].wTmnlPointType;
			rtnValue = CI_SUCCESS;
		}
		else
		{
			; /*id 错误*/
		}
	}
	else
	{
		;/* 返回失败 */
	}

	return rtnValue;
}
#endif

/**
* @brief GetLinkLineById 获取LINK上下行信息
* @param linkId 编号
* @return LINK上下行信息 0x55:上行，0xaa:下行
*/
UINT16 GetLinkLineById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wLinkLine;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkOrgnPointTypeId 获取LINK起点端点类型
* @param linkId 编号
* @return LINK起点端点类型
*/
UINT16 GetLinkOrgnPointTypeById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wOrgnPointType;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkOrgnPointIdById 获取LINK起点端点编号
* @param linkId 编号
* @return LINK起点端点编号
*/
UINT16 GetLinkOrgnPointIdById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wOrgnPointId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkOrgnJointMainLkIdById 获取LINK起点相连接的相邻正线link编号
* @param linkId 编号
* @return LINK起点相连接的相邻正线link编号
*/
UINT16 GetLinkOrgnJointMainLkIdById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wOrgnJointMainLkId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkOrgnJointSideLkIdById 获取LINK起点相连接的相邻侧线link编号
* @param linkId 编号
* @return LINK起点相连接的相邻侧线link编号
*/
UINT16 GetLinkOrgnJointSideLkIdById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wOrgnJointSideLkId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkTmnlPointTypeById 获取LINK终点端点类型
* @param linkId 编号
* @return LINK终点端点类型
*/
UINT16 GetLinkTmnlPointTypeById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wTmnlPointType;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkTmnlPointIdById 获取LINK终点端点编号
* @param linkId 编号
* @return LINK终点端点编号
*/
UINT16 GetLinkTmnlPointIdById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wTmnlPointId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkTmnlJointMainLkById 获取LINK终点相连接的相邻正线link编号
* @param linkId 编号
* @return LINK终点相连接的相邻正线link编号
*/
UINT16 GetLinkTmnlJointMainLkById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wTmnlJointMainLkId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkTmnlJointSideLkById 获取LINK终点相连接的相邻侧线link编号
* @param linkId 编号
* @return LINK终点相连接的相邻侧线link编号
*/
UINT16 GetLinkTmnlJointSideLkById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wTmnlJointSideLkId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkManageOcById 获取LINK所属OC区域编号
* @param linkId 编号
* @return LINK所属TIOC区域编号
*/
UINT16 GetLinkManageTiocById(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wManageTioc;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief GetLinkLogicDirChangedById 获取LINK逻辑方向变化点
* @param linkId 编号
* @return LINK逻辑方向变化点
*/
UINT8 GetLinkLogicDirChangedById(const UINT16 linkId)
{
	UINT8 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].chLogicDirChanged;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief 获取link逻辑方向与上下行方向的关系
* @param linkId 编号
* @return LINK逻辑方向与上下行方向的关系
*/
UINT8 GetLinkLogicLineReleationById(const UINT16 linkId)
{
	UINT8 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].chLogicLineRelation;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief 获取LINK关联物理区段编号
* @param linkId 编号
* @return LINK关联物理区段编号
*/
UINT16 GetLinkRelatedPhySec(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wRelatedPhySec;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief  获取LINK端点信息
* @param chDir 方向
* @param wLinkId LINK编号
* @param pLinkPoint 端点信息
* @return CI_SUCCESS:成功；CI_ERROR:失败
*/
UINT8 GetLinkPointInfo(UINT8 chDir, UINT16 wLinkId, pLinkPointData pLinkPoint)
{
	UINT8 rtnValue = CI_ERROR;
	LinkDataConfigStru * pLinkDataTemp = NULL;

	pLinkDataTemp = GetLinkDataById(wLinkId);

	if ((NULL == pLinkPoint) || (NULL == pLinkDataTemp))
	{
		/* 出口指针为空或link编号有误 */
	}
	else if((DIR_SAME != chDir) && (DIR_CONVERT != chDir))
	{
		/* 方向不合法 */
	}
	else
	{
		pLinkPoint->wLinkId = pLinkDataTemp->wId;
		pLinkPoint->wPointType = UINT16_MAX;
		pLinkPoint->wPointId = UINT16_MAX;
		pLinkPoint->wMainLinkId = UINT16_MAX;
		pLinkPoint->wSideLinkId = UINT16_MAX;

		/* 与逻辑方向相同 */
		if (DIR_SAME == chDir)
		{
			pLinkPoint->wPointType = pLinkDataTemp->wTmnlPointType;		/* 获取终点端点类型 */
			pLinkPoint->wPointId = pLinkDataTemp->wTmnlPointId;			/* 获取终点端点编号 */
			pLinkPoint->wMainLinkId = pLinkDataTemp->wTmnlJointMainLkId;/* 获取终点相邻正线LINK编号 */
			pLinkPoint->wSideLinkId = pLinkDataTemp->wTmnlJointSideLkId;/* 获取终点相邻侧线LINK编号 */
		}
		else
		{
			/* 与逻辑方向相反 */
			pLinkPoint->wPointType = pLinkDataTemp->wOrgnPointType;		/* 获取起点端点类型 */
			pLinkPoint->wPointId = pLinkDataTemp->wOrgnPointId;			/* 获取起点端点编号 */
			pLinkPoint->wMainLinkId = pLinkDataTemp->wOrgnJointMainLkId;/* 获取起点相邻正线LINK编号 */
			pLinkPoint->wSideLinkId = pLinkDataTemp->wOrgnJointSideLkId;/* 获取起点相邻侧线LINK编号 */
		}

		rtnValue = CI_SUCCESS;
	}
	return rtnValue;
}

/**
* @brief 根据查询方向获取link端点偏移量
* @param wLinkId link编号
* @return CI_SUCCESS:成功；CI_ERROR_:失败
*/
UINT8 GetLinkOffsetByDir(struct_PathPoint* pPoint, UINT8 chDir, UINT8 chPointType, UINT32 dwDistance)
{
	UINT8 chRtn = CI_ERROR;
	UINT32 dwRtn = UINT32_MAX;

	if(NULL == pPoint)
	{
		;/*查询失败*/
	}
	else
	{
		dwRtn = GetLinkLengthById(pPoint->wLinkId);
		if (UINT32_MAX != dwRtn)
		{
			if ((0u == pPoint->dwOffset) && ((pPoint->dwOffset + dwDistance) <= dwRtn) &&
				(((POINT_START == chPointType) && (DIR_SAME == chDir)) || ((POINT_END == chPointType) && (DIR_CONVERT == chDir))))
			{
				/*逻辑方向为0x55时，查询link沿行进方向的起点，并基于起点向前偏移dwDistance
				逻辑方向为0xaa时，查询link沿行进方向的终点，并基于终点向后偏移dwDistance*/
				pPoint->dwOffset += dwDistance;
				chRtn = CI_SUCCESS;

			}
			else if ((0u == pPoint->dwOffset) && ((dwRtn - pPoint->dwOffset) >= dwDistance) &&
				(((POINT_END == chPointType) && (DIR_SAME == chDir)) || ((POINT_START == chPointType) && (DIR_CONVERT == chDir))))
			{
				/*逻辑方向为0x55时，查询link沿行进方向的终点，并基于终点向后偏移dwDistance
				逻辑方向为0xaa时，查询link沿行进方向的起点，并基于起点向前偏移dwDistance*/
				pPoint->dwOffset = dwRtn - dwDistance;
				chRtn = CI_SUCCESS;
			}
			else if (((pPoint->dwOffset + dwDistance) <= dwRtn) &&
				(((OFFEST_FOWARD == chPointType) && (DIR_SAME == chDir)) || ((OFFEST_BACK == chPointType) && (DIR_CONVERT == chDir))))
			{
				/*逻辑方向为0x55时，基于点向前偏移dwDistance
				逻辑方向为0xaa时，基于点向后偏移dwDistance*/
				pPoint->dwOffset += dwDistance;
				chRtn = CI_SUCCESS;
			}
			else if ((pPoint->dwOffset >= dwDistance) &&
				(((OFFEST_BACK == chPointType) && (DIR_SAME == chDir)) || ((OFFEST_FOWARD == chPointType) && (DIR_CONVERT == chDir))))
			{
				/*逻辑方向为0x55时，基于点向后偏移dwDistance
				逻辑方向为0xaa时，基于点向前偏移dwDistance*/
				pPoint->dwOffset -= dwDistance;
				chRtn = CI_SUCCESS;
			}
			else
			{
				/*无需再处理的场景*/
			}
		}
	}

	return chRtn;
}

/**
* @brief 获取道岔区域相邻两Link连接时期望的道岔状态
* @param UINT16 wSwitchID
* @param UINT16 wlinkA
* @param UINT16 wlinkB
* @param UINT8 *exSwitchStatus
* @return 失败：CI_ERROR；成功：CI_SUCCESS
*/
UINT8 dsuSwitchStatusBtwLink(UINT16 wSwitchID, UINT16 wlinkA, UINT16 wlinkB, UINT8 *exSwitchStatus)
{
	UINT8 chRtn = CI_ERROR;
	UINT8 linkAInSwType = SW_DEFAUT_LINK;
	UINT8 linkBInSwType = SW_DEFAUT_LINK;
	UINT8 chFunRtnA = CI_ERROR;
	UINT8 chFunRtnB = CI_ERROR;

	/*获取link在道岔区域的类型*/
	chFunRtnA = dsuLinkofSwitchPos(wlinkA, wSwitchID, &linkAInSwType);
	chFunRtnB = dsuLinkofSwitchPos(wlinkB, wSwitchID, &linkBInSwType);

	if ((CI_SUCCESS == chFunRtnA) && (CI_SUCCESS == chFunRtnB))
	{
		if (((SW_CON_LINK == linkAInSwType) && (SW_MAIN_LINK == linkBInSwType)) ||
			((SW_CON_LINK == linkBInSwType) && (SW_MAIN_LINK == linkAInSwType)))
		{
			/*设置道岔为定位*/
			(*exSwitchStatus) = SWITCH_POSITION_DINGWEI;
			chRtn = CI_SUCCESS;
		}
		else if (((SW_CON_LINK == linkAInSwType) && (SW_SIDE_LINK == linkBInSwType)) ||
			((SW_CON_LINK == linkBInSwType) && (SW_SIDE_LINK == linkAInSwType)))
		{
			/*设置道岔为反位*/
			(*exSwitchStatus) = SWITCH_POSITION_FANWEI;
			chRtn = CI_SUCCESS;
		}
		else
		{
			;/*查询错误*/
		}
	}
	else
	{
		/*查询错误*/
		;
	}
	return chRtn;
}

/**
* @brief 判断link编号有效性
* @param wId 编号
* @return CI_ERROR:无效 CI_SUCCESS:有效
*/
UINT8 IsLinkIdValid(UINT16 wId)
{
	UINT8 rtnValue = CI_ERROR;
	UINT16 index = 0u;
	
	index = GetLinkIndexById(wId);
	if (UINT16_MAX != index)
	{
		rtnValue = CI_SUCCESS;
	}

	return rtnValue;
}

/**
* @brief 校验linkID与偏移量是否有效
* @param wLinkId：link编号 dwOffest：偏移量
* @param dwLinkOffset
* @return CI_ERROR:无效；CI_SUCCESS:有效
*/
UINT8 CheckLinkValid(UINT16 wLinkId, UINT32 dwOffest)
{
	UINT8 cRetVal = CI_ERROR;
	UINT32 dwLinkLen = 0u;

	dwLinkLen = GetLinkLengthById(wLinkId);

	if ((UINT32_MAX != dwLinkLen) && (dwOffest <= dwLinkLen))
	{
		cRetVal = CI_SUCCESS;
	}
	else
	{
		;
	}

	return cRetVal;
}

/**
* @brief 查询某一位置沿指定方向移动指定距离后的新位置及查找过程中遇到的道岔信息
* @param struct_PathPoint pStart 起点
* @param UINT32 dwDistance 距离
* @param UINT8 chDir 方向
* @param struct_PathPoint *pEnd 查询到的终点
* @param UINT16 * pSwitchId 不连通的道岔ID
* @return 0：查询失败；1：查询到线路终端；2：道岔不连通；3：查询成功
*/
UINT8 dsuNewLocAndObsByOffsetDis(IN struct_PathPoint pStart, IN UINT32 dwDistance, IN UINT8 chDir, OUT struct_PathPoint *pEnd, OUT UINT16 * pSwitchId)
{
	UINT8 chRtn = 0u;
	UINT8 chCycle = 0u;
	UINT16 wCurLinkId = 0u; /*当前link ID*/
	UINT16 wNextLinkId = 0u; /*当前link ID*/
	UINT16 wPointId = UINT16_MAX;
	UINT32 dwLinkLen = 0u;
	UINT32 dwSearchLenth = 0u;
	UINT8 chBreakRtn = CI_ERROR;
	UINT8 chFunRtn = CI_ERROR;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/
	UINT8 cDirectionPointCnt = 0U;			/*方向变化点数量*/

	if ((NULL == pEnd) 
		|| ((DIR_SAME != chDir) && (DIR_CONVERT != chDir))
		|| (NULL == pSwitchId))
	{
		/*入口参数失败，返回错误*/
	}
	else
	{
		/*获取当前link*/
		wCurLinkId = pStart.wLinkId;
		*pSwitchId = UINT16_MAX;
		/*获取当前link长度*/
		dwLinkLen = GetLinkLengthById(wCurLinkId);

		if (UINT32_MAX != dwLinkLen)
		{
			if (DIR_SAME == chDir)
			{
				dwSearchLenth = dwLinkLen - pStart.dwOffset;
			}
			else
			{
				dwSearchLenth = pStart.dwOffset;
			}

			/*判断是否继续查询*/
			if (dwSearchLenth >= dwDistance)
			{
				/*查询成功,在同一个link*/
				chRtn = 3u;
				pEnd->wLinkId = wCurLinkId;
				pEnd->dwOffset = pStart.dwOffset;
				(void)GetLinkOffsetByDir(pEnd, chDir, OFFEST_FOWARD, dwDistance);
			}
			else
			{
				while (chCycle < FIND_FRONT_PROTECT_POINT_TIME)
				{
					chCycle++;
					/*查询下一个link ID*/
					wNextLinkId = FindAdjacentLinkIDSafe(wCurLinkId, chDir, &wPointId, &cDirectionPointFlag);

					if ((UINT16_MAX == wNextLinkId) && (UINT16_MAX != wPointId))
					{/* 因道岔位置不满足，查询失败 */
						*pSwitchId = wPointId;

						pEnd->wLinkId = wCurLinkId;
						pEnd->dwOffset = 0u;
						/*根据方向变化点信息转换查询下一link方向*/
						chDir = TransDirectionPointDir(cDirectionPointFlag, chDir, &cDirectionPointCnt);

						(void)GetLinkOffsetByDir(pEnd, chDir, POINT_END, 0u);

						chRtn = 2u;/* 道岔四开 */

						chBreakRtn = CI_SUCCESS;

					}
					else if ((UINT16_MAX != wNextLinkId) && (0u != wNextLinkId))
					{
						chFunRtn = dsuCheckLinkFitPointSafe(wCurLinkId, chDir, &wPointId);
						if (CI_ERROR == chFunRtn)
						{
							/* 道岔不连通，终点为岔心 */
							*pSwitchId = wPointId;
							pEnd->wLinkId = wCurLinkId;
							pEnd->dwOffset = 0u;
							(void)GetLinkOffsetByDir(pEnd, chDir, POINT_END, 0u);

							chRtn = 2u;/* 道岔位置不满足线路拓扑条件 */
							chBreakRtn = CI_SUCCESS;
						}
						else
						{
							;
						}

						if (CI_SUCCESS != chBreakRtn)
						{
							/*根据方向变化点信息转换查询下一link方向*/
							chDir = TransDirectionPointDir(cDirectionPointFlag, chDir, &cDirectionPointCnt);

							/*获取当前link长度*/
							dwLinkLen = GetLinkLengthById(wNextLinkId);

							if (UINT32_MAX == dwLinkLen)
							{
								/*查询失败，返回错误*/
								chRtn = 0u;
								chBreakRtn = CI_SUCCESS;
							}
							else if ((dwLinkLen + dwSearchLenth) < dwDistance)
							{
								dwSearchLenth += dwLinkLen;
								wCurLinkId = wNextLinkId;
							}
							else
							{
								/*查找成功，返回*/
								pEnd->wLinkId = wNextLinkId;
								pEnd->dwOffset = 0u;
								(void)GetLinkOffsetByDir(pEnd, chDir, POINT_START, dwDistance - dwSearchLenth);
								chFunRtn = dsuCheckLinkFitPointSafe(wNextLinkId, chDir, &wPointId);
								if (CI_ERROR == chFunRtn)
								{
									/* 道岔不连通 */
									*pSwitchId = wPointId;

									chRtn = 2u;/* 道岔位置不满足线路拓扑条件 */
								}
								else
								{
									chRtn = 3u;
								}
								chBreakRtn = CI_SUCCESS;
							}
						}
						else
						{
							;
						}
					}
					else if(0u == wNextLinkId)
					{
						/*遇到线路终点，返回成功*/
						pEnd->wLinkId = wCurLinkId;
						pEnd->dwOffset = 0u;
						(void)GetLinkOffsetByDir(pEnd, chDir, POINT_END, 0u);
						chRtn = 1u;
						chBreakRtn = CI_SUCCESS;
					}
					else
					{
						pEnd->wLinkId = pStart.wLinkId;
						pEnd->dwOffset = pStart.dwOffset;
						chRtn = 0u;
						chBreakRtn = CI_SUCCESS;
					}
					
					if (CI_SUCCESS == chBreakRtn)
					{
						break;
					}
				}
			}
		}
		else
		{
			/*查询错误*/
		}
	}

	return chRtn;
}

/**
* @brief 查询当前link的相邻link,由于道岔原因导致查询失败时，返回道岔的编号信息
* @param UINT16 wCurrentLinkId 当前link编号
* @param UINT8 chDirection 查询方向
* @param UINT16 *pSwitchId 道岔编号
* @param UINT8* directionPointFlag	方向变化点信息
* @return 下一link编号 失败：UINT16_MAX；线路终点：0u
*/
UINT16 FindAdjacentLinkIDSafe(UINT16 wCurrentLinkId, UINT8 chDirection, UINT16 *pSwitchId,UINT8* directionPointFlag)
{
	UINT16 wFindLinkId = 0u;/*函数返回值*/
	UINT8 bReturn = CI_ERROR;
	UINT8 cSwitchPos = SWITCH_POSITION_INVALID;
	LinkPointDataStru pathTreeTemp = { 0u };/*端点信息*/
	DSU_POINT_STRU * pSwitchTemp = NULL;
	UINT8 cDirectionPointfirst = 0U;			/*方向变化点1*/
	UINT8 cDirectionPointsecond = 0U;			/*方向变化点2*/
	UINT8 cDirectionPointCnt = 0U;			/*方向变化点数量*/


	if ((NULL != pSwitchId)&&(NULL != directionPointFlag))
	{
		*pSwitchId = UINT16_MAX;
		*directionPointFlag = DIRECTIONPOINT_FLAG_INVALID;		/*出清标志位*/
		bReturn = CI_SUCCESS;
	}
	else
	{
		bReturn = CI_ERROR;
	}

	if (CI_SUCCESS == bReturn)
	{
		/*查询link端点信息*/
		bReturn = GetLinkPointInfo(chDirection, wCurrentLinkId, &pathTreeTemp);
	}
	else
	{
		; /*入参异常*/
	}

	if (CI_SUCCESS != bReturn)
	{
		/*返回查询失败*/
		wFindLinkId = UINT16_MAX;
	}
	else
	{
		if (UINT16_MAX == pathTreeTemp.wMainLinkId)
		{
			/*link终点端点为线路终点，无相邻link，查询失败*/
			wFindLinkId = 0u;
		}
		else
		{
			if (EMAP_AXLE_DOT == pathTreeTemp.wPointType)
			{
				/* 若端点为计轴点,获取下一linkID，并判断下一link是否为道岔link */
				wFindLinkId = pathTreeTemp.wMainLinkId;

				/*若端点为计轴点，查询本link和下一linkID是否具有方向变化点，且两个link方向变化点为对顶点，则直接返回linkID，并反馈方向变化点信息*/
				cDirectionPointfirst = GetLinkLogicDirChangedById(wCurrentLinkId);
				cDirectionPointsecond = GetLinkLogicDirChangedById(wFindLinkId);
				if (((LINK_DIRCHANGE_BEGIN == cDirectionPointfirst) || (LINK_DIRCHANGE_END == cDirectionPointfirst))
					&& (cDirectionPointsecond == cDirectionPointfirst))
				{
					*directionPointFlag = DIRECTIONPOINT_FLAG_VALID;
				}
				else
				{
					;	/*没方向变化点，继续运行*/
				}
				chDirection = TransDirectionPointDir((*directionPointFlag), chDirection, &cDirectionPointCnt);

				bReturn = GetLinkPointInfo(chDirection, wFindLinkId, &pathTreeTemp);
				if (CI_SUCCESS != bReturn)
				{
					/*返回查询失败*/
					wFindLinkId = UINT16_MAX;
				}
				else
				{
					/* 判断是否为道岔点 */
					if (EMAP_POINT_DOT == pathTreeTemp.wPointType)
					{
						*pSwitchId = pathTreeTemp.wPointId;
					}
				}

			}
			else if (EMAP_POINT_DOT == pathTreeTemp.wPointType)
			{
				/* 若端点为道岔点,获取道岔信息结构体*/
				cSwitchPos = GetSwitchCurPosition(pathTreeTemp.wPointId);
				if (SWITCH_POSITION_DINGWEI == cSwitchPos)
				{
					/*道岔在定位，终点相邻正线区段即为所求*/
					*pSwitchId = pathTreeTemp.wPointId;
					wFindLinkId = pathTreeTemp.wMainLinkId;
				}
				else if (SWITCH_POSITION_FANWEI == cSwitchPos)
				{
					pSwitchTemp = g_dsuEmapStru->dsuStaticHeadStru->pPointStru + g_dsuEmapStru->dsuEmapIndexStru->dsuPointIndex[pathTreeTemp.wPointId];
					if (wCurrentLinkId == pSwitchTemp->wConfluentLkId)
					{
						/*道岔在反位，查询link为汇合link*/
						*pSwitchId = pathTreeTemp.wPointId;
						wFindLinkId = pathTreeTemp.wSideLinkId;
					}
					else
					{
						/*道岔在反位，查询link为定位/反位link*/
						*pSwitchId = pathTreeTemp.wPointId;
						wFindLinkId = pathTreeTemp.wMainLinkId;
					}
				}
				else
				{
					/*道岔四开*/
					*pSwitchId = pathTreeTemp.wPointId;
					wFindLinkId = UINT16_MAX;
				}		
			}
			else
			{
				/*link终点端点为线路终点，无相邻link，查询失败*/
				wFindLinkId = 0u;
			}
		}
	}

	return wFindLinkId;
}

/**
* @brief 在两个link通过道岔相连时，判断连接关系与当前的道岔状态是否匹配。
* @param UINT16 wStartLinkId link编号
* @param UINT8 chDir 方向
* @param UINT16 *pSwitchId 道岔编号
* @return CI_SUCCESS匹配；CI_ERROR不匹配
*/
UINT8 dsuCheckLinkFitPointSafe(UINT16 wStartLinkId, UINT8 chDir, UINT16 *pSwitchId)
{
	UINT8 rtnValue = CI_ERROR;/*函数返回值*/
	UINT8 chSwitchPos = 0u;
	LinkPointDataStru pathTreeTemp = { 0u };
	UINT16 wMainLink = 0u;
	UINT16 wSideLink = 0u;
	UINT16 wConfluentLink = 0u;
	UINT8 chSwitchCurPos = 0u;
	UINT8 chKeepWork = CI_ERROR;
	DSU_POINT_STRU * pSwitchTemp = NULL;

	/*获取link端点连接信息*/
	rtnValue = GetLinkPointInfo(chDir, wStartLinkId, &pathTreeTemp);

	if (CI_ERROR == rtnValue)
	{
		;
	}
	else if (pathTreeTemp.wPointType != EMAP_POINT_DOT)
	{
		/*非道岔，返回匹配*/
		rtnValue = CI_SUCCESS;
	}
	else
	{
		/*利用管理函数得到道岔信息*/
		pSwitchTemp = g_dsuEmapStru->dsuStaticHeadStru->pPointStru + g_dsuEmapStru->dsuEmapIndexStru->dsuPointIndex[pathTreeTemp.wPointId];
		wMainLink = pSwitchTemp->wMainLkId;

		chSwitchCurPos = GetSwitchCurPosition(pathTreeTemp.wPointId);
		if (wStartLinkId == wMainLink)
		{
			/*定位*/
			chSwitchPos = SWITCH_POSITION_DINGWEI;
			chKeepWork = CI_SUCCESS;
		}
		else
		{
			/*反位*/
			wSideLink = pSwitchTemp->wSideLkId;
			if (wStartLinkId == wSideLink)
			{
				chSwitchPos = SWITCH_POSITION_FANWEI;
				chKeepWork = CI_SUCCESS;
			}
			else
			{
				/*汇合*/
				wConfluentLink = pSwitchTemp->wConfluentLkId;
				if (wStartLinkId == wConfluentLink)
				{
					/*判断道岔是否在有效位*/
					if ((SWITCH_POSITION_DINGWEI == chSwitchCurPos)
						|| (SWITCH_POSITION_FANWEI == chSwitchCurPos))
					{
						/*道岔状态满足*/
						rtnValue = CI_SUCCESS;
						(*pSwitchId) = pathTreeTemp.wPointId;
					}
					else
					{
						/*道岔状态不匹配*/
						(*pSwitchId) = pathTreeTemp.wPointId;
						rtnValue = CI_ERROR;
					}
				}
				else
				{
					/*不可达分支*/
					rtnValue = CI_ERROR;
				}
			}
		}


		/*判断道岔状态是否满足需求*/
		if (CI_SUCCESS == chKeepWork)
		{
			if (chSwitchPos == chSwitchCurPos)
			{
				/*道岔状态满足*/
				rtnValue = CI_SUCCESS;
				(*pSwitchId) = pathTreeTemp.wPointId;
			}
			else
			{
				/*道岔状态不匹配*/
				(*pSwitchId) = pathTreeTemp.wPointId;
				rtnValue = CI_ERROR;
			}
		}
	}
	return rtnValue;
}

/**
* @brief 查询A点是否与B点的位置关系（只适应同一link上两点的位置比较或者两点重合）
* @param p_strPathPoint pPointA
* @param p_strPathPoint pPointB
* @param UINT8 dir
* @return 查询失败：CI_ERROR；两点重合：CI_SUCCESS；A点在B点前：FLAG_SET；B点在A点钱：FLAG_UNSET
*/
UINT8 dsuJudgeLinkAandLinkBPosition(p_strPathPoint pPointA, p_strPathPoint pPointB, UINT8 dir)
{
	UINT8 chRtn = CI_ERROR;
	UINT16 LinkNearA = 0u;/* B点的相邻link */
	UINT8 chFunRtn = CI_ERROR;
	struct_PathPoint tempPointA = { 0u };
	struct_PathPoint tempPointB = { 0u };
	UINT16 wSwitchId = 0u;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/
	UINT8 cDirectionPointCnt = 0U;			/*方向变化点数量*/

	/* 入口参数检查 */
	if ((NULL == pPointA) || (NULL == pPointB))
	{
		;/*入口参数错误*/
	}
	else if ((DIR_CONVERT != dir) && (DIR_SAME != dir))
	{
		;/*方向入口参数错误*/
	}
	else if (pPointA->wLinkId == pPointB->wLinkId)
	{
		if (pPointA->dwOffset == pPointB->dwOffset)
		{
			/*A点和B点重合*/
			chRtn = CI_SUCCESS;
		}
		else if (((pPointA->dwOffset > pPointB->dwOffset) && (DIR_SAME == dir)) ||
			((pPointA->dwOffset < pPointB->dwOffset) && (DIR_CONVERT == dir)))
		{
			/*A点在B点前*/
			chRtn = FLAG_SET;
		}
		else
		{
			/*B点在A点前*/
			chRtn = FLAG_UNSET;
		}

	}
	else
	{
		/*通过link ID和方向查找link端点信息*/
		tempPointA.wLinkId = pPointA->wLinkId;

		/*查询A点link确沿方向dir的终点*/
		chFunRtn = GetLinkOffsetByDir(&tempPointA, dir, POINT_END, 0u);
		/* 查询A点相邻的link */
		LinkNearA = FindAdjacentLinkIDSafe(pPointA->wLinkId, dir, &wSwitchId, &cDirectionPointFlag);
		tempPointB.wLinkId = LinkNearA;

		/*查询B的时候考虑A处是否存在方向变化点，存在需要改方向*/
		dir = TransDirectionPointDir(cDirectionPointFlag, dir, &cDirectionPointCnt);
		/*查询LinkNearB沿方向dir的起点*/
		chFunRtn &= GetLinkOffsetByDir(&tempPointB, dir, POINT_START, 0u);

		if ((CI_SUCCESS == chFunRtn) && (pPointA->dwOffset == tempPointA.dwOffset))
		{
			if (pPointB->dwOffset == tempPointB.dwOffset)
			{
				/*A点与B点重合*/
				chRtn = CI_SUCCESS;
			}
			else
			{
				/*AB不再同一个link上*/
				chRtn = CI_ERROR;
			}

		}
		else
		{
			/*AB不再同一个link上*/
		}
	}
	return chRtn;
}

/**
* @brief 查询A点是否与B点的位置关系（任意link）
* @param p_strPathPoint pPointA
* @param p_strPathPoint pPointB
* @param UINT8 dir
* @return 查询失败：CI_ERROR；
          两点重合：CI_SUCCESS；
		  A点在B点前：FLAG_SET；
		  B点在A点钱：FLAG_UNSET
*/
UINT8 dsuJudgePointAandPointBPosition(p_strPathPoint pPointA, p_strPathPoint pPointB, UINT8 dir)
{
	UINT8 chRtn = CI_ERROR;
	struct_PathPoint tempPointA = { 0u };
	struct_PathPoint tempPointB = { 0u };
	UINT32 dwLen = UINT32_MAX;
	UINT8 chRtnDir = 0u;

	/* 入口参数检查 */
	if ((NULL == pPointA) || (NULL == pPointB))
	{
		;/*入口参数错误*/
	}
	else if ((DIR_CONVERT != dir) && (DIR_SAME != dir))
	{
		;/*方向入口参数错误*/
	}
	else
	{
		tempPointA.wLinkId = pPointA->wLinkId;
		tempPointA.dwOffset = pPointA->dwOffset;
		tempPointB.wLinkId = pPointB->wLinkId;
		tempPointB.dwOffset = pPointB->dwOffset;
		dwLen = DsuAPointToBPoint(&tempPointA, &tempPointB, &chRtnDir);
		if (UINT32_MAX == dwLen)
		{
			;
		}
		else if(0u == dwLen)
		{
			chRtn = CI_SUCCESS;
		}
		else if (chRtnDir == dir)
		{
			chRtn = FLAG_SET;
		}
		else
		{
			chRtn = FLAG_UNSET;
		}
	}
	return chRtn;
}

/**
* @brief 获取区域在指定link上的占压范围
* @param p_StrZone pZone 区域
* @param UINT16 wLinkId	link编号
* @param p_strPathPoint pStartPoint 在link占压起点
* @param p_strPathPoint pEndPoint 在link占压终点
* @return CI_ERROR失败 CI_SUCCESS成功
*/
UINT8 dsuZoneStartEndPointInLink(p_StrZone pZone, IN const UINT16 wLinkId, OUT p_strPathPoint pStartPoint, OUT p_strPathPoint pEndPoint)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 cKeepWork = CI_ERROR;
	UINT16 i = UINT16_MAX;
	UINT32 dwLinkLen = UINT32_MAX;
	UINT8 cDirChangedNum = 0U;  /*区域内存在的方向方向变化点数量*/
	UINT8 cTempZoneDir = 0U;
	LOD_STRU LODStartStru = { 0U };  /*区域起点*/
	LOD_STRU LODEndStru = { 0U };  /*区域终点*/

	if ((NULL == pStartPoint) || (NULL == pEndPoint) || (NULL == pZone))
	{
		;/* 输出地址检查 */
	}
	else
	{
		/* 将输出内存初始化为安全值 */
		pStartPoint->wLinkId = UINT16_MAX;
		pStartPoint->dwOffset = UINT32_MAX;
		pEndPoint->wLinkId = UINT16_MAX;
		pEndPoint->dwOffset = UINT32_MAX;

		dwLinkLen = GetLinkLengthById(wLinkId);

		if (UINT32_MAX != dwLinkLen)
		{
			/* 1.判断列车是否在link上 */
			for (i = 0u; i < pZone->pLinkSeq.cLinkCnt; i++)
			{
				if (wLinkId == pZone->pLinkSeq.szLinkId[i])
				{
					cKeepWork = CI_SUCCESS;
					break;
				}
				else
				{
				}
			}

			if (CI_SUCCESS == cKeepWork)
			{
				/* 列车在link上 */
				if ((wLinkId == pZone->pStart.wLinkId) && (wLinkId == pZone->pEnd.wLinkId))
				{
					/* 起点终点都在link上,根据方向判断传出占压的起点终点 */
					if (DIR_SAME == pZone->Dir)
					{
						pStartPoint->wLinkId = pZone->pStart.wLinkId;
						pStartPoint->dwOffset = pZone->pStart.dwOffset;
						pEndPoint->wLinkId = pZone->pEnd.wLinkId;
						pEndPoint->dwOffset = pZone->pEnd.dwOffset;
					}
					else
					{
						pStartPoint->wLinkId = pZone->pEnd.wLinkId;
						pStartPoint->dwOffset = pZone->pEnd.dwOffset;
						pEndPoint->wLinkId = pZone->pStart.wLinkId;
						pEndPoint->dwOffset = pZone->pStart.dwOffset;
					}
				}
				else if ((wLinkId != pZone->pStart.wLinkId) && (wLinkId != pZone->pEnd.wLinkId))
				{
					/* 起点和终点都不在,跨压link */
					pStartPoint->wLinkId = wLinkId;
					pStartPoint->dwOffset = 0u;
					pEndPoint->wLinkId = wLinkId;
					pEndPoint->dwOffset = dwLinkLen;

				}
				else if (wLinkId == pZone->pStart.wLinkId)
				{
					/* 起点在终点不在 */
					if (DIR_SAME == pZone->Dir)
					{
						pStartPoint->wLinkId = pZone->pStart.wLinkId;
						pStartPoint->dwOffset = pZone->pStart.dwOffset;
						pEndPoint->wLinkId = wLinkId;
						pEndPoint->dwOffset = dwLinkLen;
					}
					else
					{
						pStartPoint->wLinkId = wLinkId;
						pStartPoint->dwOffset = 0u;
						pEndPoint->wLinkId = pZone->pStart.wLinkId;
						pEndPoint->dwOffset = pZone->pStart.dwOffset;
					}
				}
				else
				{
					/* 起点不在终点在 */
					LODStartStru.Lnk = pZone->pStart.wLinkId;
					LODStartStru.Off = pZone->pStart.dwOffset;
					LODStartStru.Dir = pZone->Dir;

					LODEndStru.Lnk = pZone->pEnd.wLinkId;
					LODEndStru.Off = pZone->pEnd.dwOffset;
					LODEndStru.Dir = pZone->Dir;

					cTempZoneDir = pZone->Dir;
					cDirChangedNum = GetDirChangeNumBtwPoints(&LODStartStru, &LODEndStru);  /*获取区域内的方向变化点数量*/

					/*判断区域内是否存在方向变化点,并转方向*/
					cTempZoneDir = TransDirByChangeNum(cTempZoneDir, cDirChangedNum);

					if (0U != cTempZoneDir)
					{
						if (DIR_SAME == cTempZoneDir)
						{
							pStartPoint->wLinkId = wLinkId;
							pStartPoint->dwOffset = 0u;
							pEndPoint->wLinkId = pZone->pEnd.wLinkId;
							pEndPoint->dwOffset = pZone->pEnd.dwOffset;
						}
						else
						{
							pStartPoint->wLinkId = pZone->pEnd.wLinkId;
							pStartPoint->dwOffset = pZone->pEnd.dwOffset;
							pEndPoint->wLinkId = wLinkId;
							pEndPoint->dwOffset = dwLinkLen;
						}
					}
					else
					{
						/*无操作*/
					}
				}

				cRetVal = CI_SUCCESS;
			}
			else
			{
			}
		}
		else
		{
		}


	}

	return cRetVal;
}

/**
* @brief 判断点是否处于区域中
* @param strPoint 点信息
* @param strZone 区域信息
* @return CI_SUCCESS不在；CI_ERROR在
* @note 内部优化 20220421 wqm 设置返回值CI_ERROR
*/
UINT8 IsPointInPath(struct_PathPoint strPoint, str_Zone strZone)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 chFunARtn = CI_ERROR;
	UINT8 chFunBRtn = CI_ERROR;
	UINT8 i = 0u;
	struct_PathPoint strStartPoint = { 0u };
	struct_PathPoint strEndPoint = { 0u };
	UINT8 cDir = DIR_INVALID;
	LinkDataConfigStru * pLinkInfo = NULL;

	cRetVal = IsLinkIdValid(strPoint.wLinkId);

	if (CI_SUCCESS == cRetVal)
	{
		if (0u == strZone.pLinkSeq.cLinkCnt)
		{
			cRetVal = CI_ERROR;
		}
		else
		{
			for (i = 0u; i < strZone.pLinkSeq.cLinkCnt; i++)
			{
				if (strZone.pLinkSeq.szLinkId[i] == strPoint.wLinkId)
				{
					break;
				}
			}

			if (strZone.pLinkSeq.cLinkCnt != i)
			{/* 获取在link上的实际占压 */
				cRetVal = dsuZoneStartEndPointInLink(&strZone, strPoint.wLinkId, &strStartPoint, &strEndPoint);
				pLinkInfo = GetLinkDataById(strPoint.wLinkId);

				if ((CI_SUCCESS == cRetVal) && (NULL != pLinkInfo))
				{/* 获取点和区域两个端点的位置关系 */

					cDir = ConvertDirectionToLogic((UINT8)pLinkInfo->wLinkLine);
					chFunARtn = dsuJudgeLinkAandLinkBPosition(&strPoint, &strStartPoint, cDir);
					chFunBRtn = dsuJudgeLinkAandLinkBPosition(&strPoint, &strEndPoint, cDir);

					/* 点与任意一点重合，或者位置关系不一致，说明点在区域中 */
					if ((CI_ERROR == chFunARtn) || (CI_SUCCESS == chFunARtn)
						|| (CI_ERROR == chFunBRtn) || (CI_SUCCESS == chFunBRtn)
						|| (chFunARtn != chFunBRtn))
					{
						cRetVal = CI_ERROR;
					}
					else
					{
						/* 点不再区域里 */
						cRetVal = CI_SUCCESS;
					}
				}
				else
				{
					/** 内部优化 20220421 wqm 此处应返回安全侧CI_ERROR*/
					cRetVal = CI_ERROR;
				}
			}
			else
			{
				cRetVal = CI_SUCCESS;
			}
		}
	}
	else
	{
		cRetVal = CI_ERROR;
	}

	return cRetVal;
}

/**
* @brief 通过起终点link和两link中道岔信息查询两link间的link序列。
* @param UINT16 linkA
* @param UINT16 linkB
* @param UINT8 chDir 方向
* @param p_strPointInArea pSwInfo 道岔信息
* @param p_StrPathLinkInfo pLinkSeq link序列
* @return CI_ERROR失败 CI_SUCCESS成功
*/
UINT8 dsuLinkSeqBtwLinkBaseSwitchInfo(UINT16 linkA, UINT16 linkB, UINT8 chDir, IN p_strPointInArea pSwInfo, OUT p_StrPathLinkInfo pLinkSeq)
{
	UINT8 chRtn = CI_ERROR;    /*返回返回值*/
	UINT8 chFunRtn = CI_ERROR;  /*查询函数返回值*/
	UINT8 dquNum = 0u;
	UINT8 chSwCycle = 0u;  /*遍历道岔信息*/
	UINT16 currentLinkID = UINT16_MAX;
	LinkPointDataStru pathTree = { 0u };         /*link端点信息*/
	UINT8 cQueryDir = 0U;  /*link查询方向*/
	UINT8 cCurLinkDirChanged = LINK_DIRCHANGE_NONE;  /*当前Link方向变化点*/
	UINT8 cNxtLinkDirChanged = LINK_DIRCHANGE_NONE;  /*下一Link方向变化点*/
														   /*入口参数检查*/
	if ((NULL == pLinkSeq) || (NULL == pSwInfo))
	{
		/*入口函数非法，返回失败*/
	}
	else if ((DIR_SAME != chDir) && (DIR_CONVERT != chDir))
	{
		/*入口函数非法，返回失败*/
	}
	else
	{
		/*初始化*/
		(void)CommonMemSet(pLinkSeq, (UINT32)sizeof(str_PathLinkInfo), 0u, (UINT32)sizeof(str_PathLinkInfo));

		/*判断link ID是否正确*/
		chFunRtn = IsLinkIdValid(linkA);
		chFunRtn &= IsLinkIdValid(linkB);

		if (CI_SUCCESS == chFunRtn)
		{
			/*设置查询起点*/
			currentLinkID = linkA;
			pLinkSeq->cLinkCnt = 0u;
			cQueryDir = chDir;

			while ((DSU_ROUTE_STRU_wLinkId > dquNum) && (CI_SUCCESS == chFunRtn))
			{
				if (currentLinkID == linkB)
				{
					pLinkSeq->szLinkId[pLinkSeq->cLinkCnt] = currentLinkID;
					pLinkSeq->cLinkCnt++;
					chRtn = CI_SUCCESS;
					break;
				}
				else
				{
					pLinkSeq->szLinkId[pLinkSeq->cLinkCnt] = currentLinkID;
					pLinkSeq->cLinkCnt++;

					chFunRtn = GetLinkPointInfo(cQueryDir, currentLinkID, &pathTree);
					cCurLinkDirChanged = GetLinkLogicDirChangedById(currentLinkID);
					
					if (EMAP_POINT_DOT == pathTree.wPointType)
					{
						/*link连接的端点类型为道岔*/
						for (chSwCycle = 0u; chSwCycle < pSwInfo->SwitchNum; chSwCycle++)
						{
							/*设置查询未成功*/
							chFunRtn = CI_ERROR;

							if (pathTree.wPointId == pSwInfo->SwitchInfo[chSwCycle].pointID)
							{
								/*根据道岔状态设置下一个基准link*/
								if (UINT16_MAX == pathTree.wSideLinkId)
								{
									/*说明是从定位或者反位找汇合link*/
									chFunRtn = CI_SUCCESS;
									currentLinkID = pathTree.wMainLinkId;
								}
								else if (SWITCH_POSITION_DINGWEI == pSwInfo->SwitchInfo[chSwCycle].status)
								{
									chFunRtn = CI_SUCCESS;
									currentLinkID = pathTree.wMainLinkId;
								}
								else if (SWITCH_POSITION_FANWEI== pSwInfo->SwitchInfo[chSwCycle].status)
								{
									chFunRtn = CI_SUCCESS;
									currentLinkID = pathTree.wSideLinkId;
								}
								else
								{
									/*查询失败*/
								}
								break;
							}
							else
							{
								/*继续遍历*/
							}
						}
					}
					else
					{
						/*非道岔，设置下一个基准link*/
						currentLinkID = pathTree.wMainLinkId;
					}

					/*判断link ID是否正确*/
					chFunRtn &= IsLinkIdValid(currentLinkID);

					/*判断是否存在方向变化点*/
					cNxtLinkDirChanged = GetLinkLogicDirChangedById(currentLinkID);
					if (((LINK_DIRCHANGE_BEGIN == cNxtLinkDirChanged) || (LINK_DIRCHANGE_END == cNxtLinkDirChanged))
						&& (cNxtLinkDirChanged == cCurLinkDirChanged))
					{
						/*存在方向变化点*/
						cQueryDir = ~cQueryDir;
					}
					else
					{
						/*不存在方向变化点，不处理*/
					}
				}

				/*设置循环次数，防止死循环和pLinkSeq->LockLinkId数组越界*/
				dquNum++;
			}

			if (CI_SUCCESS == chRtn)
			{
				/*查询成功*/
			}
			else
			{
				/*查询不成功，清空*/
				(void)CommonMemSet(pLinkSeq, (UINT32)sizeof(str_PathLinkInfo), 0u, (UINT32)sizeof(str_PathLinkInfo));
			}
		}
		else
		{
			/*link ID错误，不处理*/
		}
	}

	return chRtn;
}

/**
* @brief 通过两点和两点中的道岔信息查询两间的link序列。
* @param struct_PathPoint pStart 起点
* @param struct_PathPoint pEnd 终点
* @param UINT8 chDir 方向
* @param p_strPointInArea pSwInfo 道岔信息
* @param p_StrPathLinkInfo pLinkSeq link序列
* @return CI_ERROR失败 CI_SUCCESS成功
*/
UINT8 dsuLinkSeqInAreaBaseSwitchInfo(struct_PathPoint pStart, struct_PathPoint pEnd, UINT8 chDir, IN p_strPointInArea pSwInfo, OUT p_StrPathLinkInfo pLinkSeq)
{
	UINT8 chRtn = CI_ERROR;    /*返回返回值*/

							   /*此函数为底层函数的封装函数，入口参数完全可由被调用函数进行校验*/
	chRtn = dsuLinkSeqBtwLinkBaseSwitchInfo(pStart.wLinkId, pEnd.wLinkId, chDir, pSwInfo, pLinkSeq);

	return chRtn;
}

/**
* @brief 查询A点到B点的距离。
* @param p_strPathPoint pAPoint
* @param p_strPathPoint pBPoint
* @param UINT8 *pDir
* @return 距离 查询失败：UINT32_MAX，距离为0表示两点重合
*/
UINT32 DsuAPointToBPoint(p_strPathPoint pAPoint, p_strPathPoint pBPoint, UINT8 *pDir)
{
	UINT32 dwRetVal = UINT32_MAX;
	LOD_STRU LODAPointStru = { 0u };
	LOD_STRU LODBPointStru = { 0u };
	UINT8 cEmpDir = EMAP_SAME_DIR;
	UINT16 wlinkNum = 0u;
	UINT16 szLinkIdBuf[USE_DSU_TWOPOINT_LINK_SIZE] = { 0u };

	if ((NULL != pDir) && (0u != pAPoint->wLinkId) && (0u != pBPoint->wLinkId))
	{
		LODAPointStru.Lnk = pAPoint->wLinkId;
		LODAPointStru.Off = pAPoint->dwOffset;
		LODAPointStru.Dir = EMAP_SAME_DIR;

		LODBPointStru.Lnk = pBPoint->wLinkId;
		LODBPointStru.Off = pBPoint->dwOffset;
		LODBPointStru.Dir = EMAP_SAME_DIR;

		dwRetVal = dsuLenByPoint(&LODAPointStru, &LODBPointStru, &wlinkNum, szLinkIdBuf, &cEmpDir);

		if (UINT32_MAX != dwRetVal)
		{
			if (EMAP_SAME_DIR == cEmpDir)
			{
				*pDir = DIR_SAME;
			}
			else
			{
				*pDir = DIR_CONVERT;
			}
		}
	}
	else
	{
		;
	}

	return dwRetVal;
}

/**
* @brief 查询link属于道岔的位置。
* @param UINT16 wLinkID
* @param UINT16 wSwitchId
* @param UINT8 *p_LinkInSW
* @return CI_ERROR:查询失败；CI_SUCCESS:查询成功
*/
UINT8 dsuLinkofSwitchPos(UINT16 wLinkID, UINT16 wSwitchId, UINT8 *p_LinkInSW)
{
	UINT8 chRtn = CI_ERROR;		/*函数返回值*/
	DSU_POINT_STRU * pSwitchTemp = NULL;

	if (NULL != p_LinkInSW)
	{
		pSwitchTemp = g_dsuEmapStru->dsuStaticHeadStru->pPointStru + g_dsuEmapStru->dsuEmapIndexStru->dsuPointIndex[wSwitchId];

		if (NULL != pSwitchTemp)
		{
			if (wLinkID == pSwitchTemp->wConfluentLkId)
			{
				/*link为道岔的汇合link*/
				*p_LinkInSW = SW_CON_LINK;
			}
			else if (wLinkID == pSwitchTemp->wMainLkId)
			{
				/*link为道岔的定位link*/
				*p_LinkInSW = SW_MAIN_LINK;
			}
			else if (wLinkID == pSwitchTemp->wSideLkId)
			{
				/*link为道岔的反位link*/
				*p_LinkInSW = SW_SIDE_LINK;
			}
			else
			{
				*p_LinkInSW = SW_DEFAUT_LINK;
			}
			chRtn = CI_SUCCESS;
		}
		else
		{
			; /*查询错误，返回*/
		}
	}
	else
	{
		; /* 返回失败 */
	}

	return chRtn;
}

/**
* @brief 查询A点到B点间的link序列。
* @param p_strPathPoint pAPoint
* @param p_strPathPoint pBPoint
* @param UINT8 *pDir
* @param UINT16 * pLinkNum LINK数量
* @param UINT16 * pLinkIdBuf LINK编号缓存区
* @return CI_ERROR:查询失败；CI_SUCCESS:查询成功
*/
UINT8 DsuLinkSeqBtwPoints(p_strPathPoint pAPoint, p_strPathPoint pBPoint, OUT UINT8 *pDir, OUT UINT16 * pLinkNum, OUT UINT16 * pLinkIdBuf)
{
	UINT32 dwRetVal = UINT32_MAX;
	LOD_STRU LODAPointStru = { 0u };
	LOD_STRU LODBPointStru = { 0u };
	UINT8 cEmpDir = EMAP_SAME_DIR;
	UINT16 wlinkNum = 0u;
	UINT16 szLinkIdBuf[USE_DSU_TWOPOINT_LINK_SIZE] = { 0u };
	UINT8 chRtn = CI_ERROR;

	if ((NULL != pDir) && (0u != pAPoint->wLinkId) && (0u != pBPoint->wLinkId))
	{
		LODAPointStru.Lnk = pAPoint->wLinkId;
		LODAPointStru.Off = pAPoint->dwOffset;
		LODAPointStru.Dir = EMAP_SAME_DIR;

		LODBPointStru.Lnk = pBPoint->wLinkId;
		LODBPointStru.Off = pBPoint->dwOffset;
		LODBPointStru.Dir = EMAP_SAME_DIR;

		dwRetVal = dsuLenByPoint(&LODAPointStru, &LODBPointStru, pLinkNum, pLinkIdBuf, &cEmpDir);

		if (UINT32_MAX != dwRetVal)
		{
			if (EMAP_SAME_DIR == cEmpDir)
			{
				*pDir = DIR_SAME;
			}
			else
			{
				*pDir = DIR_CONVERT;
			}
			chRtn = CI_SUCCESS;
		}
		else
		{
			;
		}
	}
	else
	{
		;
	}

	return chRtn;
}

/**
* @brief 获取link在当前线路拓扑关系中所属计轴区段ID
* @param wLinkId
* @return link在当前线路拓扑关系中所属计轴区段ID
*/
UINT16 GetLinkBelongAcId(UINT16 wLinkId)
{
	UINT16 szLink[AXIS_INCLUDE_LINK_SUM_MAX];/* 存放连续link序列 */
	UINT8 chLinkNum = 0u;					/* 连续link数量 */
	UINT16 wRtn = 0u;
	UINT8 chFunRtn = CI_ERROR;
	LinkPointDataStru strPoint = { 0u };
	UINT16 wNextLinkId = 0u;
	UINT16 wSwitchId = 0u;
	UINT8 chAcLinkNum = 0u;
	UINT16 * pAcLinkId = NULL;
	UINT8 chAcNum = 0u;
	UINT16 * pAcId = NULL;
	UINT16 wPhySecId = 0u;
	UINT8 chAcIndex = 0u;
	UINT8 chLinkIndex = 0u;
	UINT8 chAcLinkIndex = 0u;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/

	chFunRtn = IsLinkIdValid(wLinkId);

	if (CI_SUCCESS == chFunRtn)
	{
		wPhySecId = GetLinkRelatedPhySec(wLinkId);
		/* 查询link放入计轴区段包含的link序列中 */
		szLink[chLinkNum++] = wLinkId;

		/* 反向查到计轴区段端点 */
		chFunRtn = GetLinkPointInfo(DIR_CONVERT, wLinkId, &strPoint);
		wNextLinkId = wLinkId;
		while ((EMAP_POINT_DOT == strPoint.wPointType) && (CI_SUCCESS == chFunRtn) && (UINT16_MAX != wNextLinkId) && (0U != wNextLinkId))
		{
			/*查询计轴内道岔点，不考虑方向变化点*/
			wNextLinkId = FindAdjacentLinkIDSafe(wNextLinkId, DIR_CONVERT, &wSwitchId, &cDirectionPointFlag);
			if ((UINT16_MAX != wNextLinkId)&&(0U != wNextLinkId))
			{/* 说明道岔四开 */
				szLink[chLinkNum++] = wNextLinkId;
				chFunRtn = GetLinkPointInfo(DIR_CONVERT, wNextLinkId, &strPoint);
			}
		}

		if (CI_SUCCESS == chFunRtn)
		{
			/* 正向查到计轴区段端点 */
			chFunRtn = GetLinkPointInfo(DIR_SAME, wLinkId, &strPoint);
			wNextLinkId = wLinkId;
			while ((EMAP_POINT_DOT == strPoint.wPointType) && (CI_SUCCESS == chFunRtn) && (UINT16_MAX != wNextLinkId) && (0U != wNextLinkId))
			{
				/*查询计轴内道岔点，不考虑方向变化点*/
				wNextLinkId = FindAdjacentLinkIDSafe(wNextLinkId, DIR_SAME, &wSwitchId, &cDirectionPointFlag);
				if ((UINT16_MAX != wNextLinkId) && (0U != wNextLinkId))
				{/* 说明道岔四开 */
					szLink[chLinkNum++] = wNextLinkId;
					chFunRtn = GetLinkPointInfo(DIR_SAME, wNextLinkId, &strPoint);
				}
			}

			if (CI_SUCCESS == chFunRtn)
			{
				chAcNum = GetPAxisSectionSum(wPhySecId);
				pAcId = GetPAxisSectionIdBuf(wPhySecId);
				if ((0u != chAcNum) && (NULL != pAcId))
				{
					for (chAcIndex = 0u; chAcIndex < chAcNum; chAcIndex++)
					{/* 遍历link所属物理区段包含的计轴区段 */
						chAcLinkNum = GetAxisLinkSum(pAcId[chAcIndex]);
						pAcLinkId = GetAxisLinkIdBuf(pAcId[chAcIndex]);
						if ((0u != chAcLinkNum) && (NULL != pAcLinkId))
						{
							for (chLinkIndex = 0u; chLinkIndex < chLinkNum; chLinkIndex++)
							{/* 遍历查找到的连续link序列 */
								for (chAcLinkIndex = 0u; chAcLinkIndex < chAcLinkNum; chAcLinkIndex++)
								{
									if (szLink[chLinkIndex] == pAcLinkId[chAcLinkIndex])
									{/* 在计轴区段包含的link之内 */
										break;
									}
								}
								if (chAcLinkIndex == chAcLinkNum)
								{/* link未在该计轴区段中找到 */
									break;
								}
							}
							if (chLinkIndex == chLinkNum)
							{/* 所有link均在计轴区段包含的link中找到 */
								wRtn = pAcId[chAcIndex];
							}
						}
					}
				}
			}
		}
	}

	return wRtn;
}

/************************************************************************
函数功能：将位置信息进行转换
入口参数: UINT16 wLinkSrc, UINT32 dwOffsetSrc
出口参数: UINT16* wLinkDst, UINT32* dwOffsetDst
返回值:  查询失败或查询到线路终端或输入位置不为link端点:  CI_ERROR;        查询成功: CI_SUCCESS
************************************************************************/
UINT8 dsuCheckSameLoc(UINT16 wLinkSrc, UINT32 dwOffsetSrc, UINT16* wLinkDst, UINT32* dwOffsetDst)
{
	UINT32 tmpLinkLen = 0u;                /*临时变量*/
	UINT8  chReturnValue = CI_ERROR;   /*函数返回结果,默认失败*/
	UINT8 chDirTemp = 0u;
	UINT8  chDirChangeTimes = 0u;  /*link方向改变次数*/
	UINT16 wLinkId = 0u;           /*link缓存*/
	UINT8 chFunRtn = CI_ERROR;
	UINT16 wSwitchId = 0u;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/

	chFunRtn = CheckLinkValid(wLinkSrc, dwOffsetSrc);
	/*判断数据输入的有效性*/
	if (CI_SUCCESS != chFunRtn)
	{
		/*无效数据输入，查询失败，返回默认值*/
		;
	}
	else
	{
		/*获取源link的长度*/
		tmpLinkLen = GetLinkLengthById(wLinkSrc);

		if (dwOffsetSrc == tmpLinkLen)
		{
			/*源link的偏移量若为当前link最大,则按照电子地图的正方向查找相邻link的起点*/
			*wLinkDst = FindAdjacentLinkIDSafe(wLinkSrc, EMAP_SAME_DIR, &wSwitchId, &cDirectionPointFlag);
			if ((UINT16_MAX == (*wLinkDst)) || (0u == (*wLinkDst)))
			{
				/*查询失败或查询到线路终端，返回失败*/
				;
			}
			else
			{
				if (DIRECTIONPOINT_FLAG_VALID == cDirectionPointFlag)
				{
					*dwOffsetDst = GetLinkLengthById((*wLinkDst));
				}
				else
				{
					*dwOffsetDst = 0u;
				}
				chReturnValue = CI_SUCCESS;
			}
		}
		else if (0u == dwOffsetSrc)
		{
			/*源link的偏移量若为当前link最小,则按照电子地图的反方向查找相邻link的终点*/
			*wLinkDst = FindAdjacentLinkIDSafe(wLinkSrc, EMAP_CONVER_DIR, &wSwitchId, &cDirectionPointFlag);
			if ((UINT16_MAX == (*wLinkDst)) || (0u == (*wLinkDst)))
			{
				/*查询失败或查询到线路终端，返回失败*/
				;
			}
			else
			{
				if (DIRECTIONPOINT_FLAG_VALID == cDirectionPointFlag)
				{
					*dwOffsetDst = 0u;
				}
				else
				{
					*dwOffsetDst = GetLinkLengthById((*wLinkDst));
				}
				chReturnValue = CI_SUCCESS;
			}
		}
		else
		{
			/*若当前输入的偏移量查过link长度,或者不为当前link的始端、也不为终端,则查询结果失败*/
			;
		}
	}
	return chReturnValue;
}


/*********************************************
函数功能：根据link序列获得记轴区段编号序列
输入参数：linkId 序列首地址，LinkNum link个数
输出参数：AxleSgmtId 记轴区段编号数组地址
AxleSgmtNum 数组长度
返回值：CI_ERROR失败，CI_SUCCESS成功
注：岔区的link必须是连续的
**********************************************/
UINT8 GetAxisSeqFromLinkSeq(UINT16* linkId, UINT16 LinkNum, UINT16 *AxleSgmtId, UINT16 * AxleSgmtNum, UINT16 maxSize)
{
	UINT8 rtnValue = CI_ERROR;
	UINT8 buffValidFlag = CI_ERROR;
	UINT8 funRtn = CI_ERROR;
	UINT8 execValid = CI_ERROR;
	UINT16 acNum = 0U;
	UINT16 tmpLinkCnt = 0U;
	UINT16 tmpLinkId[LINK_SUM_MAX] = { 0U };    /*缓存同一物理区段包含的link*/
	UINT16 tmpSameLinkOfACCnt = 0U;
	UINT16 tmpSameLinkOfACID[PHYSICAL_INCLUDE_AXIS_SUM_MAX] = { 0U };  /*缓存同一物理区段包含的link所属计轴*/
	UINT16 tmpSearchedFlag[LINK_SUM_MAX] = { 0U };    /*link是否已经处理过*/
	UINT16 linkIndex = 0U;
	UINT16 linkOfPhyId = 0U;
	UINT16 tmplinkOfPhyId = 0U;
	UINT16 cycleone = 0U;
	UINT16 cycleTwo = 0U;
	UINT16 cycleAC = 0U;
	UINT16 cycleLink = 0U;
	UINT16 cycleLinkInAC = 0U;
	UINT16 cycleSw = 0U;
	UINT16 tmpACCnt = 0U;
	UINT8 tmpLinkCntInAC = 0U;
	UINT8 tmpSwCntInAC = 0U;
	UINT8 tmpLinkinSwType = SW_DEFAUT_LINK;
	UINT8 tmpSwPos = SWITCH_POSITION_INVALID;
	const UINT16* pACIDBuf = NULL;
	const UINT16* pLinkIDBuf = NULL;
	const AxisSwitchStruct* pSwitchInfoBuf = NULL;
	UINT8 chFlagOne = FLAG_UNSET;
	UINT8 chFlagTwo = FLAG_UNSET;
	UINT8 chCheckStart = FLAG_UNSET;
	UINT16 szCheckedSw[AXIS_INCLUDE_SWITCH_SUM_MAX] = { 0U };
	UINT8 chCheckedSwNum = 0U;
	UINT8 chCheckedFlag = CI_ERROR;
	UINT8 chLoopIndex = 0U;
	UINT16 szLoopLinkId[AXIS_INCLUDE_LINK_SUM_MAX] = { 0U };
	AxisSwitchStruct szLoopSwitchInfo[AXIS_INCLUDE_SWITCH_SUM_MAX] = { 0U };
	UINT8 cFuncSwitch = 0U;

	/*入参检测*/
	if ((NULL == linkId) || (0U == LinkNum) || (NULL == AxleSgmtId) || (NULL == AxleSgmtNum) || (acNum >= maxSize))
	{
		;
	}
	else
	{
		buffValidFlag = CI_SUCCESS;
		rtnValue = CI_SUCCESS;
	}


	if (CI_SUCCESS == rtnValue)
	{
		for (cycleone = 0U; cycleone < LinkNum; cycleone++)
		{
			/** 先清除缓存*/
			tmpLinkCnt = 0U;
			(void)CommonMemSet(tmpLinkId, (UINT32)(sizeof(UINT16) * LINK_SUM_MAX), 0, (UINT32)(sizeof(UINT16) * LINK_SUM_MAX));
			tmpSameLinkOfACCnt = 0U;
			(void)CommonMemSet(tmpSameLinkOfACID, (UINT32)(sizeof(UINT16) * PHYSICAL_INCLUDE_AXIS_SUM_MAX), 0, (UINT32)(sizeof(UINT16) * PHYSICAL_INCLUDE_AXIS_SUM_MAX));


			/** 获取link索引 */
			linkIndex = GetLinkIndexById(linkId[cycleone]);
			if (linkIndex >= LINK_SUM_MAX)
			{
				chFlagOne = FLAG_SET;
			}
			else if (UINT8_MAX == tmpSearchedFlag[linkIndex])
			{
				;/*此link处理过，无需处理 */
			}
			else
			{
				/*- 第一步：获取同一物理区段的所有link */
				linkOfPhyId = GetLinkRelatedPhySec(linkId[cycleone]);

				if (0U == linkOfPhyId)
				{
					/** 数据查询错误*/
					chFlagOne = FLAG_SET;
				}
				else
				{
					/** 继续处理 */
				}
				if (FLAG_UNSET == chFlagOne)
				{
					tmpLinkId[tmpLinkCnt++] = linkId[cycleone];
					tmpSearchedFlag[linkIndex] = UINT8_MAX;

					/*查询link所属物理区段相同的link*/
					for (cycleTwo = cycleone + 1U; cycleTwo < LinkNum; cycleTwo++)
					{
						/*获取link所属物理区段*/
						tmplinkOfPhyId = GetLinkRelatedPhySec(linkId[cycleTwo]);
						linkIndex = GetLinkIndexById(linkId[cycleTwo]);

						if ((linkOfPhyId == tmplinkOfPhyId) && (UINT16_MAX != linkIndex))
						{
							/*注：tmpLinkId不越界防护是因为考虑了最大情况，一定不会越界*/
							tmpLinkId[tmpLinkCnt++] = linkId[cycleTwo];
							tmpSearchedFlag[linkIndex] = UINT8_MAX;
						}
						else
						{
							/*不处理*/
						}
					}

					/*- 第二步：遍历统一物理区段的所有计轴，找到包含所有link的计轴*/
					tmpACCnt = GetPAxisSectionSum(linkOfPhyId);
					pACIDBuf = GetPAxisSectionIdBuf(linkOfPhyId);

					if ((0U == tmpACCnt) || (NULL == pACIDBuf))
					{
						/** 查询错误 */
						chFlagOne = FLAG_SET;
					}
					else if (1U == tmpACCnt)
					{
						/** 直轨*/
						if (acNum < maxSize)
						{
							AxleSgmtId[acNum++] = pACIDBuf[0];
						}
						else
						{
							/** AxleSgmtId空间不够 */
							buffValidFlag = CI_ERROR;
						}
					}
					else
					{
						/** 存在道岔，需要进行判断*/
						for (cycleAC = 0U; cycleAC < tmpACCnt; cycleAC++)
						{
							/** 获取计轴上的link数量*/
							tmpLinkCntInAC = GetAxisLinkSum(pACIDBuf[cycleAC]);
							pLinkIDBuf = GetAxisLinkIdBuf(pACIDBuf[cycleAC]);

							if ((0U == tmpLinkCntInAC) || (NULL == pLinkIDBuf))
							{
								/*查询失败*/
								break;
							}
							else
							{
								/* 判断link是否全部在计轴范围内 */
								for (cycleLink = 0U; cycleLink < tmpLinkCnt; cycleLink++)
								{
									for (cycleLinkInAC = 0U; cycleLinkInAC < tmpLinkCntInAC; cycleLinkInAC++)
									{
										if (pLinkIDBuf[cycleLinkInAC] == tmpLinkId[cycleLink])
										{
											/** 同一物理区段的link在计轴范围内 */
											break;
										}
										else
										{
											/** 继续遍历 */
										}
									}

									if (cycleLinkInAC == tmpLinkCntInAC)
									{
										/** link不属于该计轴，此计轴不是所要找寻的计轴*/
										break;
									}
									else
									{
										/* 继续遍历 */
									}
								}

								if (cycleLink == tmpLinkCnt)
								{
									/** 该计轴包含所有的link,缓存该计轴ID */
									tmpSameLinkOfACID[tmpSameLinkOfACCnt++] = pACIDBuf[cycleAC];
								}
								else
								{
									/** 继续遍历 */
								}
							}
						}

						/** 判断执行是否成功 */
						if ((cycleAC == tmpACCnt) && (0U != tmpSameLinkOfACCnt))
						{
							/** 执行正确，继续执行*/
						}
						else
						{
							/** 处理错误 */
							chFlagOne = FLAG_SET;
						}

						/*- 第三步：对计轴内的道岔进行校核*/
						if (FLAG_UNSET == chFlagOne)
						{
							if (1U == tmpSameLinkOfACCnt)
							{
								/** 只查询一个道岔，不进行道岔校验，无需判断道岔条件*/
								if (acNum < maxSize)
								{
									AxleSgmtId[acNum++] = tmpSameLinkOfACID[0];
								}
								else
								{
									/** AxleSgmtId空间不够 */
									buffValidFlag = CI_ERROR;
								}
							}
							else
							{
								/** 进入此分支，execValid一定会置成成功*/
								execValid = CI_ERROR;
								cFuncSwitch = GetCiFunctionSwitchConfig(FUNC_ROUTE_DRV_SWITCH_EARLY);
								for (cycleAC = 0U; cycleAC < tmpSameLinkOfACCnt; cycleAC++)
								{
									/** 需要周期清空 */
									if (FUNC_SWITCH_ON == cFuncSwitch)
									{
										chCheckStart = FLAG_UNSET;  /*修复缺陷YF0083-2106*/
									}
									else
									{
										chCheckStart = FLAG_SET;
									}

									/** 获取计轴上的道岔信息*/
									tmpSwCntInAC = GetAxisSwitchSum(tmpSameLinkOfACID[cycleAC]);
									pSwitchInfoBuf = GetAxisSwitchIdStru(tmpSameLinkOfACID[cycleAC]);

									/** 获取计轴上的link数量*/
									tmpLinkCntInAC = GetAxisLinkSum(tmpSameLinkOfACID[cycleAC]);
									pLinkIDBuf = GetAxisLinkIdBuf(tmpSameLinkOfACID[cycleAC]);

									if ((NULL == pSwitchInfoBuf) || (NULL == pLinkIDBuf))
									{
										/*查询失败*/
										break;
									}
									else
									{
										/* 重置标志位 */
										chCheckedSwNum = 0U;
										(void)CommonMemCpy(&szLoopLinkId[0], (UINT32)(sizeof(UINT16) * tmpLinkCntInAC), &pLinkIDBuf[0], (UINT32)(sizeof(UINT16) * tmpLinkCntInAC));
										(void)CommonMemCpy(&szLoopSwitchInfo[0], (UINT32)(sizeof(AxisSwitchStruct) * tmpSwCntInAC), &pSwitchInfoBuf[0], (UINT32)(sizeof(AxisSwitchStruct) * tmpSwCntInAC));
										/** 校验符合道岔关系的计轴区段 */
										if ((pLinkIDBuf[0] == tmpLinkId[0])
											|| (pLinkIDBuf[0] == tmpLinkId[tmpLinkCnt - 1]))
										{
											; /* 包含计轴区段第一link，按正序遍历 */
										}
										else if ((pLinkIDBuf[tmpLinkCntInAC - 1] == tmpLinkId[0])
											|| (pLinkIDBuf[tmpLinkCntInAC - 1] == tmpLinkId[tmpLinkCnt - 1]))
										{/* 不包含计轴区段第一link，单包含计轴区段最后一个link，需要倒序 */
											for (chLoopIndex = 0U; chLoopIndex < tmpLinkCntInAC / 2U; chLoopIndex++)
											{/* 遍历倒序link */
												szLoopLinkId[chLoopIndex] = pLinkIDBuf[tmpLinkCntInAC - chLoopIndex - 1];
												szLoopLinkId[tmpLinkCntInAC - chLoopIndex - 1] = pLinkIDBuf[chLoopIndex];
											}
											if (0U == tmpLinkCntInAC % 2U)
											{
												; /* 偶数个，不处理 */
											}
											else
											{/* 计轴区段包含奇数个link，倒序完成后，赋值中间link */
												szLoopLinkId[tmpLinkCntInAC / 2] = pLinkIDBuf[tmpLinkCntInAC / 2];
											}
											for (chLoopIndex = 0U; chLoopIndex < tmpSwCntInAC / 2U; chLoopIndex++)
											{/* 遍历倒序道岔信息 */
												szLoopSwitchInfo[chLoopIndex].SwitchId = pSwitchInfoBuf[tmpSwCntInAC - chLoopIndex - 1].SwitchId;
												szLoopSwitchInfo[chLoopIndex].SwitchPosition = pSwitchInfoBuf[tmpSwCntInAC - chLoopIndex - 1].SwitchPosition;
												szLoopSwitchInfo[tmpSwCntInAC - chLoopIndex - 1].SwitchId = pSwitchInfoBuf[chLoopIndex].SwitchId;
												szLoopSwitchInfo[tmpSwCntInAC - chLoopIndex - 1].SwitchPosition = pSwitchInfoBuf[chLoopIndex].SwitchPosition;
											}
											if (0U == tmpSwCntInAC % 2U)
											{
												; /* 偶数个，不处理 */
											}
											else
											{/* 计轴区段包含奇数个道岔，倒序完成后，赋值中间道岔信息 */
												szLoopSwitchInfo[tmpSwCntInAC / 2].SwitchId = pSwitchInfoBuf[tmpSwCntInAC / 2].SwitchId;
												szLoopSwitchInfo[tmpSwCntInAC / 2].SwitchPosition = pSwitchInfoBuf[tmpSwCntInAC / 2].SwitchPosition;
											}
										}
										else
										{
											; /* 不包含计轴区段第一link，也不包含最后一个link，按默认顺序遍历 */
										}

										for (cycleLinkInAC = 0U; cycleLinkInAC < tmpLinkCntInAC; cycleLinkInAC++)
										{
											if (FLAG_UNSET == chCheckStart)
											{
												for (cycleLink = 0U; cycleLink < tmpLinkCnt; cycleLink++)
												{
													if (tmpLinkId[cycleLink] == szLoopLinkId[cycleLinkInAC])
													{
														/** 找到需要开始检查的link起点 */
														chCheckStart = FLAG_SET;
													}
												}
											}
											else
											{
												/** 无需处理 */
											}

											if (FLAG_UNSET == chCheckStart)
											{
												/** 无需处理 */
											}
											else
											{
												/* 重置标志位 */
												chFlagTwo = FLAG_UNSET;

												for (cycleSw = 0U; cycleSw < tmpSwCntInAC; cycleSw++)
												{
													funRtn = dsuLinkofSwitchPos(szLoopLinkId[cycleLinkInAC], szLoopSwitchInfo[cycleSw].SwitchId, &tmpLinkinSwType);

													if (CI_ERROR == funRtn)
													{
														/** 查询错误，返回*/
														chFlagTwo = FLAG_SET;
													}
													else if ((SW_CON_LINK == tmpLinkinSwType) || (SW_MAIN_LINK == tmpLinkinSwType) || (SW_SIDE_LINK == tmpLinkinSwType))
													{
														chCheckedFlag = IsMenberOfSeq(szLoopSwitchInfo[cycleSw].SwitchId, chCheckedSwNum, szCheckedSw);
														if (CI_SUCCESS != chCheckedFlag)
														{
															if (SW_CON_LINK == tmpLinkinSwType)
															{
																tmpSwPos = GetSwitchCurPosition(szLoopSwitchInfo[cycleSw].SwitchId);

																if (((SWITCH_POSITION_DINGWEI == tmpSwPos) || (SWITCH_POSITION_FANWEI == tmpSwPos)) &&
																	(tmpSwPos != szLoopSwitchInfo[cycleSw].SwitchPosition))
																{
																	/** 道岔位置正确但不符合预期，跳出*/
																	chFlagTwo = FLAG_SET;
																}
																else
																{
																	/*继续遍历*/
																}
															}
															else
															{
																/** 非道岔汇合link,无需关心道岔位置,继续遍历*/
															}
															szCheckedSw[chCheckedSwNum++] = szLoopSwitchInfo[cycleSw].SwitchId;
														}
														else
														{
															; /* 道岔已经检查过位置。 */
														}
													}
													else
													{
														/** 非道岔link,无需关心道岔位置,继续遍历*/
													}

													if (FLAG_SET == chFlagTwo)
													{
														break;
													}
													else
													{
														;
													}
												}

												/** 判断查询结果 */
												if (cycleSw != tmpSwCntInAC)
												{
													/** 道岔不符合要求，不缓存计轴 */
													break;
												}
												else
												{
													/** 道岔符合要求， 继续遍历下一个道岔*/
												}
											}
										}

										if ((FLAG_SET == chCheckStart) && (cycleLinkInAC == tmpLinkCntInAC))
										{
											/** 该计轴为所要找的计轴*/
											if (acNum < maxSize)
											{
												AxleSgmtId[acNum++] = tmpSameLinkOfACID[cycleAC];
											}
											else
											{
												/** AxleSgmtId空间不够 */
												buffValidFlag = CI_ERROR;
											}

											execValid = CI_SUCCESS;
										}
										else
										{
											/** 不符合要求，继续查找*/
										}
									}
								}

								/** 判断执行是否成功 */
								if ((cycleAC == tmpSameLinkOfACCnt) && (CI_SUCCESS == execValid))
								{
									/** 执行正确，继续执行*/
								}
								else
								{
									/** 处理错误 */
									chFlagOne = FLAG_SET;
								}
							}
						}
						else
						{
							;/* 需要结束循环，什么也不做 */
						}
					}
				}
				else
				{
					;/* 需要结束循环，什么也不做 */
				}
			}

			if (FLAG_SET == chFlagOne)
			{
				break;
			}
			else
			{
				;
			}
		}

		/** 设置返回结果*/
		if ((cycleone == LinkNum) && (CI_SUCCESS == buffValidFlag))
		{
			(*AxleSgmtNum) = acNum;
			rtnValue = CI_SUCCESS;
		}
		else
		{
			/** 查询失败*/
			(*AxleSgmtNum) = 0U;
			rtnValue = CI_ERROR;
		}
	}
	else
	{
		/** 入口参数错误，不处理*/
	}

	return rtnValue;
}

/**
* @brief 通过起终点link和两link中link序列信息查询两link间的道岔信息。
* @param UINT16 linkA
* @param UINT16 linkB
* @param UINT8 chDir
* @param IN p_StrPathLinkInfo pLinkSeq
* @param OUT p_strPointInArea pSwInfo
* @return CI_ERROR:失败；CI_SUCCESS:成功
*/
UINT8 dsuSwitchInfoBtwLinkBaseLinkSeq(UINT16 linkA, UINT16 linkB, UINT8 chDir, IN p_StrPathLinkInfo pLinkSeq, OUT p_strPointInArea pSwInfo)
{
	UINT8 chRtn = CI_ERROR;    /*返回返回值*/
	UINT8 chFunRtn = CI_ERROR;  /*查询函数返回值*/
	UINT8 chCycle = 0u;    /*遍历link序列*/
	UINT16 currentLinkID = UINT16_MAX;   /*当前link*/
	UINT16 wPreLinkID = UINT16_MAX;   /*上一link*/
	UINT16 nextLinkID = UINT16_MAX;     /*next link*/
	UINT8 exStatus = 0u;    /*两link之间的道岔状态*/
	LinkPointDataStru pathTree = { 0u };         /*link端点信息*/
	UINT8 chBreakRtn = FLAG_UNSET;
	UINT8 cTmpIndex = 0u;
	UINT8 cQueryDir = 0U;  /*link查询方向*/
	UINT8 cCurLinkDirChanged = LINK_DIRCHANGE_NONE;  /*当前Link方向变化点*/
	UINT8 cPreLinkDirChanged = LINK_DIRCHANGE_NONE;  /*上一Link方向变化点*/

	/*入口参数检查*/
	if ((NULL == pLinkSeq) || (NULL == pSwInfo))
	{
		/*入口函数非法，返回失败*/
	}
	else if ((DIR_SAME != chDir) && (DIR_CONVERT != chDir))
	{
		/*入口函数非法，返回失败*/
	}
	else if ((0u == pLinkSeq->cLinkCnt) ||
		(linkA != pLinkSeq->szLinkId[0]) ||
		(linkB != pLinkSeq->szLinkId[pLinkSeq->cLinkCnt - 1U]))
	{
		/*起点linkID与终点linkID与计划的起终点不相符合，入口函数非法，返回失败*/
		;
	}
	else
	{
		/*初始化道岔信息*/
		(void)CommonMemSet(pSwInfo, (UINT32)sizeof(str_PointInArea), 0u, (UINT32)sizeof(str_PointInArea));

		
		cTmpIndex = pLinkSeq->cLinkCnt - 1u;
		cQueryDir = chDir;

		/*依次遍历所有的link序列*/
		for (chCycle = 0u; chCycle < pLinkSeq->cLinkCnt; chCycle++)
		{
			/*周期设置返回值为失败*/
			chRtn = CI_ERROR;

			/*缓存端点link*/
			currentLinkID = pLinkSeq->szLinkId[chCycle];
			if (0U < chCycle)
			{
				wPreLinkID = pLinkSeq->szLinkId[chCycle - 1U];  /*当前link的上一link*/
			}
			else
			{
				wPreLinkID = 0U;
			}

			/*判断方向变化点*/
			cCurLinkDirChanged = GetLinkLogicDirChangedById(currentLinkID);
			cPreLinkDirChanged = GetLinkLogicDirChangedById(wPreLinkID);
			if (((LINK_DIRCHANGE_BEGIN == cPreLinkDirChanged) || (LINK_DIRCHANGE_END == cPreLinkDirChanged))
				&& (cPreLinkDirChanged == cCurLinkDirChanged))
			{
				/*存在方向变化点*/
				cQueryDir = ~cQueryDir;
			}
			else
			{
				/*不存在方向变化点，不处理*/
			}

			/* 获取当前link端点信息 */

			chFunRtn = GetLinkPointInfo(cQueryDir, pLinkSeq->szLinkId[chCycle], &pathTree);

			if ((chCycle == cTmpIndex) && (CI_SUCCESS == chFunRtn))
			{
				/*设置查询成功*/
				chRtn = CI_SUCCESS;
			}
			else if ((chCycle != cTmpIndex) && (CI_SUCCESS == chFunRtn))
			{
				if (EMAP_POINT_DOT == pathTree.wPointType)
				{
					nextLinkID = pLinkSeq->szLinkId[chCycle + 1U];
					chFunRtn = dsuSwitchStatusBtwLink(pathTree.wPointId, currentLinkID, nextLinkID, &exStatus);

					if (CI_ERROR == chFunRtn)
					{
						/*查询错误，返回*/
						chBreakRtn = FLAG_SET;
					}
					else
					{
						pSwInfo->SwitchInfo[pSwInfo->SwitchNum].pointID = pathTree.wPointId;
						pSwInfo->SwitchInfo[pSwInfo->SwitchNum].status = exStatus;
						pSwInfo->SwitchNum++;
					}

				}
				else
				{
					/*继续查询*/
				}

				/*设置查询成功*/
				chRtn = CI_SUCCESS;
			}
			else
			{
				/*查询失败，跳出*/
				chBreakRtn = FLAG_SET;
			}

			if (FLAG_SET == chBreakRtn)
			{
				chRtn = CI_ERROR;
				break;
			}
			else
			{
			}
		}

		if (CI_SUCCESS == chRtn)
		{
			/*查询成功*/
		}
		else
		{
			/*查询不成功，清空*/
			(void)CommonMemSet(pSwInfo, (UINT32)sizeof(str_PointInArea), 0u, (UINT32)sizeof(str_PointInArea));
		}
	}

	return chRtn;
}

/**
* @brief 获取点所处逻辑区段
* @param struct_PathPoint strPoint 点
* @return 逻辑区段ID
* @note 判断点处于逻辑区段区域时，判断逻辑区段所有道岔都在期望位置，则找到逻辑区段
*/
UINT16 GetPointBelongLogSec(struct_PathPoint strPoint)
{
	UINT16 wLogicSum = 0u;
	UINT16 wLogicId = 0u;
	UINT16 wIndex = 0u;
	UINT16 wLinkNum = 0U;
	str_Zone strZone = { 0u };
	UINT16 wOrgnLink = 0u;
	UINT16 wTmanLink = 0u;
	UINT32 dwOrgnOffset = UINT32_MAX;
	UINT32 dwTmnlOffset = UINT32_MAX;
	UINT32 dwLen = UINT32_MAX;
	LOD_STRU strPointA = { 0u };
	LOD_STRU strPointB = { 0u };
	UINT8 chFunRtn = CI_ERROR;
	UINT16 wRtn = 0u;
	str_PointInArea strSwitchInfo = { 0u };
	UINT8 chSwitchIndex = 0u;
	UINT8 chSwitchPos = 0u;
	UINT16 wszLogicIdBuf[PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U] = { 0U };



	chFunRtn = CheckLinkValid(strPoint.wLinkId, strPoint.dwOffset);

	if (CI_SUCCESS == chFunRtn)
	{
		chFunRtn = GetLinkRelLgcId(1, &strPoint.wLinkId, &wLogicSum, wszLogicIdBuf);
	}
	else
	{
		; /* DO NOTHING */
	}

	if (CI_SUCCESS == chFunRtn)
	{
		for (wIndex = 0u; wIndex < wLogicSum; wIndex++)
		{
			wLogicId = wszLogicIdBuf[wIndex];
			strZone.pStart.wLinkId = GetLgcSecOrgnLink(wLogicId);
			strZone.pStart.dwOffset = GetLgcSecOrgnOffset(wLogicId);
			strZone.pEnd.wLinkId = GetLgcSecTmnlLink(wLogicId);
			strZone.pEnd.dwOffset = GetLgcSecTmnlOffset(wLogicId);
			strPointA.Lnk = strZone.pStart.wLinkId;
			strPointA.Off = strZone.pStart.dwOffset;
			strPointB.Lnk = strZone.pEnd.wLinkId;
			strPointB.Off = strZone.pEnd.dwOffset;
			dwLen = dsuLenByPoint(&strPointA, &strPointB, &wLinkNum, strZone.pLinkSeq.szLinkId, &strZone.Dir);
			/*不会超过UINT8_MAX*/
			strZone.pLinkSeq.cLinkCnt = (UINT8)wLinkNum;
			if (UINT32_MAX != dwLen)
			{
				chFunRtn = IsPointInPath(strPoint, strZone);
				if (CI_ERROR == chFunRtn)
				{
					chFunRtn = dsuSwitchInfoBtwLinkBaseLinkSeq(strZone.pStart.wLinkId, strZone.pEnd.wLinkId, strZone.Dir, &strZone.pLinkSeq, &strSwitchInfo);
					if (CI_SUCCESS == chFunRtn)
					{
						for (chSwitchIndex = 0u; chSwitchIndex < strSwitchInfo.SwitchNum; chSwitchIndex++)
						{
							chSwitchPos = GetSwitchCurPosition(strSwitchInfo.SwitchInfo[chSwitchIndex].pointID);
							if (chSwitchPos != strSwitchInfo.SwitchInfo[chSwitchIndex].status)
							{
								break;
							}
						}

						if (chSwitchIndex == strSwitchInfo.SwitchNum)
						{
							wRtn = wLogicId;
							break;
						}
					}
				}
			}
		}
	}
	else
	{
		;
	}
	return wRtn;
}

/**
* @brief 获取两点间所有逻辑区段
* @param struct_PathPoint strPoint 点
* @return 逻辑区段ID
*/
UINT8 GetLogSecBtwTwoPoints(struct_PathPoint strStart, struct_PathPoint strEnd, UINT16 * pLogSecNum, UINT16 szLogId[])
{
	UINT16 wLogicSum = 0u;
	UINT16 wLogicId = 0u;
	UINT16 wIndex = 0u;
	str_Zone strZone = { 0u };
	UINT16 wOrgnLink = 0u;
	UINT16 wTmanLink = 0u;
	UINT32 dwOrgnOffset = UINT32_MAX;
	UINT32 dwTmnlOffset = UINT32_MAX;
	UINT32 dwLen = UINT32_MAX;
	LOD_STRU strPointA = { 0u };
	LOD_STRU strPointB = { 0u };
	UINT8 chFunRtn = CI_ERROR;
	UINT16 wRtn = 0u;
	struct_PathPoint strOrgn = { 0u };
	struct_PathPoint strTmnl = { 0u };
	UINT16 wNum = 0u;
	str_Zone strZoneLgc = { 0u };
	UINT16 wLink = 0u;
	UINT8 chLinkNum = 0u;
	UINT16 wSwitchId = 0u;
	UINT8 chEstatus = 0u;
	UINT8 chSwitchPos = 0u;
	UINT16 wLinkNum = 0u;
	UINT8 chLgcSwPosCheckFlag = CI_ERROR;	/* 逻辑区段道岔连通检查标志 */
	UINT16 wLogicIdBuf[PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U] = { 0U };
	UINT16 wPrePhyId = 0u;
	UINT16 wCurPhyId = 0u;
	UINT8 chLgcSwIndex = 0u;
	UINT8 chLgcSwNum = 0u;
	LogsecSwitchStruct * pLgcSwInfo = NULL;
	UINT16 wTmpLgcNum = 0u;
	UINT8 chFitSwNum = 0u;
	UINT8 chMaxFitSwNum = 0u;
	UINT8 chSwCurPos = 0u;


	/* 入参检测 */
	if ((NULL == pLogSecNum) || (NULL == szLogId))
	{
		chFunRtn = CI_ERROR;
	}
	else
	{
		chFunRtn = CheckLinkValid(strStart.wLinkId, strStart.dwOffset);
		chFunRtn &= CheckLinkValid(strEnd.wLinkId, strEnd.dwOffset);
	}

	/* 计算列车占压区域 */
	if (CI_SUCCESS == chFunRtn)
	{
		strZone.pStart.wLinkId = strStart.wLinkId;
		strZone.pStart.dwOffset = strStart.dwOffset;
		strZone.pEnd.wLinkId = strEnd.wLinkId;
		strZone.pEnd.dwOffset = strEnd.dwOffset;
		strPointA.Lnk = strZone.pStart.wLinkId;
		strPointA.Off = strZone.pStart.dwOffset;
		strPointB.Lnk = strZone.pEnd.wLinkId;
		strPointB.Off = strZone.pEnd.dwOffset;
		dwLen = dsuLenByPoint(&strPointA, &strPointB, &wLinkNum, strZone.pLinkSeq.szLinkId, &strZone.Dir);
		strZone.pLinkSeq.cLinkCnt = (UINT8)wLinkNum;
		if (UINT32_MAX != dwLen)
		{
			chFunRtn = GetLinkRelLgcId(strZone.pLinkSeq.cLinkCnt, strZone.pLinkSeq.szLinkId,&wLogicSum, wLogicIdBuf);
		}
		else
		{
			chFunRtn = CI_ERROR;
		}
	}
	else
	{
		;
	}
	
	/* 寻找区域包含的所有逻辑区段 */
	if (CI_SUCCESS == chFunRtn)
	{
		for (wIndex = 0u; wIndex < wLogicSum; wIndex++)
		{/* 遍历逻辑区段 */
			wLogicId = wLogicIdBuf[wIndex];
			wCurPhyId = GetLgcSecRelativePhySecId(wLogicId);
			if (wCurPhyId != wPrePhyId)
			{
				wTmpLgcNum = wNum;
				chMaxFitSwNum = 0u;
			}
			else
			{
				; /* do nothing */
			}
			strOrgn.wLinkId = GetLgcSecOrgnLink(wLogicId);
			strOrgn.dwOffset = GetLgcSecOrgnOffset(wLogicId);
			strTmnl.wLinkId = GetLgcSecTmnlLink(wLogicId);
			strTmnl.dwOffset = GetLgcSecTmnlOffset(wLogicId);
			chFunRtn = CheckLinkValid(strOrgn.wLinkId, strOrgn.dwOffset);
			chFunRtn &= CheckLinkValid(strTmnl.wLinkId, strTmnl.dwOffset);
			chFitSwNum = 0u;
			if (CI_ERROR == chFunRtn)
			{
				break;
			}
			/* 获取逻辑区段区域 */
			strZoneLgc.pStart.wLinkId = strOrgn.wLinkId;
			strZoneLgc.pStart.dwOffset = strOrgn.dwOffset;
			strZoneLgc.pEnd.wLinkId = strTmnl.wLinkId;
			strZoneLgc.pEnd.dwOffset = strTmnl.dwOffset;
			strPointA.Lnk = strZoneLgc.pStart.wLinkId;
			strPointA.Off = strZoneLgc.pStart.dwOffset;
			strPointB.Lnk = strZoneLgc.pEnd.wLinkId;
			strPointB.Off = strZoneLgc.pEnd.dwOffset;
			dwLen = dsuLenByPoint(&strPointA, &strPointB, &wLinkNum, strZoneLgc.pLinkSeq.szLinkId, &strZoneLgc.Dir);
			strZoneLgc.pLinkSeq.cLinkCnt = (UINT8)wLinkNum;
			if (UINT32_MAX != dwLen)
			{
				;
			}
			else
			{
				chFunRtn = CI_ERROR;
			}

			if (CI_SUCCESS == chFunRtn)
			{/* 逻辑区段与两点形成的区域是否相交 */
				chFunRtn = CheckZoneIsCrossing(&strZone, &strZoneLgc);
				if (CI_ERROR == chFunRtn)
				{/* 相交 */
					chFunRtn = CI_SUCCESS;
					chLinkNum = GetSecIntrudeLinkSum(wLogicId);
					chLgcSwPosCheckFlag = IsLgcNeedCheckSwitchPos(wLogicId, strZone);
					chLgcSwNum = GetLogicSecSwitchSum(wLogicId);
					pLgcSwInfo = GetLogicSecSwitchIdStru(wLogicId);
					if ((chLinkNum > 1u) && (CI_SUCCESS == chLgcSwPosCheckFlag))
					{/* 逻辑区段不只包含一个link */
						for (chLgcSwIndex = 0u; chLgcSwIndex < chLgcSwNum; chLgcSwIndex++)
						{
							chSwCurPos = GetSwitchCurPosition(pLgcSwInfo[chLgcSwIndex].SwitchId);
							if (((SWITCH_POSITION_DINGWEI == chSwCurPos) || (SWITCH_POSITION_FANWEI == chSwCurPos))
								&& (chSwCurPos != pLgcSwInfo[chLgcSwIndex].SwitchPosition))
							{
								chFunRtn = CI_ERROR;
							}
							else
							{
								; /* do nothing */
							}
						}
					}
					else
					{
						chFunRtn = CI_SUCCESS;
					}
					if ((chLinkNum > 1u) && (CI_ERROR == chLgcSwPosCheckFlag))
					{
						for (chLgcSwIndex = 0u; chLgcSwIndex < chLgcSwNum; chLgcSwIndex++)
						{
							chSwCurPos = GetSwitchCurPosition(pLgcSwInfo[chLgcSwIndex].SwitchId);
							if ((chSwCurPos == pLgcSwInfo[chLgcSwIndex].SwitchPosition)
								|| ((SWITCH_POSITION_DINGWEI != chSwCurPos) && (SWITCH_POSITION_FANWEI != chSwCurPos)))
							{
								chFitSwNum++;
							}
							else
							{
								; /* do nothing */
							}
						}
						if (chFitSwNum == chLgcSwNum)
						{/* 有交集，所有道岔均在期望位置 */
							chFitSwNum = (UINT8)LOGSEC_INCLUDE_SWITCH_SUM_MAX + 1u;
						}
						else
						{
							; /* do nothing */
						}
						if (chFitSwNum > chMaxFitSwNum)
						{
							chMaxFitSwNum = chFitSwNum;
							szLogId[wTmpLgcNum] = wLogicId;
							wNum = wTmpLgcNum + 1u;
						}
						else if (chFitSwNum == chMaxFitSwNum)
						{
							szLogId[wNum++] = wLogicId;
						}
						else
						{
							; /* do nothing */
						}
					}
					else
					{
						if (CI_SUCCESS == chFunRtn)
						{
							if (SIZE_MAX_SECTION_INAC > wNum)
							{
								szLogId[wNum++] = wLogicId;
							}
						}
						else
						{
							; /* do nothing */
						}
					}
					chFunRtn = CI_SUCCESS;
				}
				else
				{
					;
				}
			}
			else
			{
				;
			}
			wPrePhyId = wCurPhyId;
		}
		(*pLogSecNum) = wNum;
	}
	else
	{
		;
	}

	

	return chFunRtn;
}

/**
* @brief 判断两个区域是否相交
* @param p_StrZone pZoneA
* @param p_StrZone pZoneB
* @return CI_ERROR 区域相交 ；CI_SUCCESS 区域不相交
*/
UINT8 CheckZoneIsCrossing(p_StrZone pZoneA, p_StrZone pZoneB)
{
	UINT8 cRetVal = CI_ERROR;
	UINT8 chFunRtnA = CI_ERROR;
	UINT8 chFunRtnB = CI_ERROR;
	UINT8 chFunRtnC = CI_ERROR;
	UINT8 chFunRtnD = CI_ERROR;
	UINT16 wLinkId = 0u;
	UINT8 i = 0u;
	UINT8 j = 0u;
	UINT8 cDir = DIR_INVALID;
	struct_PathPoint strAStartPoint = { 0u };
	struct_PathPoint strAEndPoint = { 0u };
	struct_PathPoint strBStartPoint = { 0u };
	struct_PathPoint strBEndPoint = { 0u };
	LinkDataConfigStru * pLink = NULL;

	if ((NULL != pZoneA) && (NULL != pZoneB)
		&& (0u != pZoneA->pLinkSeq.cLinkCnt) && (0u != pZoneB->pLinkSeq.cLinkCnt))
	{
		for (i = 0u; i < pZoneA->pLinkSeq.cLinkCnt; i++)
		{
			for (j = 0u; j < pZoneB->pLinkSeq.cLinkCnt; j++)
			{
				if (pZoneA->pLinkSeq.szLinkId[i] == pZoneB->pLinkSeq.szLinkId[j])
				{
					break;
				}
				else
				{
					;
				}
			}

			if (j != pZoneB->pLinkSeq.cLinkCnt)
			{
				break;
			}
		}

		if (i == pZoneA->pLinkSeq.cLinkCnt)
		{
			cRetVal = CI_SUCCESS;/* 区域不相交 */
		}
		else
		{
			wLinkId = pZoneA->pLinkSeq.szLinkId[i];
			pLink = GetLinkDataById(wLinkId);

			/* 获取link在区域上的占压 */
			chFunRtnA = dsuZoneStartEndPointInLink(pZoneA, wLinkId, &strAStartPoint, &strAEndPoint);
			chFunRtnA &= dsuZoneStartEndPointInLink(pZoneB, wLinkId, &strBStartPoint, &strBEndPoint);

			if (CI_ERROR == chFunRtnA)
			{
				/* 查询失败路径相交 */
				cRetVal = CI_ERROR;
			}
			else
			{
				cDir = (DIR_SAME == pLink->wLinkLine) ? DIR_SAME : DIR_CONVERT;

				chFunRtnA = dsuJudgeLinkAandLinkBPosition(&strAStartPoint, &strBStartPoint, cDir);
				chFunRtnB = dsuJudgeLinkAandLinkBPosition(&strAStartPoint, &strBEndPoint, cDir);
				chFunRtnC = dsuJudgeLinkAandLinkBPosition(&strAEndPoint, &strBStartPoint, cDir);
				chFunRtnD = dsuJudgeLinkAandLinkBPosition(&strAEndPoint, &strBEndPoint, cDir);

				if ((CI_ERROR == chFunRtnA) || (CI_ERROR == chFunRtnB) || (CI_ERROR == chFunRtnC) || (CI_ERROR == chFunRtnD))
				{
					/* 失败，导向安全侧 */
					cRetVal = CI_ERROR;
				}
				else if ((CI_SUCCESS == chFunRtnA) || (CI_SUCCESS == chFunRtnB) || (CI_SUCCESS == chFunRtnC) || (CI_SUCCESS == chFunRtnD))
				{
					/* 存在交集 */
					cRetVal = CI_ERROR;
				}
				else if ((chFunRtnA == chFunRtnB) && (chFunRtnB == chFunRtnC) && (chFunRtnC == chFunRtnD))
				{
					/* 没有交集 */
					cRetVal = CI_SUCCESS;
				}
				else
				{
					/* 存在交集 */
					cRetVal = CI_ERROR;
				}
			}
		}

	}
	else
	{
		;
	}
	return cRetVal;
}

/**
* @brief 判断点是否在本控区内
* @param wLink
* @param dwOffset
* @return CI_ERROR 在本控区内 ；CI_SUCCESS 不在本控区内
* @note 修复BUG YF0083-130
*/
UINT8 IsPointManaged(const UINT16 wLink, const UINT32 dwOffset)
{
	UINT8 chRtn = CI_ERROR;
	UINT8 chLocalId = 0u;
	UINT16 wLinkTioc = 0u;
	UINT8 checkResult = CI_ERROR;

	/* 修复BUG YF0083-130*/
	/** 校验linkID与偏移量是否有效*/
	checkResult = CheckLinkValid(wLink, dwOffset);
	/** 获取当前控区ID*/
	chLocalId = GetSystemParaLocalCiId();
	/** 校验无效*/
	if (CI_ERROR == checkResult)
	{
		/* 该函数用于列车注销，点link ID与偏移量无效时，应不能注销，因此返回点在本控区。*/
		chRtn = CI_ERROR;
	}
	else
	{
		/** 校验有效，获取link所属控区ID*/
		wLinkTioc = GetLinkManageTiocById(wLink);
		if (chLocalId == wLinkTioc)
		{
			/** 点在本控区*/
			chRtn = CI_ERROR;
		}
		else
		{
			/** 点不在本控区*/
			chRtn = CI_SUCCESS;
		}
	}

	return chRtn;
}

/**
* @brief 判断LINK是否为休眠唤醒轨
* @param linkId 编号
* @return CI_SUCCESS:link为休眠唤醒轨；CI_ERROR:link不为休眠唤醒轨
*/
UINT8 IsLinkSwTrack(const UINT16 linkId)
{
	UINT8 rtnValue = CI_ERROR;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		if (LINK_SW_TRACK_YES == g_szLinkConfigData[index].chSwTrack)
		{
			rtnValue = CI_SUCCESS;
		}
		else
		{
			;
		}
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}


/**
* @brief 判断LINK是否为折返区域
* @param linkId 编号
* @return CI_SUCCESS:link为折返区域；CI_ERROR:link不为折返区域
*/
extern UINT8 IsLinkRevertArea(const UINT16 linkId)
{
	UINT8 rtnValue = CI_ERROR;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		if (LINK_REVERT_AREA_YES == g_szLinkConfigData[index].chRevertArea)
		{
			rtnValue = CI_SUCCESS;
		}
		else
		{
			;
		}
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief 获取LINK停车区域编号
* @param linkId 编号
* @return LINK停车区域编号
*/
UINT16 GetLinkStopAreaId(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wStopAreaId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/*********************************************
函数功能：获取计轴区段序列中符合道岔位置中的一个
输入参数：szAxisId 序列首地址，wAxisNum wAxisNum个数
输出参数：无

返回值：0失败，其他 AxisID成功
**********************************************/
UINT16 GetAxisIdFromAxisSeqSafeSw(UINT16* szAxisId, UINT16 wAxisNum)
{
	/*变量初始化*/
	UINT8 chAxisSwitchIdSum = 0U;
	AxisSwitchStruct *pAxisSwitchIdBuf = NULL;
	UINT16 wAxisBelongPhyId = 0U;
	UINT16 wFirstAxisBelongPhyId = 0U;
	UINT16 wRetAxisId = 0U;
	UINT8 chSwitchCurPos = 0U;
	UINT16 ii = 0U;
	UINT16 jj = 0U;
	UINT8 chCycFlag = 0U;
	UINT8 chKeepWork = CI_ERROR;

	if ((NULL == szAxisId) || (0U == wAxisNum) || (AC_MAXCNT_IN_SWITCH < wAxisNum))
	{
		/*入参检查失败*/
		chKeepWork = CI_ERROR;
	}
	else
	{
		/*入参检查成功*/
		chKeepWork = CI_SUCCESS;
	}

	if (CI_SUCCESS == chKeepWork)
	{
		chCycFlag = CI_SUCCESS;
		wFirstAxisBelongPhyId = GetAxisSecRelativePhySecId(szAxisId[0]);
		for (ii = 0U; ii < wAxisNum; ii++)
		{
			wAxisBelongPhyId = GetAxisSecRelativePhySecId(szAxisId[ii]);
			if (wFirstAxisBelongPhyId == wAxisBelongPhyId)
			{
				chAxisSwitchIdSum = GetAxisSwitchSum(szAxisId[ii]);
				pAxisSwitchIdBuf = GetAxisSwitchIdStru(szAxisId[ii]);

				if (0U != chAxisSwitchIdSum)
				{
					for (jj = 0U; jj < chAxisSwitchIdSum; jj++)
					{
						chSwitchCurPos = GetSwitchCurPosition(pAxisSwitchIdBuf[jj].SwitchId);

						if (((SWITCH_POSITION_DINGWEI == chSwitchCurPos) || (SWITCH_POSITION_FANWEI == chSwitchCurPos))
							&& (chSwitchCurPos == pAxisSwitchIdBuf[jj].SwitchPosition))
						{

						}
						else
						{
							break;
						}
					}
					if (jj == chAxisSwitchIdSum)
					{
						wRetAxisId = szAxisId[ii];
						chCycFlag = CI_ERROR;
					}
				}
				else
				{
					wRetAxisId = szAxisId[0];
				}
			}
			else
			{
				chCycFlag = CI_ERROR;
				chKeepWork = CI_ERROR;
			}

			if (CI_SUCCESS != chCycFlag)
			{
				break;
			}
			else
			{
				 /*DO NOTHING*/
			}
		}
	}

	if (CI_SUCCESS == chKeepWork)
	{
		; /*DO NOTHING*/
	}
	else
	{
		wRetAxisId = 0U;
	}

	return wRetAxisId;
}

/**
* @brief 获取点所处公里标
* @param wLinkId
* @param dwLinkOffset
* @return 公里标
*/
UINT32 GetPointKm(UINT16 wLinkId, UINT32 dwLinkOffset)
{
	UINT32 rtnValue = UINT32_MAX;
	UINT32 dwLinkLen = UINT32_MAX;
	UINT16 wOrgnLinkId = 0u;
	UINT16 wOrgnLinkType = 0u;
	UINT16 wOrgnPointType = 0u;
	UINT16 wTmnlPointType = 0u;

	wOrgnPointType = GetLinkOrgnPointTypeById(wLinkId);	/* 获取link起点端点类型 */
	wTmnlPointType = GetLinkTmnlPointTypeById(wLinkId);	/* 获取link终点端点类型 */
	dwLinkLen = GetLinkLengthById(wLinkId);

	if ((dwLinkOffset <= dwLinkLen) && (UINT32_MAX != dwLinkLen))
	{
		if (EMAP_END_DOT != wOrgnPointType)
		{/* link始端不为线路终端 */
			if (EMAP_AXLE_DOT == wOrgnPointType)
			{/* 始端为计轴器 */
				rtnValue = GetAxisKmById(GetLinkOrgnPointIdById(wLinkId));
			}
			else if (EMAP_POINT_DOT == wOrgnPointType)
			{/* 始端为道岔 */
				rtnValue = GetSwitchKmById(GetLinkOrgnPointIdById(wLinkId));
			}
			else
			{
				; /* 不处理，类型错误，不可能分支 */
			}

			if (UINT32_MAX != rtnValue)
			{
				rtnValue += dwLinkOffset;
			}
			else
			{
				; /* 不处理 */
			}
		}
		else if (EMAP_END_DOT != wTmnlPointType)
		{/* link终端不为线路终端 */
			if (EMAP_AXLE_DOT == wTmnlPointType)
			{/* 始端为计轴器 */
				rtnValue = GetAxisKmById(GetLinkTmnlPointTypeById(wLinkId));
			}
			else if (EMAP_POINT_DOT == wTmnlPointType)
			{/* 终端为道岔 */
				rtnValue = GetSwitchKmById(GetLinkTmnlPointTypeById(wLinkId));
			}
			else
			{
				; /* 不处理，类型错误，不可能分支 */
			}

			rtnValue = GetAxisKmById(GetLinkTmnlPointIdById(wLinkId));
			if (UINT32_MAX != rtnValue)
			{
				rtnValue = rtnValue - (dwLinkLen - dwLinkOffset);
			}
			else
			{
				;
			}
		}
		else
		{
			; /*DO NOTHING rtn invalid value*/
		}
	}
	else
	{
		; /*DO NOTHING rtn invalid value*/
	}

	return rtnValue;
}

/**
* @brief 判断LINK是否为站台
* @param linkId 编号
* @return CI_SUCCESS:link为站台；CI_ERROR:link不为站台
*/
UINT8 IsLinkPlatform(const UINT16 linkId)
{
	UINT8 rtnValue = CI_ERROR;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		if (LINK_PLATFORM_YES == g_szLinkConfigData[index].chPlatform)
		{
			rtnValue = CI_SUCCESS;
		}
		else
		{
			;
		}
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief 获取点所处逻辑区段
* @param struct_PathPoint strPoint 点
* @param UINT16 * pLgcIdBuf 输出的逻辑区段ID
* @return 逻辑区段数量
* @note 
*/
UINT8 GetPointBelongLogSecEx(struct_PathPoint strPoint, UINT16 * pLgcIdBuf)
{
	UINT16 wLogicSum = 0u;
	UINT16 wLogicId = 0u;
	UINT16 wIndex = 0u;
	UINT16 wLinkNum = 0U;
	str_Zone strZone = { 0u };
	UINT16 wOrgnLink = 0u;
	UINT16 wTmanLink = 0u;
	UINT32 dwOrgnOffset = UINT32_MAX;
	UINT32 dwTmnlOffset = UINT32_MAX;
	UINT32 dwLen = UINT32_MAX;
	LOD_STRU strPointA = { 0u };
	LOD_STRU strPointB = { 0u };
	UINT8 chFunRtn = CI_ERROR;
	UINT8 chRtn = 0u;
	UINT16 wszLogicIdBuf[PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U] = { 0U };


	chFunRtn = CheckLinkValid(strPoint.wLinkId, strPoint.dwOffset);

	if (CI_SUCCESS == chFunRtn)
	{
		chFunRtn = GetLinkRelLgcId(1, &strPoint.wLinkId, &wLogicSum, wszLogicIdBuf);
	}
	else
	{
		; /* DO NOTHING */
	}
	if ((CI_SUCCESS == chFunRtn) && (NULL != pLgcIdBuf))
	{
		for (wIndex = 0u; wIndex < wLogicSum; wIndex++)
		{
			wLogicId = wszLogicIdBuf[wIndex];
			strZone.pStart.wLinkId = GetLgcSecOrgnLink(wLogicId);
			strZone.pStart.dwOffset = GetLgcSecOrgnOffset(wLogicId);
			strZone.pEnd.wLinkId = GetLgcSecTmnlLink(wLogicId);
			strZone.pEnd.dwOffset = GetLgcSecTmnlOffset(wLogicId);
			strPointA.Lnk = strZone.pStart.wLinkId;
			strPointA.Off = strZone.pStart.dwOffset;
			strPointB.Lnk = strZone.pEnd.wLinkId;
			strPointB.Off = strZone.pEnd.dwOffset;
			dwLen = dsuLenByPoint(&strPointA, &strPointB, &wLinkNum, strZone.pLinkSeq.szLinkId, &strZone.Dir);
			/*不会超过UINT8_MAX*/
			strZone.pLinkSeq.cLinkCnt = (UINT8)wLinkNum;
			if (UINT32_MAX != dwLen)
			{
				chFunRtn = IsPointInPath(strPoint, strZone);
				if (CI_ERROR == chFunRtn)
				{/* 记录逻辑区段 */
					pLgcIdBuf[chRtn++] = wLogicId;
				}
				else
				{
					;
				}
			}
			else
			{/* 查询失败， */
				chRtn = 0u;
				break;
			}
		}
	}
	else
	{
		;
	}
	return chRtn;
}

/**
* @brief 获取link逻辑站台编号
* @param linkId 编号
* @return link逻辑站台编号;0:link不为站台轨
*/
UINT16 GetLinkPlatfrm(const UINT16 linkId)
{
	UINT16 rtnValue = 0u;
	UINT16 index = 0u;

	index = GetLinkIndexById(linkId);
	if (UINT16_MAX != index)
	{
		rtnValue = g_szLinkConfigData[index].wPlatformId;
	}
	else
	{
		; /*id 有误*/
	}

	return rtnValue;
}

/**
* @brief 获取ATS逻辑站台所属tioc编号
* @param const UINT16 wLgcStation
* @return ATS逻辑站台所属tioc编号
* @note
*/
UINT16 GetAtsLgcStationBelongTioc(const UINT16 wLgcStation)
{
	UINT16 wTiocId = 0u;
	UINT16 wLinkIndex = 0u;
	UINT16 wLinkPltfrm = 0u;

	for (wLinkIndex = 0u; wLinkIndex < LINK_SUM_MAX; wLinkIndex++)
	{
		if (g_szLinkConfigData[wLinkIndex].wPlatformId == wLgcStation)
		{
			wTiocId = g_szLinkConfigData[wLinkIndex].wManageTioc;
			break;
		}
		else
		{
			;
		}
	}
	return wTiocId;
}

/**
* @brief 获取站台关联的Link编号
* @param const UINT16 wLgcStation
* @return 站台关联Link编号
* @note
*/
UINT16 GetLinkIDBelongPlatForm(const UINT16 wPlatform)
{
	UINT16 wLinkId = 0u;
	UINT16 wLinkIndex = 0u;
	UINT16 wLinkNum = 0u;
	UINT16 wLinkPltfrm = 0u;
	wLinkNum = GetLinkNum();
	for (wLinkIndex = 0u; wLinkIndex < wLinkNum; wLinkIndex++)
	{
		if (g_szLinkConfigData[wLinkIndex].wBelongPlatformId == wPlatform)
		{
			wLinkId = g_szLinkConfigData[wLinkIndex].wId;
			break;
		}
		else
		{
			;
		}
	}
	return wLinkId;
}
/**
* @brief 判断LINK是否封锁
* @param const UINT16 wLinkId link编号
* @return CI_ERROR:link封锁；CI_SUCCESS:link未封锁
* @note
*/
UINT8 IsLinkFlock(const UINT16 wLinkId)
{
	UINT8 chRtn = CI_ERROR;
	UINT16 wPhyId = 0u;
	UINT8 chFlock = 0u;
	wPhyId = GetLinkRelatedPhySec(wLinkId);
	chFlock = GetPhySecFLockState(wPhyId);
	if (PHYSICAL_SECTION_FLOCK_NO == chFlock)
	{
		chRtn = CI_SUCCESS;
	}
	else
	{
		chRtn = CI_ERROR;
	}
	return chRtn;
}

/**
* @brief 运营方向转换为逻辑方向
* @param const UINT8 chDir 运营方向
* @return DIR_SAME:与link逻辑方向相同；
		DIR_CONVERT:与link逻辑方向相反；
		DIR_INVALID:输入参数无效
* @note
*/
UINT8 ConvertDirectionToLogic(const UINT8 chDir)
{
	UINT8 chLinkLogicDirUpAndDown = 0U;
	UINT8 chRtn = DIR_INVALID;
	if ((CI_SYSTEM_DIRECTION_UP == chDir) || (CI_SYSTEM_DIRECTION_DOWN == chDir))
	{
		chLinkLogicDirUpAndDown = GetLinkLogicDirUpAndDown();
		if (chLinkLogicDirUpAndDown == chDir)
		{
			chRtn = DIR_CONVERT;
		}
		else
		{
			chRtn = DIR_SAME;
		}
	}
	else
	{/* 输入参数有误 */
		chRtn = DIR_INVALID;
	}
	return chRtn;
}

/**
* @brief 逻辑方向转换为运营方向
* @param const UINT8 chDir 逻辑方向
* @return 0x55:上下
*		  0xaa:下行
*		  0xff:无效
*/
UINT8 ConvertLogicDirToRun(const UINT8 chDir)
{
	UINT8 chLinkLogicDirUpAndDown = 0U;
	UINT8 chRtn = CI_SYSTEM_DIRECTION_NONE;

	chLinkLogicDirUpAndDown = GetLinkLogicDirUpAndDown();

	if (((DIR_CONVERT == chDir) || (DIR_SAME == chDir)) && ((0x55U == chLinkLogicDirUpAndDown) || (0xaaU == chLinkLogicDirUpAndDown)))
	{
		if (DIR_CONVERT == chDir)
		{
			chRtn = chLinkLogicDirUpAndDown; 
		}
		else
		{
			chRtn = ~chLinkLogicDirUpAndDown; 
		}
	}
	else
	{
		chRtn = CI_SYSTEM_DIRECTION_NONE;  /*输入参数有误，返回无效*/
	}

	return chRtn;
}

/*
* 功能描述： 将当前逻辑方向取反
* 参数说明：
*			const UINT8 chTrainDir 列车运行方向
* 返回值  ： 取反运行方向
*/
UINT8 ConvertTrainDir(UINT8 chTrainDir)
{
	UINT8 retval = 0u;
	if (DIR_CONVERT == chTrainDir)
	{
		retval = DIR_SAME;
	}
	else if (DIR_SAME == chTrainDir)
	{
		retval = DIR_CONVERT;
	}
	else
	{
		retval = DIR_INVALID;
	}
	return retval;
}

/**
* @brief 判断列车占压逻辑区段序列，是否需要判断逻辑区段道岔位置
* @param const UINT16 wLgcId 逻辑区段ID
* @param const str_Zone strZone 列车占压区域
* @return CI_ERROR:不需要检查道岔位置，CI_SUCCESS:需要检查
* @note
*/
static UINT8 IsLgcNeedCheckSwitchPos(const UINT16 wLgcId, const str_Zone strZone)
{
	UINT8 chRtn = CI_ERROR;
	UINT8 chLgcSwitchNum = 0u;
	LogsecSwitchStruct * pLgcSwitchInfo = NULL;
	UINT8 chSwitchIndex = 0u;
	UINT8 chLinkIndex = 0u;
	UINT8 chLinkType = SW_DEFAUT_LINK;
	UINT8 chFunRtn = CI_ERROR;
	chLgcSwitchNum = GetLogicSecSwitchSum(wLgcId);
	pLgcSwitchInfo = GetLogicSecSwitchIdStru(wLgcId);
	if ((0u == chLgcSwitchNum) || (NULL == pLgcSwitchInfo))
	{
		; /* 逻辑区段不包含道岔，或获取数据失败，不检查道岔位置 */
	}
	else
	{
		for (chSwitchIndex = 0u; chSwitchIndex < chLgcSwitchNum; chSwitchIndex++)
		{/* 遍历逻辑区段包含道岔 */
			for (chLinkIndex = 0u; chLinkIndex < strZone.pLinkSeq.cLinkCnt; chLinkIndex++)
			{/* 遍历区域link序列 */
				chFunRtn = dsuLinkofSwitchPos(strZone.pLinkSeq.szLinkId[chLinkIndex], pLgcSwitchInfo[chSwitchIndex].SwitchId, &chLinkType);
				
				if ((CI_SUCCESS == chFunRtn) && ((UINT8)SW_CON_LINK == chLinkType))
				{/* 区域包含逻辑区段道岔汇合link，需要检查道岔位置 */
					chRtn = CI_SUCCESS;
					break;
				}
				else
				{
					; /* 不处理 */
				}
			}
			if (CI_SUCCESS == chRtn)
			{
				break;
			}
			else
			{
				; /* 继续遍历 */
			}
		}
	}
	return chRtn;
}

/**
* @brief 根据方向变化点转换标志转换方向
* @param UINT8 wFlag	方向变换标志位
* @param UINT8 wPointDir 查询方向
* @param UINT8* wPointCnt 方向变换点数量（出参）
* @return 变换后的方向
*/
UINT8 TransDirectionPointDir(UINT8 wFlag, UINT8 wPointDir, UINT8* wPointCnt)
{
	UINT8 reVal = 0U;

	if (((DIRECTIONPOINT_FLAG_VALID != wFlag) && (DIRECTIONPOINT_FLAG_INVALID != wFlag))
		|| ((DIR_CONVERT != wPointDir) && (DIR_SAME != wPointDir)) || (NULL == wPointCnt))
	{
			/*入参防护*/
	}
	else
	{
		if (DIRECTIONPOINT_FLAG_VALID == wFlag)
		{
			switch (wPointDir)
			{
			case DIR_CONVERT:
				reVal = DIR_SAME;
				break;
			case DIR_SAME:
				reVal = DIR_CONVERT;
				break;
			default:
				/*不可达分支*/
				break;
			}
			(*wPointCnt)++;
		}
		else
		{
			reVal = wPointDir;			/*无方向变换标志，维持原有方向*/
		}
	}

	return reVal;
}

/**
* @brief 判断两点方向是否相同(可用作列车同向、对向行驶判断)
* @param[in] const LOD_STRU strPointA  A点
* @param[in] const LOD_STRU strPointB  B点
* @param[out] 无
* @return CI_ERROR:处理失败；FLAG_SET:同向；FLAG_UNSET:反向
*/
UINT8 IsPointABSameDir(const LOD_STRU strPointA, const LOD_STRU strPointB)
{
	UINT8 chRtn = CI_ERROR;
	UINT8 chDirChangeNum = 0U;
	UINT8 chDirChangeResult = 0U;

	/** 入口参数校验 */
	chRtn = CheckLinkValid(strPointA.Lnk, strPointA.Off);
	chRtn &= CheckLinkValid(strPointB.Lnk, strPointB.Off);

	if (CI_SUCCESS == chRtn)
	{
		chDirChangeNum = GetDirChangeNumBtwPoints(&(strPointA), &(strPointB));
		if (UINT8_MAX != chDirChangeNum)
		{
			/*根据方向变化点设置返回值*/
			chDirChangeResult = chDirChangeNum % 2U;
			if (0U == chDirChangeResult)
			{
				/*不存在或存在偶数个方向变化点*/
				chRtn = strPointA.Dir == strPointB.Dir? FLAG_SET : FLAG_UNSET;
			}
			else
			{
				/*存在奇数个方向变化点*/
				chRtn = strPointA.Dir == strPointB.Dir ? FLAG_UNSET : FLAG_SET;
			}
		}
		else
		{
			chRtn = CI_ERROR; 
		}
	}
	else
	{
		; /* 输入不合法 */
	}
	return chRtn;
}

/*
* 功能描述： 根据方向变换点数量的奇偶改换方向
* 参数说明：UINT8 Dir, 方向
*			UINT8 wChangeNum	方向变换点数量
* 返回值  ： 0: 获取数据失败
*           >0: 方向
*/
UINT8 TransDirByChangeNum(UINT8 Dir, UINT8 wChangeNum)
{
	UINT8 wDirRevel = 0U;

	if (((DIR_CONVERT != Dir) && (DIR_SAME != Dir))||(UINT8_MAX == wChangeNum))
	{
		/*入参防护*/
	}
	else
	{
		if (0U != (wChangeNum % 2U))
		{
			wDirRevel = ~Dir;
		}
		else
		{
			wDirRevel = Dir;		/*出现偶数个方向变换点，不转换方向*/
		}
	}

	return wDirRevel;
}


/*
* 功能描述： 查询站台link外方第一逻辑区段
 * @param[in] UINT16 wLinkId 站台LinkID
 * @param[in] UINT8 chDir 查询方向
 * @param[out] UINT16 * pLgcIdBuf 逻辑区段ID缓冲区
 * @return 逻辑区段数量，UINT8_MAX失败，0线路终端
*/
UINT8 FindPlatFormLinkOutLog(UINT16 wLinkId, UINT8 chDir, UINT16 * pLgcIdBuf)
{
	UINT8 chRtn = UINT8_MAX;
	struct_PathPoint strTmp = { 0u };
	UINT16 wSwitchId = 0u;
	UINT8 cDirectionPointFlag = 0U;			/*是否具有方向变化点标志*/

	if ((EMAP_SAME_DIR != chDir) && (EMAP_CONVER_DIR != chDir) && (NULL == pLgcIdBuf))
	{
		; /* 入参检查失败，返回0 */
	}
	else
	{
		if (EMAP_SAME_DIR == chDir)		/*考虑站台link和外方link之间存在方向变化点*/
		{
			strTmp.wLinkId = FindAdjacentLinkIDSafe(wLinkId, EMAP_SAME_DIR, &wSwitchId, &cDirectionPointFlag);
			if (DIRECTIONPOINT_FLAG_VALID == cDirectionPointFlag)
			{
				strTmp.dwOffset = GetLinkLengthById(strTmp.wLinkId) - 1u;
			}
			else
			{
				strTmp.dwOffset = 1u;
			}
		}
		else
		{
			strTmp.wLinkId = FindAdjacentLinkIDSafe(wLinkId, EMAP_CONVER_DIR, &wSwitchId, &cDirectionPointFlag);

			if (DIRECTIONPOINT_FLAG_VALID == cDirectionPointFlag)
			{
				strTmp.dwOffset = 1u;
			}
			else
			{
				strTmp.dwOffset = GetLinkLengthById(strTmp.wLinkId) - 1u;
			}
		}

		/* 获取逻辑区段 */
		if (0u == strTmp.wLinkId)
		{/* 线路终端返回0 */
			chRtn = 0u;
		}
		else if (UINT16_MAX == strTmp.wLinkId)
		{/* 查询出错，返回UINT8_MAX */
			chRtn = UINT8_MAX;
		}
		else
		{
			chRtn = GetPointBelongLogSecEx(strTmp, pLgcIdBuf);
			if (0u == chRtn)
			{/* 查询失败 */
				chRtn = UINT8_MAX;
			}
			else
			{
				;
			}
		}
	}

	return chRtn;
}

/**
* @brief 获取link脱轨及区间疏散防护线路上下行属性
* @param wLinkId 编号
* @return  0  失败
		   >0 link脱轨及区间疏散防护线路上下行属性
* by cgh 20240105
*/
UINT8 GetLinkTgEvacuateDir(const UINT16 wLinkId)
{
	UINT8 chRtnValue = CI_ERROR;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		chRtnValue = g_szLinkConfigData[wIndex].chLinkTgEvacuateDir;
	}
	else
	{
		; /*id 有误*/
	}

	return chRtnValue;
}

/**
* @brief 获取link 关联的所有逻辑区段
* @param  IN UINT16 *pLinkId linkID    UINT8 linkNum  link数量
* @param OUT UINT16 *pLgcSum 输出的逻辑区段数量
* @param OUT UINT16  pLgcIdBuf[SIZE_MAX_SECTION_BT_TRAIN] 输出的逻辑区段ID
* @return CI_ERROR 失败 CI_SUCCESS 成功
* @note
*/
UINT8 GetLinkRelLgcId(UINT8 linkNum, UINT16 *pLinkId, UINT16  *pLgcSum, UINT16  *pLgcIdBuf)
{
	UINT8 chRetVal = CI_ERROR;	/*返回值*/
	UINT8 ii = 0U;				/*循环变量*/
	UINT16 wPhySecId = 0U;
	UINT16 wPrePhySecId = 0U;
	UINT16 wPhyRelLgcSum = 0U;
	UINT16 *wPhyRelLgcId = NULL;
	UINT16 wAllLinkLgcSum = 0U;
	UINT16 szAllLinkLgcIdBuf[PHYSICAL_INCLUDE_LOG_SUM_MAX*2U] = {0U}; /*考虑两个物理区段的最大逻辑区段数量*/
	if ((linkNum != 0U)
		&&(pLgcSum!=NULL)
		&& (pLinkId !=NULL)
		&&(pLgcIdBuf!=NULL))
	{
		*pLgcSum = 0U;
		chRetVal = CI_SUCCESS;
	}
	else
	{
		chRetVal = CI_ERROR;
	}

	if (CI_SUCCESS == chRetVal)
	{
		for (ii = 0U; ii < linkNum; ii++)
		{
			wPhySecId = GetLinkRelatedPhySec(pLinkId[ii]);
			wPhyRelLgcSum = GetPhySecIncLogSecSum(wPhySecId);
			wPhyRelLgcId = GetPhySecIncLogSecIdBuf(wPhySecId);

			if ((wPhyRelLgcSum > 0U)&&(wPhyRelLgcId!=NULL))
			{
				if ((wAllLinkLgcSum + wPhyRelLgcSum) < (PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U))
				{
					if (wPhySecId != wPrePhySecId)
					{
						/*去重，使用该函数需要link按序列传入,则物理区段与上一个不一致即可保证不重复*/
						(void)CommonMemCpy((void*)&szAllLinkLgcIdBuf[wAllLinkLgcSum], (UINT32)(sizeof(UINT16)*(PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U - wAllLinkLgcSum)), (void *)wPhyRelLgcId, (UINT32)sizeof(UINT16)*wPhyRelLgcSum);
						wAllLinkLgcSum += wPhyRelLgcSum;
						wPrePhySecId = wPhySecId;
					}
					else
					{
						/*继续执行*/
					}
				}
				else
				{
					chRetVal = CI_ERROR;
				}
			}
			else
			{
				chRetVal = CI_ERROR;
			}
			if (CI_SUCCESS != chRetVal)
			{
				break;
			}

		}
	}
	else
	{
		/* DO NOTHING */
	}

	if (CI_SUCCESS == chRetVal)
	{
		if (wAllLinkLgcSum < (PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U))
		{
			*pLgcSum = wAllLinkLgcSum;
			(void)CommonMemCpy((void*)pLgcIdBuf, (UINT32)(sizeof(UINT16)*(PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U)), (void *)szAllLinkLgcIdBuf, (UINT32)(sizeof(UINT16)*(PHYSICAL_INCLUDE_LOG_SUM_MAX * 2U)));
		}
		else
		{
			/* DO NOTHING */
		}
	}
	else
	{
		/* DO NOTHING */
	}
	return chRetVal;
}

/**
* @brief 获取计轴区段序列中符合道岔位置中所有计轴区段
* @param  szAxisId 序列首地址
		  wAxisNum 计轴区段个数
* @param OUTchOutAxisSecSum 输出满足条件的计轴区段数目
		 szOutAxisSecIdBuf 输出的满足条件的计轴区段数组
* @return 符合的计轴区段数目
* @note by cgh 20240514
*/
UINT8 GetAllAxisFromAxisSeqSafeSw(UINT16* szAxisId, UINT16 wAxisNum, UINT16* szOutAxisSecIdBuf)
{
	/*变量初始化*/
	UINT8 chAxisSwitchIdSum = 0U;
	AxisSwitchStruct* pAxisSwitchIdBuf = NULL;
	UINT16 wAxisBelongPhyId = 0U;
	UINT16 wFirstAxisBelongPhyId = 0U;
	UINT8 chSwitchCurPos = 0U;
	UINT16 ii = 0U;
	UINT16 jj = 0U;
	UINT8 chKeepWork = CI_ERROR;
	UINT16 szTempAxisIdBuf[AC_MAXCNT_IN_SWITCH] = { 0U };/*临时计轴区段ID*/
	UINT8 chOutAxisSecSum = 0U;/*符合拓扑关系的计轴区段数目*/

	if ((NULL == szAxisId) || (0U == wAxisNum) || (AC_MAXCNT_IN_SWITCH < wAxisNum) || (NULL == szOutAxisSecIdBuf))
	{
		; /*数目返回0*/
	}
	else
	{
		wFirstAxisBelongPhyId = GetAxisSecRelativePhySecId(szAxisId[0]);
		for (ii = 0U; ii < wAxisNum; ii++)
		{
			wAxisBelongPhyId = GetAxisSecRelativePhySecId(szAxisId[ii]);
			if (wFirstAxisBelongPhyId == wAxisBelongPhyId)
			{
				chAxisSwitchIdSum = GetAxisSwitchSum(szAxisId[ii]);
				pAxisSwitchIdBuf = GetAxisSwitchIdStru(szAxisId[ii]);

				if (0U != chAxisSwitchIdSum)
				{
					chKeepWork = CI_SUCCESS;
					for (jj = 0U; jj < chAxisSwitchIdSum; jj++)
					{
						chSwitchCurPos = GetSwitchCurPosition(pAxisSwitchIdBuf[jj].SwitchId);

						if (((SWITCH_POSITION_DINGWEI == chSwitchCurPos) || (SWITCH_POSITION_FANWEI == chSwitchCurPos))
							&& (chSwitchCurPos == pAxisSwitchIdBuf[jj].SwitchPosition))
						{
							; /*继续查找*/
						}
						else
						{
							/*有一个不满足的道岔不添加*/
							break;
						}
					}

					if (jj == chAxisSwitchIdSum)
					{
						/*道岔均满足*/
						szTempAxisIdBuf[chOutAxisSecSum] = szAxisId[ii];
						chOutAxisSecSum++;
					}
				}
				else
				{
					/*没有道岔直接加*/
					szTempAxisIdBuf[chOutAxisSecSum] = szAxisId[ii];
					chOutAxisSecSum++;
				}
			}
			else
			{
				; /*只处理本物理区段*/
			}
		}
		/*FOR循环已经确保了数量不超限制*/
		(void)CommonMemCpy((void*)szOutAxisSecIdBuf, (UINT32)(sizeof(UINT16) * (AC_MAXCNT_IN_SWITCH)), (void*)szTempAxisIdBuf, (UINT32)(sizeof(UINT16) * (AC_MAXCNT_IN_SWITCH)));

	}

	return chOutAxisSecSum;
}

/**
* @brief 判断成员是否在序列内
* @param const UINT16 wMem 成员值
* @param const UINT8 chNum 序列成员数量
* @param UINT16 * pSeq 序列
* @return CI_ERROR:成员不在序列内；CI_SUCCESS:成员在序列内
*/
UINT8 IsMenberOfSeq(const UINT16 wMem, const UINT8 chNum, UINT16 * pSeq)
{
	UINT8 chRtn = CI_ERROR;
	UINT8 chIndex = 0u;
	if ((0u != chNum) && (NULL != pSeq))
	{
		for (chIndex = 0u; chIndex < chNum; chIndex++)
		{
			if (wMem == pSeq[chIndex])
			{
				chRtn = CI_SUCCESS;
				break;
			}
			else
			{
				; /* 继续遍历 */
			}
		}
	}
	else
	{
		; /* 不在序列内 */
	}
	return chRtn;
}

/*
* @brief 获取link关联物理区段的AG/BG属性
* @param wLinkId 编号
* @return 0x55 AG
*		  0xAA BG
*		  0xFF 非AG非BG
* Created By LQ 20240815
*/
UINT8 GetLinkRelPhySecAGorBGAttr(const UINT16 wLinkId)
{
	UINT8 chRtnValue = LINK_REL_PHYSEC_DEFAULT;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		chRtnValue = g_szLinkConfigData[wIndex].chRelPhySecIsAGorBG;
	}
	else
	{
		; /*入参错误，返回默认值*/
	}

	return chRtnValue;
}

/*
* @brief 获取BGlink关联的AGlink（用于BG1）
* @param const UINT16 wBGLinkId BGlink编号
* @return BGlink关联的AG link ID
* Created By LQ 20240815
*/
UINT16 GetBGLinkRelAGLinkId(const UINT16 wBGLinkId)
{
	UINT16 wRtnVal = 0U;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wBGLinkId);
	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		wRtnVal = g_szLinkConfigData[wIndex].wBGLinkRelAGLink;
	}
	else
	{
		; /*入参错误，返回默认值*/
	}

	return wRtnVal;
}

/*
* @brief 获取link起点关联计轴区段采集占用状态
* @param wLinkId 编号
* @return 0x55 空闲
*         0xAA 占用
* Created By LQ 20240815
*/
UINT8 GetLinkOrgAxleSecOccSta(const UINT16 wLinkId)
{
	UINT8 cRetVal = AXIS_SECTION_OCCUPY_YES;  /*计轴区段采集占用状态*/
	UINT16 wIndex = 0U;
	UINT16 wOrgLinkId = 0U;  /*起点相邻linkID*/
	UINT16 wOrgAxleSecId = 0U;  /*起点相邻计轴区段ID*/
	UINT8 cOrgAxleSecOccState = AXIS_SECTION_OCCUPY_YES;  /*起点相邻计轴区段占用状态*/

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		wOrgLinkId = GetLinkOrgnJointMainLkIdById(wLinkId);
		if ((0U != wOrgLinkId) && (UINT16_MAX != wOrgLinkId))
		{
			wOrgAxleSecId = GetLinkBelongAcId(wOrgLinkId);
			cOrgAxleSecOccState = GetAxisOccupyState(wOrgAxleSecId);
			if (AXIS_SECTION_OCCUPY_NO == cOrgAxleSecOccState)
			{
				cRetVal = AXIS_SECTION_OCCUPY_NO;
			}
			else
			{
				cRetVal = AXIS_SECTION_OCCUPY_YES;
			}
		}
		else
		{
			cRetVal = AXIS_SECTION_OCCUPY_NO;  /*无相邻link，尽头线判为空闲*/
		}
	}
	else
	{
		; /*入参错误，返回占用*/
	}

	return cRetVal;
}

/*
* @brief 获取link终点关联计轴区段采集占用状态
* @param wLinkId 编号
* @return 0x55 空闲
*         0xAA 占用
* Created By LQ 20240815
*/
UINT8 GetLinkTmlAxleSecOccSta(const UINT16 wLinkId)
{
	UINT8 cRetVal = AXIS_SECTION_OCCUPY_YES;  /*物理区段采集占用状态*/
	UINT16 wIndex = 0U;
	UINT16 wTmlLinkId = 0U;  /*终点相邻linkID*/
	UINT16 wTmlAxleSecId = 0U;  /*终点相邻计轴区段ID*/
	UINT8 cTmlAxleSecOccState = AXIS_SECTION_OCCUPY_YES;  /*终点相邻计轴区段采集占用状态*/

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		wTmlLinkId = GetLinkTmnlJointMainLkById(wLinkId);
	
		if ((0U != wTmlLinkId) && (UINT16_MAX != wTmlLinkId))
		{
			wTmlAxleSecId = GetLinkBelongAcId(wTmlLinkId);
			cTmlAxleSecOccState = GetAxisOccupyState(wTmlAxleSecId);
			if (AXIS_SECTION_OCCUPY_NO == cTmlAxleSecOccState)
			{
				cRetVal = AXIS_SECTION_OCCUPY_NO;
			}
			else
			{
				cRetVal = AXIS_SECTION_OCCUPY_YES;
			}
		}
		else
		{
			cRetVal = AXIS_SECTION_OCCUPY_NO;  /*无相邻link，尽头线判为空闲*/
		}
	}
	else
	{
		; /*入参错误，返回占用*/
	}

	return cRetVal;
}

/*
* @brief 获取AG LINK是否存在关联CG标志
* @param wLinkId 编号
* @return LINK_EXIST_REL_CG_DEFAULT *Link不需要关联CG属性
*		  LINK_EXIST_REL_CG_YES  存在
*		  LINK_EXIST_REL_CG_NO   不存在
* by cgh 20240821
*/
UINT8 GetAgLinkExistRelCgFlag(const UINT16 wLinkId)
{
	UINT8 chRtnValue = AGLINK_EXIST_REL_CG_DEFAULT;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		chRtnValue = g_szLinkConfigData[wIndex].chExistRelCGFlag;
	}
	else
	{
		; /*入参错误，返回默认值*/
	}

	return chRtnValue;
}

/*
* @brief 获取link特殊防护区域属性
* @param wLinkId 编号
* @return 0 不具备特殊防护区域属性
*         >0 特殊防护区域属性
* by cgh 20250818
*/
UINT16 GetLinkSpecialEaAttr(const UINT16 wLinkId)
{
	UINT16 wRtnValue = 0U;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		wRtnValue = g_szLinkConfigData[wIndex].wLinkSpecialEa;
	}
	else
	{
		; /*入参错误，返回默认值*/
	}

	return wRtnValue;
}

/*
* @brief 获取link特殊防护区域车头向前延伸最大防护距离
* @param wLinkId 编号
* @return 0 失败
*         >0 车头向前延伸最大防护距离
* by cgh 20250818
*/
UINT32 GetLinkSpecialEaFrontDis(const UINT16 wLinkId)
{
	UINT32 dwRtnValue = 0U;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		dwRtnValue = g_szLinkConfigData[wIndex].dwFrontDis;
	}
	else
	{
		; /*入参错误，返回默认值*/
	}

	return dwRtnValue;
}

/*
* @brief 获取link特殊防护区域车尾向后延伸最大防护距离
* @param wLinkId 编号
* @return 0 失败
*         >0 车尾向后延伸最大防护距离
* by cgh 20250818
*/
UINT32 GetLinkSpecialEaBehindDis(const UINT16 wLinkId)
{
	UINT32 dwRtnValue = 0U;
	UINT16 wIndex = 0U;

	wIndex = GetLinkIndexById(wLinkId);

	if ((0U < wIndex) && (LINK_SUM_MAX > wIndex))
	{
		dwRtnValue = g_szLinkConfigData[wIndex].dwBehindDis;
	}
	else
	{
		; /*入参错误，返回默认值*/
	}

	return dwRtnValue;
}

/**
* @brief 根据查询方向获取link剩余偏移量
* @param struct_PathPoint pPoint LINK信息
* @param UINT8 chDir 查询方向
* @return UINT32_MAX 获取失败
*		  其它取值 link剩余偏移量
* by cgh 20250819
*/
UINT32 GetRelDirLinkOffset(struct_PathPoint pPoint, UINT8 chDir)
{
	UINT32 dwRtn = UINT32_MAX;

	if ((DIR_SAME == chDir) || (DIR_CONVERT == chDir))
	{
		dwRtn = GetLinkLengthById(pPoint.wLinkId);
		if (UINT32_MAX != dwRtn)
		{
			if (((0U == pPoint.dwOffset) && (DIR_SAME == chDir))
				|| ((dwRtn == pPoint.dwOffset) && (DIR_CONVERT == chDir)))
			{
				; /*返回LINK长度*/
			}
			else
			{
				if (DIR_SAME == chDir)
				{
					dwRtn -= pPoint.dwOffset;
				}
				else
				{
					dwRtn = pPoint.dwOffset;
				}
			}
		}
		else
		{
			; 
		}
	}
	else
	{
		; /*检查失败*/
	}

	return dwRtn;
}