
#define	_IN_OCOM_C
#include "ocom.h"
#include "crc16.h"

void ReadOComBuffEmpty(OComExFuns * funs)
{
	int rslt, len;
	u8 temp;

	len = funs->GetRsvLen();

	while (len > 0)
	{
		rslt = funs->GetOComData(&temp, 1);
		if (rslt != 1)
		{
			rslt = 0;
			break;
		}
		len--;
	}
	
}

#ifndef MAX_OCOM_SCAN
#define	MAX_OCOM_SCAN		128			// 单次最大扫描个数
#endif

int GetAOComPacket(OComExFuns * funs, OComPacket * pPacket)
{
	int rslt, len;
	int i;
	int phase;

	u8 temp;
	u8 rdBuf[LEN_OCOM_PKT];
	OComPacket * pDat;

	if (funs == NULL || pPacket == NULL)
	{
		return -1;
	}

	i = 0;				// 扫描字节计数器
	pDat = (OComPacket *)rdBuf;	

	do
	{
		len = funs->GetRsvLen();

		if (len < LEN_OCOM_PKT)
		{
			rslt = -3;
			break;			// 没有足够数据
		}

		phase = 0;
		rslt = 0;

		// 从接收缓冲区中找数据包
		while(((len + phase) >= LEN_OCOM_PKT) && (phase < LEN_OCOM_PKT))
		{
			if (phase == 0 && i > MAX_OCOM_SCAN)
			{
				rslt = -4;
				break;		// 查找同步序列超出最大单次扫描字节数
			}

			rslt = funs->GetOComData(&temp, 1);		// 读取一个字节
			if (rslt != 1)
			{
				printf("error at GetOComData rslt\r\n");
				rslt = -8;
				break;
			}

			rslt = 0;
			i++;				// 扫描字数增加
			len--;				// 剩余长度减小

			if (phase < DC_SYNC_LEN)			// 识别同步序列
			{
				if (temp != OCOM_SYNC[phase])
				{
					phase = 0;
					rslt = 0;
					break;
				}
			}

			pDat->buff.normal[phase] = temp;	// 保存
			phase++;
		}

		if (rslt != 0)
		{
			break;
		}

		if (phase >= LEN_OCOM_PKT)		// 得到数据包
		{
			u16 check;
			check = CalcCheckSum(&(pDat->buff.normal[DC_SYNC_LEN]), DC_CHECK_LEN);
			if (check == pDat->normal.check)
			{
				// 得到正确数据包
				memcpy(pPacket, pDat, LEN_OCOM_PKT);
//				printf("GetANormalPacket ok\r\n");
				rslt = LEN_OCOM_PKT;
				break;
			}
			else
			{
				// CRC 不正确
				printf("1. crc error in GetANormalPacket\r\n");
				// 拷贝需要再判断的数据
//				continue;
			}
		}
		else
		{
			// 没有找到同步序列的情况
//			continue;
		}
	}while(1);

	return rslt;
}

int GetOComExData(OComExFuns * funs, u8 * pBuff, int exlen)
{
	int rslt, len;
	u16 getcrc;

	if (funs == NULL || pBuff == NULL || exlen <= 0)
	{
		return -1;
	}

	u8 * pDat = (u8 *)pBuff;
	do
	{
		len = funs->GetRsvLen();
		if (len < exlen + 2)
		{
			rslt = -3;
			break;			// 没有足够数据
		}

		rslt = 0;

		rslt = funs->GetOComData(pDat, exlen);		// 读取数据
		if (rslt != exlen)
		{
			printf("error at GetOComData rslt=%d\r\n", rslt);
			rslt = -8;
			break;
		}

		rslt = funs->GetOComData((u8*)(&getcrc), 2);		// 读取crc
		if (rslt != 2)
		{
			printf("error at GetOComData rslt=%d\r\n", rslt);
			rslt = -9;
			break;
		}

		{
			u16 check;

			check = CalcCheckSum(pDat, exlen);
			if (check == getcrc)
			{
				// 得到正确数据包
	//			printf("GetOComExData ok\r\n");
				rslt = exlen;
				break;
			}
			else
			{
				// CRC 不正确
				printf("2. crc error in GetOComExData\r\n");
				rslt = -7;
			}
		}
	}while (0);

	return rslt;
}

int SendAOComPacket(OComExFuns * funs, OComPacket * pPacket)
{
	int rslt;
	int freelen, sendlen;

	if (funs == NULL || pPacket == NULL)
	{
		return -1;
	}
	sendlen = LEN_OCOM_PKT;

	freelen = funs->GetTrsFreeLen();

	if (freelen < sendlen)
	{
//		printf("buff is full in SendAOComPacket\r\n");
		return 1;
	}

	rslt = funs->SendOComData(pPacket->buff.normal, sendlen);
	if (rslt != sendlen)
	{
		printf("error at call SendOComData, rslt=%d\r\n", rslt);
		return -2;
	}

	return 0;
}

int SendOComExData(OComExFuns * funs, u8 * pBuff, int exlen)
{
	int rslt;
	int freelen, sendlen;
	u16 check;

	if (funs == NULL || pBuff == NULL || exlen <= 0)
	{
		return -1;
	}
	sendlen = exlen;

	freelen = funs->GetTrsFreeLen();

	if (freelen < sendlen + 2)
	{
//		printf("buff is full in SendOComExData\r\n");
		return 1;
	}

	rslt = funs->SendOComData(pBuff, sendlen);
	if (rslt != sendlen)
	{
		printf("error at call SendOComData, rslt=%d\r\n", rslt);
		return -2;
	}

	check = CalcCheckSum(pBuff, sendlen);
	rslt = funs->SendOComData((u8*)(&check), 2);
	if (rslt != 2)
	{
		printf("error at call SendOComData, rslt=%d\r\n", rslt);
		return -2;
	}

	return 0;
}

int PacketAOCom(OComPacket * pPacket)
{
	if (pPacket == NULL)
	{
		return -1;
	}

	memcpy(pPacket->normal.sync, OCOM_SYNC, DC_SYNC_LEN);
	pPacket->normal.check = CalcCheckSum(&(pPacket->buff.normal[DC_SYNC_LEN]), DC_CHECK_LEN);

	return 0;

}
