Arranged the BBMD functions so that BBMD_ENABLE shrouds all the code used just by implementations which serve as a BBMD device.

Left the few for registering as a foreign device in the common code body (no #ifdef around them), and moved them to one area toward the end of the file.  (Seemed like too few to justify having their own source code file.) Allow foreign device registration function without requiring BBMD_ENABLE.
This commit is contained in:
tbrennan3
2011-09-12 11:54:42 +00:00
parent a41c8fcc99
commit 46d7daf405
4 changed files with 113 additions and 71 deletions
+6 -1
View File
@@ -25,8 +25,13 @@ BACNET_DEFINES ?= $(MY_BACNET_DEFINES)
#BACDL_DEFINE=-DBACDL_MSTP=1
BACDL_DEFINE?=-DBACDL_BIP=1
# Declare your level of BBMD support
BBMD_DEFINE ?=
#BBMD_DEFINE ?= -DBBMD_ENABLE
#BBMD_DEFINE ?= -DBBMD_CLIENT_ENABLED
# Define WEAK_FUNC for [...somebody help here; I can't find any uses of it]
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) -DWEAK_FUNC=
DEFINES = $(BACNET_DEFINES) $(BACDL_DEFINE) $(BBMD_DEFINE) -DWEAK_FUNC=
# directories
BACNET_PORT = linux
+13 -13
View File
@@ -38,7 +38,7 @@
/** @file dlenv.c Initialize the DataLink configuration. */
#if defined(BACDL_BIP) && BBMD_ENABLED
#if defined(BACDL_BIP)
/* timer used to renew Foreign Device Registration */
static uint16_t BBMD_Timer_Seconds;
/* BBMD variables */
@@ -95,7 +95,7 @@ int dlenv_bbmd_result( void )
* internal variables or Environment variables.
* If no address for the BBMD is provided, no BBMD registration will occur.
*
* The Environment Variables depend on defines BACDL_BIP and BBMD_ENABLED:
* The Environment Variables depend on define of BACDL_BIP:
* - BACNET_BBMD_PORT - 0..65534, defaults to 47808
* - BACNET_BBMD_TIMETOLIVE - 0..65535 seconds, defaults to 60000
* - BACNET_BBMD_ADDRESS - dotted IPv4 address
@@ -107,7 +107,7 @@ int dlenv_register_as_foreign_device(
void)
{
int retval = 0;
#if defined(BACDL_BIP) && BBMD_ENABLED
#if defined(BACDL_BIP)
char *pEnv = NULL;
pEnv = getenv("BACNET_BBMD_PORT");
@@ -152,12 +152,13 @@ int dlenv_register_as_foreign_device(
/** Datalink maintenance timer
* @ingroup DataLink
*
* Call this function to renew Foreign Device Registration
* Call this function to renew our Foreign Device Registration
* @param elapsed_seconds Number of seconds that have elapsed since last called.
*/
void dlenv_maintenance_timer(
uint16_t elapsed_seconds)
{
#if defined(BACDL_BIP) && BBMD_ENABLED
#if defined(BACDL_BIP)
if (BBMD_Timer_Seconds) {
if (BBMD_Timer_Seconds <= elapsed_seconds) {
BBMD_Timer_Seconds = 0;
@@ -167,10 +168,10 @@ void dlenv_maintenance_timer(
if (BBMD_Timer_Seconds == 0) {
int retval;
retval = dlenv_register_as_foreign_device();
/* If that failed, maybe just a network issue.
* Retry again later. */
if ( retval < 0 )
BBMD_Timer_Seconds = bbmd_timetolive_seconds;
/* If that failed (negative), maybe just a network issue.
* If nothing happened (0), may be un/misconfigured.
* Set up to try again later in all cases. */
BBMD_Timer_Seconds = bbmd_timetolive_seconds;
}
}
#endif
@@ -203,12 +204,11 @@ void dlenv_maintenance_timer(
* - BACDL_BIP: (BACnet/IP)
* - BACNET_IP_PORT - UDP/IP port number (0..65534) used for BACnet/IP
* communications. Default is 47808 (0xBAC0).
* - with BBMD_ENABLED also:
* - BACNET_BBMD_PORT - UDP/IP port number (0..65534) used for Foreign
* - BACNET_BBMD_PORT - UDP/IP port number (0..65534) used for Foreign
* Device Registration. Defaults to 47808 (0xBAC0).
* - BACNET_BBMD_TIMETOLIVE - number of seconds used in Foreign Device
* - BACNET_BBMD_TIMETOLIVE - number of seconds used in Foreign Device
* Registration (0..65535). Defaults to 60000 seconds.
* - BACNET_BBMD_ADDRESS - dotted IPv4 address of the BBMD or Foreign
* - BACNET_BBMD_ADDRESS - dotted IPv4 address of the BBMD or Foreign
* Device Registrar.
* - BACDL_MSTP: (BACnet MS/TP)
* - BACNET_MAX_INFO_FRAMES
+1
View File
@@ -229,6 +229,7 @@ int main(
/* blink LEDs, Turn on or off outputs, etc */
}
return 0;
}
/* @} */
+93 -57
View File
@@ -51,6 +51,18 @@
* Foreign Device Registration.
*/
/* if we are a foreign device, store the
remote BBMD address/port here in network byte order */
static struct sockaddr_in Remote_BBMD;
/* Define BBMD_ENABLED to get the functions that a
* BBMD needs to handle its services.
* Separately, define BBMD_CLIENT_ENABLED to get the
* functions that allow a client to manage a BBMD.
*/
#if defined(BBMD_ENABLED) && BBMD_ENABLED
typedef struct {
/* true if valid entry - false if not */
bool valid;
@@ -62,7 +74,9 @@ typedef struct {
struct in_addr broadcast_mask; /* in tework format */
} BBMD_TABLE_ENTRY;
#ifndef MAX_BBMD_ENTRIES
#define MAX_BBMD_ENTRIES 128
#endif
static BBMD_TABLE_ENTRY BBMD_Table[MAX_BBMD_ENTRIES];
/*Each device that registers as a foreign device shall be placed
@@ -86,17 +100,15 @@ typedef struct {
time_t seconds_remaining; /* includes 30 second grace period */
} FD_TABLE_ENTRY;
#ifndef MAX_FD_ENTRIES
#define MAX_FD_ENTRIES 128
#endif
static FD_TABLE_ENTRY FD_Table[MAX_FD_ENTRIES];
/* result from a client request */
BACNET_BVLC_RESULT BVLC_Result_Code = BVLC_RESULT_SUCCESSFUL_COMPLETION;
/* if we are a foreign device, store the
remote BBMD address/port here in network byte order */
static struct sockaddr_in Remote_BBMD;
#if defined(BBMD_ENABLED) && BBMD_ENABLED
void bvlc_maintenance_timer(
time_t seconds)
{
@@ -117,7 +129,6 @@ void bvlc_maintenance_timer(
}
}
}
#endif
/* copy the source internet address to the BACnet address */
/* FIXME: IPv6? */
@@ -209,6 +220,7 @@ static int bvlc_encode_bvlc_result(
return 6;
}
#endif
#if defined(BBMD_CLIENT_ENABLED) && BBMD_CLIENT_ENABLED
int bvlc_encode_write_bdt_init(
@@ -253,6 +265,8 @@ int bvlc_encode_read_bdt(
}
#endif
#if defined(BBMD_ENABLED) && BBMD_ENABLED
static int bvlc_encode_read_bdt_ack_init(
uint8_t * pdu,
unsigned entries)
@@ -336,26 +350,7 @@ static int bvlc_encode_forwarded_npdu(
return len;
}
static int bvlc_encode_register_foreign_device(
uint8_t * pdu,
uint16_t time_to_live_seconds)
{
int len = 0;
if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP;
pdu[1] = BVLC_REGISTER_FOREIGN_DEVICE;
/* The 2-octet BVLC Length field is the length, in octets,
of the entire BVLL message, including the two octets of the
length field itself, most significant octet first. */
encode_unsigned16(&pdu[2], 6);
encode_unsigned16(&pdu[4], time_to_live_seconds);
len = 6;
}
return len;
}
#endif
#if defined(BBMD_CLIENT_ENABLED) && BBMD_CLIENT_ENABLED
int bvlc_encode_read_fdt(
@@ -377,6 +372,8 @@ int bvlc_encode_read_fdt(
}
#endif
#if defined(BBMD_ENABLED) && BBMD_ENABLED
static int bvlc_encode_read_fdt_ack_init(
uint8_t * pdu,
unsigned entries)
@@ -436,6 +433,8 @@ static int bvlc_encode_read_fdt_ack(
return pdu_len;
}
#endif
#if defined(BBMD_CLIENT_ENABLED) && BBMD_CLIENT_ENABLED
int bvlc_encode_delete_fdt_entry(
@@ -518,6 +517,8 @@ int bvlc_encode_original_broadcast_npdu(
}
#endif
#if defined(BBMD_ENABLED) && BBMD_ENABLED
static bool bvlc_create_bdt(
uint8_t * npdu,
uint16_t npdu_length)
@@ -551,6 +552,7 @@ static bool bvlc_create_bdt(
return status;
}
/** Handle a foreign device registration. */
static bool bvlc_register_foreign_device(
struct sockaddr_in *sin, /* source address in network order */
uint16_t time_to_live)
@@ -614,7 +616,9 @@ static bool bvlc_delete_foreign_device(
}
return status;
}
#endif
/** The common send function for bvlc functions, using b/ip. */
static int bvlc_send_mpdu(
struct sockaddr_in *dest, /* the destination address */
uint8_t * mtu, /* the data */
@@ -636,6 +640,8 @@ static int bvlc_send_mpdu(
(struct sockaddr *) &bvlc_dest, sizeof(struct sockaddr));
}
#if defined(BBMD_ENABLED) && BBMD_ENABLED
static void bvlc_bdt_forward_npdu(
struct sockaddr_in *sin, /* source address in network order */
uint8_t * npdu, /* the NPDU */
@@ -734,38 +740,6 @@ static void bvlc_fdt_forward_npdu(
}
/** Register as a foreign device with the indicated BBMD.
* @param bbmd_address - IPv4 address (long) of BBMD to register with,
* in network byte order.
* @param bbmd_port - Network port of BBMD, in network byte order
* @param time_to_live_seconds - Lease time to use when registering.
* @return Positive number (of bytes sent) on success,
* 0 if no registration request is sent, or
* -1 if registration fails.
*/
int bvlc_register_with_bbmd(
uint32_t bbmd_address,
uint16_t bbmd_port,
uint16_t time_to_live_seconds)
{
uint8_t mtu[MAX_MPDU] = { 0 };
uint16_t mtu_len = 0;
int retval = 0;
/* Store the BBMD address and port so that we
won't broadcast locally. */
Remote_BBMD.sin_addr.s_addr = bbmd_address;
Remote_BBMD.sin_port = bbmd_port;
/* In order for their broadcasts to get here,
we need to register our address with the remote BBMD using
Write Broadcast Distribution Table, or
register with the BBMD as a Foreign Device */
mtu_len =
(uint16_t) bvlc_encode_register_foreign_device(&mtu[0],
time_to_live_seconds);
retval = bvlc_send_mpdu(&Remote_BBMD, &mtu[0], mtu_len);
return retval;
}
static void bvlc_send_result(
struct sockaddr_in *dest, /* the destination address */
@@ -1194,6 +1168,68 @@ int bvlc_send_pdu(
mtu_len += (uint16_t) pdu_len;
return bvlc_send_mpdu(&bvlc_dest, mtu, mtu_len);
}
#endif
/***********************************************
* Functions to register us as a foreign device.
********************************************* */
static int bvlc_encode_register_foreign_device(
uint8_t * pdu,
uint16_t time_to_live_seconds)
{
int len = 0;
if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP;
pdu[1] = BVLC_REGISTER_FOREIGN_DEVICE;
/* The 2-octet BVLC Length field is the length, in octets,
of the entire BVLL message, including the two octets of the
length field itself, most significant octet first. */
encode_unsigned16(&pdu[2], 6);
encode_unsigned16(&pdu[4], time_to_live_seconds);
len = 6;
}
return len;
}
/** Register as a foreign device with the indicated BBMD.
* @param bbmd_address - IPv4 address (long) of BBMD to register with,
* in network byte order.
* @param bbmd_port - Network port of BBMD, in network byte order
* @param time_to_live_seconds - Lease time to use when registering.
* @return Positive number (of bytes sent) on success,
* 0 if no registration request is sent, or
* -1 if registration fails.
*/
int bvlc_register_with_bbmd(
uint32_t bbmd_address,
uint16_t bbmd_port,
uint16_t time_to_live_seconds)
{
uint8_t mtu[MAX_MPDU] = { 0 };
uint16_t mtu_len = 0;
int retval = 0;
/* Store the BBMD address and port so that we
won't broadcast locally. */
Remote_BBMD.sin_addr.s_addr = bbmd_address;
Remote_BBMD.sin_port = bbmd_port;
/* In order for their broadcasts to get here,
we need to register our address with the remote BBMD using
Write Broadcast Distribution Table, or
register with the BBMD as a Foreign Device */
mtu_len =
(uint16_t) bvlc_encode_register_foreign_device(&mtu[0],
time_to_live_seconds);
retval = bvlc_send_mpdu(&Remote_BBMD, &mtu[0], mtu_len);
return retval;
}
#ifdef TEST
#include <assert.h>