/********************************************************
*                                                                                                            
* 文 件 名： GaragedoorDataManage.c   
* 版权说明： 北京交控科技有限公司 
* 创建时间： 2014-12-17
* 作    者： 联锁组
* 功能描述： 车库门数据管理  
* 修改记录：   
*
********************************************************/ 

#include "GaragedoorDataManage.h"
#include "ELMDataPrepare.h"
#include "WLScreenDataPrepare.h"

GaragedoorDataStruct GaragedoorDataStru[GARAGE_DOOR_SUM_MAX];   /*定义车库门数据结构体*/


/*
* 功能描述： 获取指定车库门数据
* 参数说明：    
* 返回值  ： 
            GaragedoorDataStruct *  
*/
GaragedoorDataStruct *GetGaragedoorData(void)
{
    return GaragedoorDataStru;
}

/*
* 功能描述： 获取指定ID车库门状态
* 参数说明： const UINT16 garagedoorId, 车库门ID    
* 返回值  ： 0u: 获取数据失败
*			>0u: 车库门状态      
*/
UINT8 GetGaragedoorState(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 garagedoorState = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		garagedoorState = GaragedoorDataStru[bufIndex].GaragedoorState;
	}
	return garagedoorState;
}


/*
* 功能描述： 设置指定ID车库门状态
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT8 garagedoorState, 车库门状态   
* 返回值  ： 0u: 设置失败
*			 1: 设置成功  
*/
UINT8 SetGaragedoorState(const UINT16 garagedoorId, const UINT8 garagedoorState)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 returnValue = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		if ((GARAGE_DOOR_STATE_OPEN == garagedoorState) || (GARAGE_DOOR_STATE_CLOSE == garagedoorState)
            || (GARAGE_DOOR_STATE_UNVALID == garagedoorState))
		{
			GaragedoorDataStru[bufIndex].GaragedoorState = garagedoorState;  /*车库门状态*/

			returnValue = CI_SUCCESS;
		}
		else
		{
			returnValue = CI_ERROR;
		}
	}
	else
	{
		returnValue = CI_ERROR;
	}
	return returnValue;
}

/*
* 功能描述： 获取指定ID车库门允许关门标志,ZC
* 参数说明： const UINT16 garagedoorId, 车库门ID
* 返回值  ： 0u: 获取数据失败
*            >0u: 获取数据成功
*/
UINT8 GetGaragedoorAllowCloseFlag(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 reVal = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取进路数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		reVal = GaragedoorDataStru[bufIndex].GaragedoorAllowCloseFlag;
	}

	return reVal;

}

/*
* 功能描述： 设置指定ID车库门允许关门标志 ZC
* 参数说明： const UINT16 garagedoorId, 车库门ID
* 返回值  ： 无
*             
*/
void SetGaragedoorAllowCloseFlag(const UINT16 garagedoorId, const UINT8 allowCloseFlag)
{
	UINT16 bufIndex = 0u;  /*数组下标*/

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取进路数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		if ((GARAGE_DOOR_ALLOW_CLOSE_YES == allowCloseFlag) || (GARAGE_DOOR_ALLOW_CLOSE_NO == allowCloseFlag))
		{

			GaragedoorDataStru[bufIndex].GaragedoorAllowCloseFlag = allowCloseFlag;  /*允许关门标志*/

		}
	}
}

/*
* 功能描述： 获取指定ID车库门允许关门标志,IVOC
* 参数说明： const UINT16 garagedoorId, 车库门ID
* 返回值  ： 0u: 获取数据失败
*            >0u: 获取数据成功
*/
UINT8 GetGaragedoorAllowCloseFlagIVOC(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 reVal = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取进路数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		reVal = GaragedoorDataStru[bufIndex].GDAllowCloseFlagIVOC;
	}

	return reVal;

}

/*
* 功能描述： 设置指定ID车库门允许关门标志 IVOC
* 参数说明： const UINT16 garagedoorId, 车库门ID
* 返回值  ： 无
*
*/
void SetGaragedoorAllowCloseFlagIVOC(const UINT16 garagedoorId, const UINT8 allowCloseFlag)
{
	UINT16 bufIndex = 0u;  /*数组下标*/

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取进路数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		if ((GARAGE_DOOR_ALLOW_CLOSE_YES == allowCloseFlag) || (GARAGE_DOOR_ALLOW_CLOSE_NO == allowCloseFlag))
		{

			GaragedoorDataStru[bufIndex].GDAllowCloseFlagIVOC = allowCloseFlag;  /*允许关门标志*/

		}
	}
}


/*
* 功能描述： 获取A库区段上最接近车库门的列车ID
* 参数说明： const UINT16 garagedoorId, 车库门ID
* 返回值  ： 0u: 获取数据失败
*            >0u: 列车ID
* LC
*/
UINT16 GetGaragedoorNearestTrainId(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT16 reVal = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取进路数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		reVal = GaragedoorDataStru[bufIndex].GDAkuNearestTrainId;
	}

	return reVal;

}

