From 0da61e52bb8e45eb48b1ae8b5352470c18cc2694 Mon Sep 17 00:00:00 2001 From: Steve Karg Date: Thu, 11 Sep 2025 10:53:16 -0500 Subject: [PATCH] Added MS/TP statistics counters for BadCRC and Poll-For-Master. (#1081) --- ports/bsd/dlmstp.c | 10 +++++++++- ports/linux/dlmstp.c | 3 +++ ports/win32/dlmstp.c | 10 +++++++++- src/bacnet/datalink/dlenv.c | 7 +++++-- src/bacnet/datalink/dlmstp.c | 8 ++++++++ src/bacnet/datalink/dlmstp.h | 2 ++ test/bacnet/datalink/dlmstp/src/main.c | 5 +++++ 7 files changed, 41 insertions(+), 4 deletions(-) diff --git a/ports/bsd/dlmstp.c b/ports/bsd/dlmstp.c index e1c7677e..a8ed2f58 100644 --- a/ports/bsd/dlmstp.c +++ b/ports/bsd/dlmstp.c @@ -513,6 +513,9 @@ static void *dlmstp_thread(void *pArg) } if (MSTP_Port.ReceivedValidFrame) { DLMSTP_Statistics.receive_valid_frame_counter++; + if (MSTP_Port.FrameType == FRAME_TYPE_POLL_FOR_MASTER) { + DLMSTP_Statistics.poll_for_master_counter++; + } if (Valid_Frame_Rx_Callback) { Valid_Frame_Rx_Callback( MSTP_Port.SourceAddress, MSTP_Port.DestinationAddress, @@ -530,8 +533,13 @@ static void *dlmstp_thread(void *pArg) } run_master = true; } else if (MSTP_Port.ReceivedInvalidFrame) { + DLMSTP_Statistics.receive_invalid_frame_counter++; + if (MSTP_Port.HeaderCRC != 0x55) { + DLMSTP_Statistics.bad_crc_counter++; + } else if (MSTP_Port.DataCRC != 0xF0B8) { + DLMSTP_Statistics.bad_crc_counter++; + } if (Invalid_Frame_Rx_Callback) { - DLMSTP_Statistics.receive_invalid_frame_counter++; Invalid_Frame_Rx_Callback( MSTP_Port.SourceAddress, MSTP_Port.DestinationAddress, MSTP_Port.FrameType, MSTP_Port.InputBuffer, diff --git a/ports/linux/dlmstp.c b/ports/linux/dlmstp.c index 1b6eeab4..06b9087c 100644 --- a/ports/linux/dlmstp.c +++ b/ports/linux/dlmstp.c @@ -535,6 +535,9 @@ static void *dlmstp_thread(void *pArg) } if (MSTP_Port.ReceivedValidFrame) { DLMSTP_Statistics.receive_valid_frame_counter++; + if (MSTP_Port.FrameType == FRAME_TYPE_POLL_FOR_MASTER) { + DLMSTP_Statistics.poll_for_master_counter++; + } if (Valid_Frame_Rx_Callback) { Valid_Frame_Rx_Callback( MSTP_Port.SourceAddress, MSTP_Port.DestinationAddress, diff --git a/ports/win32/dlmstp.c b/ports/win32/dlmstp.c index 6cafe2ef..6151b073 100644 --- a/ports/win32/dlmstp.c +++ b/ports/win32/dlmstp.c @@ -444,6 +444,9 @@ static void dlmstp_thread(void *pArg) } if (MSTP_Port.ReceivedValidFrame) { DLMSTP_Statistics.receive_valid_frame_counter++; + if (MSTP_Port.FrameType == FRAME_TYPE_POLL_FOR_MASTER) { + DLMSTP_Statistics.poll_for_master_counter++; + } if (Valid_Frame_Rx_Callback) { Valid_Frame_Rx_Callback( MSTP_Port.SourceAddress, MSTP_Port.DestinationAddress, @@ -461,8 +464,13 @@ static void dlmstp_thread(void *pArg) } run_master = true; } else if (MSTP_Port.ReceivedInvalidFrame) { + DLMSTP_Statistics.receive_invalid_frame_counter++; + if (MSTP_Port.HeaderCRC != 0x55) { + DLMSTP_Statistics.bad_crc_counter++; + } else if (MSTP_Port.DataCRC != 0xF0B8) { + DLMSTP_Statistics.bad_crc_counter++; + } if (Invalid_Frame_Rx_Callback) { - DLMSTP_Statistics.receive_invalid_frame_counter++; Invalid_Frame_Rx_Callback( MSTP_Port.SourceAddress, MSTP_Port.DestinationAddress, MSTP_Port.FrameType, MSTP_Port.InputBuffer, diff --git a/src/bacnet/datalink/dlenv.c b/src/bacnet/datalink/dlenv.c index 7296eee8..47ef8cc6 100644 --- a/src/bacnet/datalink/dlenv.c +++ b/src/bacnet/datalink/dlenv.c @@ -833,14 +833,17 @@ void dlenv_maintenance_timer(uint16_t elapsed_seconds) dlmstp_fill_statistics(&statistics); fprintf( stderr, - "MSTP: Frames Rx:%u/%u/%u Tx:%u PDU Rx:%u Tx:%u Lost:%u\n", + "MSTP: Frames Rx:%u/%u/%u Tx:%u PDU Rx:%u Tx:%u " + "Lost:%u BadCRC:%u PFM:%u\n", statistics.receive_valid_frame_counter, statistics.receive_valid_frame_not_for_us_counter, statistics.receive_invalid_frame_counter, statistics.transmit_frame_counter, statistics.receive_pdu_counter, statistics.transmit_pdu_counter, - statistics.lost_token_counter); + statistics.lost_token_counter, statistics.bad_crc_counter, + statistics.poll_for_master_counter); + fflush(stderr); #endif } diff --git a/src/bacnet/datalink/dlmstp.c b/src/bacnet/datalink/dlmstp.c index 929f8f3d..0b52544d 100644 --- a/src/bacnet/datalink/dlmstp.c +++ b/src/bacnet/datalink/dlmstp.c @@ -400,6 +400,9 @@ uint16_t dlmstp_receive( } if (MSTP_Port->ReceivedValidFrame) { user->Statistics.receive_valid_frame_counter++; + if (MSTP_Port->FrameType == FRAME_TYPE_POLL_FOR_MASTER) { + user->Statistics.poll_for_master_counter++; + } if (user->Valid_Frame_Rx_Callback) { user->Valid_Frame_Rx_Callback( MSTP_Port->SourceAddress, MSTP_Port->DestinationAddress, @@ -418,6 +421,11 @@ uint16_t dlmstp_receive( } if (MSTP_Port->ReceivedInvalidFrame) { user->Statistics.receive_invalid_frame_counter++; + if (MSTP_Port->HeaderCRC != 0x55) { + user->Statistics.bad_crc_counter++; + } else if (MSTP_Port->DataCRC != 0xF0B8) { + user->Statistics.bad_crc_counter++; + } if (user->Invalid_Frame_Rx_Callback) { user->Invalid_Frame_Rx_Callback( MSTP_Port->SourceAddress, MSTP_Port->DestinationAddress, diff --git a/src/bacnet/datalink/dlmstp.h b/src/bacnet/datalink/dlmstp.h index 8a2bab4c..c591f8f9 100644 --- a/src/bacnet/datalink/dlmstp.h +++ b/src/bacnet/datalink/dlmstp.h @@ -42,6 +42,8 @@ typedef struct dlmstp_statistics { uint32_t transmit_pdu_counter; uint32_t receive_pdu_counter; uint32_t lost_token_counter; + uint32_t bad_crc_counter; + uint32_t poll_for_master_counter; } DLMSTP_STATISTICS; #ifndef DLMSTP_MAX_INFO_FRAMES diff --git a/test/bacnet/datalink/dlmstp/src/main.c b/test/bacnet/datalink/dlmstp/src/main.c index f60299bd..090ef894 100644 --- a/test/bacnet/datalink/dlmstp/src/main.c +++ b/test/bacnet/datalink/dlmstp/src/main.c @@ -128,6 +128,11 @@ static void test_MSTP_Datalink(void) zassert_equal( test_stats.receive_pdu_counter, MSTP_User.Statistics.receive_pdu_counter, NULL); + zassert_equal( + test_stats.bad_crc_counter, MSTP_User.Statistics.bad_crc_counter, NULL); + zassert_equal( + test_stats.poll_for_master_counter, + MSTP_User.Statistics.poll_for_master_counter, NULL); dlmstp_reset_statistics(); dlmstp_set_frame_rx_complete_callback(NULL); dlmstp_set_invalid_frame_rx_complete_callback(NULL);