⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hl_serve.c

📁 是zmac的协议的全部完整的解析.代码例子很全
💻 C
字号:

#include	"Holley_ext.h"


/************************************************************************/
/*	本函数从缓冲区 HL_Buffered_Data 数据结构中查找第一个				*/
/*	有效的数据帧, 并将查找到的数据帧保存到指定的位置					*/
/*	参数																*/
/*		pBuf		指向缓冲区的指针									*/
/*		pucData		查找到的数据帧存放位置								*/
/*	返回值																*/
/*		int8u		查找到的数据帧的长度. 如果没有查找到,则返回 0		*/
/*	其他说明															*/
/*	1. 对于 UART 数据, 在将数据复制到 pucData 时, 去掉帧头帧尾			*/
/*	2. 数据在保存到 HL_Buffered_Data 之前, 已经进行了校验, 因此不必		*/
/*		在本函数中再次校验												*/
/************************************************************************/
int8u	Get_First_Valid_Frame( HL_Buffered_Data * pBuf, int8u * pucData )
{
	int8u	ucLength = 0;
	int16u	uiRear;

	if ( pBuf->uiValid_Frames == 0 )	// 此时不能将 pBuf 清除,因为可能正在接收新数据帧
		return 0;

	if ( pBuf->uiStart_Of_First_Frame + 1 == HL_BUFFER_SIZE )
		ucLength= pBuf->acBuffer[0];
	else
		ucLength= pBuf->acBuffer[pBuf->uiStart_Of_First_Frame+1];	// 获得帧长度

	ucLength += 4;

	uiRear	= HL_BUFFER_SIZE - pBuf->uiStart_Of_First_Frame;

	if ( uiRear >= ucLength )
	{
		MEMCOPY ( pucData, pBuf->acBuffer + pBuf->uiStart_Of_First_Frame, ucLength );
	}
	else
	{
		MEMCOPY ( pucData, pBuf->acBuffer + pBuf->uiStart_Of_First_Frame, uiRear );
		MEMCOPY ( pucData + uiRear, pBuf->acBuffer, ucLength-uiRear );
	}

	ucLength -= 4;
	MEMCOPY ( pucData, pucData+2, ucLength );	// 去掉帧头帧尾

	return	ucLength;
}


/************************************************************************/
/*	检测数据帧是否符合帧格式											*/
/*	参数																*/
/*		pBuf		要检查的数据缓冲区指针								*/
/*	返回值																*/
/*		TRUE		数据符合帧格式										*/
/*		FALSE		数据不符合帧格式									*/
/*	其他说明															*/
/*		1. 仅在 SINK 端使用 HL_Buffered_Data 来缓存 UART 数据, 因此		*/
/*	数据帧最大长度不能超过 HL_UART_MAX_FRAME_LENGTH 字节				*/
/*		2. 在从 UART 接收到新的数据后, 调用本函数来判断接收到的数据		*/
/*	格式是否正确														*/
/*		3. 如果数据格式正确, 则在本函数中修改 uiEnd_Of_Last_Frame		*/
/*	和 uiValid_Frames 参数												*/
/************************************************************************/
BOOL	Check_Buffered_Frame( HL_Buffered_Data * pBuf )
{
	int8u	i;
	int8u	ucSum = 0;
	int8u	ucLength;
	int16u	j;
	int16u	uiStart_Of_New_Frame;
	int16u	uiEnd_Of_New_Frame;
	int16u	uiSum_Position;

	if ( pBuf->uiStart_Of_First_Frame == pBuf->uiEnd_Of_Last_Frame )	// 新数据帧起始位置
	{
		uiStart_Of_New_Frame = pBuf->uiStart_Of_First_Frame;	// = 0, 初始状态
	}
	else
	{
		uiStart_Of_New_Frame = pBuf->uiEnd_Of_Last_Frame + 1;
		if ( uiStart_Of_New_Frame == HL_BUFFER_SIZE )
			uiStart_Of_New_Frame = 0;
	}

	if ( pBuf->acBuffer[uiStart_Of_New_Frame] == HL_UART_FRAME_HEADER )		// 判断帧头
	{
		if ( uiStart_Of_New_Frame + 1 ==  HL_BUFFER_SIZE )
			ucLength = pBuf->acBuffer[0];
		else
			ucLength = pBuf->acBuffer[uiStart_Of_New_Frame+1];			// 获得帧长度

		if ( ( ucLength > 0 ) && ( ucLength <= HL_UART_MAX_FRAME_LENGTH ) )	// 判断帧长度
		{
			uiEnd_Of_New_Frame = uiStart_Of_New_Frame + ucLength + 3;
			if ( uiEnd_Of_New_Frame >= HL_BUFFER_SIZE )
				uiEnd_Of_New_Frame -= HL_BUFFER_SIZE;

			if ( pBuf->acBuffer[uiEnd_Of_New_Frame] == HL_UART_FRAME_END )	// 判断帧尾
			{
				for ( i=0; i<ucLength; i++ )
				{
					j = uiStart_Of_New_Frame + i + 2;
					if ( j >= HL_BUFFER_SIZE )
						j -= HL_BUFFER_SIZE;

					ucSum += pBuf->acBuffer[j];
				}

				uiSum_Position = uiStart_Of_New_Frame + ucLength + 2;
				if ( uiSum_Position >= HL_BUFFER_SIZE )
					uiSum_Position -= HL_BUFFER_SIZE;

				if ( ucSum == pBuf->acBuffer[uiSum_Position] )	// 检查校验和
				{
					pBuf->uiEnd_Of_Last_Frame = uiEnd_Of_New_Frame;
					pBuf->uiValid_Frames ++;
					return	TRUE;
				}
			}
		}
	}

	return	FALSE;
}