/*
* 功能描述： 设置A库区段上最接近车库门的列车ID
* 参数说明： const UINT16 garagedoorId, 车库门ID
*          const UINT16 trainId  列车ID
* 返回值  ： 无
* LC
*/
void SetGaragedoorNearestTrainId(const UINT16 garagedoorId, const UINT16 trainId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取进路数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		if (UINT16_MAX!= trainId)
		{

			GaragedoorDataStru[bufIndex].GDAkuNearestTrainId = trainId;  /*允许关门标志*/

		}
	}
}

/*
* 功能描述： 获取指定ID车库门模式状态
* 参数说明： const UINT16 garagedoorId, 车库门ID   
* 返回值  ： 0u: 获取失败
*			 >0u: 获取车库门模式状态
*/
UINT8 GetGaragedoorModeState(const UINT16 garagedoorId)
{
    UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 reVal = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        reVal = GaragedoorDataStru[bufIndex].GaragedoorModeState;
    }
    return reVal;
}



/*
* 功能描述： 设置指定ID车库门模式状态
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT8 garagedoorModeState, 车库门模式状态   
* 返回值  ： 0u: 设置失败
*			 1: 设置成功  
*/
UINT8 SetGaragedoorModeState(const UINT16 garagedoorId, const UINT8 garagedoorModeState)
{
    UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 returnValue = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        if ((GARAGE_DOOR_STATE_MODE_REMOTE == garagedoorModeState) || (GARAGE_DOOR_STATE_MODE_LOCAL == garagedoorModeState))
        {
			GaragedoorDataStru[bufIndex].GaragedoorModeState = garagedoorModeState;  /*车库门模式状态*/

            returnValue = CI_SUCCESS;
        }
        else
        {
            returnValue = CI_ERROR;
        }
    }

    return returnValue;
}

/*
* 功能描述： 获取指定ID车库门故障状态
* 参数说明： const UINT16 garagedoorId, 车库门ID   
* 返回值  ：
				GARAGE_DOOR_FAULT_TRUE 车库门故障为真
				GARAGE_DOOR_FAULT_FALSE 车库门故障为假
				CI_ERROR   获取失败 
*/
UINT8 GetGaragedoorFaultState(const UINT16 garagedoorId)
{
    UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 reVal = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        reVal = GaragedoorDataStru[bufIndex].GaragedoorFaultState;
    }

    return reVal;
}



/*
* 功能描述： 设置指定ID车库门故障状态
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT8 garagedoorFaultState, 车库门故障状态   
* 返回值  ： 0u: 设置失败
*			 1: 设置成功  
*/
UINT8 SetGaragedoorFaultState(const UINT16 garagedoorId, const UINT8 garagedoorFaultState)
{
    UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 returnValue = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        if ((GARAGE_DOOR_FAULT_TRUE == garagedoorFaultState) || (GARAGE_DOOR_FAULT_FALSE == garagedoorFaultState))
        {
			GaragedoorDataStru[bufIndex].GaragedoorFaultState = garagedoorFaultState;  /*车库门故障状态*/

            returnValue = CI_SUCCESS;
        }

    }

    return returnValue;
}

/*
* 功能描述： 获取指定ID车库门旁路状态
* 参数说明： const UINT16 garagedoorId, 车库门ID   
* 返回值  ：
				GARAGE_DOOR_PANGLU_TRUE 车库门旁路为真
				GARAGE_DOOR_PANGLU_FALSE 车库门旁路为假
				CI_ERROR   获取失败 
*/
UINT8 GetGaragedoorPangLuState(const UINT16 garagedoorId)
{
    UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 reVal = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        reVal = GaragedoorDataStru[bufIndex].GaragedoorPangLuState;
    }

    return reVal;
}

/*
* 功能描述： 设置指定ID车库门旁路状态
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT8 garagedoorPangLuState, 车库门旁路状态   
* 返回值  ： 0u: 设置失败
*			 1: 设置成功  
*/
UINT8 SetGaragedoorPangLuState(const UINT16 garagedoorId, const UINT8 garagedoorPangLuState)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 returnValue = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		if ((GARAGE_DOOR_PANGLU_TRUE == garagedoorPangLuState) || (GARAGE_DOOR_PANGLU_FALSE == garagedoorPangLuState))
		{
			GaragedoorDataStru[bufIndex].GaragedoorPangLuState = garagedoorPangLuState;  /*车库门旁路状态*/

			returnValue = CI_SUCCESS;
		}
	}

	return returnValue;
}



/*
* 功能描述： 获取指定ID车库门驱动状态
* 参数说明： const UINT16 garagedoorId, 车库门ID    
* 返回值  ： 0u: 获取数据失败
*			>0u: GARAGE_DOOR_DRV_OPEN GARAGE_DOOR_DRV_CLOSE GARAGE_DOOR_DRV_NULL      
*/
UINT8 GetDrvGaragedoorState(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 ret = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
		ret = GaragedoorDataStru[bufIndex].drvDoorState;
    }

	return ret;
}

