From 56f9492dcb90a5497c91b43d791c3c30da5ec697 Mon Sep 17 00:00:00 2001 From: skarg Date: Mon, 23 Jun 2008 00:19:17 +0000 Subject: [PATCH] Corrected BVLC module for Foreign Device registration. --- bacnet-stack/src/bvlc.c | 91 +++++++++++++++++++++++++++++++++++------ 1 file changed, 79 insertions(+), 12 deletions(-) diff --git a/bacnet-stack/src/bvlc.c b/bacnet-stack/src/bvlc.c index 5fd5049d..c3c0c435 100644 --- a/bacnet-stack/src/bvlc.c +++ b/bacnet-stack/src/bvlc.c @@ -34,12 +34,14 @@ #include /* for standard integer types uint8_t etc. */ #include /* for the standard bool type. */ -#include /* for the standard bool type. */ +#include #include "bacenum.h" #include "bacdcode.h" #include "bacint.h" #include "bvlc.h" #include "bip.h" +#define DEBUG_ENABLED 0 +#include "debug.h" /* Handle the BACnet Virtual Link Control (BVLC), which includes: BACnet Broadcast Management Device, @@ -89,7 +91,7 @@ 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) @@ -674,7 +676,7 @@ int bvlc_send_mpdu( } void bvlc_bdt_forward_npdu( - struct sockaddr_in *sin, /* the source address */ + struct sockaddr_in *sin, /* source address in network order */ uint8_t * npdu, /* the NPDU */ uint16_t npdu_length) { /* length of the NPDU */ @@ -707,13 +709,14 @@ void bvlc_bdt_forward_npdu( continue; } bytes_sent = bvlc_send_mpdu(&bip_dest, mtu, mtu_len); + debug_printf("BVLC: BDT Sent Forwarded NPDU [len=%d]\n", bytes_sent); } } return; } -void bvlc_broadcast_forward_npdu( +void bvlc_distribute_broadcast( struct sockaddr_in *sin, /* the source address */ uint8_t * npdu, /* returns the NPDU */ uint16_t npdu_len) @@ -736,10 +739,12 @@ void bvlc_broadcast_forward_npdu( memcpy(&mtu[mtu_len], npdu, npdu_len); mtu_len += npdu_len; bvlc_send_mpdu(&bvlc_dest, mtu, mtu_len); + debug_printf("BVLC: Distributed Broadcast [local network]\n"); } -void bvlc_fdt_forward_npdu( - struct sockaddr_in *sin, /* the source address */ +/* distribute it to everyone but the source */ +void bvlc_fdt_distrbute_broadcast( + struct sockaddr_in *sin, /* source address in network order */ uint8_t * npdu, /* returns the NPDU */ uint16_t max_npdu) { /* amount of space available in the NPDU */ @@ -747,15 +752,51 @@ void bvlc_fdt_forward_npdu( uint16_t mtu_len = 0; int bytes_sent = 0; unsigned i = 0; /* loop counter */ - struct sockaddr_in bvlc_dest; + struct sockaddr_in bip_dest; mtu_len = bvlc_encode_forwarded_npdu(&mtu[0], sin, npdu, max_npdu); /* 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_port = htons(FD_Table[i].dest_port); - bytes_sent = bvlc_send_mpdu(&bvlc_dest, mtu, mtu_len); + bip_dest.sin_addr.s_addr = htonl(FD_Table[i].dest_address.s_addr); + bip_dest.sin_port = htons(FD_Table[i].dest_port); + /* don't send to src ip address and same port */ + if ((bip_dest.sin_addr.s_addr == sin->sin_addr.s_addr) && + (bip_dest.sin_port == sin->sin_port)) { + continue; + } + bytes_sent = bvlc_send_mpdu(&bip_dest, mtu, mtu_len); + debug_printf("BVLC: FDT Distribute Broadcast [len=%d]\n", bytes_sent); + } + } + + return; +} + +void bvlc_fdt_forward_npdu( + struct sockaddr_in *sin, /* source address in network order */ + uint8_t * npdu, /* returns the NPDU */ + uint16_t max_npdu) +{ /* amount of space available in the NPDU */ + uint8_t mtu[MAX_MPDU] = { 0 }; + uint16_t mtu_len = 0; + int bytes_sent = 0; + unsigned i = 0; /* loop counter */ + struct sockaddr_in bip_dest; + + mtu_len = bvlc_encode_forwarded_npdu(&mtu[0], sin, npdu, max_npdu); + /* 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) { + bip_dest.sin_addr.s_addr = htonl(FD_Table[i].dest_address.s_addr); + bip_dest.sin_port = htons(FD_Table[i].dest_port); + /* don't send to my ip address and same port */ + if ((bip_dest.sin_addr.s_addr == htonl(bip_get_addr())) && + (bip_dest.sin_port == htons(bip_get_port()))) { + continue; + } + bytes_sent = bvlc_send_mpdu(&bip_dest, mtu, mtu_len); + debug_printf("BVLC: FDT Sent Forwarded NPDU [len=%d]\n", bytes_sent); } } @@ -914,6 +955,9 @@ uint16_t bvlc_receive( /* FIXME: clients may need this result */ (void) decode_unsigned16(&npdu[4], &result_code); BVLC_Result_Code = result_code; + debug_printf("BVLC: Result Code=%d\n",BVLC_Result_Code); + /* not an NPDU */ + npdu_len = 0; break; case BVLC_WRITE_BROADCAST_DISTRIBUTION_TABLE: /* Upon receipt of a BVLL Write-Broadcast-Distribution-Table @@ -931,6 +975,8 @@ uint16_t bvlc_receive( bvlc_send_result(&sin, BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK); } + /* not an NPDU */ + npdu_len = 0; break; case BVLC_READ_BROADCAST_DIST_TABLE: /* Upon receipt of a BVLL Read-Broadcast-Distribution-Table @@ -944,9 +990,13 @@ uint16_t bvlc_receive( bvlc_send_result(&sin, BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK); } + /* not an NPDU */ + npdu_len = 0; break; case BVLC_READ_BROADCAST_DIST_TABLE_ACK: /* FIXME: complete the code for client side read */ + /* not an NPDU */ + npdu_len = 0; break; case BVLC_FORWARDED_NPDU: /* Upon receipt of a BVLL Forwarded-NPDU message, a BBMD shall @@ -992,6 +1042,7 @@ uint16_t bvlc_receive( /* clients should check my max-apdu first */ npdu_len = 0; } + debug_printf("BVLC: Forwarded NPDU Received [len=%u].\n",npdu_len); break; case BVLC_REGISTER_FOREIGN_DEVICE: /* Upon receipt of a BVLL Register-Foreign-Device message, a BBMD @@ -1006,10 +1057,14 @@ uint16_t bvlc_receive( (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); + debug_printf("BVLC: Registered a Foreign Device.\n"); } else { bvlc_send_result(&sin, BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK); + debug_printf("BVLC: Failed to Register a Foreign Device.\n"); } + /* not an NPDU */ + npdu_len = 0; break; case BVLC_READ_FOREIGN_DEVICE_TABLE: /* Upon receipt of a BVLL Read-Foreign-Device-Table message, a @@ -1023,9 +1078,13 @@ uint16_t bvlc_receive( bvlc_send_result(&sin, BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK); } + /* not an NPDU */ + npdu_len = 0; break; case BVLC_READ_FOREIGN_DEVICE_TABLE_ACK: /* FIXME: complete the code for client side read */ + /* not an NPDU */ + npdu_len = 0; break; case BVLC_DELETE_FOREIGN_DEVICE_TABLE_ENTRY: /* Upon receipt of a BVLL Delete-Foreign-Device-Table-Entry @@ -1042,8 +1101,11 @@ uint16_t bvlc_receive( bvlc_send_result(&sin, BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK); } + /* not an NPDU */ + npdu_len = 0; break; case BVLC_DISTRIBUTE_BROADCAST_TO_NETWORK: + debug_printf("BVLC: Received Distribute Broadcast to Network.\n"); /* 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 @@ -1056,10 +1118,14 @@ uint16_t bvlc_receive( 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 */ - bvlc_broadcast_forward_npdu(&sin, &npdu[4], npdu_len); - bvlc_fdt_forward_npdu(&sin, &npdu[4], npdu_len); + bvlc_distribute_broadcast(&sin, &npdu[4], npdu_len); + bvlc_bdt_forward_npdu(&sin, &npdu[4], npdu_len); + bvlc_fdt_distrbute_broadcast(&sin, &npdu[4], npdu_len); + /* not an NPDU */ + npdu_len = 0; break; case BVLC_ORIGINAL_UNICAST_NPDU: + debug_printf("BVLC: Original Unicast NPDU.\n"); /* ignore messages from me */ if ((sin.sin_addr.s_addr == htonl(bip_get_addr())) && (sin.sin_port == htons(bip_get_port()))) { @@ -1079,6 +1145,7 @@ uint16_t bvlc_receive( } break; case BVLC_ORIGINAL_BROADCAST_NPDU: + debug_printf("BVLC: Original Broadcast NPDU.\n"); /* Upon receipt of a BVLL Original-Broadcast-NPDU message, a BBMD shall construct a BVLL Forwarded-NPDU message and send it to each IP subnet in its BDT with the exception