Discard confirmed APDU from original broadcast in BIP and BIP6 datalink (#149)
Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
@@ -37,6 +37,7 @@
|
|||||||
#include <stdbool.h> /* for the standard bool type. */
|
#include <stdbool.h> /* for the standard bool type. */
|
||||||
#include <string.h> /* for memcpy */
|
#include <string.h> /* for memcpy */
|
||||||
#include "bacnet/bacdcode.h"
|
#include "bacnet/bacdcode.h"
|
||||||
|
#include "bacnet/npdu.h"
|
||||||
#include "bacnet/datalink/bip.h"
|
#include "bacnet/datalink/bip.h"
|
||||||
#include "bacnet/datalink/bvlc.h"
|
#include "bacnet/datalink/bvlc.h"
|
||||||
#include "bacnet/basic/sys/debug.h"
|
#include "bacnet/basic/sys/debug.h"
|
||||||
@@ -663,6 +664,7 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
int function_len = 0;
|
int function_len = 0;
|
||||||
uint8_t *pdu = NULL;
|
uint8_t *pdu = NULL;
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
|
uint8_t *npdu = NULL;
|
||||||
uint16_t npdu_len = 0;
|
uint16_t npdu_len = 0;
|
||||||
bool send_result = false;
|
bool send_result = false;
|
||||||
uint16_t offset = 0;
|
uint16_t offset = 0;
|
||||||
@@ -765,8 +767,20 @@ int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
if (function_len) {
|
if (function_len) {
|
||||||
bvlc_ip_address_to_bacnet_local(src, addr);
|
bvlc_ip_address_to_bacnet_local(src, addr);
|
||||||
offset = header_len + function_len - npdu_len;
|
offset = header_len + function_len - npdu_len;
|
||||||
debug_print_npdu(
|
/* BTL test: verifies that the IUT will quietly discard any
|
||||||
"Original-Broadcast-NPDU", offset, npdu_len);
|
Confirmed-Request-PDU, whose destination address is a
|
||||||
|
multicast or broadcast address, received from the
|
||||||
|
network layer. */
|
||||||
|
npdu = &mtu[offset];
|
||||||
|
if (npdu_confirmed_service(npdu, npdu_len)) {
|
||||||
|
offset = 0;
|
||||||
|
debug_print_string(
|
||||||
|
"Original-Broadcast-NPDU: "
|
||||||
|
"Confirmed Service! Discard!");
|
||||||
|
} else {
|
||||||
|
debug_print_npdu(
|
||||||
|
"Original-Broadcast-NPDU", offset, npdu_len);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debug_print_string(
|
debug_print_string(
|
||||||
"Original-Broadcast-NPDU: Unable to decode!");
|
"Original-Broadcast-NPDU: Unable to decode!");
|
||||||
@@ -1075,9 +1089,21 @@ int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
|
|||||||
shall be sent directly to each foreign device currently in
|
shall be sent directly to each foreign device currently in
|
||||||
the BBMD's FDT also using the BVLL Forwarded-NPDU message. */
|
the BBMD's FDT also using the BVLL Forwarded-NPDU message. */
|
||||||
npdu = &mtu[offset];
|
npdu = &mtu[offset];
|
||||||
bbmd_fdt_forward_npdu(addr, npdu, npdu_len, true);
|
/* BTL test: verifies that the IUT will quietly discard any
|
||||||
bbmd_bdt_forward_npdu(addr, npdu, npdu_len, true);
|
Confirmed-Request-PDU, whose destination address is a
|
||||||
debug_print_npdu("Original-Broadcast-NPDU", offset, npdu_len);
|
multicast or broadcast address, received from the
|
||||||
|
network layer. */
|
||||||
|
if (npdu_confirmed_service(npdu, npdu_len)) {
|
||||||
|
offset = 0;
|
||||||
|
debug_print_string(
|
||||||
|
"Original-Broadcast-NPDU: "
|
||||||
|
"Confirmed Service! Discard!");
|
||||||
|
} else {
|
||||||
|
bbmd_fdt_forward_npdu(addr, npdu, npdu_len, true);
|
||||||
|
bbmd_bdt_forward_npdu(addr, npdu, npdu_len, true);
|
||||||
|
debug_print_npdu("Original-Broadcast-NPDU",
|
||||||
|
offset, npdu_len);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debug_print_string(
|
debug_print_string(
|
||||||
"Original-Broadcast-NPDU: Unable to decode!");
|
"Original-Broadcast-NPDU: Unable to decode!");
|
||||||
|
|||||||
@@ -615,6 +615,7 @@ int bvlc6_bbmd_disabled_handler(BACNET_IP6_ADDRESS *addr,
|
|||||||
int function_len = 0;
|
int function_len = 0;
|
||||||
uint8_t *pdu = NULL;
|
uint8_t *pdu = NULL;
|
||||||
uint16_t pdu_len = 0;
|
uint16_t pdu_len = 0;
|
||||||
|
uint8_t *npdu = NULL;
|
||||||
uint16_t npdu_len = 0;
|
uint16_t npdu_len = 0;
|
||||||
bool send_result = false;
|
bool send_result = false;
|
||||||
uint16_t offset = 0;
|
uint16_t offset = 0;
|
||||||
@@ -696,6 +697,18 @@ int bvlc6_bbmd_disabled_handler(BACNET_IP6_ADDRESS *addr,
|
|||||||
bbmd6_add_vmac(vmac_src, addr);
|
bbmd6_add_vmac(vmac_src, addr);
|
||||||
bvlc6_vmac_address_set(src, vmac_src);
|
bvlc6_vmac_address_set(src, vmac_src);
|
||||||
offset = header_len + (function_len - npdu_len);
|
offset = header_len + (function_len - npdu_len);
|
||||||
|
/* BTL test: verifies that the IUT will quietly
|
||||||
|
discard any Confirmed-Request-PDU, whose
|
||||||
|
destination address is a multicast or
|
||||||
|
broadcast address, received from the
|
||||||
|
network layer. */
|
||||||
|
npdu = &mtu[offset];
|
||||||
|
if (npdu_confirmed_service(npdu, npdu_len)) {
|
||||||
|
offset = 0;
|
||||||
|
debug_printf(
|
||||||
|
"BIP6: Original-Broadcast-NPDU: "
|
||||||
|
"Confirmed Service! Discard!");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
debug_printf("BIP6: Original-Broadcast-NPDU: Unable to "
|
debug_printf("BIP6: Original-Broadcast-NPDU: Unable to "
|
||||||
"decode!\n");
|
"decode!\n");
|
||||||
@@ -853,18 +866,30 @@ int bvlc6_bbmd_enabled_handler(BACNET_IP6_ADDRESS *addr,
|
|||||||
if (function_len) {
|
if (function_len) {
|
||||||
offset = header_len + (function_len - npdu_len);
|
offset = header_len + (function_len - npdu_len);
|
||||||
npdu = &mtu[offset];
|
npdu = &mtu[offset];
|
||||||
/* Upon receipt of a BVLL Original-Broadcast-NPDU
|
/* BTL test: verifies that the IUT will quietly
|
||||||
message from the local multicast domain, a BBMD
|
discard any Confirmed-Request-PDU, whose
|
||||||
shall construct a BVLL Forwarded-NPDU message and
|
destination address is a multicast or
|
||||||
unicast it to each entry in its BDT. In addition,
|
broadcast address, received from the
|
||||||
the constructed BVLL Forwarded-NPDU message shall
|
network layer. */
|
||||||
be unicast to each foreign device currently in
|
if (npdu_confirmed_service(npdu, npdu_len)) {
|
||||||
the BBMD's FDT */
|
offset = 0;
|
||||||
BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu(
|
debug_printf(
|
||||||
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src, addr,
|
"BIP6: Original-Broadcast-NPDU: "
|
||||||
npdu, npdu_len);
|
"Confirmed Service! Discard!");
|
||||||
bbmd6_send_pdu_bdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len);
|
} else {
|
||||||
bbmd6_send_pdu_fdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len);
|
/* Upon receipt of a BVLL Original-Broadcast-NPDU
|
||||||
|
message from the local multicast domain, a BBMD
|
||||||
|
shall construct a BVLL Forwarded-NPDU message and
|
||||||
|
unicast it to each entry in its BDT. In addition,
|
||||||
|
the constructed BVLL Forwarded-NPDU message shall
|
||||||
|
be unicast to each foreign device currently in
|
||||||
|
the BBMD's FDT */
|
||||||
|
BVLC6_Buffer_Len = bvlc6_encode_forwarded_npdu(
|
||||||
|
&BVLC6_Buffer[0], sizeof(BVLC6_Buffer), vmac_src,
|
||||||
|
addr, npdu, npdu_len);
|
||||||
|
bbmd6_send_pdu_bdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len);
|
||||||
|
bbmd6_send_pdu_fdt(&BVLC6_Buffer[0], BVLC6_Buffer_Len);
|
||||||
|
}
|
||||||
if (!bbmd6_address_match_self(addr)) {
|
if (!bbmd6_address_match_self(addr)) {
|
||||||
/* The Virtual MAC address table shall be updated
|
/* The Virtual MAC address table shall be updated
|
||||||
using the respective parameter values of the
|
using the respective parameter values of the
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ void routed_get_my_address(
|
|||||||
#elif defined(BACDL_BIP6)
|
#elif defined(BACDL_BIP6)
|
||||||
#include "bacnet/datalink/bip6.h"
|
#include "bacnet/datalink/bip6.h"
|
||||||
#include "bacnet/datalink/bvlc6.h"
|
#include "bacnet/datalink/bvlc6.h"
|
||||||
|
#include "bacnet/basic/bbmd6/h_bbmd6.h"
|
||||||
#define datalink_init bip6_init
|
#define datalink_init bip6_init
|
||||||
#define datalink_send_pdu bip6_send_pdu
|
#define datalink_send_pdu bip6_send_pdu
|
||||||
#define datalink_receive bip6_receive
|
#define datalink_receive bip6_receive
|
||||||
|
|||||||
@@ -501,6 +501,38 @@ int bacnet_npdu_decode(uint8_t *npdu,
|
|||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Helper for datalink detecting an application confirmed service
|
||||||
|
* @param pdu [in] Buffer containing the NPDU and APDU of the received packet.
|
||||||
|
* @param pdu_len [in] The size of the received message in the pdu[] buffer.
|
||||||
|
* @return true if the PDU is a confirmed APDU
|
||||||
|
*/
|
||||||
|
bool npdu_confirmed_service(
|
||||||
|
uint8_t *pdu,
|
||||||
|
uint16_t pdu_len)
|
||||||
|
{
|
||||||
|
bool status = false;
|
||||||
|
int apdu_offset = 0;
|
||||||
|
BACNET_NPDU_DATA npdu_data = { 0 };
|
||||||
|
|
||||||
|
if (pdu_len > 0) {
|
||||||
|
if (pdu[0] == BACNET_PROTOCOL_VERSION) {
|
||||||
|
/* only handle the version that we know how to handle */
|
||||||
|
apdu_offset =
|
||||||
|
bacnet_npdu_decode(&pdu[0], pdu_len, NULL, NULL, &npdu_data);
|
||||||
|
if ((!npdu_data.network_layer_message) && (apdu_offset > 0) &&
|
||||||
|
(apdu_offset < pdu_len)) {
|
||||||
|
if ((pdu[apdu_offset] & 0xF0) ==
|
||||||
|
PDU_TYPE_CONFIRMED_SERVICE_REQUEST) {
|
||||||
|
status = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef BAC_TEST
|
#ifdef BAC_TEST
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|||||||
@@ -103,6 +103,11 @@ extern "C" {
|
|||||||
BACNET_ADDRESS * src,
|
BACNET_ADDRESS * src,
|
||||||
BACNET_NPDU_DATA * npdu_data);
|
BACNET_NPDU_DATA * npdu_data);
|
||||||
|
|
||||||
|
BACNET_STACK_EXPORT
|
||||||
|
bool npdu_confirmed_service(
|
||||||
|
uint8_t *pdu,
|
||||||
|
uint16_t pdu_len);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif /* __cplusplus */
|
#endif /* __cplusplus */
|
||||||
|
|||||||
Reference in New Issue
Block a user