Feature/add bbmd unit tests (#65)

* Added som BBMD IPv4 and IPv6 unit tests

Co-authored-by: Steve Karg <skarg@users.sourceforge.net>
This commit is contained in:
Steve Karg
2020-04-11 22:58:07 -05:00
committed by GitHub
parent eedfa58a55
commit d7918bb2ea
11 changed files with 715 additions and 296 deletions
+4 -144
View File
@@ -639,7 +639,6 @@ static int bvlc_send_result(BACNET_IP_ADDRESS *dest_addr, uint16_t result_code)
return bip_send_mpdu(dest_addr, mtu, mtu_len);
}
#if ((!BBMD_ENABLED) || (TEST))
/**
* Use this handler when you are not a BBMD.
* Sets the BVLC_Function_Code in case it is needed later.
@@ -651,7 +650,7 @@ static int bvlc_send_result(BACNET_IP_ADDRESS *dest_addr, uint16_t result_code)
*
* @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/
static int handler_bbmd_for_non_bbmd(BACNET_IP_ADDRESS *addr,
int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len)
@@ -785,7 +784,6 @@ static int handler_bbmd_for_non_bbmd(BACNET_IP_ADDRESS *addr,
return offset;
}
#endif
#if BBMD_ENABLED
/**
@@ -799,7 +797,7 @@ static int handler_bbmd_for_non_bbmd(BACNET_IP_ADDRESS *addr,
*
* @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/
static int handler_bbmd_for_bbmd(BACNET_IP_ADDRESS *addr,
int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len)
@@ -1111,10 +1109,10 @@ int bvlc_handler(BACNET_IP_ADDRESS *addr,
{
#if BBMD_ENABLED
debug_print_bip("Received BVLC (BBMD Enabled)", addr);
return handler_bbmd_for_bbmd(addr, src, npdu, npdu_len);
return bvlc_bbmd_enabled_handler(addr, src, npdu, npdu_len);
#else
debug_print_bip("Received BVLC (BBMD Disabled)", addr);
return handler_bbmd_for_non_bbmd(addr, src, npdu, npdu_len);
return bvlc_bbmd_disabled_handler(addr, src, npdu, npdu_len);
#endif
}
@@ -1254,141 +1252,3 @@ void bvlc_init(void)
bvlc_foreign_device_table_link_array(&FD_Table[0], MAX_FD_ENTRIES);
#endif
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
static uint32_t Device_ID = 0;
static BACNET_IP_ADDRESS BIP_Addr;
static BACNET_IP_ADDRESS BIP_Broadcast_Addr;
/* network stub functions */
/**
* BACnet/IP Datalink Receive handler.
*
* @param src - returns the source address
* @param npdu - returns the NPDU buffer
* @param max_npdu -maximum size of the NPDU buffer
* @param timeout - number of milliseconds to wait for a packet
*
* @return Number of bytes received, or 0 if none or timeout.
*/
uint16_t bip_receive(
BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout)
{
return 0;
}
/**
* The send function for BACnet/IPv4 driver layer
*
* @param dest - Points to a BACNET_IP_ADDRESS structure containing the
* destination address.
* @param mtu - the bytes of data to send
* @param mtu_len - the number of bytes of data to send
*
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
int bip_send_mpdu(BACNET_IP_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
{
return 0;
}
/** Return the Object Instance number for our (single) Device Object.
* This is a key function, widely invoked by the handler code, since
* it provides "our" (ie, local) address.
*
* @return The Instance number used in the BACNET_OBJECT_ID for the Device.
*/
uint32_t Device_Object_Instance_Number(void)
{
return Device_ID;
}
/**
* Get the BACnet/IP address
*
* @return BACnet/IP address
*/
bool bip_get_addr(BACNET_IP_ADDRESS *addr)
{
return bvlc_address_copy(addr, &BIP_Addr);
}
/**
* Get the BACnet/IP address
*
* @return BACnet/IP address
*/
bool bip_get_broadcast_addr(BACNET_IP_ADDRESS *addr)
{
return bvlc_address_copy(addr, &BIP_Broadcast_Addr);
}
static void test_BBMD_Result(Test *pTest)
{
int result = 0;
uint16_t result_code[] = { BVLC_RESULT_SUCCESSFUL_COMPLETION,
BVLC_RESULT_WRITE_BROADCAST_DISTRIBUTION_TABLE_NAK,
BVLC_RESULT_READ_BROADCAST_DISTRIBUTION_TABLE_NAK,
BVLC_RESULT_REGISTER_FOREIGN_DEVICE_NAK,
BVLC_RESULT_READ_FOREIGN_DEVICE_TABLE_NAK,
BVLC_RESULT_DELETE_FOREIGN_DEVICE_TABLE_ENTRY_NAK,
BVLC_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK };
size_t result_code_max = sizeof(result_code) / sizeof(result_code[0]);
uint16_t test_result_code = 0;
uint8_t test_function_code = 0;
BACNET_IP_ADDRESS addr;
BACNET_ADDRESS src;
unsigned int i = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
uint16_t mtu_len = 0;
bvlc_address_port_from_ascii(&addr, "192.168.0.1", "0xBAC0");
for (i = 0; i < result_code_max; i++) {
mtu_len = bvlc_encode_result(&mtu[0], sizeof(mtu), result_code[i]);
result = handler_bbmd_for_non_bbmd(&addr, &src, &mtu[0], mtu_len);
/* validate that the result is handled (0) */
ct_test(pTest, result == 0);
test_result_code = bvlc_get_last_result();
ct_test(pTest, test_result_code == result_code[i]);
test_function_code = bvlc_get_function_code();
ct_test(pTest, test_function_code == BVLC_RESULT);
result = handler_bbmd_for_bbmd(&addr, &src, &mtu[0], mtu_len);
/* validate that the result is handled (0) */
ct_test(pTest, result == 0);
test_result_code = bvlc_get_last_result();
ct_test(pTest, test_result_code == result_code[i]);
test_function_code = bvlc_get_function_code();
ct_test(pTest, test_function_code == BVLC_RESULT);
}
}
static void test_BBMD_Handler(Test *pTest)
{
bool rc;
/* individual tests */
rc = ct_addTestFunction(pTest, test_BBMD_Result);
assert(rc);
}
#ifdef TEST_BBMD_HANDLER
int main(void)
{
Test *pTest;
pTest = ct_create("BACnet Broadcast Management Device Handler", NULL);
test_BBMD_Handler(pTest);
/* configure output */
ct_setStream(pTest, stdout);
ct_run(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif
#endif
+13
View File
@@ -47,6 +47,19 @@ int bvlc_handler(BACNET_IP_ADDRESS *addr,
uint8_t *npdu,
uint16_t npdu_len);
BACNET_STACK_EXPORT
int bvlc_bbmd_enabled_handler(BACNET_IP_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len);
BACNET_STACK_EXPORT
int bvlc_bbmd_disabled_handler(BACNET_IP_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len);
BACNET_STACK_EXPORT
int bvlc_send_pdu(BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data,
-47
View File
@@ -1,47 +0,0 @@
#Makefile to build test case
CC = gcc
SRC_DIR = ../../../../src
TEST_DIR = ../../../../test
INCLUDES = -I$(SRC_DIR) -I$(TEST_DIR)
DEFINES = -DBIG_ENDIAN=0 -DBACDL_BIP -DBBMD_ENABLED=1 -DTEST -DTEST_BBMD_HANDLER
CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g
SRCS = $(SRC_DIR)/bacnet/basic/bbmd/h_bbmd.c \
$(SRC_DIR)/bacnet/bacdcode.c \
$(SRC_DIR)/bacnet/bacint.c \
$(SRC_DIR)/bacnet/bacstr.c \
$(SRC_DIR)/bacnet/bacreal.c \
$(SRC_DIR)/bacnet/datalink/bvlc.c \
$(SRC_DIR)/bacnet/basic/sys/debug.c \
$(TEST_DIR)/ctest.c
TARGET_NAME = bbmd
ifeq ($(OS),Windows_NT)
TARGET_EXT = .exe
else
TARGET_EXT =
endif
TARGET = $(TARGET_NAME)$(TARGET_EXT)
all: ${TARGET}
OBJS = ${SRCS:.c=.o}
${TARGET}: ${OBJS}
${CC} -o $@ ${OBJS}
.c.o:
${CC} -c ${CFLAGS} $*.c -o $@
depend:
rm -f .depend
${CC} -MM ${CFLAGS} *.c >> .depend
clean:
rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini
test: ${TARGET}
./${TARGET}
include: .depend
+22 -143
View File
@@ -42,9 +42,6 @@
#include "bacnet/basic/sys/debug.h"
#include "bacnet/basic/object/device.h"
#include "bacnet/basic/bbmd6/vmac.h"
#ifndef TEST
#include "bacport.h"
#endif
/** result from a client request */
static uint16_t BVLC6_Result_Code = BVLC6_RESULT_SUCCESSFUL_COMPLETION;
@@ -603,7 +600,7 @@ static void bbmd6_address_resolution_ack_handler(
*
* @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/
static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr,
int bvlc6_bbmd_disabled_handler(BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len)
@@ -770,7 +767,7 @@ static int handler_bbmd6_for_non_bbmd(BACNET_IP6_ADDRESS *addr,
*
* @return number of bytes offset into the NPDU for APDU, or 0 if handled
*/
static int handler_bbmd6_for_bbmd(BACNET_IP6_ADDRESS *addr,
int bvlc6_bbmd_enabled_handler(BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len)
@@ -960,9 +957,9 @@ int bvlc6_handler(BACNET_IP6_ADDRESS *addr,
uint16_t npdu_len)
{
#if defined(BACDL_BIP6) && BBMD6_ENABLED
return handler_bbmd6_for_bbmd(addr, src, npdu, npdu_len);
return bvlc6_bbmd_enabled_handler(addr, src, npdu, npdu_len);
#else
return handler_bbmd6_for_non_bbmd(addr, src, npdu, npdu_len);
return bvlc6_bbmd_disabled_handler(addr, src, npdu, npdu_len);
#endif
}
@@ -1013,144 +1010,26 @@ uint8_t bvlc6_get_function_code(void)
return BVLC6_Function_Code;
}
/**
* Cleanup any memory usage
*/
void bvlc6_cleanup(void)
{
VMAC_Cleanup();
}
/**
* Initialize any tables or other memory
*/
void bvlc6_init(void)
{
VMAC_Init();
}
#ifdef TEST
#include <assert.h>
#include <string.h>
#include "ctest.h"
static uint32_t Device_ID = 0;
static uint32_t Test_Device_ID = 12345;
static BACNET_IP6_ADDRESS BIP6_Addr;
static BACNET_IP6_ADDRESS Test_BIP6_Addr;
static BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
static uint8_t BIP6_MTU_Buffer[MAX_MPDU];
/* network stub functions */
/**
* BACnet/IP Datalink Receive handler.
*
* @param src - returns the source address
* @param npdu - returns the NPDU buffer
* @param max_npdu -maximum size of the NPDU buffer
* @param timeout - number of milliseconds to wait for a packet
*
* @return Number of bytes received, or 0 if none or timeout.
*/
uint16_t bip6_receive(
BACNET_ADDRESS *src, uint8_t *npdu, uint16_t max_npdu, unsigned timeout)
{
return 0;
}
/**
* The send function for BACnet/IPv6 driver layer
*
* @param dest - Points to a BACNET_IP6_ADDRESS structure containing the
* destination address.
* @param mtu - the bytes of data to send
* @param mtu_len - the number of bytes of data to send
*
* @return Upon successful completion, returns the number of bytes sent.
* Otherwise, -1 shall be returned and errno set to indicate the error.
*/
int bip6_send_mpdu(BACNET_IP6_ADDRESS *dest, uint8_t *mtu, uint16_t mtu_len)
{
return 0;
}
/** Return the Object Instance number for our (single) Device Object.
* This is a key function, widely invoked by the handler code, since
* it provides "our" (ie, local) address.
*
* @return The Instance number used in the BACNET_OBJECT_ID for the Device.
*/
uint32_t Device_Object_Instance_Number(void)
{
return Device_ID;
}
/**
* Get the BACnet/IP address
*
* @return BACnet/IP address
*/
bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(addr, &BIP6_Addr);
}
/**
* Get the BACnet/IP address
*
* @return BACnet/IP address
*/
bool bip6_get_broadcast_addr(BACNET_IP6_ADDRESS *addr)
{
return bvlc6_address_copy(addr, &BIP6_Broadcast_Addr);
}
static void test_BBMD_Result(Test *pTest)
{
int result = 0;
uint32_t vmac_src = 0x1234;
uint16_t result_code[6] = { BVLC6_RESULT_SUCCESSFUL_COMPLETION,
BVLC6_RESULT_ADDRESS_RESOLUTION_NAK,
BVLC6_RESULT_VIRTUAL_ADDRESS_RESOLUTION_NAK,
BVLC6_RESULT_REGISTER_FOREIGN_DEVICE_NAK,
BVLC6_RESULT_DELETE_FOREIGN_DEVICE_NAK,
BVLC6_RESULT_DISTRIBUTE_BROADCAST_TO_NETWORK_NAK };
uint16_t test_result_code = 0;
uint8_t test_function_code = 0;
BACNET_IP6_ADDRESS addr;
BACNET_ADDRESS src;
unsigned int i = 0;
uint8_t mtu[MAX_MPDU] = { 0 };
uint16_t mtu_len = 0;
bvlc6_address_set(&addr, BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
BVLC6_Result_Code = BVLC6_RESULT_SUCCESSFUL_COMPLETION;
BVLC6_Function_Code = BVLC6_RESULT;
bvlc6_address_set(&Remote_BBMD, 0, 0, 0, 0, 0, 0, 0,
BIP6_MULTICAST_GROUP_ID);
addr.port = 0xBAC0U;
bvlc6_vmac_address_set(&src, vmac_src);
for (i = 0; i < 6; i++) {
mtu_len =
bvlc6_encode_result(&mtu[0], sizeof(mtu), vmac_src, result_code[i]);
result = handler_bbmd6_for_non_bbmd(&addr, &src, &mtu[0], mtu_len);
/* validate that the result is handled (0) */
ct_test(pTest, result == 0);
test_result_code = bvlc6_get_last_result();
ct_test(pTest, test_result_code == result_code[i]);
test_function_code = bvlc6_get_function_code();
ct_test(pTest, test_function_code == BVLC6_RESULT);
}
}
static void test_BBMD6(Test *pTest)
{
bool rc;
/* individual tests */
rc = ct_addTestFunction(pTest, test_BBMD_Result);
assert(rc);
}
#ifdef TEST_BBMD6
int main(void)
{
Test *pTest;
pTest = ct_create("BACnet Broadcast Management Device IP/v6", NULL);
test_BBMD6(pTest);
/* configure output */
ct_setStream(pTest, stdout);
ct_run(pTest);
(void)ct_report(pTest);
ct_destroy(pTest);
return 0;
}
#endif
#if defined(BACDL_BIP6) && BBMD6_ENABLED
memset(&BBMD_Table, 0, sizeof(BBMD_Table));
memset(&FD_Table, 0, sizeof(FD_Table));
#endif
}
+15 -1
View File
@@ -48,6 +48,18 @@ extern "C" {
uint8_t * npdu,
uint16_t npdu_len);
BACNET_STACK_EXPORT
int bvlc6_bbmd_enabled_handler(BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len);
BACNET_STACK_EXPORT
int bvlc6_bbmd_disabled_handler(BACNET_IP6_ADDRESS *addr,
BACNET_ADDRESS *src,
uint8_t *mtu,
uint16_t mtu_len);
BACNET_STACK_EXPORT
int bvlc6_send_pdu(BACNET_ADDRESS *dest,
BACNET_NPDU_DATA *npdu_data,
@@ -73,8 +85,10 @@ extern "C" {
uint16_t seconds);
BACNET_STACK_EXPORT
void bvlc6_init(void);
void bvlc6_cleanup(void);
BACNET_STACK_EXPORT
void bvlc6_init(void);
#ifdef __cplusplus
}
+2 -2
View File
@@ -1464,7 +1464,7 @@ int bvlc_decode_original_unicast(uint8_t *pdu,
int bytes_consumed = 0;
uint16_t i = 0;
if (pdu_len >= npdu_size) {
if (pdu_len <= npdu_size) {
if (pdu && npdu) {
for (i = 0; i < pdu_len; i++) {
npdu[i] = pdu[i];
@@ -1541,7 +1541,7 @@ int bvlc_decode_original_broadcast(uint8_t *pdu,
int bytes_consumed = 0;
uint16_t i = 0;
if (pdu_len >= npdu_size) {
if (pdu_len <= npdu_size) {
if (pdu && npdu) {
for (i = 0; i < pdu_len; i++) {
npdu[i] = pdu[i];