From 23a00b7676d3f7cfef9a746ffc70a7c9b571caa5 Mon Sep 17 00:00:00 2001 From: skarg Date: Thu, 20 Apr 2006 21:13:53 +0000 Subject: [PATCH] adding BBMD support. --- bacnet-stack/bacenum.h | 10 +++++ bacnet-stack/bbmd.c | 97 +++++++++++++++++++++++++++++++++++++----- bacnet-stack/bip.c | 14 +++--- bacnet-stack/bip.h | 4 +- 4 files changed, 106 insertions(+), 19 deletions(-) diff --git a/bacnet-stack/bacenum.h b/bacnet-stack/bacenum.h index 9ba88a46..431395c7 100644 --- a/bacnet-stack/bacenum.h +++ b/bacnet-stack/bacenum.h @@ -901,6 +901,16 @@ typedef enum { MAX_BVLC_FUNCTION = 12 } BACNET_BVLC_FUNCTION; +typedef enum { + BVLC_RESULT_SUCCESSFUL_COMPLETION = 0x0000, + BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK = 0x0010, + BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK = 0x0020, + BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK = 0X0030, + BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK = 0x0040, + BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK = 0x0050, + BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK = 0x0060 +} BACNET_BVLC_RESULT; + /* Bit String Enumerations */ typedef enum { STATUS_FLAG_IN_ALARM = 0, diff --git a/bacnet-stack/bbmd.c b/bacnet-stack/bbmd.c index 0f616855..0ba83f94 100644 --- a/bacnet-stack/bbmd.c +++ b/bacnet-stack/bbmd.c @@ -40,36 +40,111 @@ /* Handle the BACnet Broadcast Management Device, Broadcast Distribution Table, and Foreign Device Registration */ + +int bbmd_encode_bvlc_result( + uint8_t *pdu, + BACNET_BVLC_RESULT result_code) +{ + if (pdu) { + pdu[0] = BVLL_TYPE_BACNET_IP; + pdu[1] = BVLC_RESULT; + /* 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], result_code); + } + + return 6; +} + +int bbmd_encode_write_bdt_init( + uint8_t *pdu, + unsigned entries) +{ + int len = 0; + + if (pdu) { + pdu[0] = BVLL_TYPE_BACNET_IP; + pdu[1] = BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE; + /* 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], 4 + entries * 10); + len = 4; + } + + return len; +} + +int bbmd_encode_write_bdt_entry( + uint8_t *pdu, + struct in_addr *address, + uint16_t port, + struct in_addr *mask) +{ + int len = 0; + + if (pdu) { + encode_unsigned32(&pdu[0], address->s_addr); + encode_unsigned16(&pdu[4], port); + encode_unsigned32(&pdu[6], mask->s_addr); + len = 10; + } + + return len; +} + +int bbmd_encode_read_bdt( + uint8_t *pdu) +) +{ + int len = 0; + + if (pdu) { + pdu[0] = BVLL_TYPE_BACNET_IP; + pdu[1] = BVLC_READ_BROADCAST_DISTRIBUTION_TABLE; + /* 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], 4); + len = 4; + } + + return len; +} void bbmd_handler(uint8_t *buf, int len, struct sockaddr_in *sin) { int function_type = 0; - if (buf[0] != 0x81) + if (buf[0] != BVLL_TYPE_BACNET_IP) return; function_type = buf[1]; switch (function_type) { - case 0: + case BVLC_RESULT: break; - case 1: + case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE: break; - case 2: + case BVLC_READ_BROADCAST_DISTRIBUTION_TABLE: break; - case 3: + case BVLC_READ_BROADCAST_DISTRIBUTION_TABLE_ACK: break; - case 4: + case BVLC_FORWARDED_NPDU: break; - case 5: + case BVLC_REGISTER_FOREIGN_DEVICE: break; - case 6: + case BVLC_READ_FOREIGN_DEVICE_TABLE: break; - case 7: + case BVLC_READ_FOREIGN_DEVICE_TABLE_ACK: break; - case 8: + case BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY: break; - case 9: + case BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: break; + case BVLC_ORIGINAL_BROADCAST_NPDU: + break; default: break; } diff --git a/bacnet-stack/bip.c b/bacnet-stack/bip.c index c0252682..801081af 100644 --- a/bacnet-stack/bip.c +++ b/bacnet-stack/bip.c @@ -144,11 +144,11 @@ static int bip_send(struct sockaddr_in *bip_dest, uint8_t * pdu, /* any d if (BIP_Socket < 0) return BIP_Socket; - mtu[0] = 0x81; /* BVLL for BACnet/IP */ + mtu[0] = BVLL_TYPE_BACNET_IP; if (bip_dest->sin_addr.s_addr == htonl(BIP_Broadcast_Address.s_addr)) - mtu[1] = 0x0B; /* Original-Broadcast-NPDU */ + mtu[1] = BVLC_ORIGINAL_BROADCAST_NPDU; else - mtu[1] = 0x0A; /* Original-Unicast-NPDU */ + mtu[1] = BVLC_ORIGINAL_UNICAST_NPDU; mtu_len = 2; mtu_len += encode_unsigned16(&mtu[mtu_len], @@ -246,10 +246,10 @@ uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */ return 0; /* the signature of a BACnet/IP packet */ - if (buf[0] != 0x81) + if (buf[0] != BVLL_TYPE_BACNET_IP) return 0; - /* Original-Broadcast-NPDU or Original-Unicast-NPDU */ - if ((buf[1] == 0x0B) || (buf[1] == 0x0A)) { + if ((buf[1] == BVLC_ORIGINAL_UNICAST_NPDU) || + (buf[1] == BVLC_ORIGINAL_BROADCAST_NPDU)) { /* ignore messages from me */ if (sin.sin_addr.s_addr == BIP_Address.s_addr) pdu_len = 0; @@ -274,7 +274,7 @@ uint16_t bip_receive(BACNET_ADDRESS * src, /* source address */ } } #ifdef BBMD_ENABLED - if (buf[1] <= 0x09) { + if (buf[1] < MAX_BVLC_FUNCTION) { bbmd_handler(&buf[0], received_bytes, &sin); } #endif diff --git a/bacnet-stack/bip.h b/bacnet-stack/bip.h index 28e29bef..5884ca7d 100644 --- a/bacnet-stack/bip.h +++ b/bacnet-stack/bip.h @@ -40,10 +40,12 @@ #include "bacdef.h" #include "net.h" -/* specific defines for Ethernet */ +/* specific defines for BACnet/IP over Ethernet */ #define MAX_HEADER (1 + 1 + 2) #define MAX_MPDU (MAX_HEADER+MAX_PDU) +#define BVLL_TYPE_BACNET_IP (0x81) + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */