Indented.

This commit is contained in:
skarg
2007-11-29 15:56:53 +00:00
parent c585241c03
commit 411d6c1b24
236 changed files with 17864 additions and 15724 deletions
+196 -203
View File
@@ -32,9 +32,9 @@
-------------------------------------------
####COPYRIGHTEND####*/
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include <time.h> /* for the standard bool type. */
#include <stdint.h> /* for standard integer types uint8_t etc. */
#include <stdbool.h> /* for the standard bool type. */
#include <time.h> /* for the standard bool type. */
#include "bacdcode.h"
#include "bacint.h"
#include "bvlc.h"
@@ -45,8 +45,7 @@
Broadcast Distribution Table, and
Foreign Device Registration */
typedef struct
{
typedef struct {
/* true if valid entry - false if not */
bool valid;
/* BACnet/IP address */
@@ -69,8 +68,7 @@ seconds remaining before the BBMD will purge the registrant's FDT
entry if no re-registration occurs. This value will be initialized
to the 2-octet Time-to-Live value supplied at the time of
registration.*/
typedef struct
{
typedef struct {
bool valid;
/* BACnet/IP address */
struct in_addr dest_address;
@@ -79,7 +77,7 @@ typedef struct
/* seconds for valid entry lifetime */
uint16_t time_to_live;
/* our counter */
time_t seconds_remaining; /* includes 30 second grace period */
time_t seconds_remaining; /* includes 30 second grace period */
} FD_TABLE_ENTRY;
#define MAX_FD_ENTRIES 128
@@ -88,7 +86,8 @@ static FD_TABLE_ENTRY FD_Table[MAX_FD_ENTRIES];
/* result from a client request */
BACNET_BVLC_RESULT BVLC_Result_Code = BVLC_RESULT_SUCCESSFUL_COMPLETION;
void bvlc_maintenance_timer(unsigned seconds)
void bvlc_maintenance_timer(
unsigned seconds)
{
unsigned i = 0;
@@ -109,8 +108,8 @@ void bvlc_maintenance_timer(unsigned seconds)
}
int bvlc_encode_bip_address(
uint8_t * pdu, /* buffer to store encoding */
struct in_addr *address, /* in host format */
uint8_t * pdu, /* buffer to store encoding */
struct in_addr *address, /* in host format */
uint16_t port)
{
int len = 0;
@@ -124,8 +123,8 @@ int bvlc_encode_bip_address(
}
int bvlc_decode_bip_address(
uint8_t * pdu, /* buffer to extract encoded address */
struct in_addr * address, /* in host format */
uint8_t * pdu, /* buffer to extract encoded address */
struct in_addr *address, /* in host format */
uint16_t * port)
{
int len = 0;
@@ -142,7 +141,8 @@ int bvlc_decode_bip_address(
}
/* used for both read and write entries */
int bvlc_encode_address_entry(uint8_t * pdu,
int bvlc_encode_address_entry(
uint8_t * pdu,
struct in_addr *address,
uint16_t port,
struct in_addr *mask)
@@ -234,7 +234,7 @@ int bvlc_encode_read_bdt_ack(
uint8_t * pdu,
uint16_t max_pdu)
{
int pdu_len = 0; /* return value */
int pdu_len = 0; /* return value */
int len = 0;
unsigned count = 0;
unsigned i;
@@ -244,20 +244,18 @@ int bvlc_encode_read_bdt_ack(
count++;
}
}
len = bvlc_encode_read_bdt_ack_init(&pdu[0],count);
len = bvlc_encode_read_bdt_ack_init(&pdu[0], count);
pdu_len += len;
for (i = 0; i < MAX_BBMD_ENTRIES; i++) {
if (BBMD_Table[i].valid) {
/* too much to send */
if ((pdu_len+10) > max_pdu) {
if ((pdu_len + 10) > max_pdu) {
pdu_len = 0;
break;
}
len = bvlc_encode_address_entry(
&pdu[pdu_len],
len = bvlc_encode_address_entry(&pdu[pdu_len],
&BBMD_Table[i].dest_address,
BBMD_Table[i].dest_port,
&BBMD_Table[i].broadcast_mask);
BBMD_Table[i].dest_port, &BBMD_Table[i].broadcast_mask);
pdu_len += len;
}
}
@@ -266,14 +264,15 @@ int bvlc_encode_read_bdt_ack(
}
int bvlc_encode_forwarded_npdu(uint8_t * pdu,
int bvlc_encode_forwarded_npdu(
uint8_t * pdu,
BACNET_ADDRESS * src,
uint8_t * npdu,
unsigned npdu_length)
{
int len = 0;
unsigned i; /* for loop counter */
unsigned i; /* for loop counter */
if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP;
@@ -296,7 +295,8 @@ int bvlc_encode_forwarded_npdu(uint8_t * pdu,
return len;
}
int bvlc_encode_register_foreign_device(uint8_t * pdu,
int bvlc_encode_register_foreign_device(
uint8_t * pdu,
uint16_t time_to_live_seconds)
{
int len = 0;
@@ -356,7 +356,7 @@ int bvlc_encode_read_fdt_ack(
uint8_t * pdu,
uint16_t max_pdu)
{
int pdu_len = 0; /* return value */
int pdu_len = 0; /* return value */
int len = 0;
unsigned count = 0;
unsigned i;
@@ -366,19 +366,17 @@ int bvlc_encode_read_fdt_ack(
count++;
}
}
len = bvlc_encode_read_fdt_ack_init(&pdu[0],count);
len = bvlc_encode_read_fdt_ack_init(&pdu[0], count);
pdu_len += len;
for (i = 0; i < MAX_FD_ENTRIES; i++) {
if (FD_Table[i].valid) {
/* too much to send */
if ((pdu_len+10) > max_pdu) {
if ((pdu_len + 10) > max_pdu) {
pdu_len = 0;
break;
}
len = bvlc_encode_bip_address(
&pdu[pdu_len],
&FD_Table[i].dest_address,
FD_Table[i].dest_port);
len = bvlc_encode_bip_address(&pdu[pdu_len],
&FD_Table[i].dest_address, FD_Table[i].dest_port);
pdu_len += len;
encode_unsigned16(&pdu[pdu_len], FD_Table[i].time_to_live);
pdu_len += len;
@@ -391,7 +389,8 @@ int bvlc_encode_read_fdt_ack(
}
int bvlc_encode_delete_fdt_entry(uint8_t * pdu,
int bvlc_encode_delete_fdt_entry(
uint8_t * pdu,
struct in_addr *address,
uint16_t port)
{
@@ -413,12 +412,13 @@ int bvlc_encode_delete_fdt_entry(uint8_t * pdu,
return len;
}
int bvlc_encode_distribute_broadcast_to_network(uint8_t * pdu,
int bvlc_encode_distribute_broadcast_to_network(
uint8_t * pdu,
uint8_t * npdu,
unsigned npdu_length)
{
int len = 0; /* return value */
unsigned i; /* for loop counter */
int len = 0; /* return value */
unsigned i; /* for loop counter */
if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP;
@@ -436,12 +436,13 @@ int bvlc_encode_distribute_broadcast_to_network(uint8_t * pdu,
return len;
}
int bvlc_encode_original_unicast_npdu(uint8_t * pdu,
int bvlc_encode_original_unicast_npdu(
uint8_t * pdu,
uint8_t * npdu,
unsigned npdu_length)
{
int len = 0; /* return value */
unsigned i = 0; /* loop counter */
int len = 0; /* return value */
unsigned i = 0; /* loop counter */
if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP;
@@ -460,12 +461,13 @@ int bvlc_encode_original_unicast_npdu(uint8_t * pdu,
}
int bvlc_encode_original_broadcast_npdu(uint8_t * pdu,
int bvlc_encode_original_broadcast_npdu(
uint8_t * pdu,
uint8_t * npdu,
unsigned npdu_length)
{
int len = 0; /* return value */
unsigned i = 0; /* loop counter */
int len = 0; /* return value */
unsigned i = 0; /* loop counter */
if (pdu) {
pdu[0] = BVLL_TYPE_BACNET_IP;
@@ -486,9 +488,9 @@ int bvlc_encode_original_broadcast_npdu(uint8_t * pdu,
/* copy the source internet address to the BACnet address */
/* FIXME: IPv6? */
void bvlc_internet_to_bacnet_address(
BACNET_ADDRESS * src, /* returns the BACnet source address */
BACNET_ADDRESS * src, /* returns the BACnet source address */
struct sockaddr_in *sin)
{ /* source internet address */
{ /* source internet address */
int len = 0;
uint32_t address;
uint16_t port;
@@ -510,9 +512,9 @@ void bvlc_internet_to_bacnet_address(
/* FIXME: IPv6? */
/* FIXME: is sockaddr_in host or network order? */
void bvlc_bacnet_to_internet_address(
struct sockaddr_in *sin, /* source internet address */
BACNET_ADDRESS * src) /* returns the BACnet source address */
{
struct sockaddr_in *sin, /* source internet address */
BACNET_ADDRESS * src)
{ /* returns the BACnet source address */
int len = 0;
uint32_t address;
uint16_t port;
@@ -520,7 +522,7 @@ void bvlc_bacnet_to_internet_address(
if (src && sin) {
if (src->mac_len == 6) {
len = decode_unsigned32(&src->mac[0], &address);
len += decode_unsigned16(&src->mac[4], &port );
len += decode_unsigned16(&src->mac[4], &port);
sin->sin_addr.s_addr = htonl(address);
sin->sin_port = htons(port);
}
@@ -567,16 +569,17 @@ bool bvlc_create_bdt(
}
bool bvlc_register_foreign_device(
struct sockaddr_in *sin, /* the source address */
uint16_t time_to_live) /* time in seconds */
{
struct sockaddr_in * sin, /* the source address */
uint16_t time_to_live)
{ /* time in seconds */
unsigned i = 0;
bool status = false;
/* am I here already? If so, update my time to live... */
for (i = 0; i < MAX_FD_ENTRIES; i++) {
if (FD_Table[i].valid) {
if ((FD_Table[i].dest_address.s_addr == ntohl(sin->sin_addr.s_addr)) &&
if ((FD_Table[i].dest_address.s_addr ==
ntohl(sin->sin_addr.s_addr)) &&
(FD_Table[i].dest_port == ntohs(sin->sin_port))) {
status = true;
FD_Table[i].time_to_live = time_to_live;
@@ -602,11 +605,12 @@ bool bvlc_register_foreign_device(
return status;
}
bool bvlc_delete_foreign_device(uint8_t * pdu)
bool bvlc_delete_foreign_device(
uint8_t * pdu)
{
struct sockaddr_in sin = {0}; /* the ip address */
uint16_t port = 0; /* the decoded port */
bool status = false; /* return value */
struct sockaddr_in sin = { 0 }; /* the ip address */
uint16_t port = 0; /* the decoded port */
bool status = false; /* return value */
unsigned i = 0;
bvlc_decode_bip_address(pdu, &sin.sin_addr, &port);
@@ -625,14 +629,14 @@ bool bvlc_delete_foreign_device(uint8_t * pdu)
}
void bvlc_bdt_forward_npdu(
struct sockaddr_in *sin, /* the source address */
uint8_t * npdu, /* the NPDU */
struct sockaddr_in *sin, /* the source address */
uint8_t * npdu, /* the NPDU */
uint16_t npdu_length)
{ /* length of the NPDU */
uint8_t mtu[MAX_MPDU] = {0};
{ /* length of the NPDU */
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
int bytes_sent = 0;
unsigned i = 0; /* loop counter */
unsigned i = 0; /* loop counter */
struct sockaddr_in bip_dest;
BACNET_ADDRESS src;
@@ -641,11 +645,7 @@ void bvlc_bdt_forward_npdu(
return;
}
bvlc_internet_to_bacnet_address(&src, sin);
mtu_len = bvlc_encode_forwarded_npdu(
&mtu[0],
&src,
npdu,
npdu_length);
mtu_len = bvlc_encode_forwarded_npdu(&mtu[0], &src, npdu, npdu_length);
/* load destination IP address */
bip_dest.sin_family = AF_INET;
/* loop through the BDT and send one to each entry, except us */
@@ -660,8 +660,8 @@ void bvlc_bdt_forward_npdu(
BBMD_Table[i].dest_address.s_addr));
bip_dest.sin_port = htons(BBMD_Table[i].dest_port);
/* don't send to my broadcast address and same port */
if ((bip_dest.sin_addr.s_addr == htonl(bip_get_broadcast_addr())) &&
(bip_dest.sin_port == htons(bip_get_port()))) {
if ((bip_dest.sin_addr.s_addr == htonl(bip_get_broadcast_addr()))
&& (bip_dest.sin_port == htons(bip_get_port()))) {
continue;
}
/* don't send to my ip address and same port */
@@ -672,8 +672,7 @@ void bvlc_bdt_forward_npdu(
/* Send the packet */
bytes_sent =
sendto(bip_socket(), (char *) mtu, mtu_len, 0,
(struct sockaddr *) &bip_dest,
sizeof(struct sockaddr));
(struct sockaddr *) &bip_dest, sizeof(struct sockaddr));
}
}
@@ -681,22 +680,22 @@ void bvlc_bdt_forward_npdu(
}
void bvlc_broadcast_forward_npdu(
struct sockaddr_in *sin, /* the source address */
uint8_t * npdu, /* returns the NPDU */
uint16_t npdu_len) /* amount of space available in the NPDU */
{
struct sockaddr_in *sin, /* the source address */
uint8_t * npdu, /* returns the NPDU */
uint16_t npdu_len)
{ /* amount of space available in the NPDU */
/* FIXME: write the code... */
}
void bvlc_fdt_forward_npdu(
struct sockaddr_in *sin, /* the source address */
uint8_t * npdu, /* returns the NPDU */
uint16_t max_npdu) /* amount of space available in the NPDU */
{
uint8_t mtu[MAX_MPDU] = {0};
struct sockaddr_in *sin, /* the source address */
uint8_t * npdu, /* returns the NPDU */
uint16_t max_npdu)
{ /* amount of space available in the NPDU */
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
int bytes_sent = 0;
unsigned i = 0; /* loop counter */
unsigned i = 0; /* loop counter */
struct sockaddr_in bvlc_dest;
BACNET_ADDRESS src;
@@ -705,24 +704,18 @@ void bvlc_fdt_forward_npdu(
return;
}
bvlc_internet_to_bacnet_address(&src, sin);
mtu_len = bvlc_encode_forwarded_npdu(
&mtu[0],
&src,
npdu,
max_npdu);
mtu_len = bvlc_encode_forwarded_npdu(&mtu[0], &src, npdu, max_npdu);
/* load destination IP address */
bvlc_dest.sin_family = AF_INET;
/* loop through the FDT and send one to each entry */
for (i = 0; i < MAX_FD_ENTRIES; i++) {
if (FD_Table[i].valid && FD_Table[i].seconds_remaining) {
bvlc_dest.sin_addr.s_addr =
htonl(FD_Table[i].dest_address.s_addr);
bvlc_dest.sin_addr.s_addr = htonl(FD_Table[i].dest_address.s_addr);
bvlc_dest.sin_port = htons(FD_Table[i].dest_port);
/* Send the packet */
bytes_sent =
sendto(bip_socket(), (char *) mtu, mtu_len, 0,
(struct sockaddr *) &bvlc_dest,
sizeof(struct sockaddr));
(struct sockaddr *) &bvlc_dest, sizeof(struct sockaddr));
}
}
@@ -730,10 +723,10 @@ void bvlc_fdt_forward_npdu(
}
void bvlc_send_mpdu(
struct sockaddr_in *dest, /* the destination address */
uint8_t * mtu, /* the data */
uint16_t mtu_len) /* amount of data to send */
{
struct sockaddr_in *dest, /* the destination address */
uint8_t * mtu, /* the data */
uint16_t mtu_len)
{ /* amount of data to send */
int bytes_sent = 0;
struct sockaddr_in bvlc_dest;
@@ -748,17 +741,16 @@ void bvlc_send_mpdu(
/* Send the packet */
bytes_sent =
sendto(bip_socket(), (char *) mtu, mtu_len, 0,
(struct sockaddr *) &bvlc_dest,
sizeof(struct sockaddr));
(struct sockaddr *) &bvlc_dest, sizeof(struct sockaddr));
return;
}
void bvlc_send_result(
struct sockaddr_in *dest, /* the destination address */
struct sockaddr_in *dest, /* the destination address */
BACNET_BVLC_RESULT result_code)
{
uint8_t mtu[MAX_MPDU] = {0};
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
mtu_len = bvlc_encode_bvlc_result(&mtu[0], result_code);
@@ -767,9 +759,10 @@ void bvlc_send_result(
return;
}
int bvlc_send_bdt(struct sockaddr_in *dest)
int bvlc_send_bdt(
struct sockaddr_in *dest)
{
uint8_t mtu[MAX_MPDU] = {0};
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
mtu_len = bvlc_encode_read_bdt_ack(&mtu[0], sizeof(mtu));
@@ -780,9 +773,10 @@ int bvlc_send_bdt(struct sockaddr_in *dest)
return mtu_len;
}
int bvlc_send_fdt(struct sockaddr_in *dest)
int bvlc_send_fdt(
struct sockaddr_in *dest)
{
uint8_t mtu[MAX_MPDU] = {0};
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
mtu_len = bvlc_encode_read_fdt_ack(&mtu[0], sizeof(mtu));
@@ -794,8 +788,8 @@ int bvlc_send_fdt(struct sockaddr_in *dest)
}
bool bvlc_broadcast_address_same(
struct sockaddr_in *sin) /* network order address */
{
struct sockaddr_in * sin)
{ /* network order address */
bool same = false;
if ((sin->sin_addr.s_addr == htonl(bip_get_broadcast_addr())) &&
@@ -809,12 +803,12 @@ bool bvlc_broadcast_address_same(
/* returns:
Number of bytes received, or 0 if none or timeout. */
uint16_t bvlc_receive(
BACNET_ADDRESS * src, /* returns the source address */
uint8_t * npdu, /* returns the NPDU */
uint16_t max_npdu, /* amount of space available in the NPDU */
unsigned timeout) /* number of milliseconds to wait for a packet */
{
uint16_t npdu_len = 0; /* return value */
BACNET_ADDRESS * src, /* returns the source address */
uint8_t * npdu, /* returns the NPDU */
uint16_t max_npdu, /* amount of space available in the NPDU */
unsigned timeout)
{ /* number of milliseconds to wait for a packet */
uint16_t npdu_len = 0; /* return value */
fd_set read_fds;
int max = 0;
struct timeval select_timeout;
@@ -824,7 +818,7 @@ uint16_t bvlc_receive(
int function_type = 0;
int received_bytes = 0;
uint16_t result_code = 0;
unsigned i =0;
unsigned i = 0;
bool status = false;
uint16_t time_to_live = 0;
@@ -839,7 +833,7 @@ uint16_t bvlc_receive(
if (timeout >= 1000) {
select_timeout.tv_sec = timeout / 1000;
select_timeout.tv_usec =
1000 * (timeout - select_timeout.tv_sec * 1000);
1000 * (timeout - select_timeout.tv_sec * 1000);
} else {
select_timeout.tv_sec = 0;
select_timeout.tv_usec = 1000 * timeout;
@@ -849,11 +843,9 @@ uint16_t bvlc_receive(
max = bip_socket();
/* see if there is a packet for us */
if (select(max + 1, &read_fds, NULL, NULL, &select_timeout) > 0) {
received_bytes = recvfrom(
bip_socket(),
received_bytes = recvfrom(bip_socket(),
(char *) &npdu[0],
max_npdu, 0,
(struct sockaddr *) &sin, &sin_len);
max_npdu, 0, (struct sockaddr *) &sin, &sin_len);
} else {
return 0;
}
@@ -877,40 +869,41 @@ uint16_t bvlc_receive(
switch (function_type) {
case BVLC_RESULT:
/* Upon receipt of a BVLC-Result message containing a result code
of X'0000' indicating the successful completion of the
registration, a foreign device shall start a timer with a value
equal to the Time-to-Live parameter of the preceding Register-
Foreign-Device message. At the expiration of the timer, the
foreign device shall re-register with the BBMD by sending a BVLL
Register-Foreign-Device message */
of X'0000' indicating the successful completion of the
registration, a foreign device shall start a timer with a value
equal to the Time-to-Live parameter of the preceding Register-
Foreign-Device message. At the expiration of the timer, the
foreign device shall re-register with the BBMD by sending a BVLL
Register-Foreign-Device message */
/* FIXME: clients may need this result */
(void) decode_unsigned16(&npdu[4], &result_code);
BVLC_Result_Code = result_code;
break;
case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE:
/* Upon receipt of a BVLL Write-Broadcast-Distribution-Table
message, a BBMD shall attempt to create or replace its BDT,
depending on whether or not a BDT has previously existed.
If the creation or replacement of the BDT is successful, the BBMD
shall return a BVLC-Result message to the originating device with
a result code of X'0000'. Otherwise, the BBMD shall return a
BVLC-Result message to the originating device with a result code
of X'0010' indicating that the write attempt has failed. */
status = bvlc_create_bdt(&npdu[4],npdu_len);
message, a BBMD shall attempt to create or replace its BDT,
depending on whether or not a BDT has previously existed.
If the creation or replacement of the BDT is successful, the BBMD
shall return a BVLC-Result message to the originating device with
a result code of X'0000'. Otherwise, the BBMD shall return a
BVLC-Result message to the originating device with a result code
of X'0010' indicating that the write attempt has failed. */
status = bvlc_create_bdt(&npdu[4], npdu_len);
if (status) {
bvlc_send_result(&sin, BVLC_RESULT_SUCCESSFUL_COMPLETION);
} else {
bvlc_send_result(&sin, BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK);
bvlc_send_result(&sin,
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK);
}
break;
case BVLC_READ_BROADCAST_DISTRIBUTION_TABLE:
/* Upon receipt of a BVLL Read-Broadcast-Distribution-Table
message, a BBMD shall load the contents of its BDT into a BVLL
Read-Broadcast-Distribution-Table-Ack message and send it to the
originating device. If the BBMD is unable to perform the
read of its BDT, it shall return a BVLC-Result message to the
originating device with a result code of X'0020' indicating that
the read attempt has failed.*/
message, a BBMD shall load the contents of its BDT into a BVLL
Read-Broadcast-Distribution-Table-Ack message and send it to the
originating device. If the BBMD is unable to perform the
read of its BDT, it shall return a BVLC-Result message to the
originating device with a result code of X'0020' indicating that
the read attempt has failed. */
if (bvlc_send_bdt(&sin) <= 0) {
bvlc_send_result(&sin,
BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK);
@@ -921,23 +914,23 @@ uint16_t bvlc_receive(
break;
case BVLC_FORWARDED_NPDU:
/* Upon receipt of a BVLL Forwarded-NPDU message, a BBMD shall
process it according to whether it was received from a peer
BBMD as the result of a directed broadcast or a unicast
transmission. A BBMD may ascertain the method by which Forwarded-
NPDU messages will arrive by inspecting the broadcast distribution
mask field in its own BDT entry since all BDTs are required
to be identical. If the message arrived via directed broadcast,
it was also received by the other devices on the BBMD's subnet. In
this case the BBMD merely retransmits the message directly to each
foreign device currently in the BBMD's FDT. If the
message arrived via a unicast transmission it has not yet been
received by the other devices on the BBMD's subnet. In this case,
the message is sent to the devices on the BBMD's subnet using the
B/IP broadcast address as well as to each foreign device
currently in the BBMD's FDT. A BBMD on a subnet with no other
BACnet devices may omit the broadcast using the B/IP
broadcast address. The method by which a BBMD determines whether
or not other BACnet devices are present is a local matter. */
process it according to whether it was received from a peer
BBMD as the result of a directed broadcast or a unicast
transmission. A BBMD may ascertain the method by which Forwarded-
NPDU messages will arrive by inspecting the broadcast distribution
mask field in its own BDT entry since all BDTs are required
to be identical. If the message arrived via directed broadcast,
it was also received by the other devices on the BBMD's subnet. In
this case the BBMD merely retransmits the message directly to each
foreign device currently in the BBMD's FDT. If the
message arrived via a unicast transmission it has not yet been
received by the other devices on the BBMD's subnet. In this case,
the message is sent to the devices on the BBMD's subnet using the
B/IP broadcast address as well as to each foreign device
currently in the BBMD's FDT. A BBMD on a subnet with no other
BACnet devices may omit the broadcast using the B/IP
broadcast address. The method by which a BBMD determines whether
or not other BACnet devices are present is a local matter. */
/* if this was received via Broadcast, don't broadcast it */
/* FIXME: how do I know if I received a unicast or broadcast? */
@@ -950,18 +943,17 @@ uint16_t bvlc_receive(
break;
case BVLC_REGISTER_FOREIGN_DEVICE:
/* Upon receipt of a BVLL Register-Foreign-Device message, a BBMD
shall start a timer with a value equal to the Time-to-Live
parameter supplied plus a fixed grace period of 30 seconds. If,
within the period during which the timer is active, another BVLL
Register-Foreign-Device message from the same device is received,
the timer shall be reset and restarted. If the time expires
without the receipt of another BVLL Register-Foreign-Device
message from the same foreign device, the FDT entry for this
device shall be cleared.*/
shall start a timer with a value equal to the Time-to-Live
parameter supplied plus a fixed grace period of 30 seconds. If,
within the period during which the timer is active, another BVLL
Register-Foreign-Device message from the same device is received,
the timer shall be reset and restarted. If the time expires
without the receipt of another BVLL Register-Foreign-Device
message from the same foreign device, the FDT entry for this
device shall be cleared. */
(void) decode_unsigned16(&npdu[4], &time_to_live);
if (bvlc_register_foreign_device(&sin, time_to_live)) {
bvlc_send_result(&sin,
BVLC_RESULT_SUCCESSFUL_COMPLETION);
bvlc_send_result(&sin, BVLC_RESULT_SUCCESSFUL_COMPLETION);
} else {
bvlc_send_result(&sin,
BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK);
@@ -969,12 +961,12 @@ uint16_t bvlc_receive(
break;
case BVLC_READ_FOREIGN_DEVICE_TABLE:
/* Upon receipt of a BVLL Read-Foreign-Device-Table message, a
BBMD shall load the contents of its FDT into a BVLL Read-
Foreign-Device-Table-Ack message and send it to the originating
device. If the BBMD is unable to perform the read of its FDT,
it shall return a BVLC-Result message to the originating device
with a result code of X'0040' indicating that the read attempt has
failed.*/
BBMD shall load the contents of its FDT into a BVLL Read-
Foreign-Device-Table-Ack message and send it to the originating
device. If the BBMD is unable to perform the read of its FDT,
it shall return a BVLC-Result message to the originating device
with a result code of X'0040' indicating that the read attempt has
failed. */
if (bvlc_send_fdt(&sin) <= 0) {
bvlc_send_result(&sin,
BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK);
@@ -985,16 +977,15 @@ uint16_t bvlc_receive(
break;
case BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY:
/* Upon receipt of a BVLL Delete-Foreign-Device-Table-Entry
message, a BBMD shall search its foreign device table for an entry
corresponding to the B/IP address supplied in the message. If an
entry is found, it shall be deleted and the BBMD shall return a
BVLC-Result message to the originating device with a result code
of X'0000'. Otherwise, the BBMD shall return a BVLCResult
message to the originating device with a result code of X'0050'
indicating that the deletion attempt has failed.*/
message, a BBMD shall search its foreign device table for an entry
corresponding to the B/IP address supplied in the message. If an
entry is found, it shall be deleted and the BBMD shall return a
BVLC-Result message to the originating device with a result code
of X'0000'. Otherwise, the BBMD shall return a BVLCResult
message to the originating device with a result code of X'0050'
indicating that the deletion attempt has failed. */
if (bvlc_delete_foreign_device(&npdu[4])) {
bvlc_send_result(&sin,
BVLC_RESULT_SUCCESSFUL_COMPLETION);
bvlc_send_result(&sin, BVLC_RESULT_SUCCESSFUL_COMPLETION);
} else {
bvlc_send_result(&sin,
BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK);
@@ -1002,17 +993,17 @@ uint16_t bvlc_receive(
break;
case BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK:
/* Upon receipt of a BVLL Distribute-Broadcast-To-Network message
from a foreign device, the receiving BBMD shall transmit a
BVLL Forwarded-NPDU message on its local IP subnet using the
local B/IP broadcast address as the destination address. In
addition, a Forwarded-NPDU message shall be sent to each entry
in its BDT as described above in the case of the receipt of a
BVLL Original-Broadcast-NPDU as well as directly to each foreign
device currently in the BBMD's FDT except the originating
node. If the BBMD is unable to perform the forwarding function,
it shall return a BVLC-Result message to the foreign device
with a result code of X'0060' indicating that the forwarding
attempt was unsuccessful*/
from a foreign device, the receiving BBMD shall transmit a
BVLL Forwarded-NPDU message on its local IP subnet using the
local B/IP broadcast address as the destination address. In
addition, a Forwarded-NPDU message shall be sent to each entry
in its BDT as described above in the case of the receipt of a
BVLL Original-Broadcast-NPDU as well as directly to each foreign
device currently in the BBMD's FDT except the originating
node. If the BBMD is unable to perform the forwarding function,
it shall return a BVLC-Result message to the foreign device
with a result code of X'0060' indicating that the forwarding
attempt was unsuccessful */
/* FIXME: complete the function code */
bvlc_broadcast_forward_npdu(&sin, &npdu[4], npdu_len);
bvlc_fdt_forward_npdu(&sin, &npdu[4], npdu_len);
@@ -1027,7 +1018,7 @@ uint16_t bvlc_receive(
if (npdu_len < max_npdu) {
/* shift the buffer to return a valid PDU */
for (i = 0; i < npdu_len; i++) {
npdu[i] = npdu[i+4];
npdu[i] = npdu[i + 4];
}
} else {
/* ignore packets that are too large */
@@ -1054,7 +1045,7 @@ uint16_t bvlc_receive(
if (npdu_len < max_npdu) {
/* shift the buffer to return a valid PDU */
for (i = 0; i < npdu_len; i++) {
npdu[i] = npdu[i+4];
npdu[i] = npdu[i + 4];
}
/* if BDT or FDT entries exist, Forward the NPDU */
bvlc_bdt_forward_npdu(&sin, &npdu[0], npdu_len);
@@ -1073,11 +1064,12 @@ uint16_t bvlc_receive(
/* function to send a packet out the BACnet/IP socket (Annex J) */
/* returns number of bytes sent on success, negative number on failure */
int bvlc_send_pdu(BACNET_ADDRESS * dest, /* destination address */
int bvlc_send_pdu(
BACNET_ADDRESS * dest, /* destination address */
BACNET_NPDU_DATA * npdu_data, /* network information */
uint8_t * pdu, /* any data to be sent - may be null */
uint8_t * pdu, /* any data to be sent - may be null */
unsigned pdu_len)
{ /* number of bytes of data */
{ /* number of bytes of data */
struct sockaddr_in bvlc_dest;
uint8_t mtu[MAX_MPDU] = { 0 };
int mtu_len = 0;
@@ -1129,7 +1121,8 @@ int bvlc_send_pdu(BACNET_ADDRESS * dest, /* destination address */
#include <string.h>
#include "ctest.h"
void testBIPAddress(Test * pTest)
void testBIPAddress(
Test * pTest)
{
uint8_t apdu[50] = { 0 };
uint32_t value = 0, test_value = 0;
@@ -1139,16 +1132,15 @@ void testBIPAddress(Test * pTest)
uint16_t port = 0, test_port = 0;
address.s_addr = 42;
len = bvlc_encode_bip_address(&apdu[0],
&address, port);
test_len = bvlc_decode_bip_address(&apdu[0],
&test_address, &test_port);
len = bvlc_encode_bip_address(&apdu[0], &address, port);
test_len = bvlc_decode_bip_address(&apdu[0], &test_address, &test_port);
ct_test(pTest, len == test_len);
ct_test(pTest, address.s_addr == test_address.s_addr);
ct_test(pTest, port == test_port);
}
void testInternetAddress(Test * pTest)
void testInternetAddress(
Test * pTest)
{
BACNET_ADDRESS src;
BACNET_ADDRESS test_src;
@@ -1164,9 +1156,10 @@ void testInternetAddress(Test * pTest)
}
#ifdef TEST_BVLC
int main(void)
int main(
void)
{
Test * pTest;
Test *pTest;
bool rc;
pTest = ct_create("BACnet Virtual Link Control", NULL);
@@ -1184,5 +1177,5 @@ int main(void)
return 0;
}
#endif /* TEST_BBMD */
#endif /* TEST */
#endif /* TEST_BBMD */
#endif /* TEST */