/*
* 功能描述： 设置指定ID车库门驱动状态
* 参数说明： const UINT16 garagedoorId, 车库门ID  
*            UINT8 drvState , 车库门驱动状态    
* 返回值  ： CI_ERROR: 设置失败
*			 CI_SUCCESS: 设置成功       
*/
UINT8 SetDrvGaragedoorState(const UINT16 garagedoorId,const UINT8 drvState)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 ret = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
		if((GARAGE_DOOR_DRV_OPEN == drvState) || (GARAGE_DOOR_DRV_CLOSE == drvState) ||  (GARAGE_DOOR_DRV_NULL == drvState))
		{
			GaragedoorDataStru[bufIndex].drvDoorState = drvState;
			ret = CI_SUCCESS;
		}
    }

	return ret;
}



/*
* 功能描述： 获取指定ID车库门命令处理状态
* 参数说明： const UINT16 garagedoorId, 车库门ID    
* 返回值  ： 0u: 获取数据失败
*			>0u: 命令处理状态      
*/
UINT8 GetGrgdoorCmdProcessState(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 ret = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
		ret = GaragedoorDataStru[bufIndex].cmdProcessState;
    }

	return ret;
}
/*
* 功能描述： 设置指定ID车库门命令处理状态
* 参数说明： const UINT16 garagedoorId, 车库门ID  
*            UINT8 state , 车库门状态
* 返回值  ： 0u: 设置失败
*			>0u: 设置成功     
*/
UINT8 SetGrgdoorCmdProcessState(const UINT16 garagedoorId,UINT8 state)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
    UINT8 ret = CI_ERROR;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
		if((GARAGE_DOOR_CMD_OPEN == state) || (GARAGE_DOOR_CMD_CLOSE == state) ||  (GARAGE_DOOR_CMD_NULL == state))
		{
			GaragedoorDataStru[bufIndex].cmdProcessState = state;
			ret = CI_SUCCESS;
		}
    }

	return ret;
}

#if 0
/*
* 功能描述： 设置所有车库门命令处理状态
* 参数说明：  
*            UINT8 state , 车库门状态
* 返回值  ： 0u: 设置失败
*			>0u: 设置成功     
*/
UINT8 SetAllGrgdoorCmdProcessState(const UINT8 state)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 ret = CI_SUCCESS;
	UINT8 tmpRet = CI_SUCCESS;
	UINT8 ii = 0u;
	UINT16 doorId = 0u;
	for (ii=0u;ii<GetGaragedoorSum();ii++)
	{
		 doorId = GetGaragedoorId(ii);
		 if (doorId > 0u )
		 {
			 tmpRet = SetGrgdoorCmdProcessState(doorId, state);
			 if (CI_ERROR == tmpRet)
			 {
				 ret = tmpRet;
			 }
		 }
	}

	return ret;
}
#endif

/*
* 功能描述： 设置指定ID车库门等待ZC反馈开始时间
* 参数说明： const UINT16 garagedoorId, 车库门ID 
*			 const UINT32 startCycNum, 起始周期号
* 返回值  ： 无
*			    
*/
void SetWaiteZCResponseStartCycNum(const UINT16 garagedoorId, const UINT32 startCycNum)
{
    UINT16 bufIndex = 0u;  /*数组下标*/

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        GaragedoorDataStru[bufIndex].waiteZCResponseStartCycNum = startCycNum;   /*起始周期号*/
    }

}
/*
* 功能描述： 获取指定ID车库门等待ZC反馈开始时间
* 参数说明： const UINT16 garagedoorId, 车库门ID 
* 返回值  ： 0u: 获取失败
*			 >0u: 获取成功  
*/
UINT32 GetWaiteZCResponseStartCycNum(const UINT16 garagedoorId)
{
    UINT16 bufIndex = 0u;  /*数组下标*/
    UINT32 ret = 0u;

    bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

    if (bufIndex < GARAGE_DOOR_SUM_MAX)
    {
        ret = GaragedoorDataStru[bufIndex].waiteZCResponseStartCycNum;
    }

    return ret;
}

/*
* 功能描述： 设置指定ID车库门等待IVOC反馈开始时间
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT32 startCycNum, 起始周期号
* 返回值  ： 无
* BY LC
*/
void SetWaiteIVOCResponseStartCycNum(const UINT16 garagedoorId, const UINT32 startCycNum)
{
	UINT16 bufIndex = 0u;  /*数组下标*/

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		GaragedoorDataStru[bufIndex].waiteIVOCResponseStartCycNum = startCycNum;   /*起始周期号*/
	}

}
/*
* 功能描述： 获取指定ID车库门等待IVOC反馈开始时间
* 参数说明： const UINT16 garagedoorId, 车库门ID
* 返回值  ： 0u: 获取失败
*			 >0u: 获取成功
* BY LC
*/
UINT32 GetWaiteIVOCResponseStartCycNum(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT32 ret = 0u;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		ret = GaragedoorDataStru[bufIndex].waiteIVOCResponseStartCycNum;
	}

	return ret;
}

/*
* 功能描述： 获取指定ID车库门关门起始周期号
* 参数说明： const UINT16 garagedoorId, 车库门ID    
* 返回值  ： 0u: 获取数据失败
*			>0u: 关闭车库门起始周期号      
*/
UINT32 GetGaragedoorCloseStartCycNum(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT32 retVal = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取区段数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		retVal = GaragedoorDataStru[bufIndex].GaragedoorCloseStartCycNum;
	}
	else
	{
		retVal = CI_ERROR;
	}
	return retVal;
}

