diff --git a/bacnet-stack/demo/dcc/main.c b/bacnet-stack/demo/dcc/main.c index 464c2fb4..9d492caf 100644 --- a/bacnet-stack/demo/dcc/main.c +++ b/bacnet-stack/demo/dcc/main.c @@ -44,6 +44,7 @@ #include "datalink.h" #include "whois.h" #include "dcc.h" +#include "version.h" /* some demo stuff needed */ #include "filename.h" #include "handlers.h" @@ -73,7 +74,7 @@ static void MyErrorHandler( /* FIXME: verify src and invoke id */ (void) src; (void) invoke_id; - printf("BACnet Error: %s: %s\r\n", bactext_error_class_name(error_class), + printf("BACnet Error: %s: %s\n", bactext_error_class_name(error_class), bactext_error_code_name(error_code)); Error_Detected = true; } @@ -88,7 +89,7 @@ void MyAbortHandler( (void) src; (void) invoke_id; (void) server; - printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason)); + printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason)); Error_Detected = true; } @@ -100,7 +101,7 @@ void MyRejectHandler( /* FIXME: verify src and invoke id */ (void) src; (void) invoke_id; - printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason)); + printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason)); Error_Detected = true; } @@ -110,7 +111,7 @@ void MyDeviceCommunicationControlSimpleAckHandler( { (void) src; (void) invoke_id; - printf("DeviceCommunicationControl Acknowledged!\r\n"); + printf("DeviceCommunicationControl Acknowledged!\n"); } static void Init_Service_Handlers( @@ -143,6 +144,27 @@ static void Init_Service_Handlers( apdu_set_reject_handler(MyRejectHandler); } +static void print_usage(char *filename) +{ + printf("Usage: %s device-instance state [timeout [password]]\n", filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Send BACnet DeviceCommunicationControl service to device.\n" + "\n" "The device-instance can be 0 to %lu.\n" + "Possible state values:\n" " 0=enable\n" " 1=disable\n" + " 2=disable-initiation\n" + "The timeout can be 0 for infinite, or a value in minutes for disable.\n" + "The optional password is a character string of 1 to 20 characters.\n" + "\nExample:\n" + "If you want disable Device Communications in Device 123\n" + "for 60 minutes with password 'filister', use the following command:\n" + "%s 123 1 60 filister\n", + (unsigned long)(BACNET_MAX_INSTANCE - 1), filename); +} + int main( int argc, char *argv[]) @@ -159,33 +181,45 @@ int main( time_t timeout_seconds = 0; uint8_t invoke_id = 0; bool found = false; + int argi = 0; + char *filename = NULL; + 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("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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 (argc < 3) { - printf("Usage: %s device-instance state timeout [password]\r\n" - "Send BACnet DeviceCommunicationControl service to device.\r\n" - "\r\n" "The device-instance can be 0 to %d.\r\n" - "Possible state values:\r\n" " 0=enable\r\n" " 1=disable\r\n" - " 2=disable-initiation\r\n" - "The timeout can be 0 for infinite, or a value in minutes for disable.\r\n" - "The optional password is a character string of 1 to 20 characters.\r\n" - "Use BACNET_IFACE environment variable for the interface\r\n", - filename_remove_path(argv[0]), BACNET_MAX_INSTANCE - 1); + print_usage(filename); return 0; } /* decode the command line parameters */ Target_Device_Object_Instance = strtol(argv[1], NULL, 0); Communication_State = (uint16_t) strtol(argv[2], NULL, 0); - Communication_Timeout_Minutes = (uint16_t) strtol(argv[3], NULL, 0); + /* optional timeout, required if password is included */ + if (argc > 3) { + Communication_Timeout_Minutes = (uint16_t) strtol(argv[3], NULL, 0); + } /* optional password */ - if (argc > 4) + if (argc > 4) { Communication_Password = argv[4]; - + } if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { - fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "device-instance=%u - it must be less than %u\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } - /* setup my info */ Device_Set_Object_Instance_Number(BACNET_MAX_INSTANCE); address_init(); @@ -229,7 +263,7 @@ int main( } else if (tsm_invoke_id_free(invoke_id)) break; else if (tsm_invoke_id_failed(invoke_id)) { - fprintf(stderr, "\rError: TSM Timeout!\r\n"); + fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(invoke_id); /* try again or abort? */ break; @@ -238,7 +272,7 @@ int main( /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { - printf("\rError: APDU Timeout!\r\n"); + printf("\rError: APDU Timeout!\n"); break; } } diff --git a/bacnet-stack/demo/epics/main.c b/bacnet-stack/demo/epics/main.c index 8e948e65..88ce0d46 100644 --- a/bacnet-stack/demo/epics/main.c +++ b/bacnet-stack/demo/epics/main.c @@ -48,6 +48,7 @@ #include "whois.h" #include "rp.h" #include "proplist.h" +#include "version.h" /* some demo stuff needed */ #include "filename.h" #include "handlers.h" @@ -999,32 +1000,34 @@ EPICS_STATES ProcessRPMData( return nextState; } -void PrintUsage( - ) +static void print_usage(char *filename) { - printf - ("bacepics -- Generates Full EPICS file, including Object and Property List \n"); - printf("Usage: \n"); - printf - (" bacepics [-v] [-d] [-p sport] [-t target_mac [-n dnet]] device-instance \n"); - printf(" -v: show values instead of '?' \n"); - printf(" -d: show only device object properties\n"); - printf - (" -p: Use sport for \"my\" port, instead of 0xBAC0 (BACnet/IP only) \n"); - printf(" Allows you to communicate with a localhost target. \n"); - printf - (" -t: declare target's MAC instead of using Who-Is to bind to \n"); - printf - (" device-instance. Format is \"C0:A8:00:18:BA:C0\" (as usual) \n"); - printf(" Use \"7F:00:00:01:BA:C0\" for loopback testing \n"); - printf(" -n: specify target's DNET if not local BACnet network \n"); - printf(" or on routed Virtual Network \n"); + printf("Usage: %s [-v] [-d] [-p sport] [-t target_mac [-n dnet]]" + " device-instance\n", filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Generates Full EPICS file, including Object and Property List\n"); + printf("device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services.\n"); printf("\n"); - printf - ("You can redirect the output to a .tpi file for VTS use,\n"); - printf(" eg, bacepics -v 2701876 > epics-2701876.tpi \n"); + printf("-v: show values instead of '?' \n"); + printf("-d: show only device object properties\n"); + printf("-p: Use sport for \"my\" port. 0xBAC0 is default.\n"); + printf(" Allows you to communicate with a localhost target.\n"); + printf("-t: declare target's MAC instead of using Who-Is to bind to \n"); + printf(" device-instance. Format is \"C0:A8:00:18:BA:C0\"\n"); + printf(" Use \"7F:00:00:01:BA:C0\" for loopback testing \n"); + printf("-n: specify target's DNET if not local BACnet network \n"); + printf(" or on routed Virtual Network \n"); printf("\n"); - exit(0); + printf("You can redirect the output to a .tpi file for VTS use,\n"); + printf("e.g., bacepics 2701876 > epics-2701876.tpi \n"); } int CheckCommandLineArgs( @@ -1033,12 +1036,28 @@ int CheckCommandLineArgs( { int i; bool bFoundTarget = false; - /* FIXME: handle multi homed systems - use an argument passed to the datalink_init() */ + int argi = 0; + char *filename = NULL; - /* print help if not enough arguments */ + filename = filename_remove_path(argv[0]); + for (argi = 1; argi < argc; argi++) { + if (strcmp(argv[argi], "--help") == 0) { + print_usage(filename); + print_help(filename); + exit(0); + } + if (strcmp(argv[argi], "--version") == 0) { + printf("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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"); + exit(0); + } + } if (argc < 2) { - fprintf(stdout, "Error: Must provide a device-instance \n\n"); - PrintUsage(); /* Will exit */ + print_usage(filename); + exit(0); } for (i = 1; i < argc; i++) { char *anArg = argv[i]; @@ -1094,12 +1113,13 @@ int CheckCommandLineArgs( } else printf("ERROR: invalid Target MAC %s \n", argv[i]); - /* And fall through to PrintUsage */ + /* And fall through to print_usage */ } /* Either break or fall through, as above */ /* break; */ default: - PrintUsage(); + print_usage(filename); + exit(0); break; } } else { @@ -1109,20 +1129,21 @@ int CheckCommandLineArgs( fprintf(stdout, "Error: device-instance=%u - it must be less than %u\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); - PrintUsage(); + print_usage(filename); + exit(0); } bFoundTarget = true; } } if (!bFoundTarget) { fprintf(stdout, "Error: Must provide a device-instance \n\n"); - PrintUsage(); /* Will exit */ + print_usage(filename); + exit(0); } return 0; /* All OK if we reach here */ } - void PrintHeading( ) { diff --git a/bacnet-stack/demo/iamrouter/main.c b/bacnet-stack/demo/iamrouter/main.c index 1c682fac..73a90565 100644 --- a/bacnet-stack/demo/iamrouter/main.c +++ b/bacnet-stack/demo/iamrouter/main.c @@ -39,6 +39,7 @@ #include "apdu.h" #include "device.h" #include "datalink.h" +#include "version.h" /* some demo stuff needed */ #include "filename.h" #include "handlers.h" @@ -62,7 +63,7 @@ void MyAbortHandler( (void) src; (void) invoke_id; (void) server; - printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason)); + printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason)); Error_Detected = true; } @@ -74,7 +75,7 @@ void MyRejectHandler( /* FIXME: verify src and invoke id */ (void) src; (void) invoke_id; - printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason)); + printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason)); Error_Detected = true; } @@ -99,33 +100,57 @@ static void Init_Service_Handlers( apdu_set_reject_handler(MyRejectHandler); } +static void print_usage(char *filename) +{ + printf("Usage: %s DNET [DNET] [DNET] [...]\n", filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Send BACnet I-Am-Router-To-Network message for \n" + "one or more networks.\n" "\nDNET:\n" + "BACnet destination network number 0-65534\n" + "To send a I-Am-Router-To-Network message for DNET 86:\n" + "%s 86\n" + "To send a I-Am-Router-To-Network message for multiple DNETs\n" + "use the following command:\n" "%s 86 42 24 14\n", + filename, filename); +} + int main( int argc, char *argv[]) { unsigned arg_count = 0; + int argi = 0; + char *filename = NULL; - if (argc < 2) { - printf("Usage: %s DNET [DNET] [DNET] [...]\r\n", - filename_remove_path(argv[0])); - return 0; + filename = filename_remove_path(argv[0]); + for (argi = 1; argi < argc; argi++) { + if (strcmp(argv[argi], "--help") == 0) { + print_usage(filename); + print_help(filename); + exit(0); + } + if (strcmp(argv[argi], "--version") == 0) { + printf("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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"); + exit(0); + } } - if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { - printf("Send BACnet I-Am-Router-To-Network message for \r\n" - "one or more networks.\r\n" "\r\nDNET:\r\n" - "BACnet destination network number 0-65534\r\n" - "To send a I-Am-Router-To-Network message for DNET 86:\r\n" - "%s 86\r\n" - "To send a I-Am-Router-To-Network message for multiple DNETs\r\n" - "use the following command:\r\n" "%s 86 42 24 14\r\n", - filename_remove_path(argv[0]), filename_remove_path(argv[0])); + if (argc < 2) { + print_usage(filename); return 0; } /* decode the command line parameters */ if (argc > 1) { for (arg_count = 1; arg_count < argc; arg_count++) { if (arg_count > MAX_ROUTER_DNETS) { - fprintf(stderr, "Limited to %u DNETS. Sorry!\r\n", + fprintf(stderr, "Limited to %u DNETS. Sorry!\n", MAX_ROUTER_DNETS); break; } @@ -135,7 +160,7 @@ int main( Target_Router_Networks[arg_count] = -1; /* invalid DNET? */ if (Target_Router_Networks[arg_count - 1] >= 65535) { - fprintf(stderr, "DNET=%u - it must be less than %u\r\n", + fprintf(stderr, "DNET=%u - it must be less than %u\n", Target_Router_Networks[arg_count - 1], 65535); return 1; } diff --git a/bacnet-stack/demo/initrouter/main.c b/bacnet-stack/demo/initrouter/main.c index bb731a76..208f3fcc 100644 --- a/bacnet-stack/demo/initrouter/main.c +++ b/bacnet-stack/demo/initrouter/main.c @@ -39,6 +39,7 @@ #include "apdu.h" #include "device.h" #include "datalink.h" +#include "version.h" /* some demo stuff needed */ #define DEBUG_ENABLED 0 #include "debug.h" @@ -75,7 +76,7 @@ static void MyAbortHandler( (void) src; (void) invoke_id; (void) server; - printf("BACnet Abort: %s\r\n", bactext_abort_reason_name(abort_reason)); + printf("BACnet Abort: %s\n", bactext_abort_reason_name(abort_reason)); Error_Detected = true; } @@ -87,7 +88,7 @@ static void MyRejectHandler( /* FIXME: verify src and invoke id */ (void) src; (void) invoke_id; - printf("BACnet Reject: %s\r\n", bactext_reject_reason_name(reject_reason)); + printf("BACnet Reject: %s\n", bactext_reject_reason_name(reject_reason)); Error_Detected = true; } @@ -232,6 +233,27 @@ static void Init_Service_Handlers( apdu_set_reject_handler(MyRejectHandler); } +static void print_usage(char *filename) +{ + printf("Usage: %s address [DNET ID Len Info]\n", filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Send BACnet Initialize-Routing-Table message to a network\n" + "and wait for responses. Displays their network information.\n" + "\n" "address:\n" + "MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\n" + "DNET ID Len Info:\n" "Port-info data:\n" " DNET:\n" + " Destination network number 0-65534\n" " ID:\n" + " Port Identifier number 0-255\n" " Info:\n" + " Octet string of data, up to 255 octets\n" + "To query the complete routing table, do not include any port-info.\n" + "To query using Initialize-Routing-Table message to 192.168.0.18:\n" + "%s 192.168.0.18:47808\n", filename); +} + static void address_parse( BACNET_ADDRESS * dst, int argc, @@ -287,24 +309,30 @@ int main( time_t last_seconds = 0; time_t current_seconds = 0; time_t timeout_seconds = 0; + int argi = 0; + char *filename = NULL; + filename = filename_remove_path(argv[0]); + for (argi = 1; argi < argc; argi++) { + if (strcmp(argv[argi], "--help") == 0) { + print_usage(filename); + print_help(filename); + exit(0); + } + if (strcmp(argv[argi], "--version") == 0) { + printf("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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"); + exit(0); + } + } if (argc < 2) { - printf("Usage: %s address [DNET ID Len Info]\r\n", - filename_remove_path(argv[0])); + print_usage(filename); return 0; } if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { - printf("Send BACnet Initialize-Routing-Table message to a network\r\n" - "and wait for responses. Displays their network information.\r\n" - "\r\n" "address:\r\n" - "MAC address in xx:xx:xx:xx:xx:xx format or IP x.x.x.x:port\r\n" - "DNET ID Len Info:\r\n" "Port-info data:\r\n" " DNET:\r\n" - " Destination network number 0-65534\r\n" " ID:\r\n" - " Port Identifier number 0-255\r\n" " Info:\r\n" - " Octet string of data, up to 255 octets\r\n" - "To query the complete routing table, do not include any port-info.\r\n" - "To query using Initialize-Routing-Table message to 192.168.0.18:\r\n" - "%s 192.168.0.18:47808\r\n", filename_remove_path(argv[0])); return 0; } /* decode the command line parameters */ diff --git a/bacnet-stack/demo/readfile/main.c b/bacnet-stack/demo/readfile/main.c index 23cc5da4..982f198e 100644 --- a/bacnet-stack/demo/readfile/main.c +++ b/bacnet-stack/demo/readfile/main.c @@ -43,6 +43,7 @@ #include "net.h" #include "datalink.h" #include "whois.h" +#include "version.h" /* some demo stuff needed */ #include "filename.h" #include "handlers.h" @@ -71,9 +72,9 @@ static void Atomic_Read_File_Error_Handler( /* FIXME: verify src and invoke id */ (void) src; (void) invoke_id; - printf("\r\nBACnet Error!\r\n"); - printf("Error Class: %s\r\n", bactext_error_class_name(error_class)); - printf("Error Code: %s\r\n", bactext_error_code_name(error_code)); + printf("\nBACnet Error!\n"); + printf("Error Class: %s\n", bactext_error_class_name(error_class)); + printf("Error Code: %s\n", bactext_error_code_name(error_code)); Error_Detected = true; } @@ -87,8 +88,8 @@ void MyAbortHandler( (void) src; (void) invoke_id; (void) server; - printf("\r\nBACnet Abort!\r\n"); - printf("Abort Reason: %s\r\n", bactext_abort_reason_name(abort_reason)); + printf("\nBACnet Abort!\n"); + printf("Abort Reason: %s\n", bactext_abort_reason_name(abort_reason)); Error_Detected = true; } @@ -100,8 +101,8 @@ void MyRejectHandler( /* FIXME: verify src and invoke id */ (void) src; (void) invoke_id; - printf("\r\nBACnet Reject!\r\n"); - printf("Reject Reason: %s\r\n", bactext_reject_reason_name(reject_reason)); + printf("\nBACnet Reject!\n"); + printf("Reject Reason: %s\n", bactext_reject_reason_name(reject_reason)); Error_Detected = true; } @@ -146,7 +147,7 @@ static void AtomicReadFileAckHandler( } if (data.endOfFile) { End_Of_File_Detected = true; - printf("\r\n"); + printf("\n"); } } } @@ -202,6 +203,37 @@ static void Init_Service_Handlers( apdu_set_reject_handler(MyRejectHandler); } +static void print_usage(char *filename) +{ + printf("Usage: %s device-instance file-instance local-name\n", + filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Read a file from a BACnet device and save it locally.\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are trying to\n" + "communicate to. This number will be used to try and bind with\n" + "the device using Who-Is and I-Am services. For example, if you were\n" + "reading from Device Object 123, the device-instance would be 123.\n" + "\n" + "file-instance:\n" + "This is the file object instance number that you are reading from.\n" + "For example, if you were reading from File 2, \n" + "the file-instance would be 2.\n" + "\n" + "local-name:\n" + "The name of the file that will be stored locally.\n" + "\n" + "Example:\n" + "If you want read File 2 from Device 123 and save it to temp.txt,\n" + "use the following command:\n" + "%s 123 2 temp.txt\n", + filename); +} + int main( int argc, char *argv[]) @@ -221,11 +253,28 @@ int main( uint8_t invoke_id = 0; bool found = false; uint16_t my_max_apdu = 0; + int argi = 0; + char *filename = NULL; + /* print help if requested */ + 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("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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 (argc < 4) { - /* FIXME: what about access method - record or stream? */ - printf("%s device-instance file-instance local-name\r\n", - filename_remove_path(argv[0])); + print_usage(filename); return 0; } /* decode the command line parameters */ @@ -233,12 +282,12 @@ int main( Target_File_Object_Instance = strtol(argv[2], NULL, 0); Local_File_Name = argv[3]; if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { - fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "device-instance=%u - it must be less than %u\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } if (Target_File_Object_Instance >= BACNET_MAX_INSTANCE) { - fprintf(stderr, "file-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "file-instance=%u - it must be less than %u\n", Target_File_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } @@ -310,7 +359,7 @@ int main( requestedOctetCount); Current_Invoke_ID = invoke_id; } else if (tsm_invoke_id_failed(invoke_id)) { - fprintf(stderr, "\rError: TSM Timeout!\r\n"); + fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(invoke_id); /* try again or abort? */ Error_Detected = true; @@ -320,7 +369,7 @@ int main( /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { - fprintf(stderr, "\rError: APDU Timeout!\r\n"); + fprintf(stderr, "\rError: APDU Timeout!\n"); Error_Detected = true; break; } diff --git a/bacnet-stack/demo/readprop/main.c b/bacnet-stack/demo/readprop/main.c index ab3ad24d..5ac47230 100644 --- a/bacnet-stack/demo/readprop/main.c +++ b/bacnet-stack/demo/readprop/main.c @@ -46,6 +46,7 @@ #include "net.h" #include "datalink.h" #include "whois.h" +#include "version.h" /* some demo stuff needed */ #include "filename.h" #include "handlers.h" @@ -75,7 +76,7 @@ static void MyErrorHandler( { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Error: %s: %s\r\n", + printf("BACnet Error: %s: %s\n", bactext_error_class_name((int) error_class), bactext_error_code_name((int) error_code)); Error_Detected = true; @@ -91,7 +92,7 @@ void MyAbortHandler( (void) server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\r\n", + printf("BACnet Abort: %s\n", bactext_abort_reason_name((int) abort_reason)); Error_Detected = true; } @@ -104,7 +105,7 @@ void MyRejectHandler( { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Reject: %s\r\n", + printf("BACnet Reject: %s\n", bactext_reject_reason_name((int) reject_reason)); Error_Detected = true; } @@ -135,7 +136,7 @@ void My_Read_Property_Ack_Handler( len = rp_ack_decode_service_request(service_request, service_len, &data); if (len < 0) { - printf("\r\n"); + printf("\n"); } else { rp_ack_print_data(&data); } @@ -167,6 +168,51 @@ static void Init_Service_Handlers( apdu_set_reject_handler(MyRejectHandler); } +static void print_usage(char *filename) +{ + printf("Usage: %s device-instance object-type object-instance " + "property [index]\n", filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Read a property from an object in a BACnet device\n" + "and print the value.\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services. For example, if you were reading\n" + "Device Object 123, the device-instance would be 123.\n" + "\nobject-type:\n" + "The object type is the integer value of the enumeration\n" + "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" + "that you are reading. For example if you were\n" + "reading Analog Output 2, the object-type would be 1.\n" + "\nobject-instance:\n" + "This is the object instance number of the object that\n" + "you are reading. For example, if you were reading\n" + "Analog Output 2, the object-instance would be 2.\n" + "\nproperty:\n" + "The property is an integer value of the enumeration\n" + "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" + "you are reading. For example, if you were reading the\n" + "Present Value property, use 85 as the property.\n" + "\nindex:\n" + "This integer parameter is the index number of an array.\n" + "If the property is an array, individual elements can\n" + "be read. If this parameter is missing and the property\n" + "is an array, the entire array will be read.\n" + "\nExample:\n" + "If you want read the Present-Value of Analog Output 101\n" + "in Device 123, you could send the following command:\n" + "%s 123 1 101 85\n" + "If you want read the Priority-Array of Analog Output 101\n" + "in Device 123, you could send the following command:\n" + "%s 123 1 101 87\n", filename, filename); +} + int main( int argc, char *argv[]) @@ -182,45 +228,27 @@ int main( time_t current_seconds = 0; time_t timeout_seconds = 0; bool found = false; + int argi = 0; + char *filename = NULL; - if (argc < 5) { - printf("Usage: %s device-instance object-type object-instance " - "property [index]\r\n", filename_remove_path(argv[0])); - if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { - printf("device-instance:\r\n" - "BACnet Device Object Instance number that you are\r\n" - "trying to communicate to. This number will be used\r\n" - "to try and bind with the device using Who-Is and\r\n" - "I-Am services. For example, if you were reading\r\n" - "Device Object 123, the device-instance would be 123.\r\n" - "\r\nobject-type:\r\n" - "The object type is the integer value of the enumeration\r\n" - "BACNET_OBJECT_TYPE in bacenum.h. It is the object\r\n" - "that you are reading. For example if you were\r\n" - "reading Analog Output 2, the object-type would be 1.\r\n" - "\r\nobject-instance:\r\n" - "This is the object instance number of the object that\r\n" - "you are reading. For example, if you were reading\r\n" - "Analog Output 2, the object-instance would be 2.\r\n" - "\r\nproperty:\r\n" - "The property is an integer value of the enumeration\r\n" - "BACNET_PROPERTY_ID in bacenum.h. It is the property\r\n" - "you are reading. For example, if you were reading the\r\n" - "Present Value property, use 85 as the property.\r\n" - "\r\nindex:\r\n" - "This integer parameter is the index number of an array.\r\n" - "If the property is an array, individual elements can\r\n" - "be read. If this parameter is missing and the property\r\n" - "is an array, the entire array will be read.\r\n" - "\r\nExample:\r\n" - "If you want read the Present-Value of Analog Output 101\r\n" - "in Device 123, you could send the following command:\r\n" - "%s 123 1 101 85\r\n" - "If you want read the Priority-Array of Analog Output 101\r\n" - "in Device 123, you could send the following command:\r\n" - "%s 123 1 101 87\r\n", filename_remove_path(argv[0]), - filename_remove_path(argv[0])); + 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("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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 (argc < 5) { + print_usage(filename_remove_path(argv[0])); return 0; } /* decode the command line parameters */ @@ -231,7 +259,7 @@ int main( if (argc > 5) Target_Object_Index = strtol(argv[5], NULL, 0); if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { - fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "device-instance=%u - it must be less than %u\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } @@ -279,7 +307,7 @@ int main( } else if (tsm_invoke_id_free(Request_Invoke_ID)) break; else if (tsm_invoke_id_failed(Request_Invoke_ID)) { - fprintf(stderr, "\rError: TSM Timeout!\r\n"); + fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; /* try again or abort? */ @@ -289,7 +317,7 @@ int main( /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { - printf("\rError: APDU Timeout!\r\n"); + printf("\rError: APDU Timeout!\n"); Error_Detected = true; break; } diff --git a/bacnet-stack/demo/readpropm/main.c b/bacnet-stack/demo/readpropm/main.c index 9fb97329..8f6d77b9 100644 --- a/bacnet-stack/demo/readpropm/main.c +++ b/bacnet-stack/demo/readpropm/main.c @@ -46,6 +46,7 @@ #include "net.h" #include "datalink.h" #include "whois.h" +#include "version.h" /* some demo stuff needed */ #include "rpm.h" #include "filename.h" @@ -74,7 +75,7 @@ static void MyErrorHandler( { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Error: %s: %s\r\n", + printf("BACnet Error: %s: %s\n", bactext_error_class_name((int) error_class), bactext_error_code_name((int) error_code)); Error_Detected = true; @@ -90,7 +91,7 @@ void MyAbortHandler( (void) server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\r\n", + printf("BACnet Abort: %s\n", bactext_abort_reason_name((int) abort_reason)); Error_Detected = true; } @@ -104,7 +105,7 @@ void MyRejectHandler( /* FIXME: verify src and invoke id */ if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Reject: %s\r\n", + printf("BACnet Reject: %s\n", bactext_reject_reason_name((int) reject_reason)); Error_Detected = true; } @@ -233,6 +234,63 @@ void cleanup( } } +static void print_usage(char *filename) +{ + printf("Usage: %s device-instance object-type object-instance " + "property[index][,property[index]] [object-type ...]\n", + filename); + printf(" [--version][--help]\n"); +} + +static void print_help(char *filename) +{ + printf("Read one or more properties from one or more objects\n" + "in a BACnet device and print the value(s).\n" + "device-instance:\n" + "BACnet Device Object Instance number that you are\n" + "trying to communicate to. This number will be used\n" + "to try and bind with the device using Who-Is and\n" + "I-Am services. For example, if you were reading\n" + "Device Object 123, the device-instance would be 123.\n" + "\nobject-type:\n" + "The object type is the integer value of the enumeration\n" + "BACNET_OBJECT_TYPE in bacenum.h. It is the object\n" + "that you are reading. For example if you were\n" + "reading Analog Output 2, the object-type would be 1.\n" + "\nobject-instance:\n" + "This is the object instance number of the object that\n" + "you are reading. For example, if you were reading\n" + "Analog Output 2, the object-instance would be 2.\n" + "\nproperty:\n" + "The property is an integer value of the enumeration\n" + "BACNET_PROPERTY_ID in bacenum.h. It is the property\n" + "you are reading. For example, if you were reading the\n" + "Present Value property, use 85 as the property.\n" + "\n[index]:\n" + "This optional integer parameter is the index number of \n" + "an array property. Individual elements of an array can\n" + "be read. If this parameter is missing and the property\n" + "is an array, the entire array will be read.\n" + "\nExample:\n" + "If you want read the PRESENT_VALUE property and various\n" + "array elements of the PRIORITY_ARRAY in Device 123\n" + "Analog Output object 99, use the following command:\n" + "%s 123 1 99 85,87[0],87\n" + "If you want read the PRESENT_VALUE property in objects\n" + "Analog Input 77 and Analog Input 78 in Device 123\n" + "use the following command:\n" "%s 123 0 77 85 0 78 85\n" + "If you want read the ALL property in\n" + "Device object 123, you would use the following command:\n" + "%s 123 8 123 8\n" + "If you want read the OPTIONAL property in\n" + "Device object 123, you would use the following command:\n" + "%s 123 8 123 80\n" + "If you want read the REQUIRED property in\n" + "Device object 123, you would use the following command:\n" + "%s 123 8 123 105\n", filename, filename, filename, filename, + filename); +} + int main( int argc, char *argv[]) @@ -258,64 +316,33 @@ int main( unsigned property_id = 0; unsigned property_array_index = 0; int scan_count = 0; + int argi = 0; char *filename = NULL; - if (argc < 5) { - filename = filename_remove_path(argv[0]); - printf("Usage: %s device-instance object-type object-instance " - "property[index][,property[index]] [object-type ...]\r\n", - filename); - if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { - printf("device-instance:\r\n" - "BACnet Device Object Instance number that you are\r\n" - "trying to communicate to. This number will be used\r\n" - "to try and bind with the device using Who-Is and\r\n" - "I-Am services. For example, if you were reading\r\n" - "Device Object 123, the device-instance would be 123.\r\n" - "\r\nobject-type:\r\n" - "The object type is the integer value of the enumeration\r\n" - "BACNET_OBJECT_TYPE in bacenum.h. It is the object\r\n" - "that you are reading. For example if you were\r\n" - "reading Analog Output 2, the object-type would be 1.\r\n" - "\r\nobject-instance:\r\n" - "This is the object instance number of the object that\r\n" - "you are reading. For example, if you were reading\r\n" - "Analog Output 2, the object-instance would be 2.\r\n" - "\r\nproperty:\r\n" - "The property is an integer value of the enumeration\r\n" - "BACNET_PROPERTY_ID in bacenum.h. It is the property\r\n" - "you are reading. For example, if you were reading the\r\n" - "Present Value property, use 85 as the property.\r\n" - "\r\n[index]:\r\n" - "This optional integer parameter is the index number of \r\n" - "an array property. Individual elements of an array can\r\n" - "be read. If this parameter is missing and the property\r\n" - "is an array, the entire array will be read.\r\n" - "\r\nExample:\r\n" - "If you want read the PRESENT_VALUE property and various\r\n" - "array elements of the PRIORITY_ARRAY in Device 123\r\n" - "Analog Output object 99, use the following command:\r\n" - "%s 123 1 99 85,87[0],87\r\n" - "If you want read the PRESENT_VALUE property in objects\r\n" - "Analog Input 77 and Analog Input 78 in Device 123\r\n" - "use the following command:\r\n" "%s 123 0 77 85 0 78 85\r\n" - "If you want read the ALL property in\r\n" - "Device object 123, you would use the following command:\r\n" - "%s 123 8 123 8\r\n" - "If you want read the OPTIONAL property in\r\n" - "Device object 123, you would use the following command:\r\n" - "%s 123 8 123 80\r\n" - "If you want read the REQUIRED property in\r\n" - "Device object 123, you would use the following command:\r\n" - "%s 123 8 123 105\r\n", filename, filename, filename, filename, - filename); + 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("%s %s\n", filename, BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 by Steve Karg and others.\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 (argc < 5) { + print_usage(filename); return 0; } /* decode the command line parameters */ Target_Device_Object_Instance = strtol(argv[1], NULL, 0); if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { - fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "device-instance=%u - it must be less than %u\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE); return 1; } @@ -330,11 +357,11 @@ int main( tag_value_arg++; args_remaining--; if (args_remaining <= 0) { - fprintf(stderr, "Error: not enough object property triples.\r\n"); + fprintf(stderr, "Error: not enough object property triples.\n"); return 1; } if (rpm_object->object_type >= MAX_BACNET_OBJECT_TYPE) { - fprintf(stderr, "object-type=%u - it must be less than %u\r\n", + fprintf(stderr, "object-type=%u - it must be less than %u\n", rpm_object->object_type, MAX_BACNET_OBJECT_TYPE); return 1; } @@ -342,11 +369,11 @@ int main( tag_value_arg++; args_remaining--; if (args_remaining <= 0) { - fprintf(stderr, "Error: not enough object property triples.\r\n"); + fprintf(stderr, "Error: not enough object property triples.\n"); return 1; } if (rpm_object->object_instance > BACNET_MAX_INSTANCE) { - fprintf(stderr, "object-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "object-instance=%u - it must be less than %u\n", rpm_object->object_instance, BACNET_MAX_INSTANCE + 1); return 1; } @@ -362,7 +389,7 @@ int main( rpm_property->propertyIdentifier = property_id; if (rpm_property->propertyIdentifier > MAX_BACNET_PROPERTY_ID) { fprintf(stderr, - "property=%u - it must be less than %u\r\n", + "property=%u - it must be less than %u\n", rpm_property->propertyIdentifier, MAX_BACNET_PROPERTY_ID + 1); return 1; @@ -437,7 +464,7 @@ int main( } else if (tsm_invoke_id_free(Request_Invoke_ID)) break; else if (tsm_invoke_id_failed(Request_Invoke_ID)) { - fprintf(stderr, "\rError: TSM Timeout!\r\n"); + fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; /* try again or abort? */ @@ -447,7 +474,7 @@ int main( /* increment timer - exit if timed out */ elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { - printf("\rError: APDU Timeout!\r\n"); + printf("\rError: APDU Timeout!\n"); Error_Detected = true; break; } diff --git a/bacnet-stack/demo/writeprop/main.c b/bacnet-stack/demo/writeprop/main.c index f807b271..bc545121 100644 --- a/bacnet-stack/demo/writeprop/main.c +++ b/bacnet-stack/demo/writeprop/main.c @@ -45,6 +45,7 @@ #include "net.h" #include "datalink.h" #include "whois.h" +#include "version.h" /* some demo stuff needed */ #include "filename.h" #include "handlers.h" @@ -86,7 +87,7 @@ static void MyErrorHandler( { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Error: %s: %s\r\n", + printf("BACnet Error: %s: %s\n", bactext_error_class_name((int) error_class), bactext_error_code_name((int) error_code)); Error_Detected = true; @@ -102,7 +103,7 @@ void MyAbortHandler( (void) server; if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Abort: %s\r\n", + printf("BACnet Abort: %s\n", bactext_abort_reason_name((int) abort_reason)); Error_Detected = true; } @@ -115,7 +116,7 @@ void MyRejectHandler( { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("BACnet Reject: %s\r\n", + printf("BACnet Reject: %s\n", bactext_reject_reason_name((int) reject_reason)); Error_Detected = true; } @@ -127,7 +128,7 @@ void MyWritePropertySimpleAckHandler( { if (address_match(&Target_Address, src) && (invoke_id == Request_Invoke_ID)) { - printf("\r\nWriteProperty Acknowledged!\r\n"); + printf("\nWriteProperty Acknowledged!\n"); } } @@ -156,6 +157,72 @@ static void Init_Service_Handlers( apdu_set_reject_handler(MyRejectHandler); } +static void print_usage(char *filename) +{ + printf("Usage: %s device-instance object-type object-instance " + "property priority index tag value [tag value...]\n", + filename); +} + +static void print_help(char *filename) +{ + printf("device-instance:\n" + "BACnet Device Object Instance number that you are trying to\n" + "communicate to. This number will be used to try and bind with\n" + "the device using Who-Is and I-Am services. For example, if you were\n" + "writing to Device Object 123, the device-instance would be 123.\n" + "\n" "object-type:\n" + "The object type is the integer value of the enumeration\n" + "BACNET_OBJECT_TYPE in bacenum.h. It is the object that you are\n" + "writing to. For example if you were writing to Analog Output 2, \n" + "the object-type would be 1.\n" "\n" "object-instance:\n" + "This is the object instance number of the object that you are \n" + "writing to. For example, if you were writing to Analog Output 2, \n" + "the object-instance would be 2.\n" "\n" "property:\n" + "The property is an integer value of the enumeration \n" + "BACNET_PROPERTY_ID in bacenum.h. It is the property you are \n" + "writing to. For example, if you were writing to the Present Value\n" + "property, you would use 85 as the property.\n" "\n" + "priority:\n" + "This parameter is used for setting the priority of the\n" + "write. If Priority 0 is given, no priority is sent. The BACnet \n" + "standard states that the value is written at the lowest \n" + "priority (16) if the object property supports priorities\n" + "when no priority is sent.\n" "\n" "index\n" + "This integer parameter is the index number of an array.\n" + "If the property is an array, individual elements can be written\n" + "to if supported. If this parameter is -1, the index is ignored.\n" + "\n" "tag:\n" + "Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \n" + "in bacenum.h. It is the data type of the value that you are\n" + "writing. For example, if you were writing a REAL value, you would \n" + "use a tag of 4.\n" + "Context tags are created using two tags in a row. The context tag\n" + "is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged REAL.\n" + "\n" "value:\n" + "The value is an ASCII representation of some type of data that you\n" + "are writing. It is encoded using the tag information provided. For\n" + "example, if you were writing a REAL value of 100.0, you would use \n" + "100.0 as the value.\n" "\n" + "Here is a brief overview of BACnet property and tags:\n" + "Certain properties are expected to be written with certain \n" + "application tags, so you probably need to know which ones to use\n" + "with each property of each object. It is almost safe to say that\n" + "given a property and an object and a table, the tag could be looked\n" + "up automatically. There may be a few exceptions to this, such as\n" + "the Any property type in the schedule object and the Present Value\n" + "accepting REAL, BOOLEAN, NULL, etc. Perhaps it would be simpler for\n" + "the demo to use this kind of table - but I also wanted to be able\n" + "to do negative testing by passing the wrong tag and have the server\n" + "return a reject message.\n" "\nExample:\n" + "If you want send a value of 100 to the Present-Value in\n" + "Analog Output 0 of Device 123 at priority 16,\n" + "send the following command:\n" + "%s 123 1 0 85 16 -1 4 100\n" + "To send a relinquish command to the same object:\n" + "%s 123 1 0 85 16 -1 0 0\n", filename, filename); +} + int main( int argc, char *argv[]) @@ -176,70 +243,28 @@ int main( int args_remaining = 0, tag_value_arg = 0, i = 0; BACNET_APPLICATION_TAG property_tag; uint8_t context_tag = 0; + int argi = 0; - if (argc < 9) { - /* note: priority 16 and 0 should produce the same end results... */ - printf("Usage: %s device-instance object-type object-instance " - "property priority index tag value [tag value...]\r\n", - filename_remove_path(argv[0])); - if ((argc > 1) && (strcmp(argv[1], "--help") == 0)) { - printf("device-instance:\r\n" - "BACnet Device Object Instance number that you are trying to\r\n" - "communicate to. This number will be used to try and bind with\r\n" - "the device using Who-Is and I-Am services. For example, if you were\r\n" - "writing to Device Object 123, the device-instance would be 123.\r\n" - "\r\n" "object-type:\r\n" - "The object type is the integer value of the enumeration\r\n" - "BACNET_OBJECT_TYPE in bacenum.h. It is the object that you are\r\n" - "writing to. For example if you were writing to Analog Output 2, \r\n" - "the object-type would be 1.\r\n" "\r\n" "object-instance:\r\n" - "This is the object instance number of the object that you are \r\n" - "writing to. For example, if you were writing to Analog Output 2, \r\n" - "the object-instance would be 2.\r\n" "\r\n" "property:\r\n" - "The property is an integer value of the enumeration \r\n" - "BACNET_PROPERTY_ID in bacenum.h. It is the property you are \r\n" - "writing to. For example, if you were writing to the Present Value\r\n" - "property, you would use 85 as the property.\r\n" "\r\n" - "priority:\r\n" - "This parameter is used for setting the priority of the\r\n" - "write. If Priority 0 is given, no priority is sent. The BACnet \r\n" - "standard states that the value is written at the lowest \r\n" - "priority (16) if the object property supports priorities\r\n" - "when no priority is sent.\r\n" "\r\n" "index\r\n" - "This integer parameter is the index number of an array.\r\n" - "If the property is an array, individual elements can be written\r\n" - "to if supported. If this parameter is -1, the index is ignored.\r\n" - "\r\n" "tag:\r\n" - "Tag is the integer value of the enumeration BACNET_APPLICATION_TAG \r\n" - "in bacenum.h. It is the data type of the value that you are\r\n" - "writing. For example, if you were writing a REAL value, you would \r\n" - "use a tag of 4.\r\n" - "Context tags are created using two tags in a row. The context tag\r\n" - "is preceded by a C. Ctag tag. C2 4 creates a context 2 tagged REAL.\r\n" - "\r\n" "value:\r\n" - "The value is an ASCII representation of some type of data that you\r\n" - "are writing. It is encoded using the tag information provided. For\r\n" - "example, if you were writing a REAL value of 100.0, you would use \r\n" - "100.0 as the value.\r\n" "\r\n" - "Here is a brief overview of BACnet property and tags:\r\n" - "Certain properties are expected to be written with certain \r\n" - "application tags, so you probably need to know which ones to use\r\n" - "with each property of each object. It is almost safe to say that\r\n" - "given a property and an object and a table, the tag could be looked\r\n" - "up automatically. There may be a few exceptions to this, such as\r\n" - "the Any property type in the schedule object and the Present Value\r\n" - "accepting REAL, BOOLEAN, NULL, etc. Perhaps it would be simpler for\r\n" - "the demo to use this kind of table - but I also wanted to be able\r\n" - "to do negative testing by passing the wrong tag and have the server\r\n" - "return a reject message.\r\n" "\r\nExample:\r\n" - "If you want send a value of 100 to the Present-Value in\r\n" - "Analog Output 0 of Device 123 at priority 16,\r\n" - "send the following command:\r\n" - "%s 123 1 0 85 16 -1 4 100\r\n" - "To send a relinquish command to the same object:\r\n" - "%s 123 1 0 85 16 -1 0 0\r\n", filename_remove_path(argv[0]), - filename_remove_path(argv[0])); + /* print help if requested */ + for (argi = 1; argi < argc; argi++) { + if (strcmp(argv[argi], "--help") == 0) { + print_usage(filename_remove_path(argv[0])); + print_help(filename_remove_path(argv[0])); + return 0; } + if (strcmp(argv[argi], "--version") == 0) { + printf("%s %s\n", + filename_remove_path(argv[0]), + BACNET_VERSION_TEXT); + printf("Copyright (C) 2014 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 (argc < 9) { + print_usage(filename_remove_path(argv[0])); return 0; } /* decode the command line parameters */ @@ -252,22 +277,22 @@ int main( if (Target_Object_Property_Index == -1) Target_Object_Property_Index = BACNET_ARRAY_ALL; if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { - fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "device-instance=%u - it must be less than %u\n", Target_Device_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Type > MAX_BACNET_OBJECT_TYPE) { - fprintf(stderr, "object-type=%u - it must be less than %u\r\n", + fprintf(stderr, "object-type=%u - it must be less than %u\n", Target_Object_Type, MAX_BACNET_OBJECT_TYPE + 1); return 1; } if (Target_Object_Instance > BACNET_MAX_INSTANCE) { - fprintf(stderr, "object-instance=%u - it must be less than %u\r\n", + fprintf(stderr, "object-instance=%u - it must be less than %u\n", Target_Object_Instance, BACNET_MAX_INSTANCE + 1); return 1; } if (Target_Object_Property > MAX_BACNET_PROPERTY_ID) { - fprintf(stderr, "property=%u - it must be less than %u\r\n", + fprintf(stderr, "property=%u - it must be less than %u\n", Target_Object_Property, MAX_BACNET_PROPERTY_ID + 1); return 1; } @@ -287,15 +312,15 @@ int main( property_tag = strtol(argv[tag_value_arg], NULL, 0); args_remaining--; if (args_remaining <= 0) { - fprintf(stderr, "Error: not enough tag-value pairs\r\n"); + fprintf(stderr, "Error: not enough tag-value pairs\n"); return 1; } value_string = argv[tag_value_arg + 1]; args_remaining--; - /* printf("tag[%d]=%u value[%d]=%s\r\n", + /* printf("tag[%d]=%u value[%d]=%s\n", i, property_tag, i, value_string); */ if (property_tag >= MAX_BACNET_APPLICATION_TAG) { - fprintf(stderr, "Error: tag=%u - it must be less than %u\r\n", + fprintf(stderr, "Error: tag=%u - it must be less than %u\n", property_tag, MAX_BACNET_APPLICATION_TAG); return 1; } @@ -304,7 +329,7 @@ int main( &Target_Object_Property_Value[i]); if (!status) { /* FIXME: show the expected entry format for the tag */ - fprintf(stderr, "Error: unable to parse the tag value\r\n"); + fprintf(stderr, "Error: unable to parse the tag value\n"); return 1; } Target_Object_Property_Value[i].next = NULL; @@ -317,7 +342,7 @@ int main( } } if (args_remaining > 0) { - fprintf(stderr, "Error: Exceeded %d tag-value pairs.\r\n", + fprintf(stderr, "Error: Exceeded %d tag-value pairs.\n", MAX_PROPERTY_VALUES); return 1; } @@ -366,7 +391,7 @@ int main( } else if (tsm_invoke_id_free(Request_Invoke_ID)) break; else if (tsm_invoke_id_failed(Request_Invoke_ID)) { - fprintf(stderr, "\rError: TSM Timeout!\r\n"); + fprintf(stderr, "\rError: TSM Timeout!\n"); tsm_free_invoke_id(Request_Invoke_ID); Error_Detected = true; /* try again or abort? */ @@ -377,7 +402,7 @@ int main( elapsed_seconds += (current_seconds - last_seconds); if (elapsed_seconds > timeout_seconds) { Error_Detected = true; - printf("\rError: APDU Timeout!\r\n"); + printf("\rError: APDU Timeout!\n"); break; } }