基于状态机的DLT645协议解析

DLT645-2007协议格式如下:
基于状态机的DLT645协议解析_第1张图片
/* 根据协议格式的状态定义 /
#define FRAME_STATES_DLT645_NULL 0 /
no synchronisation /
#define FRAME_STATES_DLT645_68 1 /
have the first Flag Byte received /
#define FRAME_STATES_DLT645_ADDR 2 /
have the length byte /
#define FRAME_STATES_DLT645_68_2 3 /
have the length byte /
#define FRAME_STATES_DLT645_C 4 /
have the control byte /
#define FRAME_STATES_DLT645_L 5 /
have the confirm length byte /
#define FRAME_STATES_DLT645_DATA 6 /
have the confirm length byte /
#define FRAME_STATES_DLT645_CS 7 /
wait for the CS /
#define FRAME_STATES_DLT645_END 8 /
wait for the 16H /
#define FRAME_STATES_DLT645_COMPLETE 9 /
complete frame */

/* 数据结构体定义 /
typedef struct _CHKFRAME {
int eFrameState; /
报文状态 /
uint8 nControlWord; /
普通报文中的控制字 /
time_t iUpdate_Time; /
更新时间 /
time_t iOvertime; /
报文等待超时时间*/
uint8 nChannelType; /* 报文信道来源类型 /
uint8 aBuffer[MAX_FRAME_LEN]; /
buffer, that hold the received bytes /
uint16 nFrameLen; /
actual length of the buffer */
uint8 pBufferPtr; / pointer to buffer /
uint32 nDataLen; /
length of information field in bytes */
uint16 nLenth;
uint16 nLenthCfm;
uint8 nCS;
} T_CHKFRAME,*P_CHKFRAME;

解析接口:

int chkframe_dlt645_07(T_CHKFRAME  *pChkFrame, uint8 *pScanBuf,
    uint32 nScanBufLen, uint8 *pChnParam, uint8 nType, VOIDFUNCPTR pRecvFun)
{
    uint16 nLenth = 0;
    uint8  nCS = 0;
    uint8 *pSrcBuf = NULL;
	uint8 nSrcBuf[512];
	uint8 nBufLen, nTtlLen;
	uint16 nPos;

    /* 如果已经完成的桢则重新开始 */
    if (pChkFrame->eFrameState == FRAME_STATES_DLT645_COMPLETE) pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;

    /* 如果信道变化则重新开始 */
    if (nType != pChkFrame->nChannelType) {
        pChkFrame->nChannelType = nType;
        pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
    }

    /* 如果超时则重新开始 */
    if (abs(time(NULL) - pChkFrame->iUpdate_Time) > pChkFrame->iOvertime) {
        pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
        pChkFrame->iUpdate_Time = time(NULL);
        pChkFrame->nDataLen = 0;
        pChkFrame->pBufferPtr = pChkFrame->aBuffer;
    }

    if (pChkFrame->nFrameLen > 255)	{
    	pChkFrame->nFrameLen = 0;
    }

    memcpy(&(nSrcBuf[0]), &(pChkFrame->aBuffer[0]), pChkFrame->nFrameLen);
    memcpy(&(nSrcBuf[pChkFrame->nFrameLen]), pScanBuf, nScanBufLen);
    nBufLen = pChkFrame->nFrameLen + nScanBufLen;
    nTtlLen = nBufLen;
    pSrcBuf = nSrcBuf;

    nPos = 0;
    while (nBufLen > 0) {
        switch(pChkFrame->eFrameState){
            case FRAME_STATES_DLT645_NULL:
                if (*pSrcBuf == 0x68){
                    pChkFrame->nFrameLen= 0;
                    pChkFrame->pBufferPtr = pChkFrame->aBuffer;
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_ADDR;
                }else{
                    nPos++;
                }
                pChkFrame->iUpdate_Time = time(NULL);
                break;

            case FRAME_STATES_DLT645_ADDR:
                if (pChkFrame->nFrameLen == 6) {
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_68_2;
                }
                break;

            case FRAME_STATES_DLT645_68_2:
                if (0x68 != (*pSrcBuf)) {
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
					pSrcBuf = &nSrcBuf[nPos];
					nBufLen = nTtlLen - nPos;
					nPos++;
                } else {
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_C;
                }
                break;

            case FRAME_STATES_DLT645_C:
                if (((*pSrcBuf) & 0x80) != 0x00) {
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
					pSrcBuf = &nSrcBuf[nPos];
					nBufLen = nTtlLen - nPos;
					nPos++;
                } else {
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_L;
                }
                break;

            case FRAME_STATES_DLT645_L:
                nLenth = (*pSrcBuf);
                if(nLenth == 0){
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_CS;
                }else{
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_DATA;
                }
                pChkFrame->nDataLen = 0;
                break;

            case FRAME_STATES_DLT645_DATA:
                pChkFrame->nDataLen++;
                if(pChkFrame->nDataLen == nLenth){
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_CS;
                }
                break;

            case FRAME_STATES_DLT645_CS:
                nCS = getCS(pChkFrame->aBuffer, pChkFrame->nFrameLen);
                if(*pSrcBuf == nCS){
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_END;
                }else{
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
					pSrcBuf = &nSrcBuf[nPos];
					nBufLen = nTtlLen - nPos;
					nPos++;
                }
                break;

            case FRAME_STATES_DLT645_END:
                if (*pSrcBuf == 0x16){
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_COMPLETE;
                }else{
                    pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
					pSrcBuf = &nSrcBuf[nPos];
					nBufLen = nTtlLen - nPos;
					nPos++;
                }
                break;
            default:
                break;
        }

        if (pChkFrame->eFrameState != FRAME_STATES_DLT645_NULL){
            *(pChkFrame->pBufferPtr) = *pSrcBuf;
            pChkFrame->pBufferPtr++;
            pChkFrame->nFrameLen++;
        }

        /* 完整报文,调用处理函数接口 */
        if(pChkFrame->eFrameState == FRAME_STATES_DLT645_COMPLETE){
            if (NULL != pRecvFun) pRecvFun(&pChkFrame->nChannelType);
			nScanBufLen = nTtlLen - nPos - pChkFrame->nFrameLen;
            pChkFrame->eFrameState = FRAME_STATES_DLT645_NULL;
            pChkFrame->iUpdate_Time = time(NULL);
            pChkFrame->nFrameLen = pChkFrame->nDataLen = 0;
            pChkFrame->pBufferPtr = pChkFrame->aBuffer;
        }

        nBufLen--;
        nScanBufLen--;
        pSrcBuf++;
    }

    return nScanBufLen;
}

你可能感兴趣的:(嵌入式软件)