/*
* 功能描述： 设置指定ID车库门关门起始周期号
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT32 startCycNum, 关闭车库门起始周期号
* 返回值  ： void   
*/
void SetGaragedoorCloseStartCycNum(const UINT16 garagedoorId, const UINT32 startCycNum)
{
	UINT16 bufIndex = 0u;  /*数组下标*/

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取区段数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		GaragedoorDataStru[bufIndex].GaragedoorCloseStartCycNum = startCycNum;  /*车库门关门起始周期号*/	
	}
	else
	{
		; /*不处理*/
	}
}

/*
* 功能描述： 获取指定ID车库门开门起始周期号
* 参数说明： const UINT16 garagedoorId, 车库门ID    
* 返回值  ： 0u: 获取数据失败
*			>0u: 打开车库门起始周期号      
*/
UINT32 GetGaragedoorOpenStartCycNum(const UINT16 garagedoorId)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT32 retVal = CI_ERROR;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取区段数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		retVal = GaragedoorDataStru[bufIndex].GaragedoorOpenStartCycNum;
	}
	else
	{
		retVal = CI_ERROR;
	}
	return retVal;
}

/*
* 功能描述： 设置指定ID车库门开门起始周期号
* 参数说明： const UINT16 garagedoorId, 车库门ID
*			 const UINT32 startCycNum, 打开车库门起始周期号
* 返回值  ： 0u: 设置失败
*			 1: 设置成功      
*/
UINT8 SetGaragedoorOpenStartCycNum(const UINT16 garagedoorId, const UINT32 startCycNum)
{
	UINT16 bufIndex = 0u;  /*数组下标*/
	UINT8 retVal = CI_SUCCESS;

	bufIndex = GetGaragedoorConfigBufIndex(garagedoorId);  /*获取区段数组下标*/

	if (bufIndex < GARAGE_DOOR_SUM_MAX)
	{
		GaragedoorDataStru[bufIndex].GaragedoorOpenStartCycNum = startCycNum;  /*车库门开门起始周期号*/

		retVal = CI_SUCCESS;
	}
	else
	{
		retVal = CI_ERROR;
	}
	return retVal;
}

/*
* 功能描述： 获取指定ID车库门相邻计轴
* 参数说明： const UINT16 garagedoorId, 车库门ID
*          UINT16 adjacentACID[GARAGE_DOOR_ADJACENT_AXIS]  相邻计轴区段
* 返回值  ： 0u: 获取数据失败
*			>0u: 相邻计轴数目
* BY LC
*/
UINT8 GetGarageDoorAdjacentAC(const UINT16 garagedoorId, OUT UINT16 adjacentACID[GARAGE_DOOR_ADJACENT_AXIS])
{
	UINT8 retval = 0U;
	UINT8 keepWork = CI_ERROR;
	UINT16 phySecAId = 0U;   /*车库门对应A库线物理区段ID*/
	UINT8 phyAxisSecNum = 0U;  /*物理区段关联计轴区段数量*/
	UINT16* pPhyAxisIDBuf = NULL; /*物理区段关联计轴区段ID数组*/
	UINT8 i = 0U;
	UINT8 indexAC = 0U;
	UINT16* proSignalIdBuff = NULL;  /*防护信号机数组*/
	UINT8 outSignalDir = 0U;    /*出库防护信号机方向*/
	UINT8 attribute = 0U;       /*车库门属性*/
	UINT8 adjacentACNumLJK = 0U;
	UINT16 tmpACIdLJK[AC_MAXCNT_IN_SWITCH] = { 0u };
	UINT8 adjacentACNumXCK = 0U;
	UINT16 tmpACIdXCK[AC_MAXCNT_IN_SWITCH] = { 0u };
	UINT8 cDirectionPointFlag = 0U;   /*查询到是否有方向变化点*/

	if ((NULL != adjacentACID) && (0U != garagedoorId) && (GARAGE_DOOR_SUM_MAX > garagedoorId))
	{
		keepWork = CI_SUCCESS;
		/*查找车库门A库线物理区段包含计轴区段*/
		phySecAId = GetGarageDoorAKuPhySec(garagedoorId);
		if (0U != phySecAId)
		{
			phyAxisSecNum = GetPAxisSectionSum(phySecAId);/*获取物理区段关联计轴区段数量*/
			pPhyAxisIDBuf = GetPAxisSectionIdBuf(phySecAId);/*获取物理区段关联计轴区段ID数组*/
			/*A库线物理区段无道岔，只存在一个计轴区段*/
			if ((1U == phyAxisSecNum)&&(NULL!= pPhyAxisIDBuf))
			{
				adjacentACID[indexAC] = pPhyAxisIDBuf[0];
				indexAC++;
			}
			else
			{
				/*返回失败*/
				keepWork = CI_ERROR;
			}
		}
		else
		{
			/*查询车库门对应A库线物理区段ID失败*/
			keepWork = CI_ERROR;
		}

		/*查找相邻计轴*/
		if (CI_SUCCESS == keepWork)
		{
			attribute = GetGarageDoorAttribute(garagedoorId);

			/*列检库 查询出库方向相邻第一个计轴*/
			if (GARAGE_DOOR_ATTRIBUTE_LJK == attribute)
			{
				/*获取出库信号机防护方向*/
				outSignalDir = GetGardoorProOutDir(garagedoorId);
				/*按照信号机防护方向查找下一个计轴*/
				adjacentACNumLJK = elm_PrepareAdjacentAC(pPhyAxisIDBuf[0], outSignalDir, tmpACIdLJK, &cDirectionPointFlag);
				if ((1U == adjacentACNumLJK) && (UINT8_MAX != adjacentACNumLJK))
				{/*查询下一计轴成功*/
					adjacentACID[indexAC] = tmpACIdLJK[0];
					indexAC++;
				}
				else
				{
					keepWork = CI_ERROR;
				}
			}
			/*洗车库 按两个方向都查询相邻第一个计轴*/
			else if (GARAGE_DOOR_ATTRIBUTE_XCK == attribute)
			{
				/*查询反向计轴*/
				adjacentACNumXCK = elm_PrepareAdjacentAC(pPhyAxisIDBuf[0], EMAP_CONVER_DIR, tmpACIdXCK, &cDirectionPointFlag);
				if ((1U == adjacentACNumXCK) && (UINT8_MAX != adjacentACNumXCK))
				{
					adjacentACID[indexAC] = tmpACIdXCK[0];
					indexAC++;
				}
				else
				{
					keepWork = CI_ERROR;
				}
				(void)CommonMemSet(tmpACIdXCK, (UINT32)sizeof(tmpACIdXCK), 0, (UINT32)sizeof(tmpACIdXCK));
				/*查询正向计轴*/
				adjacentACNumXCK = elm_PrepareAdjacentAC(pPhyAxisIDBuf[0], EMAP_SAME_DIR, tmpACIdXCK, &cDirectionPointFlag);
				if ((1U == adjacentACNumXCK) && (UINT8_MAX != adjacentACNumXCK))
				{
					adjacentACID[indexAC] = tmpACIdXCK[0];
					indexAC++;
				}
				else
				{
					keepWork = CI_ERROR;
				}
			}
			else
			{
				/*车库门属性无效*/
				keepWork = CI_ERROR;
			}
		}
	}
	else
	{
		/*计算失败*/
	}

	if (CI_SUCCESS == keepWork)
	{
		retval = indexAC;
	}
	else
	{
		retval = 0U;
	}

	return retval;
}


/*
* 功能描述： 检查指定计轴区段是否都属于车库门A库线上的休眠轨
* 参数说明： const UINT16 garagedoorId, 车库门ID
*          const UINT8 axisNum  计轴区段数目
*          UINT16 axisID[GARAGE_DOOR_ADJACENT_AXIS]  计轴区段
* 返回值  ： 0u: 检查失败
*			1u: 检查通过
* BY LC
*/
UINT8 CheckGarageDoorSleepAC(const UINT16 garagedoorId, UINT16 axisID)
{
	UINT8 i = 0U;
	UINT16 gdAkuPhySecId = 0U;
	UINT16 tmpPhySecId = 0U;
	UINT8 retval = CI_ERROR;
	UINT8 sleepFlag = 0U;  /*休眠轨判断标志*/
	UINT8 tmpLinkcnt = 0u;
	const UINT16* pLinkIdBuf = NULL;

	/*获取计轴包含的link数据*/
	tmpLinkcnt = GetAxisLinkSum(axisID);
	pLinkIdBuf = GetAxisLinkIdBuf(axisID);
	if ((AXIS_SECTION_SUM_MAX > axisID) && (0U != axisID) && (0U != tmpLinkcnt) && (NULL != pLinkIdBuf))
	{
		gdAkuPhySecId = GetGarageDoorAKuPhySec(garagedoorId);

		/*获取计轴所属物理区段*/
		tmpPhySecId = elm_PrepareACRelPhyId(axisID);
		/*判断休眠轨属性*/
		sleepFlag = IsLinkSwTrack(pLinkIdBuf[0]);

		if (gdAkuPhySecId != tmpPhySecId)
		{
			/*占压区段不为A库线物理区段*/
			retval = CI_ERROR;
		}
		else
		{
			/*A库轨上包含link有休眠轨属性*/
			if (CI_SUCCESS==sleepFlag)
			{
				retval = CI_SUCCESS;
			}
			else
			{
				/*占压区段不存在休眠轨属性*/
				retval = CI_ERROR;
			}
			
		}
	}
	else
	{
		retval = CI_ERROR;
	}
	return retval;
}


