/********************************************************
*                                                      
*  文件名   ：   VobcNetPack.c         
*  版权说明 ：   北京瑞安时代科技有限责任公司 
*  版本号   ：   1.0
*  创建时间 ：   2008.07.29
*  作者     ：   车载及协议部
*  功能描述 ：   vobc内网信息层协议函数                                                                    
*  修改记录 ：  
*
********************************************************/ 

#include "VobcNetPack.h"
#include "Convert.h"
#include "CRC32.h"

/*
*  功能描述： 内网信息层打包函数
*  参数说明： IN UINT8 DataType，   报文类型
*             IN UINT32 Seq,        控制周期序列号
*             IN const UINT8 *pData,应用数据
*             IN UINT16 DataLen,    应用数据长度
*             OUT UINT8 *pPackData, 打包数据指针
*  返回值：   打包后信息的数据长度
*  修改记录： 修复产品白盒集成测试缺陷Bug-2012,hc,20200218
*/
UINT16 VobcNetPack(IN UINT8 DataType,IN UINT32 Seq,IN const UINT8 *pData, IN UINT16 DataLen,OUT UINT8 *pPackData)
{
    UINT16 PackDataLen= 0u;
    UINT8 *pPack=pPackData;
    UINT32 CRCValue = 0u;
    UINT16 tempLen = 0u;
    UINT16 i = 0u;

	if((NULL != pData) && (NULL != pPackData))
	{
		/*数据赋值*/
		PackDataLen = DataLen + 11u;

		/*数据长度2个字节*/
		tempLen=PackDataLen-2u;
		ShortToChar(tempLen,pPack);
		pPack+=2u;

		/*报文类型*/
		*pPack=DataType;
		pPack+=1u;

		/*控制周期序列号,4个字节*/
		LongToChar(Seq,pPack);
		pPack+=4u;


		/*应用数据*/
		for(i=0u;i<DataLen;i++)
		{
			*pPack=*pData;
			pPack++;
			pData++;
		}

		/*CRC32*/
		CRCValue=Crc32(pPackData,(UINT32)(PackDataLen-4u));
		LongToChar(CRCValue,pPack);
	}
    
    return PackDataLen;
}

/*
*  功能描述： 内网信息层解包函数
*  参数说明： IN const UINT8 *pPackData,     打包数据
*             IN const UINT16 PackDataLen,   打包数据长度
*             OUT UINT8 *pDataType,          数据类型
*             OUT UINT32 *pSeq,              控制周期序列号
*             OUT UINT8  *pData,             解包后的应用数据
*  返回值：   >0,  解包后的数据长度
*             0,   表示解包错误,或者解包后的数据长度为0
*  修改记录： 修复产品白盒集成测试缺陷Bug-2012,hc,20200218
*/
UINT16 VobcNetUnpack(IN const UINT8 *pPackData,IN const UINT16 PackDataLen,OUT UINT8 *pDataType,OUT UINT32 *pSeq,OUT UINT8 *pData)
{
    UINT16 DataLen=PackDataLen-11u;
    UINT8 *pData1=pData;
    const UINT8 *pPackData1=pPackData;
    UINT32 PackCRCValue = 0u;
    UINT32 CalcCRCValue = 0u;
    UINT16 tempLen = 0u;
    UINT16 i = 0u;


    /*判断数据长度是否正确*/
    if ((NULL != pPackData) && (NULL != pDataType) && (NULL != pSeq) && (NULL != pData))
    { 
		tempLen = ShortFromChar(pPackData1);
		pPackData1 += 2u;
		if ((tempLen + 2u) == PackDataLen)
		{
			/*自己计算得到的CRC32*/
			tempLen = PackDataLen - 4u;
			CalcCRCValue = Crc32(pPackData, (UINT32)tempLen);

			/*打包数据中取出的crc32*/
			PackCRCValue = LongFromChar((const UINT8 *)(pPackData + PackDataLen - 4u));

			if (CalcCRCValue == PackCRCValue)
			{
				/*报文类型*/
				*pDataType = *pPackData1;
				pPackData1 += 1u;

				/*周期序列号*/
				*pSeq = LongFromChar(pPackData1);
				pPackData1 += 4u;

				/*应用数据*/
				for (i = 0u; i < DataLen; i++)
				{
					*pData1 = *pPackData1;
					pData1++;
					pPackData1++;
				}
			}
			else
			{
				/*失败,CRC错误*/
				DataLen = 0u;
			}
		} 
		else
		{
			DataLen = 0u;
		}

    }
    else
    {
        /*入口参数检查未通过，长度置0*/
        DataLen=0u;
    }

    return DataLen;
}
