Bacnet MSTP帧头CRC校验失败问题排查求助
问题:BACnet MSTP客户端周期性读取属性数小时后间歇性失败
问题场景
将BACnet源码编译为动态库,编写客户端程序调用该库周期性发送请求读取服务器属性。程序初始运行正常,但数小时后开始出现间歇性属性读取失败。
调试捕获日志
开启Makefile调试选项后,捕获到如下错误日志:
MSTP: Rx Header: BadCRC [01] MSTP: Rx Data: SilenceTimer 96ms > 95ms MSTP: Rx Header: BadCRC [01] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [27] MSTP: Rx Header: BadCRC [3B] MSTP: Rx Header: BadCRC [3E] MSTP: Rx Header: BadCRC [4B] MSTP: Rx Header: BadCRC [4D] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [5E] MSTP: Rx Header: SilenceTimer 96 > 95 MSTP: Rx Header: BadCRC [6E] MSTP: Rx Header: BadCRC [74] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [03] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [00] MSTP: Rx Header: BadCRC [45] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [FF] MSTP: Rx Header: BadCRC [00] MSTP: Rx Header: BadCRC [55] MSTP: Rx Header: BadCRC [FF]
源码定位与分析
报错为帧头CRC校验错误,触发后该帧会被标记为非法,程序切换到MSTP_RECEIVE_STATE_IDLE状态寻找下一帧起始码。理论上单帧校验错误不应持续影响后续帧,但实际结果与预期不符。
出错代码位于bacnet-stack-1.0.0/ports/linux/dlmstp.c的MSTP_Receive_Frame_FSM函数中,相关片段:
case MSTP_RECEIVE_STATE_HEADER: /* Timeout */ if (mstp_port->SilenceTimer((void *)mstp_port) > Tframe_abort) { /* indicate that an error has occurred during the reception of a * frame */ mstp_port->ReceivedInvalidFrame = true; /* wait for the start of a frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; debug_printf("MSTP: Rx Header: SilenceTimer %u > %d\n", (unsigned)mstp_port->SilenceTimer((void *)mstp_port), Tframe_abort); } /* don't wait for next state - do it here */ if (mstp_port->HeaderCRC != 0x55) { /* BadCRC */ /* indicate that an error has occurred during the reception of a frame */ mstp_port->ReceivedInvalidFrame = true; debug_printf("MSTP: Rx Header: BadCRC [%02X], Tframe_abort = %d\n", mstp_port->DataRegister, Tframe_abort); /* wait for the start of the next frame. */ mstp_port->receive_state = MSTP_RECEIVE_STATE_IDLE; }
抓包验证
故障期间通过Wireshark抓包,发现报文正常且CRC校验无错误,推测问题出在程序接收报文后的自身处理环节。
诉求
寻求该问题的根因分析及解决思路。
内容的提问来源于stack exchange,提问作者PYHAO
相关产品推荐
相关产品推荐