/*
* 功能描述： 获取车库门A库线区段是否为VBTC车占用
* 参数说明： const UINT16 garagedoorId, 车库门ID
*
* 返回值  ： 0u: 非VBTC车占用
*			1u: VBTC车占用或无车
* BY LC
*/
UINT8 CheckGarageDoorAKuIsCTOccu(const UINT16 garagedoorId)
{
	UINT8 i = 0U;
	UINT16 gdAkuPhySecId = 0U;
	UINT8 phySecStatus = 0U;
	UINT8 retval = CI_ERROR;
	UINT8 cPhySecIncLogSecSum = 0U;  /*物理区段包含的逻辑区段数量*/
	UINT16* pPhySecIncLogSecId = NULL;  /*物理区段包含的逻辑区段ID*/
	UINT8 logOccuState = 0U;

	gdAkuPhySecId = GetGarageDoorAKuPhySec(garagedoorId);

	
	if ((0U != gdAkuPhySecId) && (PHYSICAL_SECTION_SUM_MAX > gdAkuPhySecId))
	{
		retval = CI_SUCCESS;
		/*获取物理区段关联逻辑区段信息*/
		cPhySecIncLogSecSum = GetPhySecIncLogSecSum(gdAkuPhySecId);
		pPhySecIncLogSecId = GetPhySecIncLogSecIdBuf(gdAkuPhySecId);
		
		for ( i = 0U; i < cPhySecIncLogSecSum; i++)
		{
			logOccuState = GetLogSecCurCtOrUtOccupyState(pPhySecIncLogSecId[i]);
			if ((LOGICSECTION_OCCUPY_NO == logOccuState) || (LOGICSECTION_OCCUPY_CT == logOccuState))
			{
				/*逻辑区段空闲或CT占用，继续遍历*/

			}
			else
			{
				retval = CI_ERROR;
				break;
			}

		}
	}

	return retval;
}

/*
* 功能描述： 获取车库门A库线物理区段是否占用
* 参数说明： const UINT16 garagedoorId, 车库门ID
*
* 返回值  ： 0u: 占用
*			1u: 未占用
*/
UINT8 GetGarageDoorAKuIsOccu(const UINT16 garagedoorId)
{
	UINT8 i = 0U;
	UINT16 gdAkuPhySecId = 0U;
	UINT8 phySecStatus = 0U;
	UINT8 retval = CI_ERROR;

	gdAkuPhySecId = GetGarageDoorAKuPhySec(garagedoorId);
	if ((0U != gdAkuPhySecId) && (PHYSICAL_SECTION_SUM_MAX > gdAkuPhySecId))
	{
		phySecStatus = GetPhySecCurOccupyState(gdAkuPhySecId);
		if (SECTION_OCCUPY_NO == phySecStatus)
		{
			retval = CI_SUCCESS;
		}
		else
		{
			/*不为空闲状态，返回失败*/
		}
	}

	return retval;
}



/* 功能描述： 获取车库门关联的处于已办理状态的防护进路
*  参数说明：  const UINT16 garagedoorId, 车库门ID
             UINT16 routeId[GARAGE_DOOR_ROUTE_MAX]    已办理的进路ID
*  返回值：    已办理的进路数量
*/
UINT8 GetProRouteInTransactState(const UINT16 garagedoorId, OUT UINT16  routeId[GARAGE_DOOR_ROUTE_MAX])
{
	UINT16* routeIdbuff = NULL;  /*防护进路数组*/
	UINT8 routeNum = 0U;    /*防护进路数*/
	UINT8 i = 0U;
	UINT8 transactFlag = CI_ERROR;  /*进路未办理标志标志*/
	UINT8 transactNum = 0U;

	routeNum = GetGardoorRouteSum(garagedoorId);
	routeIdbuff = GetGardoorRouteIdBuf(garagedoorId);

	if ((0U != routeNum) && (NULL != routeIdbuff))
	{
		/*查找已办理的防护进路*/
		for (i = 0U; i < routeNum; i++)
		{
			transactFlag = CheckRouteTransactState(routeIdbuff[i]);
			if (ROUTE_TRANSACT_NO != transactFlag)
			{
				/*进路已办理*/
				routeId[transactNum] = routeIdbuff[i];
				transactNum++;
			
			}
			else
			{
				/*进路未被办理，继续遍历*/
			}

		}
	}
	return transactNum;
}


