/* simple test to packetize the data and print it */ int main( int argc, char *argv[]) { volatile struct mstp_port_struct_t *mstp_port; long my_baud = 38400; uint32_t packet_count = 0; MSTP_Port.InputBuffer = &RxBuffer[0]; MSTP_Port.InputBufferSize = sizeof(RxBuffer); MSTP_Port.OutputBuffer = &TxBuffer[0]; MSTP_Port.OutputBufferSize = sizeof(TxBuffer); MSTP_Port.This_Station = 127; MSTP_Port.Nmax_info_frames = 1; MSTP_Port.Nmax_master = 127; MSTP_Port.SilenceTimer = Timer_Silence; MSTP_Port.SilenceTimerReset = Timer_Silence_Reset; /* mimic our pointer in the state machine */ mstp_port = &MSTP_Port; MSTP_Init(mstp_port); packet_statistics_clear(); /* initialize our interface */ if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { printf("mstpcap --scan <filename>\r\n" "perform statistic analysis on MS/TP capture file.\r\n"); printf("\r\n"); printf("mstpcap [interface] [baud] [named pipe]\r\n" "Captures MS/TP packets from a serial interface\r\n" "and save them to a file. Saves packets in a\r\n" "filename mstp_20090123091200.cap that has data and time.\r\n" "After receiving 65535 packets, a new file is created.\r\n" "\r\n" "Command line options:\r\n" "[interface] - serial interface.\r\n" " defaults to COM4 on Windows, and /dev/ttyUSB0 on linux.\r\n" "[baud] - baud rate. 9600, 19200, 38400, 57600, 115200\r\n" " defaults to 38400.\r\n" "[named pipe] - use \\\\.\\pipe\\wireshark as the name\r\n" " and set that name as the interface name in Wireshark\r\n"); return 0; } if ((argc > 1) && (strcmp(argv[1], "--version") == 0)) { printf("mstpcap %s\r\n", BACNET_VERSION_TEXT); printf("Copyright (C) 2011 by Steve Karg\r\n" "This is free software; see the source for copying conditions.\r\n" "There is NO warranty; not even for MERCHANTABILITY or\r\n" "FITNESS FOR A PARTICULAR PURPOSE.\r\n"); return 0; } if ((argc > 1) && (strcmp(argv[1], "--scan") == 0)) { if (argc > 2) { printf("Scanning %s\r\n", argv[2]); /* perform statistics on the file */ if (test_global_header(argv[2])) { while (read_received_packet(mstp_port)) { packet_count++; fprintf(stderr, "\r%u packets", (unsigned) packet_count); } if (packet_count) { packet_statistics_print(); } } else { fprintf(stderr, "File header does not match.\n"); } return 1; } } if (argc > 1) { RS485_Set_Interface(argv[1]); } else { #if defined(_WIN32) print_com_ports(); return 0; #endif } if (argc > 2) { my_baud = strtol(argv[2], NULL, 0); RS485_Set_Baud_Rate(my_baud); } atexit(cleanup); RS485_Initialize(); timer_init(); fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n", RS485_Interface(), (long) RS485_Get_Baud_Rate()); #if defined(_WIN32) SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT); SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlCHandler, TRUE); #else signal_init(); #endif if (argc > 3) { named_pipe_create(argv[3]); } filename_create_new(); /* run forever */ for (;;) { RS485_Check_UART_Data(mstp_port); MSTP_Receive_Frame_FSM(mstp_port); /* process the data portion of the frame */ if (mstp_port->ReceivedValidFrame) { write_received_packet(mstp_port); mstp_port->ReceivedValidFrame = false; packet_count++; } else if (mstp_port->ReceivedValidFrameNotForUs) { write_received_packet(mstp_port); mstp_port->ReceivedValidFrameNotForUs = false; packet_count++; } else if (mstp_port->ReceivedInvalidFrame) { write_received_packet(mstp_port); Invalid_Frame_Count++; mstp_port->ReceivedInvalidFrame = false; packet_count++; } if (!(packet_count % 100)) { fprintf(stdout, "\r%hu packets, %hu invalid frames", packet_count, Invalid_Frame_Count); } if (packet_count >= 65535) { packet_statistics_print(); packet_statistics_clear(); filename_create_new(); packet_count = 0; } } }
/* simple test to packetize the data and print it */ int main( int argc, char *argv[]) { volatile struct mstp_port_struct_t *mstp_port; long my_baud = 38400; uint32_t packet_count = 0; int argi = 0; char *filename = NULL; MSTP_Port.InputBuffer = &RxBuffer[0]; MSTP_Port.InputBufferSize = sizeof(RxBuffer); MSTP_Port.OutputBuffer = &TxBuffer[0]; MSTP_Port.OutputBufferSize = sizeof(TxBuffer); MSTP_Port.This_Station = 127; MSTP_Port.Nmax_info_frames = 1; MSTP_Port.Nmax_master = 127; MSTP_Port.SilenceTimer = Timer_Silence; MSTP_Port.SilenceTimerReset = Timer_Silence_Reset; /* mimic our pointer in the state machine */ mstp_port = &MSTP_Port; MSTP_Init(mstp_port); packet_statistics_clear(); /* decode any command line parameters */ filename = filename_remove_path(argv[0]); for (argi = 1; argi < argc; argi++) { if (strcmp(argv[argi], "--help") == 0) { print_usage(filename); print_help(filename); return 0; } if (strcmp(argv[argi], "--version") == 0) { printf("mstpcap %s\n", BACNET_VERSION_TEXT); printf("Copyright (C) 2011 by Steve Karg\n" "This is free software; see the source for copying conditions.\n" "There is NO warranty; not even for MERCHANTABILITY or\n" "FITNESS FOR A PARTICULAR PURPOSE.\n"); return 0; } if (strcmp(argv[argi], "--scan") == 0) { argi++; if (argi >= argc) { printf("An file name must be provided.\n"); return 1; } printf("Scanning %s\n", argv[argi]); /* perform statistics on the file */ if (test_global_header(argv[argi])) { while (read_received_packet(mstp_port)) { packet_count++; fprintf(stderr, "\r%u packets", (unsigned) packet_count); } if (packet_count) { packet_statistics_print(); } } else { fprintf(stderr, "File header does not match.\n"); } } if (strcmp(argv[argi], "--extcap-interfaces") == 0) { RS485_Print_Ports(); return 0; } if (strcmp(argv[argi], "--extcap-dlts") == 0) { argi++; if (argi >= argc) { printf("An interface must be provided.\n"); return 0; } printf("dlt {number=%u}{name=BACnet MS/TP}" "{display=BACnet MS/TP}\n", DLT_BACNET_MS_TP); Exit_Requested = true; } if (strcmp(argv[argi], "--extcap-config") == 0) { printf("arg {number=0}{call=--baud}{display=Baud Rate}" "{tooltip=Serial port baud rate in bits per second}" "{type=selector}\n"); printf("value {arg=0}{value=9600}{display=9600}{default=false}\n"); printf("value {arg=0}{value=19200}{display=19200}{default=false}\n"); printf("value {arg=0}{value=38400}{display=38400}{default=true}\n"); printf("value {arg=0}{value=57600}{display=57600}{default=false}\n"); printf("value {arg=0}{value=76800}{display=76800}{default=false}\n"); printf("value {arg=0}{value=115200}{display=115200}{default=false}\n"); return 0; } if (strcmp(argv[argi], "--capture") == 0) { /* do nothing - fall through and start running! */ } if (strcmp(argv[argi], "--extcap-interface") == 0) { argi++; if (argi >= argc) { printf("An interface must be provided or " "the selection must be displayed.\n"); return 0; } RS485_Set_Interface(argv[argi]); } if (strcmp(argv[argi], "--baud") == 0) { argi++; if (argi >= argc) { printf("A baud rate must be provided.\n"); return 0; } my_baud = strtol(argv[argi], NULL, 0); RS485_Set_Baud_Rate(my_baud); } if (strcmp(argv[argi], "--fifo") == 0) { argi++; if (argi >= argc) { printf("A named pipe must be provided.\n"); return 0; } named_pipe_create(argv[argi]); } } if (Exit_Requested) { return 0; } if (argc <= 1) { RS485_Print_Ports(); return 0; } atexit(cleanup); RS485_Initialize(); timer_init(); fprintf(stdout, "mstpcap: Using %s for capture at %ld bps.\n", RS485_Interface(), (long) RS485_Get_Baud_Rate()); #if defined(_WIN32) SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE), ENABLE_PROCESSED_INPUT); SetConsoleCtrlHandler((PHANDLER_ROUTINE) CtrlCHandler, TRUE); #else signal_init(); #endif filename_create_new(); /* run forever */ for (;;) { RS485_Check_UART_Data(mstp_port); MSTP_Receive_Frame_FSM(mstp_port); /* process the data portion of the frame */ if (mstp_port->ReceivedValidFrame) { write_received_packet(mstp_port); mstp_port->ReceivedValidFrame = false; packet_count++; } else if (mstp_port->ReceivedValidFrameNotForUs) { write_received_packet(mstp_port); mstp_port->ReceivedValidFrameNotForUs = false; packet_count++; } else if (mstp_port->ReceivedInvalidFrame) { write_received_packet(mstp_port); Invalid_Frame_Count++; mstp_port->ReceivedInvalidFrame = false; packet_count++; } if (!(packet_count % 100)) { fprintf(stdout, "\r%hu packets, %hu invalid frames", packet_count, Invalid_Frame_Count); } if (packet_count >= 65535) { packet_statistics_print(); packet_statistics_clear(); filename_create_new(); packet_count = 0; } if (Exit_Requested) { break; } } /* tell signal interrupts we are done */ Exit_Requested = false; return 0; }