Indented.
This commit is contained in:
+196
-203
@@ -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 */
|
||||
|
||||
Reference in New Issue
Block a user