/* 功能描述： 查询A库物理区段上离车库门最接近的列车
*  参数说明：  const UINT16 garagedoorId, 车库门ID
*  返回值：    !=UINT16_MAX  列车ID
*             UINT16_MAX  查询失败
* BY LC
*/
UINT16 FindNearestTrainInAKuPhy(const UINT16 garagedoorId)
{
	UINT16 phySecAKuId = 0U;
	UINT8 cPhySecIncLogSecSum = 0U;  /*物理区段包含的逻辑区段数量*/
	UINT16* pPhySecIncLogSecId = NULL;  /*物理区段包含的逻辑区段ID*/
	UINT8 i = 0U;
	UINT8 j = 0U;
	UINT8 wTrainNum = 0U;
	UINT16 wTrainIdBuff[SIZE_MAX_TRAINOFAC] = { 0U };
	UINT8 tmpLogState = 0U;
	UINT8 retVal = CI_ERROR;
	UINT32 dwLen = 0U;

	UINT32 minLen = UINT32_MAX;
	UINT16 minTrainId = 0U;
	LOD_STRU gDPoint = { 0U };  /*车库门位置*/
	LOD_STRU trainMinTailPoint = { 0U }; /*列车小后点所在位置*/
	UINT8 keepwork = CI_ERROR;


	gDPoint.Lnk = GetGardoorPointLink(garagedoorId);
	gDPoint.Off = GetGardoorPointLinkOffset(garagedoorId);

	phySecAKuId = GetGarageDoorAKuPhySec(garagedoorId);
	cPhySecIncLogSecSum = GetPhySecIncLogSecSum(phySecAKuId);
	pPhySecIncLogSecId = GetPhySecIncLogSecIdBuf(phySecAKuId);

	if ((0U != cPhySecIncLogSecSum) && (NULL != pPhySecIncLogSecId))
	{
		keepwork = CI_SUCCESS;

		/* 获取A库物理区段上最近的占压逻辑区段 */
		for (i = 0U; i < cPhySecIncLogSecSum; i++)
		{
			tmpLogState= GetLogSecCurCtOrUtOccupyState(pPhySecIncLogSecId[i]);
			if (LOGICSECTION_OCCUPY_NO == tmpLogState)
			{
				/*继续检查*/
			}
			else
			{
				/*清空缓存*/
				(void)CommonMemSet(wTrainIdBuff, (UINT32)sizeof(wTrainIdBuff), 0u, (UINT32)sizeof(wTrainIdBuff));
				wTrainNum = 0U;

				/*获取逻辑区段上所有列车*/
				wTrainNum = GetLogSecTrainId(pPhySecIncLogSecId[i], &wTrainIdBuff);

				for (j = 0; j < wTrainNum; j++)
				{
					if (NAME_FAILUREAREA != wTrainIdBuff[j])
					{
						trainMinTailPoint.Lnk= GetTrainMinTailLink(wTrainIdBuff[j]);
						trainMinTailPoint.Off= GetTrainMinTailOffset(wTrainIdBuff[j]);

						dwLen = elm_PrepareDistanceBtwPoints(trainMinTailPoint, gDPoint);
						if (minLen > dwLen)
						{
							minLen = dwLen;
							minTrainId = wTrainIdBuff[j];
						}
					}
				}
				if (UINT32_MAX == minLen)
				{
					keepwork = CI_ERROR;
				}

			}
			

			if (CI_ERROR == keepwork)
			{
				minTrainId = UINT16_MAX;
				break;
			}

		}
	}
	return minTrainId;
}



/* 功能描述： 检查列车接近车库门一端无可疑
*  参数说明：   UINT16 garageDoorId 车库门
*            UINT16 trainId 列车ID
*  返回值：    CI_ERROR  存在可疑
*             CI_SUCCESS 无可疑
* BY LC
*/
UINT8 CheckNearestTrainScreen(const UINT16 garageDoorId, const UINT16 trainId, const  UINT8 functionId, const UINT8 sendLevel)
{
	UINT8 retVal = CI_ERROR;
	LOD_STRU pointMaxHead = { 0U };
	LOD_STRU pointMinTail = { 0U };
	LOD_STRU pointGD = { 0U };
	UINT16 linkNum = 0U;
	UINT16 szLinkIdBuf[100u] = { 0u };
	UINT8 chDir = 0U;
	UINT32 dwLenMaxHead = 0U;
	UINT32 dwLenMinTail = 0U;
	UINT8 flag = CI_ERROR;
	UINT16 phySecAku = 0U;
	UINT16 AxisAku = 0U;
	UINT16* axisSecIdBuf = NULL;                                  /*物理区段包含计轴区段ID数组指针*/
	UINT8 axisSectionSum = 0U;

	phySecAku = GetGarageDoorAKuPhySec(garageDoorId);
	axisSecIdBuf = GetPAxisSectionIdBuf(phySecAku);         /*获取物理区段包含计轴区段ID数组指针*/
	axisSectionSum = GetPAxisSectionSum(phySecAku);         /*获取物理区段包含计轴区段数目*/

	pointMaxHead.Lnk = GetTrainMaxHeadLink(trainId);
	pointMaxHead.Off = GetTrainMaxHeadOffset(trainId);
	pointMinTail.Lnk = GetTrainMinTailLink(trainId);
	pointMinTail.Off = GetTrainMinTailOffset(trainId);
	pointGD.Lnk = GetGardoorPointLink(garageDoorId);
	pointGD.Off = GetGardoorPointLinkOffset(garageDoorId);
	dwLenMaxHead = dsuLenByPoint(&pointMaxHead, &pointGD, &linkNum, szLinkIdBuf, &chDir);
	dwLenMinTail = dsuLenByPoint(&pointMinTail, &pointGD, &linkNum, szLinkIdBuf, &chDir);


	if (dwLenMaxHead > dwLenMinTail)
	{
		/*查询后端*/
		flag = elm_CheckTrainTailTrain(axisSecIdBuf[0],trainId);
		if (FLAG_SET == flag)
		{
			retVal = CI_SUCCESS;
		}
		else
		{
			retVal = CI_ERROR;
			SetErrorData(functionId, CI_DEVICE_TYPE_TRAIN_VOBC, trainId, ETYPE_GDOOR_TRAIN_TAILSCREEN, flag, sendLevel);
		}
	}
	else
	{
		/*查询前端*/
		flag = elm_CheckTrainheadTrain(axisSecIdBuf[0], trainId);

		if (FLAG_SET == flag)
		{
			retVal = CI_SUCCESS;
		}
		else
		{
			retVal = CI_ERROR;
			SetErrorData(functionId, CI_DEVICE_TYPE_TRAIN_VOBC, trainId, ETYPE_GDOOR_TRAIN_HEADSCREEN, flag, sendLevel);
		}
	}


	return retVal;
}


