Enhanced the statistics and usage reporting of mstpcap utility. Now counts each frame type emitted by a node, calculates Npoll, checks for tokens sent to self, and still all the existing timing statistics.
This commit is contained in:
@@ -65,14 +65,31 @@ static uint8_t TxBuffer[MAX_MPDU];
|
|||||||
struct mstp_statistics {
|
struct mstp_statistics {
|
||||||
/* counts how many times the node passes the token */
|
/* counts how many times the node passes the token */
|
||||||
uint32_t token_count;
|
uint32_t token_count;
|
||||||
|
/* counts how many times the node receives the token */
|
||||||
|
uint32_t token_received_count;
|
||||||
/* counts how many times the node polls for another master */
|
/* counts how many times the node polls for another master */
|
||||||
uint32_t pfm_count;
|
uint32_t pfm_count;
|
||||||
|
/* counts how many times the node replies to polls from another master */
|
||||||
|
uint32_t rpfm_count;
|
||||||
|
/* counts how many times the node sends reply postponed */
|
||||||
|
uint32_t reply_postponed_count;
|
||||||
|
/* counts how many times the node sends a test request */
|
||||||
|
uint32_t test_request_count;
|
||||||
|
/* counts how many times the node sends a test response */
|
||||||
|
uint32_t test_response_count;
|
||||||
|
/* counts how many times the node sends a DER frame */
|
||||||
|
uint32_t der_count;
|
||||||
|
/* counts how many times the node sends a DNER frame */
|
||||||
|
uint32_t dner_count;
|
||||||
|
/* -- inferred data -- */
|
||||||
/* counts how many times the node gets a second token */
|
/* counts how many times the node gets a second token */
|
||||||
uint32_t token_retries;
|
uint32_t token_retries;
|
||||||
/* delay after poll for master */
|
/* delay after poll for master */
|
||||||
uint32_t tusage_timeout;
|
uint32_t tusage_timeout;
|
||||||
/* highest number MAC during poll for master */
|
/* highest number MAC during poll for master */
|
||||||
uint8_t max_master;
|
uint8_t max_master;
|
||||||
|
/* highest number of frames sent during a token */
|
||||||
|
uint8_t max_info_frames;
|
||||||
/* how long it takes a node to pass the token */
|
/* how long it takes a node to pass the token */
|
||||||
uint32_t token_reply;
|
uint32_t token_reply;
|
||||||
/* how long it takes a node to reply to PFM */
|
/* how long it takes a node to reply to PFM */
|
||||||
@@ -81,6 +98,13 @@ struct mstp_statistics {
|
|||||||
uint32_t der_reply;
|
uint32_t der_reply;
|
||||||
/* how long it takes a node to send a reply post poned */
|
/* how long it takes a node to send a reply post poned */
|
||||||
uint32_t reply_postponed;
|
uint32_t reply_postponed;
|
||||||
|
/* number of tokens received before a Poll For Master cycle is executed */
|
||||||
|
uint32_t npoll;
|
||||||
|
/* number of total tokens at the last PFM */
|
||||||
|
uint32_t last_pfm_tokens;
|
||||||
|
/* Addendum 2008v - sending tokens to myself */
|
||||||
|
/* counts how many times the node passes the token */
|
||||||
|
uint32_t self_token_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct mstp_statistics MSTP_Statistics[256];
|
static struct mstp_statistics MSTP_Statistics[256];
|
||||||
@@ -109,6 +133,7 @@ static void packet_statistics(
|
|||||||
static uint8_t old_dst = 255;
|
static uint8_t old_dst = 255;
|
||||||
uint8_t frame, src, dst;
|
uint8_t frame, src, dst;
|
||||||
uint32_t delta;
|
uint32_t delta;
|
||||||
|
uint32_t npoll;
|
||||||
|
|
||||||
dst = mstp_port->DestinationAddress;
|
dst = mstp_port->DestinationAddress;
|
||||||
src = mstp_port->SourceAddress;
|
src = mstp_port->SourceAddress;
|
||||||
@@ -116,6 +141,10 @@ static void packet_statistics(
|
|||||||
switch (frame) {
|
switch (frame) {
|
||||||
case FRAME_TYPE_TOKEN:
|
case FRAME_TYPE_TOKEN:
|
||||||
MSTP_Statistics[src].token_count++;
|
MSTP_Statistics[src].token_count++;
|
||||||
|
MSTP_Statistics[dst].token_received_count++;
|
||||||
|
if (src == dst) {
|
||||||
|
MSTP_Statistics[src].self_token_count++;
|
||||||
|
}
|
||||||
if (old_frame == FRAME_TYPE_TOKEN) {
|
if (old_frame == FRAME_TYPE_TOKEN) {
|
||||||
if ((old_dst == dst) && (old_src == src)) {
|
if ((old_dst == dst) && (old_src == src)) {
|
||||||
/* repeated token */
|
/* repeated token */
|
||||||
@@ -142,12 +171,21 @@ static void packet_statistics(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_POLL_FOR_MASTER:
|
case FRAME_TYPE_POLL_FOR_MASTER:
|
||||||
|
if (MSTP_Statistics[src].last_pfm_tokens) {
|
||||||
|
npoll = MSTP_Statistics[src].token_received_count -
|
||||||
|
MSTP_Statistics[src].last_pfm_tokens;
|
||||||
|
if (npoll > MSTP_Statistics[src].npoll) {
|
||||||
|
MSTP_Statistics[src].npoll = npoll;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MSTP_Statistics[src].last_pfm_tokens =
|
||||||
|
MSTP_Statistics[src].token_received_count;
|
||||||
MSTP_Statistics[src].pfm_count++;
|
MSTP_Statistics[src].pfm_count++;
|
||||||
if (dst > MSTP_Statistics[src].max_master) {
|
if (dst > MSTP_Statistics[src].max_master) {
|
||||||
MSTP_Statistics[src].max_master = dst;
|
MSTP_Statistics[src].max_master = dst;
|
||||||
}
|
}
|
||||||
if ((old_frame == FRAME_TYPE_POLL_FOR_MASTER) && (old_src == src)) {
|
if ((old_frame == FRAME_TYPE_POLL_FOR_MASTER) && (old_src == src)) {
|
||||||
/* Tusage_timeout */
|
/* Tusage_timeout - sole master */
|
||||||
delta = timeval_diff_ms(&old_tv, tv);
|
delta = timeval_diff_ms(&old_tv, tv);
|
||||||
if (delta > MSTP_Statistics[src].tusage_timeout) {
|
if (delta > MSTP_Statistics[src].tusage_timeout) {
|
||||||
MSTP_Statistics[src].tusage_timeout = delta;
|
MSTP_Statistics[src].tusage_timeout = delta;
|
||||||
@@ -155,6 +193,7 @@ static void packet_statistics(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER:
|
case FRAME_TYPE_REPLY_TO_POLL_FOR_MASTER:
|
||||||
|
MSTP_Statistics[src].rpfm_count++;
|
||||||
if (old_frame == FRAME_TYPE_POLL_FOR_MASTER) {
|
if (old_frame == FRAME_TYPE_POLL_FOR_MASTER) {
|
||||||
delta = timeval_diff_ms(&old_tv, tv);
|
delta = timeval_diff_ms(&old_tv, tv);
|
||||||
if (delta > MSTP_Statistics[src].pfm_reply) {
|
if (delta > MSTP_Statistics[src].pfm_reply) {
|
||||||
@@ -163,12 +202,16 @@ static void packet_statistics(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_TEST_REQUEST:
|
case FRAME_TYPE_TEST_REQUEST:
|
||||||
|
MSTP_Statistics[src].test_request_count++;
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_TEST_RESPONSE:
|
case FRAME_TYPE_TEST_RESPONSE:
|
||||||
|
MSTP_Statistics[src].test_response_count++;
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
case FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY:
|
||||||
|
MSTP_Statistics[src].der_count++;
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
case FRAME_TYPE_BACNET_DATA_NOT_EXPECTING_REPLY:
|
||||||
|
MSTP_Statistics[src].dner_count++;
|
||||||
if ((old_frame == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) &&
|
if ((old_frame == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) &&
|
||||||
(old_dst == src)) {
|
(old_dst == src)) {
|
||||||
/* DER response time */
|
/* DER response time */
|
||||||
@@ -179,6 +222,7 @@ static void packet_statistics(
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case FRAME_TYPE_REPLY_POSTPONED:
|
case FRAME_TYPE_REPLY_POSTPONED:
|
||||||
|
MSTP_Statistics[src].reply_postponed_count++;
|
||||||
if ((old_frame == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) &&
|
if ((old_frame == FRAME_TYPE_BACNET_DATA_EXPECTING_REPLY) &&
|
||||||
(old_dst == src)) {
|
(old_dst == src)) {
|
||||||
/* Postponed response time */
|
/* Postponed response time */
|
||||||
@@ -207,24 +251,52 @@ static void packet_statistics_save(
|
|||||||
unsigned node_count = 0;
|
unsigned node_count = 0;
|
||||||
|
|
||||||
fprintf(stdout, "\r\n");
|
fprintf(stdout, "\r\n");
|
||||||
/* separate with tabs (8) keep words under 8 characters */
|
fprintf(stdout, "==== MS/TP Frame Counts ====\r\n");
|
||||||
fprintf(stdout,
|
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s",
|
||||||
"MAC\tMaxMstr\tTokens\tRetries\tPFM"
|
"MAC",
|
||||||
"\tTreply\tTusage\tTrpfm\tTder\tTpostpd");
|
"Tokens","PFM","RPFM","DER",
|
||||||
|
"Postpd","DNER","TestReq","TestRsp");
|
||||||
fprintf(stdout, "\r\n");
|
fprintf(stdout, "\r\n");
|
||||||
for (i = 0; i < 256; i++) {
|
for (i = 0; i < 256; i++) {
|
||||||
/* check for masters or slaves */
|
/* check for masters or slaves */
|
||||||
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply)
|
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply)
|
||||||
|| (MSTP_Statistics[i].pfm_count)) {
|
|| (MSTP_Statistics[i].pfm_count)) {
|
||||||
node_count++;
|
node_count++;
|
||||||
fprintf(stdout, "%u\t%u", i,
|
fprintf(stdout, "%-8u", i);
|
||||||
(unsigned) MSTP_Statistics[i].max_master);
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu",
|
||||||
fprintf(stdout, "\t%lu\t%lu\t%lu\t%lu",
|
|
||||||
(long unsigned int) MSTP_Statistics[i].token_count,
|
(long unsigned int) MSTP_Statistics[i].token_count,
|
||||||
(long unsigned int) MSTP_Statistics[i].token_retries,
|
|
||||||
(long unsigned int) MSTP_Statistics[i].pfm_count,
|
(long unsigned int) MSTP_Statistics[i].pfm_count,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].rpfm_count,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].der_count);
|
||||||
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu",
|
||||||
|
(long unsigned int) MSTP_Statistics[i].reply_postponed_count,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].dner_count,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].test_request_count,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].test_response_count);
|
||||||
|
fprintf(stdout, "\r\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fprintf(stdout, "Node Count: %u\r\n", node_count);
|
||||||
|
node_count = 0;
|
||||||
|
fprintf(stdout, "\r\n");
|
||||||
|
fprintf(stdout, "==== MS/TP Usage and Timing Maximums ====\r\n");
|
||||||
|
fprintf(stdout, "%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-8s%-7s",
|
||||||
|
"MAC","MaxMstr","Retries","Npoll","Self",
|
||||||
|
"Treply","Tusage","Trpfm","Tder","Tpostpd");
|
||||||
|
fprintf(stdout, "\r\n");
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
/* check for masters or slaves */
|
||||||
|
if ((MSTP_Statistics[i].token_count) || (MSTP_Statistics[i].der_reply)
|
||||||
|
|| (MSTP_Statistics[i].pfm_count)) {
|
||||||
|
node_count++;
|
||||||
|
fprintf(stdout, "%-8u", i);
|
||||||
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-8lu%-8lu",
|
||||||
|
(long unsigned int) MSTP_Statistics[i].max_master,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].token_retries,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].npoll,
|
||||||
|
(long unsigned int) MSTP_Statistics[i].self_token_count,
|
||||||
(long unsigned int) MSTP_Statistics[i].token_reply);
|
(long unsigned int) MSTP_Statistics[i].token_reply);
|
||||||
fprintf(stdout, "\t%lu\t%lu\t%lu\t%lu",
|
fprintf(stdout, "%-8lu%-8lu%-8lu%-7lu",
|
||||||
(long unsigned int) MSTP_Statistics[i].tusage_timeout,
|
(long unsigned int) MSTP_Statistics[i].tusage_timeout,
|
||||||
(long unsigned int) MSTP_Statistics[i].pfm_reply,
|
(long unsigned int) MSTP_Statistics[i].pfm_reply,
|
||||||
(long unsigned int) MSTP_Statistics[i].der_reply,
|
(long unsigned int) MSTP_Statistics[i].der_reply,
|
||||||
@@ -240,19 +312,7 @@ static void packet_statistics_save(
|
|||||||
static void packet_statistics_clear(
|
static void packet_statistics_clear(
|
||||||
void)
|
void)
|
||||||
{
|
{
|
||||||
unsigned i; /* loop counter */
|
memset(&MSTP_Statistics[0], 0, sizeof(MSTP_Statistics));
|
||||||
|
|
||||||
for (i = 0; i < 256; i++) {
|
|
||||||
MSTP_Statistics[i].token_count = 0;
|
|
||||||
MSTP_Statistics[i].pfm_count = 0;
|
|
||||||
MSTP_Statistics[i].token_retries = 0;
|
|
||||||
MSTP_Statistics[i].tusage_timeout = 0;
|
|
||||||
MSTP_Statistics[i].max_master = 0;
|
|
||||||
MSTP_Statistics[i].token_reply = 0;
|
|
||||||
MSTP_Statistics[i].pfm_reply = 0;
|
|
||||||
MSTP_Statistics[i].der_reply = 0;
|
|
||||||
MSTP_Statistics[i].reply_postponed = 0;
|
|
||||||
}
|
|
||||||
Invalid_Frame_Count = 0;
|
Invalid_Frame_Count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -781,6 +841,7 @@ int main(
|
|||||||
}
|
}
|
||||||
RS485_Set_Baud_Rate(my_baud);
|
RS485_Set_Baud_Rate(my_baud);
|
||||||
RS485_Initialize();
|
RS485_Initialize();
|
||||||
|
timer_init();
|
||||||
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n",
|
fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n",
|
||||||
RS485_Interface(), (long) RS485_Get_Baud_Rate());
|
RS485_Interface(), (long) RS485_Get_Baud_Rate());
|
||||||
atexit(cleanup);
|
atexit(cleanup);
|
||||||
|
|||||||
Reference in New Issue
Block a user