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:
@@ -21,6 +21,14 @@ mstpwin32:
|
||||
mstp:
|
||||
$(MAKE) BACDL=mstp -C apps all
|
||||
|
||||
.PHONY: bip6-win32
|
||||
bip6-win32:
|
||||
$(MAKE) BACDL=bip6 BACNET_PORT=win32 -C apps all
|
||||
|
||||
.PHONY: bip6
|
||||
bip6:
|
||||
$(MAKE) BACDL=bip6 -C apps all
|
||||
|
||||
.PHONY: apps
|
||||
apps:
|
||||
$(MAKE) -s -C apps all
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
+12
-1
@@ -2,10 +2,11 @@
|
||||
|
||||
LOGFILE = test.log
|
||||
|
||||
all: abort address arf awf bvlc6 bacapp bacdcode bacerror bacint bacstr \
|
||||
all: abort address arf awf bvlc bvlc6 bacapp bacdcode bacerror bacint bacstr \
|
||||
cov crc datetime dcc event filename fifo getevent iam ihave \
|
||||
indtext keylist key lighting lso memcopy npdu proplist ptransfer \
|
||||
rd reject ringbuf rp rpm sbuf timesync vmac \
|
||||
bbmd bbmd6 \
|
||||
whohas whois wp
|
||||
|
||||
clean: logfile
|
||||
@@ -70,11 +71,21 @@ bvlc: logfile bvlc.mak
|
||||
( ./bvlc >> ${LOGFILE} )
|
||||
$(MAKE) -s -f bvlc.mak clean
|
||||
|
||||
bbmd: logfile bacnet/basic/bbmd/Makefile
|
||||
$(MAKE) -s -C bacnet/basic/bbmd/ clean all
|
||||
( ./bacnet/basic/bbmd/unittest >> ${LOGFILE} )
|
||||
$(MAKE) -s -C bacnet/basic/bbmd/ clean
|
||||
|
||||
bvlc6: logfile bvlc6.mak
|
||||
$(MAKE) -s -f bvlc6.mak clean all
|
||||
( ./bvlc6 >> ${LOGFILE} )
|
||||
$(MAKE) -s -f bvlc6.mak clean
|
||||
|
||||
bbmd6: logfile bacnet/basic/bbmd6/Makefile
|
||||
$(MAKE) -s -C bacnet/basic/bbmd6/ clean all
|
||||
( ./bacnet/basic/bbmd6/unittest >> ${LOGFILE} )
|
||||
$(MAKE) -s -C bacnet/basic/bbmd6/ clean
|
||||
|
||||
cov: logfile cov.mak
|
||||
$(MAKE) -s -f cov.mak clean all
|
||||
( ./cov >> ${LOGFILE} )
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
#Makefile to build test case
|
||||
CC = gcc
|
||||
SRC_DIR = ../../../../src
|
||||
TEST_DIR = ../../../../test
|
||||
TEST_DIR = ../../..
|
||||
INCLUDES = -I$(SRC_DIR) -I$(TEST_DIR)
|
||||
DEFINES = -DBIG_ENDIAN=0 -DBACDL_BIP -DBBMD_ENABLED=1 -DTEST -DTEST_BBMD_HANDLER
|
||||
DEFINES = -DBIG_ENDIAN=0 -DDEBUG_ENABLED=0
|
||||
|
||||
CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g
|
||||
|
||||
SRCS = $(SRC_DIR)/bacnet/basic/bbmd/h_bbmd.c \
|
||||
SRCS = main.c \
|
||||
$(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/iam.c \
|
||||
$(SRC_DIR)/bacnet/npdu.c \
|
||||
$(SRC_DIR)/bacnet/datalink/bvlc.c \
|
||||
$(SRC_DIR)/bacnet/basic/sys/debug.c \
|
||||
$(TEST_DIR)/ctest.c
|
||||
|
||||
TARGET_NAME = bbmd
|
||||
TARGET_NAME = unittest
|
||||
ifeq ($(OS),Windows_NT)
|
||||
TARGET_EXT = .exe
|
||||
else
|
||||
@@ -39,7 +42,7 @@ depend:
|
||||
${CC} -MM ${CFLAGS} *.c >> .depend
|
||||
|
||||
clean:
|
||||
rm -rf core ${TARGET} $(OBJS) *.bak *.1 *.ini
|
||||
rm -rf ${TARGET} $(OBJS)
|
||||
|
||||
test: ${TARGET}
|
||||
./${TARGET}
|
||||
@@ -0,0 +1,267 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date April 2020
|
||||
* @brief Test file for a basic BBMD for BVLC IPv4 handler
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h> /* for standard i/o, like printing */
|
||||
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
||||
#include <stdbool.h> /* for the standard bool type. */
|
||||
#include <string.h> /* for memcpy */
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/datalink/bip.h"
|
||||
#include "bacnet/datalink/bvlc.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/bbmd/h_bbmd.h"
|
||||
#include "ctest.h"
|
||||
|
||||
struct device_info_t {
|
||||
uint32_t Device_ID;
|
||||
BACNET_IP_ADDRESS BIP_Addr;
|
||||
BACNET_IP_ADDRESS BIP_Broadcast_Addr;
|
||||
BACNET_ADDRESS BACnet_Address;
|
||||
};
|
||||
static struct device_info_t TD;
|
||||
static struct device_info_t IUT;
|
||||
|
||||
/* for the reply sent from the handler */
|
||||
static uint8_t Test_Sent_Message_Type;
|
||||
static uint8_t Test_Sent_Message_Length;
|
||||
static uint8_t Test_Sent_Message_Buffer[MAX_MPDU];
|
||||
static uint16_t Test_Sent_Message_Buffer_Length;
|
||||
static BACNET_IP_ADDRESS Test_Sent_Message_Dest;
|
||||
|
||||
/* 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/IPv6 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)
|
||||
{
|
||||
uint8_t message_type = 0;
|
||||
uint16_t message_length = 0;
|
||||
int header_len = 0;
|
||||
|
||||
header_len =
|
||||
bvlc_decode_header(mtu, mtu_len, &message_type, &message_length);
|
||||
Test_Sent_Message_Type = message_type;
|
||||
Test_Sent_Message_Length = message_length;
|
||||
bvlc_address_copy(&Test_Sent_Message_Dest, dest);
|
||||
if ((header_len == 4) && (mtu_len >= 4)) {
|
||||
memcpy(&Test_Sent_Message_Buffer[0], &mtu[4], mtu_len-4);
|
||||
Test_Sent_Message_Buffer_Length = mtu_len - 4;
|
||||
} else {
|
||||
Test_Sent_Message_Buffer_Length = 0;
|
||||
}
|
||||
|
||||
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 IUT.Device_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BACnet/IP address
|
||||
*
|
||||
* @return BACnet/IP address
|
||||
*/
|
||||
bool bip_get_addr(BACNET_IP_ADDRESS *addr)
|
||||
{
|
||||
return bvlc_address_copy(addr, &IUT.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, &IUT.BIP_Broadcast_Addr);
|
||||
}
|
||||
|
||||
static void test_setup(void)
|
||||
{
|
||||
bvlc_init();
|
||||
bvlc_address_set(&TD.BIP_Broadcast_Addr, 255, 255, 255, 255);
|
||||
bvlc_address_set(&TD.BIP_Addr, 192, 168, 1, 100);
|
||||
TD.Device_ID = 12345;
|
||||
|
||||
bvlc_address_set(&IUT.BIP_Broadcast_Addr, 255, 255, 255, 255);
|
||||
bvlc_address_set(&IUT.BIP_Addr, 192, 168, 1, 10);
|
||||
IUT.Device_ID = 54321;
|
||||
}
|
||||
|
||||
static void test_cleanup(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test 15.2.1.1 Initiate Original-Broadcast-NPDU
|
||||
*/
|
||||
static void test_Initiate_Original_Broadcast_NPDU(Test *pTest)
|
||||
{
|
||||
uint8_t pdu[MAX_MPDU] = {0};
|
||||
int npdu_len = 0;
|
||||
int apdu_len = 0;
|
||||
int pdu_len = 0;
|
||||
BACNET_ADDRESS dest = {0};
|
||||
BACNET_NPDU_DATA npdu_data = {0};
|
||||
uint8_t test_pdu[MAX_MPDU] = {0};
|
||||
uint16_t test_pdu_len = 0;
|
||||
int function_len = 0;
|
||||
|
||||
test_setup();
|
||||
/* MAKE(the IUT send a broadcast) */
|
||||
dest.net = BACNET_BROADCAST_NETWORK;
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_len = npdu_encode_pdu(&pdu[0], &dest, &IUT.BACnet_Address, &npdu_data);
|
||||
apdu_len = iam_encode_apdu(&pdu[npdu_len], IUT.Device_ID, MAX_APDU,
|
||||
SEGMENTATION_NONE, BACNET_VENDOR_ID);
|
||||
pdu_len = npdu_len + apdu_len;
|
||||
bvlc_send_pdu(&dest, &npdu_data, pdu, pdu_len);
|
||||
/* DA=Link Local Multicast Address */
|
||||
ct_test(pTest, !bvlc_address_different(&TD.BIP_Broadcast_Addr,
|
||||
&Test_Sent_Message_Dest));
|
||||
/* SA = IUT - done in port layer */
|
||||
/* Original-Broadcast-NPDU */
|
||||
ct_test(pTest, Test_Sent_Message_Type ==
|
||||
BVLC_ORIGINAL_BROADCAST_NPDU);
|
||||
if (Test_Sent_Message_Type == BVLC_ORIGINAL_BROADCAST_NPDU) {
|
||||
function_len = bvlc_decode_original_broadcast(
|
||||
Test_Sent_Message_Buffer, Test_Sent_Message_Buffer_Length,
|
||||
test_pdu, sizeof(test_pdu), &test_pdu_len);
|
||||
printf("len=%u pdu[%u] test_pdu[%u]\n",
|
||||
(unsigned)function_len,
|
||||
(unsigned)Test_Sent_Message_Buffer_Length,
|
||||
(unsigned)sizeof(test_pdu));
|
||||
ct_test(pTest, function_len > 0);
|
||||
/* (any valid BACnet-Unconfirmed-Request-PDU,
|
||||
with any valid broadcast network options */
|
||||
ct_test(pTest, test_pdu_len == pdu_len);
|
||||
}
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
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 = bvlc_bbmd_disabled_handler(&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 = bvlc_bbmd_enabled_handler(&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);
|
||||
rc = ct_addTestFunction(pTest, test_Initiate_Original_Broadcast_NPDU);
|
||||
assert(rc);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
Test *pTest;
|
||||
|
||||
pTest = ct_create("BACnet Broadcast Management Device IP/v4", NULL);
|
||||
test_BBMD_Handler(pTest);
|
||||
/* configure output */
|
||||
ct_setStream(pTest, stdout);
|
||||
ct_run(pTest);
|
||||
(void)ct_report(pTest);
|
||||
ct_destroy(pTest);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
#Makefile to build test case
|
||||
CC = gcc
|
||||
SRC_DIR = ../../../../src
|
||||
TEST_DIR = ../../..
|
||||
INCLUDES = -I$(SRC_DIR) -I$(TEST_DIR)
|
||||
DEFINES = -DBIG_ENDIAN=0 -DDEBUG_ENABLED=0
|
||||
|
||||
CFLAGS = -Wall $(INCLUDES) $(DEFINES) -g
|
||||
|
||||
SRCS = main.c \
|
||||
$(SRC_DIR)/bacnet/bacdcode.c \
|
||||
$(SRC_DIR)/bacnet/bacint.c \
|
||||
$(SRC_DIR)/bacnet/bacstr.c \
|
||||
$(SRC_DIR)/bacnet/bacreal.c \
|
||||
$(SRC_DIR)/bacnet/iam.c \
|
||||
$(SRC_DIR)/bacnet/npdu.c \
|
||||
$(SRC_DIR)/bacnet/basic/sys/keylist.c \
|
||||
$(SRC_DIR)/bacnet/basic/bbmd6/h_bbmd6.c \
|
||||
$(SRC_DIR)/bacnet/basic/bbmd6/vmac.c \
|
||||
$(SRC_DIR)/bacnet/datalink/bvlc6.c \
|
||||
$(SRC_DIR)/bacnet/basic/sys/debug.c \
|
||||
$(TEST_DIR)/ctest.c
|
||||
|
||||
TARGET_NAME = unittest
|
||||
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 ${TARGET} $(OBJS)
|
||||
|
||||
test: ${TARGET}
|
||||
./${TARGET}
|
||||
|
||||
include: .depend
|
||||
@@ -0,0 +1,312 @@
|
||||
/**
|
||||
* @file
|
||||
* @author Steve Karg
|
||||
* @date April 2020
|
||||
* @brief Test file for a basic BBMD for BVLC IPv6 handler
|
||||
*
|
||||
* @section LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included
|
||||
* in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#include <stdio.h> /* for standard i/o, like printing */
|
||||
#include <stdint.h> /* for standard integer types uint8_t etc. */
|
||||
#include <stdbool.h> /* for the standard bool type. */
|
||||
#include <string.h> /* for memcpy */
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "bacnet/bacdcode.h"
|
||||
#include "bacnet/iam.h"
|
||||
#include "bacnet/npdu.h"
|
||||
#include "bacnet/datalink/bip6.h"
|
||||
#include "bacnet/datalink/bvlc6.h"
|
||||
#include "bacnet/basic/sys/debug.h"
|
||||
#include "bacnet/basic/object/device.h"
|
||||
#include "bacnet/basic/bbmd6/h_bbmd6.h"
|
||||
#include "bacnet/basic/bbmd6/vmac.h"
|
||||
#include "ctest.h"
|
||||
|
||||
struct device_info_t {
|
||||
uint32_t Device_ID;
|
||||
BACNET_IP6_ADDRESS BIP6_Addr;
|
||||
BACNET_IP6_ADDRESS BIP6_Broadcast_Addr;
|
||||
BACNET_ADDRESS BACnet_Address;
|
||||
};
|
||||
static struct device_info_t TD;
|
||||
static struct device_info_t IUT;
|
||||
|
||||
/* for the reply sent from the handler */
|
||||
static uint8_t Test_Sent_Message_Type;
|
||||
static uint8_t Test_Sent_Message_Length;
|
||||
static uint8_t Test_Sent_Message_Buffer[MAX_MPDU];
|
||||
static uint16_t Test_Sent_Message_Buffer_Length;
|
||||
static BACNET_IP6_ADDRESS Test_Sent_Message_Dest;
|
||||
|
||||
/* 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)
|
||||
{
|
||||
uint8_t message_type = 0;
|
||||
uint16_t message_length = 0;
|
||||
int header_len = 0;
|
||||
|
||||
header_len =
|
||||
bvlc6_decode_header(mtu, mtu_len, &message_type, &message_length);
|
||||
Test_Sent_Message_Type = message_type;
|
||||
Test_Sent_Message_Length = message_length;
|
||||
bvlc6_address_copy(&Test_Sent_Message_Dest, dest);
|
||||
if ((header_len == 4) && (mtu_len >= 4)) {
|
||||
memcpy(&Test_Sent_Message_Buffer[0], &mtu[4], mtu_len-4);
|
||||
Test_Sent_Message_Buffer_Length = mtu_len - 4;
|
||||
} else {
|
||||
Test_Sent_Message_Buffer_Length = 0;
|
||||
}
|
||||
|
||||
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 IUT.Device_ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the BACnet/IP address
|
||||
*
|
||||
* @return BACnet/IP address
|
||||
*/
|
||||
bool bip6_get_addr(BACNET_IP6_ADDRESS *addr)
|
||||
{
|
||||
return bvlc6_address_copy(addr, &IUT.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, &IUT.BIP6_Broadcast_Addr);
|
||||
}
|
||||
|
||||
static void test_setup(void)
|
||||
{
|
||||
bvlc6_init();
|
||||
/* BACnet_IPv6_Multicast_Address is FF02::BAC0 */
|
||||
bvlc6_address_set(&TD.BIP6_Broadcast_Addr,
|
||||
BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
|
||||
BIP6_MULTICAST_GROUP_ID);
|
||||
bvlc6_address_set(&TD.BIP6_Addr,
|
||||
0x2001, 0x0DBB, 0xAC10, 0xFE01, 0, 0, 0,
|
||||
BIP6_MULTICAST_GROUP_ID);
|
||||
TD.Device_ID = 12345;
|
||||
bvlc6_vmac_address_set(&TD.BACnet_Address, TD.Device_ID);
|
||||
|
||||
|
||||
/* BACnet_IPv6_Multicast_Address is FF02::BAC0 */
|
||||
bvlc6_address_set(&IUT.BIP6_Broadcast_Addr,
|
||||
BIP6_MULTICAST_LINK_LOCAL, 0, 0, 0, 0, 0, 0,
|
||||
BIP6_MULTICAST_GROUP_ID);
|
||||
bvlc6_address_set(&IUT.BIP6_Addr,
|
||||
0x2001, 0x0DBB, 0xAC10, 0xFE01, 0, 0, 1,
|
||||
BIP6_MULTICAST_GROUP_ID);
|
||||
IUT.Device_ID = 54321;
|
||||
bvlc6_vmac_address_set(&IUT.BACnet_Address, IUT.Device_ID);
|
||||
}
|
||||
|
||||
static void test_cleanup(void)
|
||||
{
|
||||
bvlc6_cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test 15.2.1.1 Initiate Original-Broadcast-NPDU
|
||||
*/
|
||||
static void test_Initiate_Original_Broadcast_NPDU(Test *pTest)
|
||||
{
|
||||
uint8_t pdu[MAX_MPDU] = {0};
|
||||
int npdu_len = 0;
|
||||
int apdu_len = 0;
|
||||
int pdu_len = 0;
|
||||
BACNET_ADDRESS dest = {0};
|
||||
BACNET_NPDU_DATA npdu_data = {0};
|
||||
uint8_t test_pdu[MAX_MPDU] = {0};
|
||||
uint16_t test_pdu_len = 0;
|
||||
uint32_t test_vmac_src = 0;
|
||||
int function_len = 0;
|
||||
|
||||
test_setup();
|
||||
/* MAKE(the IUT send a broadcast) */
|
||||
dest.net = BACNET_BROADCAST_NETWORK;
|
||||
npdu_encode_npdu_data(&npdu_data, false, MESSAGE_PRIORITY_NORMAL);
|
||||
npdu_len = npdu_encode_pdu(&pdu[0], &dest, &IUT.BACnet_Address, &npdu_data);
|
||||
apdu_len = iam_encode_apdu(&pdu[npdu_len], IUT.Device_ID, MAX_APDU,
|
||||
SEGMENTATION_NONE, BACNET_VENDOR_ID);
|
||||
pdu_len = npdu_len + apdu_len;
|
||||
bvlc6_send_pdu(&dest, &npdu_data, pdu, pdu_len);
|
||||
/* DA=Link Local Multicast Address */
|
||||
ct_test(pTest, !bvlc6_address_different(&TD.BIP6_Broadcast_Addr,
|
||||
&Test_Sent_Message_Dest));
|
||||
/* SA = IUT - done in port layer */
|
||||
/* Original-Broadcast-NPDU */
|
||||
ct_test(pTest, Test_Sent_Message_Type ==
|
||||
BVLC6_ORIGINAL_BROADCAST_NPDU);
|
||||
if (Test_Sent_Message_Type == BVLC6_ORIGINAL_BROADCAST_NPDU) {
|
||||
function_len = bvlc6_decode_original_broadcast(
|
||||
Test_Sent_Message_Buffer, Test_Sent_Message_Buffer_Length,
|
||||
&test_vmac_src, test_pdu, sizeof(test_pdu), &test_pdu_len);
|
||||
ct_test(pTest, function_len > 0);
|
||||
/* Source-Virtual-Address = IUT */
|
||||
ct_test(pTest, test_vmac_src == IUT.Device_ID);
|
||||
/* (any valid BACnet-Unconfirmed-Request-PDU,
|
||||
with any valid broadcast network options */
|
||||
ct_test(pTest, test_pdu_len == pdu_len);
|
||||
}
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test 15.1.2 Execute Virtual-Address-Resolution
|
||||
*/
|
||||
static void test_Execute_Virtual_Address_Resolution(Test *pTest)
|
||||
{
|
||||
uint8_t mtu[MAX_MPDU] = {0};
|
||||
uint16_t mtu_len = 0;
|
||||
uint32_t test_vmac_src = 0;
|
||||
uint32_t test_vmac_dst = 0;
|
||||
int result = 0;
|
||||
int function_len = 0;
|
||||
|
||||
test_setup();
|
||||
mtu_len = bvlc6_encode_virtual_address_resolution(
|
||||
&mtu[0], sizeof(mtu), TD.Device_ID);
|
||||
result = bvlc6_bbmd_disabled_handler(&TD.BIP6_Addr, &TD.BACnet_Address,
|
||||
&mtu[0], mtu_len);
|
||||
ct_test(pTest, result == 0);
|
||||
ct_test(pTest, bvlc6_get_function_code() ==
|
||||
BVLC6_VIRTUAL_ADDRESS_RESOLUTION);
|
||||
ct_test(pTest, Test_Sent_Message_Type ==
|
||||
BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK);
|
||||
ct_test(pTest, VMAC_Find_By_Key(TD.Device_ID) != NULL);
|
||||
if (Test_Sent_Message_Type == BVLC6_VIRTUAL_ADDRESS_RESOLUTION_ACK) {
|
||||
function_len = bvlc6_decode_virtual_address_resolution_ack(
|
||||
Test_Sent_Message_Buffer, Test_Sent_Message_Buffer_Length,
|
||||
&test_vmac_src, &test_vmac_dst);
|
||||
ct_test(pTest, function_len > 0);
|
||||
ct_test(pTest, test_vmac_src == IUT.Device_ID);
|
||||
ct_test(pTest, test_vmac_dst == TD.Device_ID);
|
||||
}
|
||||
test_cleanup();
|
||||
}
|
||||
|
||||
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,
|
||||
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 = bvlc6_bbmd_disabled_handler(&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);
|
||||
rc = ct_addTestFunction(pTest, test_Execute_Virtual_Address_Resolution);
|
||||
assert(rc);
|
||||
rc = ct_addTestFunction(pTest, test_Initiate_Original_Broadcast_NPDU);
|
||||
assert(rc);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user