/* 功能描述： 检查列车包络是否跨压车库门
*  参数说明：   UINT16 garageDoorId 车库门
*            UINT16 trainId 列车ID
*  返回值：    CI_ERROR  跨压
*             CI_SUCCESS 未跨压
* BY LC
*/
UINT8 CheckNearestTrainKuaya(const UINT16 garageDoorId, const UINT16 trainId, const  UINT8 functionId, const UINT8 sendLevel)
{
	UINT8 retVal = CI_ERROR;
	LOD_STRU pointMaxHead = { 0U };
	LOD_STRU pointMinTail = { 0U };
	struct_PathPoint pointGD = { 0U };
	UINT16 wLinkNum = 0U;
	str_Zone strTrainZone = { 0u };


	pointMaxHead.Lnk = GetTrainMaxHeadLink(trainId);
	pointMaxHead.Off = GetTrainMaxHeadOffset(trainId);
	pointMinTail.Lnk = GetTrainMinTailLink(trainId);
	pointMinTail.Off = GetTrainMinTailOffset(trainId);


	strTrainZone.Dir = GetTrainDir(trainId);
	strTrainZone.pStart.wLinkId = pointMaxHead.Lnk;
	strTrainZone.pStart.dwOffset = pointMaxHead.Off;
	strTrainZone.pEnd.wLinkId = pointMinTail.Lnk;
	strTrainZone.pEnd.dwOffset = pointMinTail.Off;

	retVal = DsuLinkSeqBtwPoints(&strTrainZone.pStart, &strTrainZone.pEnd, &strTrainZone.Dir, &wLinkNum, strTrainZone.pLinkSeq.szLinkId);
	strTrainZone.pLinkSeq.cLinkCnt = (UINT8)wLinkNum;

	pointGD.wLinkId = GetGardoorPointLink(garageDoorId);
	pointGD.dwOffset = GetGardoorPointLinkOffset(garageDoorId);


	retVal=IsPointInPath(pointGD, strTrainZone);



	if (CI_SUCCESS== retVal)
	{
		/*未跨压*/
	}
	else
	{
		/*跨压*/
		retVal = CI_ERROR;
		SetErrorData(functionId, CI_DEVICE_TYPE_TRAIN_VOBC, trainId, ETYPE_GDOOR_TRAIN_KUAYAGD, 0U, sendLevel);
	}


	return retVal;
}

/* 功能描述： 检查车库门相邻计轴是否存在锁闭
*  参数说明：   UINT16 garageDoorId 车库门
* *           UINT16* pDevId 锁闭的物理区段ID（出参）
*             UINT8* pDevState 锁闭状态（出参）
*  返回值：    CI_ERROR  存在锁闭
*             CI_SUCCESS 未存在锁闭
* BY LC
*/
UINT8 CheckGDAdjacentACLockState(const UINT16 garageDoorId,UINT16* pDevId, UINT8* pDevState)
{
	UINT8 retVal = CI_ERROR;
	UINT16 adjacentACID[GARAGE_DOOR_ADJACENT_AXIS] = { 0U }; /*相邻计轴ID数组*/
	UINT8 adjacentACNum = 0U;    /*相邻计轴数量*/
	UINT8 i = 0U;
	UINT16 phySecId = 0U;
	UINT8 phyLockState = 0U;
	/*查询车库门的相邻计轴——车库门对应A库线物理区段包含计轴及其出库方向第一个关联计轴*/
	adjacentACNum = GetGarageDoorAdjacentAC(garageDoorId, adjacentACID);
	if ((0U != adjacentACNum) && (GARAGE_DOOR_ADJACENT_AXIS > adjacentACNum) && (NULL != pDevId) && (NULL != pDevState))
	{/*相邻计轴查询成功*/
		retVal = CI_SUCCESS;
		/*遍历车库门相邻计轴，筛选存在占用的相邻计轴*/
		for (i = 0U; i < adjacentACNum; i++)
		{
			phySecId = GetAxisSecRelativePhySecId(adjacentACID[i]);

			phyLockState = GetPhySecLockState(phySecId);

			if (PHYSICAL_SECTION_LOCK_NO == phyLockState)
			{
				/*此计轴未锁闭，继续检查*/
			}
			else
			{
				*pDevId = phySecId;
				*pDevState = phyLockState;
				/*此区段已锁闭，返回失败*/
				retVal = CI_ERROR;
				break;
			}
		}
	}
	else
	{
		/*查询失败*/
	}
	return retVal;
}


