From 7fc3060dbf50a2143571068905db629c02951c97 Mon Sep 17 00:00:00 2001 From: skarg Date: Thu, 19 Apr 2018 20:10:45 +0000 Subject: [PATCH] Added environment variables to enhance BBMD behavior in the example server demo. BACNET_BDT_ADDR_1 - dotted IPv4 address of the BBMD table entry 1..128 BACNET_BDT_PORT_1 - UDP port of the BBMD table entry 1..128 (optional) BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table entry 1..128 (optional) Added environment variable to allow setting of the public NAT address. BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router --- bacnet-stack/bin/readme.txt | 7 ++++ bacnet-stack/demo/handler/dlenv.c | 57 ++++++++++++++++++++++++++++++- bacnet-stack/src/bvlc.c | 5 ++- 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/bacnet-stack/bin/readme.txt b/bacnet-stack/bin/readme.txt index 2935435d..cb031434 100644 --- a/bacnet-stack/bin/readme.txt +++ b/bacnet-stack/bin/readme.txt @@ -83,6 +83,13 @@ BACNET_BBMD_TIMETOLIVE - number of seconds used in Foreign Device BACNET_BBMD_ADDRESS - dotted IPv4 address of the BBMD or Foreign Device Registrar. +BACNET_BDT_ADDR_1 - dotted IPv4 address of the BBMD table entry 1..128 +BACNET_BDT_PORT_1 - UDP port of the BBMD table entry 1..128 (optional) +BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table + entry 1..128 (optional) + +BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router + Example Usage ------------- You can communicate with the virtual BACnet Device by using the other BACnet diff --git a/bacnet-stack/demo/handler/dlenv.c b/bacnet-stack/demo/handler/dlenv.c index a392e0e1..2d1f5a65 100644 --- a/bacnet-stack/demo/handler/dlenv.c +++ b/bacnet-stack/demo/handler/dlenv.c @@ -45,7 +45,10 @@ static uint16_t BBMD_Timer_Seconds; static long bbmd_timetolive_seconds = 60000; static long bbmd_port = 0xBAC0; static long bbmd_address = 0; +static long bbmd_mask = 0xFFFFFFFF; static int bbmd_result = 0; +static BBMD_TABLE_ENTRY BBMD_Table_Entry; + /* Simple setters for BBMD registration variables. */ @@ -120,6 +123,10 @@ int dlenv_register_as_foreign_device( int retval = 0; #if defined(BACDL_BIP) char *pEnv = NULL; + unsigned a[4] = {0}; + char bbmd_env[32] = ""; + unsigned entry_number = 0; + int c; pEnv = getenv("BACNET_BBMD_PORT"); if (pEnv) { @@ -151,8 +158,43 @@ int dlenv_register_as_foreign_device( fprintf(stderr, "FAILED to Register with BBMD at %s \n", inet_ntoa(addr)); BBMD_Timer_Seconds = (uint16_t) bbmd_timetolive_seconds; + } else { + for (entry_number = 1; entry_number <= 128; entry_number++) { + sprintf(bbmd_env,"BACNET_BDT_ADDR_%u", entry_number); + pEnv = getenv(bbmd_env); + if (pEnv) { + bbmd_address = bip_getaddrbyname(pEnv); + } + if (bbmd_address) { + bbmd_port = 0xBAC0; + sprintf(bbmd_env,"BACNET_BDT_PORT_%u", entry_number); + pEnv = getenv(bbmd_env); + if (pEnv) { + bbmd_port = strtol(pEnv, NULL, 0); + if (bbmd_port > 0xFFFF) { + bbmd_port = 0xBAC0; + } + } + bbmd_mask = 0xFFFFFFFF; + sprintf(bbmd_env,"BACNET_BDT_MASK_%u", entry_number); + pEnv = getenv(bbmd_env); + if (pEnv) { + c = sscanf(pEnv, "%3u.%3u.%3u.%3u", + &a[0],&a[1],&a[2],&a[3]); + if (c == 4) { + bbmd_mask = + ((a[0]&0xFF)<<24)|((a[1]&0xFF)<<16)| + ((a[2]&0xFF)<<8)|(a[3]&0xFF); + } + } + BBMD_Table_Entry.valid = true; + BBMD_Table_Entry.dest_address.s_addr = bbmd_address; + BBMD_Table_Entry.dest_port = bbmd_port; + BBMD_Table_Entry.broadcast_mask.s_addr = bbmd_mask; + bvlc_add_bdt_entry_local(&BBMD_Table_Entry); + } + } } - bbmd_result = retval; #endif return retval; @@ -221,6 +263,11 @@ void dlenv_maintenance_timer( * Registration (0..65535). Defaults to 60000 seconds. * - BACNET_BBMD_ADDRESS - dotted IPv4 address of the BBMD or Foreign * Device Registrar. + * - BACNET_BDT_ADDR_1 - dotted IPv4 address of the BBMD table entry 1..128 + * - BACNET_BDT_PORT_1 - UDP port of the BBMD table entry 1..128 (optional) + * - BACNET_BDT_MASK_1 - dotted IPv4 mask of the BBMD table + * entry 1..128 (optional) + * - BACNET_IP_NAT_ADDR - dotted IPv4 address of the public facing router * - BACDL_MSTP: (BACnet MS/TP) * - BACNET_MAX_INFO_FRAMES * - BACNET_MAX_MASTER @@ -282,6 +329,14 @@ void dlenv_init( if (ntohs(bip_get_port()) < 1024) bip_set_port(htons(0xBAC0)); } + pEnv = getenv("BACNET_IP_NAT_ADDR"); + if (pEnv) { + struct in_addr nat_addr; + nat_addr.s_addr = bip_getaddrbyname(pEnv); + if (nat_addr.s_addr) { + bvlc_set_global_address_for_nat(&nat_addr); + } + } #elif defined(BACDL_MSTP) pEnv = getenv("BACNET_MAX_INFO_FRAMES"); if (pEnv) { diff --git a/bacnet-stack/src/bvlc.c b/bacnet-stack/src/bvlc.c index 60b9fa81..cb91abfa 100644 --- a/bacnet-stack/src/bvlc.c +++ b/bacnet-stack/src/bvlc.c @@ -668,7 +668,6 @@ int bvlc_encode_original_broadcast_npdu( } #endif - #if defined(BBMD_ENABLED) && BBMD_ENABLED /** Create a Broadcast Distribution Table from message * @@ -1707,6 +1706,7 @@ void bvlc_clear_bdt_local( BBMD_Table[i].dest_port = 0; BBMD_Table[i].broadcast_mask.s_addr = 0; } + debug_printf("BVLC: BBMD Table entries cleared.\n"); } /** Add new entry to broadcast distribution table. @@ -1743,6 +1743,7 @@ bool bvlc_add_bdt_entry_local( /* Copy new entry to the empty slot */ BBMD_Table[i] = *entry; BBMD_Table[i].valid = true; + debug_printf("BVLC: BBMD Table entry added.\n"); return true; } @@ -1754,6 +1755,7 @@ void bvlc_set_global_address_for_nat(const struct in_addr* addr) { BVLC_Global_Address = *addr; BVLC_NAT_Handling = true; + debug_printf("BVLC: NAT Address enabled.\n"); } /** Disable NAT handling. @@ -1762,6 +1764,7 @@ void bvlc_disable_nat(void) { BVLC_NAT_Handling = false; BVLC_Global_Address.s_addr = 0; + debug_printf("BVLC: NAT Address disabled.\n"); }