From 78cec1d8c4ebdb34d40f79a0fb97a3f5269e0756 Mon Sep 17 00:00:00 2001 From: skarg Date: Tue, 22 May 2007 00:19:05 +0000 Subject: [PATCH] Added ability to specify the BACnet/IP interface on multi-homed machines from the command line demo for demo/epics on a Win32 platform. --- bacnet-stack/demo/epics/main.c | 68 ++++++++++++++++++++++++---- bacnet-stack/demo/epics/makefile.b32 | 2 +- bacnet-stack/ports/win32/bip-init.c | 30 ++++++++---- 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/bacnet-stack/demo/epics/main.c b/bacnet-stack/demo/epics/main.c index 7065b064..74db9a3e 100644 --- a/bacnet-stack/demo/epics/main.c +++ b/bacnet-stack/demo/epics/main.c @@ -57,7 +57,8 @@ static uint8_t Rx_Buf[MAX_MPDU] = { 0 }; /* global variables used in this file */ static uint32_t Target_Device_Object_Instance = BACNET_MAX_INSTANCE; static bool Error_Detected = false; -static BACNET_ADDRESS Target_Address; +static BACNET_ADDRESS Target_Address; +static char *Network_Interface = NULL; typedef struct BACnet_RP_Service_Data_t { bool new_data; @@ -267,7 +268,48 @@ static uint8_t Read_Properties(uint32_t device_instance) } return invoke_id; -} +} + +static void Interpret_Arguments(int argc, char *argv[]) +{ + int i = 0, j = 0; /* used to index through arguments */ + char *p_arg = NULL; /* points to current argument */ + long number = 0; /* used for strtol */ + char *p_data = NULL; /* points to data portion of argument */ + + if (!argv) + return; + + /* skip 1st one [0] - its the command line for the filename */ + for (i = 1; i < argc; i++) { + p_arg = argv[i]; + if (p_arg[0] == '-') { + p_data = p_arg + 2; + switch (p_arg[1]) { + case 'a': + bip_set_addr(inet_addr(p_data)); + break; + case 'd': + Network_Interface = p_data; + break; + /* double dash */ + case '-': + if (strcmp(p_data, "help") == 0) { + printf + ("%s device-instance\r\n", + filename_remove_path(argv[0])); + } + exit(1); + break; + default: + /* do nothing */ + break; + } /* end of arguments beginning with - */ + } /* dash arguments */ + } /* end of arg loop */ + return; +} + int main(int argc, char *argv[]) { @@ -288,11 +330,13 @@ int main(int argc, char *argv[]) filename_remove_path(argv[0])); return 0; } + Interpret_Arguments(argc, argv); + /* decode the command line parameters */ Target_Device_Object_Instance = strtol(argv[1], NULL, 0); - if (Target_Device_Object_Instance >= BACNET_MAX_INSTANCE) { + if (Target_Device_Object_Instance > BACNET_MAX_INSTANCE) { fprintf(stderr, "device-instance=%u - it must be less than %u\r\n", - Target_Device_Object_Instance, BACNET_MAX_INSTANCE); + Target_Device_Object_Instance, BACNET_MAX_INSTANCE+1); return 1; } /* setup my info */ @@ -300,19 +344,25 @@ int main(int argc, char *argv[]) address_init(); Init_Service_Handlers(); #if defined(BACDL_ETHERNET) - /* init the physical layer */ - if (!ethernet_init("eth0")) + /* init the physical layer */ + if (!Network_Interface) + Network_Interface = "eth0"; + if (!ethernet_init(Network_Interface)) return 1; #elif defined(BACDL_BIP) - bip_set_interface("eth0"); + if (!Network_Interface) + Network_Interface = "eth0"; + bip_set_interface(Network_Interface); if (!bip_init()) return 1; /* printf("bip: using port %hu\r\n", bip_get_port()); */ #elif defined(BACDL_ARCNET) - if (!arcnet_init("arc0")) + if (!Network_Interface) + Network_Interface = "arc0"; + if (!arcnet_init(Network_Interface)) return 1; #else -#error Datalink (BACDL_ETHERNET,BACDL_BIP, or BACDL_ARCNET) undefined +#error Define a datalink (BACDL_ETHERNET,BACDL_BIP, or BACDL_ARCNET) #endif /* configure the timeout values */ last_seconds = time(NULL); diff --git a/bacnet-stack/demo/epics/makefile.b32 b/bacnet-stack/demo/epics/makefile.b32 index 183e97da..cee684da 100644 --- a/bacnet-stack/demo/epics/makefile.b32 +++ b/bacnet-stack/demo/epics/makefile.b32 @@ -15,7 +15,7 @@ PRODUCT = bacepics PRODUCT_EXE = $(PRODUCT).exe # Choose the Data Link Layer to Enable -DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1;BIG_ENDIAN=0;PRINT_ENABLED=1 +DEFINES = -DBACDL_BIP=1;TSM_ENABLED=1;BIG_ENDIAN=0;PRINT_ENABLED=1;BIP_DEBUG=0 SRCS = main.c \ ..\..\ports\win32\bip-init.c \ diff --git a/bacnet-stack/ports/win32/bip-init.c b/bacnet-stack/ports/win32/bip-init.c index b509cb60..ad0e9c94 100644 --- a/bacnet-stack/ports/win32/bip-init.c +++ b/bacnet-stack/ports/win32/bip-init.c @@ -55,13 +55,13 @@ static long gethostaddr(void) if ((host_ent = gethostbyname(host_name)) == NULL) return -1; #ifdef BIP_DEBUG - printf("host: %s at %03u.%03u.%03u.%03u\n", host_name, + printf("host: %s at %u.%u.%u.%u\n", host_name, ((uint8_t*)host_ent->h_addr)[0], ((uint8_t*)host_ent->h_addr)[1], ((uint8_t*)host_ent->h_addr)[2], ((uint8_t*)host_ent->h_addr)[3]); #endif - + /* note: network byte order */ return *(long *) host_ent->h_addr; } @@ -115,6 +115,7 @@ bool bip_init(void) int Code; WSADATA wd; struct in_addr address; + struct in_addr broadcast_address; Result = WSAStartup((1 << 8) | 1, &wd); /*Result = WSAStartup(MAKEWORD(2,2), &wd); */ @@ -126,17 +127,28 @@ bool bip_init(void) } atexit(cleanup); - address.s_addr = gethostaddr(); - if (address.s_addr == (unsigned) -1) { - Code = WSAGetLastError(); - printf("Get host address failed, error code: %i\n", Code); - exit(1); + /* has address been set? */ + address.s_addr = htonl(bip_get_addr()); + if (address.s_addr == 0) { + address.s_addr = gethostaddr(); + if (address.s_addr == (unsigned) -1) { + Code = WSAGetLastError(); + printf("Get host address failed, error code: %i\n", Code); + exit(1); + } + bip_set_addr(address.s_addr); } #ifdef BIP_DEBUG printf("host address: %s\n", inet_ntoa(address)); #endif - bip_set_addr(address.s_addr); - set_broadcast_address(address.s_addr); + /* has broadcast address been set? */ + if (bip_get_broadcast_addr() == 0) { + set_broadcast_address(address.s_addr); + } +#ifdef BIP_DEBUG + broadcast_address.s_addr = htonl(bip_get_broadcast_addr()); + printf("broadcast address: %s\n", inet_ntoa(broadcast_address)); +#endif /* assumes that the driver has already been initialized */ sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);