/************************************************************************/
/*	删除 HL_Buffered_Data 缓冲区中的一个帧, 如果缓冲区中已经没有		*/
/*	缓存数据, 则清空缓冲区												*/
/*	参数																*/
/*		pBuf		要删除的数据缓冲区指针								*/
/*	返回值																*/
/*		无																*/
/************************************************************************/
void	Delete_Buffered_Frame( HL_Buffered_Data * pBuf )
{
	int16u	uiStart_Of_Next_Frame;
	int8u	ucLength;

	if ( pBuf->uiValid_Frames == 0 )
	{
		if ( pBuf->uiEnd_Of_Last_Frame == pBuf->uiPoint )
			MEMSET( ( int8u *) pBuf, 0, sizeof( HL_Buffered_Data ) );
		return;
	}

	if ( pBuf->uiStart_Of_First_Frame + 1 == HL_BUFFER_SIZE )
		ucLength = pBuf->acBuffer[0];
	else
		ucLength = pBuf->acBuffer[pBuf->uiStart_Of_First_Frame+1];

	uiStart_Of_Next_Frame = pBuf->uiStart_Of_First_Frame + ucLength + 4;
	if ( uiStart_Of_Next_Frame >= HL_BUFFER_SIZE )
		uiStart_Of_Next_Frame -= HL_BUFFER_SIZE;

	pBuf->uiStart_Of_First_Frame = uiStart_Of_Next_Frame;	// 下一帧的起始位置
	pBuf->uiValid_Frames --;

	if ( pBuf->uiValid_Frames == 0 )
	{
		if ( pBuf->uiEnd_Of_Last_Frame == pBuf->uiPoint )
			MEMSET( ( int8u *) pBuf, 0, sizeof( HL_Buffered_Data ) );
	}
}


/************************************************************************/
/*	本函数检查数据是否符合 UART 帧格式									*/
/*	参数																*/
/*		pData		要检查的数据指针									*/
/*		ucPoint		要检查的数据长度									*/
/*	返回值																*/
/*		int8u		实际有效数据帧的长度, 不包括帧头帧尾那 4 个字节		*/
/*					返回 0 则说明数据帧无效								*/
/************************************************************************/
int8u	Check_UART_Frame( int8u *pData, int16u uiPoint )
{
	int8u	ucLength;
	int8u	i;
	int8u	ucSum = 0;

	if ( uiPoint <= HL_UART_MAX_FRAME_LENGTH )
	{
		if ( pData[0] == HL_UART_FRAME_HEADER )
		{
			ucLength = pData[1];
			if ( ucLength > 0 && ucLength <= uiPoint-4 )
			{
				for ( i=2; i<ucLength+2; i++ )
					ucSum += pData[i];

				if ( ucSum == pData[ucLength+2] )
					if ( pData[ucLength+3] == HL_UART_FRAME_END )
						return	ucLength;
			}
		}
	}

	return	0;
}

/************************************************************************/
/*	获得节点的 Neighbor_Table											*/
/*	参数																*/
/*		pucResult	Neighbor_Table 存放指针								*/
/*	返回值																*/
/*		int8u		Neighbor 的个数										*/
/************************************************************************/
int8u	Get_Neighbor_Table( int8u * pucResult )
{
	EmberNeighborTableEntry		sEntry;
	int8u						i, j=0;

	for ( i=0; i<EMBER_NEIGHBOR_TABLE_SIZE; i++ )
	{
		if ( emberGetNeighbor( i, &sEntry ) == EMBER_SUCCESS )
		{
			Store_BIT16_Value( pucResult+2*j, sEntry.shortId );
			j ++;
		}
	}

	return	j;
}


/************************************************************************/
/*	返回格式的读 OD 函数												*/
/*	参数																*/
/*		uiIndex		被读参数的 OD 索引									*/
/*		ucSub		被读参数的 OD 子索引								*/
/*		pucResult	读操作返回结果的娣胖刚?						*/
/*	返回值																*/
/*		int8u		读操作返回结果的长度								*/
/*	其他说明															*/
/*		本函数与 Read_OD() 函数之间的区别在于, 本函数的返回结果中		*/
/*	已经包含的帧结构信息, 可直接发送									*/
/************************************************************************/
int8u	Read_OD_Shell( int16u uiIndex, int8u ucSub, int8u * pucResult )
{
	MEMCOPY( pucResult+1, emberGetEui64(), 8 );		// long addr.
	Store_BIT16_Value( pucResult+9, uiIndex );		// index
	pucResult[11] = ucSub;							// subindex

	pucResult[12] = Read_OD( uiIndex, ucSub, pucResult+13 );
	if ( pucResult[12] == 0 )
	{
		pucResult[0] = HL_CMD_READ_OD_ERR;
		pucResult[12]= 1;
	}
	else
	{
		if ( pucResult[12] > HL_RF_PAYLOAD_LENGTH )		// 读取的数据太长
		{
			pucResult[0] = HL_CMD_READ_OD_ERR;			// 无法用 RF 发送
			pucResult[12]= 1;
			pucResult[13]= HL_OD_ERR_WRONG_LENGTH;
		}
		else
			pucResult[0] = HL_CMD_READ_OD;
	}

	return	( pucResult[12] + 13 );
}


/************************************************************************/
/*	读 OD 函数															*/
/*	参数																*/
/*		uiIndex		被读参数的 OD 索引									*/
/*		ucSub		被读参数的 OD 子索引								*/
/*		pucResult	读操作返回结果的存放指针							*/
/*	返回值																*/
/*		int8u		读操作返回结果的长度								*/
/*					如果返回 0, 则说明出现了读错误, 并且错误

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -