From efdb70b7f927cd810db4f1e731e7d8cb6dfd0054 Mon Sep 17 00:00:00 2001 From: skarg Date: Tue, 24 Feb 2015 20:01:18 +0000 Subject: [PATCH] =?UTF-8?q?Added=20simple=20local=20interface=20to=20manag?= =?UTF-8?q?e=20entries=20in=20the=20broadcast=20distribution=20table.=20Us?= =?UTF-8?q?ing=20this=20interface,=20the=20BDT=20can=20be=20supplied=20by?= =?UTF-8?q?=20local=20means,=20e.g.=20device's=20local=20user=20interface?= =?UTF-8?q?=20as=20stated=20in=20Annex=20J.4.4.=20Thank=20you,=20Sami=20Pi?= =?UTF-8?q?etik=C3=A4inen,=20for=20the=20contribution!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bacnet-stack/include/bvlc.h | 32 +++++++++++++ bacnet-stack/src/bvlc.c | 91 ++++++++++++++++++++++++++++++++----- 2 files changed, 112 insertions(+), 11 deletions(-) diff --git a/bacnet-stack/include/bvlc.h b/bacnet-stack/include/bvlc.h index 1cbe076f..a0c8de53 100644 --- a/bacnet-stack/include/bvlc.h +++ b/bacnet-stack/include/bvlc.h @@ -30,6 +30,7 @@ #include #include "bacdef.h" #include "npdu.h" +#include "bip.h" struct sockaddr_in; /* Defined elsewhere, needed here. */ @@ -45,6 +46,17 @@ extern "C" { #define bvlc_maintenance_timer(x) #endif + typedef struct { + /* true if valid entry - false if not */ + bool valid; + /* BACnet/IP address */ + struct in_addr dest_address; /* in network format */ + /* BACnet/IP port number - not always 47808=BAC0h */ + uint16_t dest_port; /* in network format */ + /* Broadcast Distribution Mask */ + struct in_addr broadcast_mask; /* in tework format */ + } BBMD_TABLE_ENTRY; + uint16_t bvlc_receive( BACNET_ADDRESS * src, /* returns the source address */ uint8_t * npdu, /* returns the NPDU */ @@ -112,6 +124,26 @@ extern "C" { BACNET_BVLC_FUNCTION bvlc_get_function_code( void); + + /* Local interface to manage BBMD. + * The interface user needs to handle mutual exclusion if needed i.e. + * BACnet packet is not being handled when the BBMD table is modified. + */ + + /* Get handle to broadcast distribution table. Returns the number of + * valid entries in the table. */ + int bvlc_get_bdt_local( + const BBMD_TABLE_ENTRY** table); + + /* Invalidate all entries in the broadcast distribution table */ + void bvlc_clear_bdt_local(void); + + /* Add new entry to broadcast distribution table. Returns true if the new + * entry was added successfully */ + bool bvlc_add_bdt_entry_local( + BBMD_TABLE_ENTRY* entry); + + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/bacnet-stack/src/bvlc.c b/bacnet-stack/src/bvlc.c index fa74b3d1..15dde4dc 100644 --- a/bacnet-stack/src/bvlc.c +++ b/bacnet-stack/src/bvlc.c @@ -39,7 +39,6 @@ #include "bacdcode.h" #include "bacint.h" #include "bvlc.h" -#include "bip.h" #ifndef DEBUG_ENABLED #define DEBUG_ENABLED 0 #endif @@ -68,16 +67,6 @@ BACNET_BVLC_FUNCTION BVLC_Function_Code = BVLC_RESULT; /* A safe default */ */ #if defined(BBMD_ENABLED) && BBMD_ENABLED -typedef struct { - /* true if valid entry - false if not */ - bool valid; - /* BACnet/IP address */ - struct in_addr dest_address; /* in network format */ - /* BACnet/IP port number - not always 47808=BAC0h */ - uint16_t dest_port; /* in network format */ - /* Broadcast Distribution Mask */ - struct in_addr broadcast_mask; /* in tework format */ -} BBMD_TABLE_ENTRY; #ifndef MAX_BBMD_ENTRIES #define MAX_BBMD_ENTRIES 128 @@ -1375,6 +1364,86 @@ BACNET_BVLC_FUNCTION bvlc_get_function_code( return BVLC_Function_Code; } +/** Get handle to broadcast distribution table (BDT). + * + * Do not modify the table using the returned pointer, + * use the dedicated functions instead. + * (For optimization the table is not copied to caller) + * + * @return Number of valid entries in the table or -1 on error. + */ +int bvlc_get_bdt_local( + const BBMD_TABLE_ENTRY** table) +{ + int count = 0; + + if(table == NULL) + return -1; + + *table = BBMD_Table; + + for (count = 0; count < MAX_BBMD_ENTRIES; ++count) { + if (!BBMD_Table[count].valid) { + break; + } + } + + return count; +} + +/** Invalidate all entries in the broadcast distribution table (BDT). + */ +void bvlc_clear_bdt_local( + void) +{ + int i = 0; + for (i = 0; i < MAX_BBMD_ENTRIES; ++i) { + BBMD_Table[i].valid = false; + BBMD_Table[i].dest_address.s_addr = 0; + BBMD_Table[i].dest_port = 0; + BBMD_Table[i].broadcast_mask.s_addr = 0; + } +} + +/** Add new entry to broadcast distribution table. + * + * @return True if the new entry was added successfully. + */ +bool bvlc_add_bdt_entry_local( + BBMD_TABLE_ENTRY* entry) +{ + bool found = false; + int i = 0; + + if(entry == NULL) + return false; + + /* Find first empty slot */ + for (i = 0; i < MAX_BBMD_ENTRIES; ++i) { + if (!BBMD_Table[i].valid) { + found = true; + break; + } + + /* Make sure that we are not adding a duplicate */ + if(BBMD_Table[i].dest_address.s_addr == entry->dest_address.s_addr && + BBMD_Table[i].broadcast_mask.s_addr == entry->broadcast_mask.s_addr && + BBMD_Table[i].dest_port == entry->dest_port) { + return false; + } + } + + if(!found) + return false; + + /* Copy new entry to the empty slot */ + BBMD_Table[i] = *entry; + BBMD_Table[i].valid = true; + + return true; +} + + #ifdef TEST #include #include