/** * @file * @brief tests for BACnet/SC encode/decode APIs * @author Kirill Neznamov * @date May 2022 * @copyright SPDX-License-Identifier: MIT */ #include /* For calloc() */ #include #include static bool verify_bsc_bvll_header( BVLC_SC_DECODED_HDR *hdr, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, bool dest_options_absent, bool data_options_absent, size_t payload_len) { if (hdr->bvlc_function != bvlc_function) { return false; } if (hdr->message_id != message_id) { return false; } if (origin) { if (memcmp(hdr->origin->address, origin->address, BVLC_SC_VMAC_SIZE) != 0) { return false; } } else { if (hdr->origin) { return false; } } if (dest) { if (memcmp(hdr->dest->address, dest->address, BVLC_SC_VMAC_SIZE) != 0) { return false; } } else { if (hdr->dest) { return false; } } if (dest_options_absent) { if (hdr->dest_options != NULL) { return false; } if (hdr->dest_options_len != 0) { return false; } if (hdr->dest_options_num != 0) { return false; } } else { if (!hdr->dest_options) { return false; } if (!hdr->dest_options_len) { return false; } if (!hdr->dest_options_num) { return false; } } if (data_options_absent) { if (hdr->data_options != NULL) { return false; } if (hdr->data_options_len != 0) { return false; } if (hdr->data_options_num != 0) { return false; } } else { if (!hdr->data_options) { return false; } if (!hdr->data_options_len) { return false; } if (!hdr->data_options_num) { return false; } } if (hdr->payload_len != payload_len) { return false; } return true; } static void test_header_modifications( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len, bool dest_options_absent, bool data_options_absent) { uint8_t sbuf[BSC_PRE + 256]; uint8_t *buf = &sbuf[BSC_PRE]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; const char *err_desc = NULL; size_t len; bool ret; BACNET_SC_VMAC_ADDRESS test; BACNET_SC_VMAC_ADDRESS test_dest; uint8_t *ppdu; int res; memset(&test.address[0], 0x99, sizeof(test.address)); memcpy(buf, pdu, pdu_size); if (dest && !origin) { bvlc_sc_remove_dest_set_orig(buf, pdu_size, &test); ret = bvlc_sc_decode_message( buf, pdu_size, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, &test, NULL, dest_options_absent, data_options_absent, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); zassert_equal( memcmp(&test.address, message.hdr.origin, sizeof(test.address)), 0, NULL); zassert_equal(message.hdr.dest, NULL, NULL); } else { bvlc_sc_remove_dest_set_orig(buf, pdu_size, &test); ret = bvlc_sc_decode_message( buf, pdu_size, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, dest_options_absent, data_options_absent, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); if (origin) { zassert_equal( memcmp( &origin->address, message.hdr.origin, sizeof(origin->address)), 0, NULL); } else { zassert_equal(message.hdr.origin, NULL, NULL); } if (dest) { zassert_equal( memcmp(&dest->address, message.hdr.dest, sizeof(dest->address)), 0, NULL); zassert_equal(bvlc_sc_pdu_has_no_dest(buf, pdu_size), false, NULL); ret = bvlc_sc_pdu_get_dest(buf, pdu_size, &test_dest); zassert_equal(ret, true, NULL); zassert_equal( memcmp( &test_dest.address, message.hdr.dest, sizeof(dest->address)), 0, NULL); } else { zassert_equal(message.hdr.dest, NULL, NULL); zassert_equal(bvlc_sc_pdu_has_no_dest(buf, pdu_size), true, NULL); ret = bvlc_sc_pdu_get_dest(buf, pdu_size, &test_dest); zassert_equal(ret, false, NULL); } } memcpy(buf, pdu, pdu_size); ppdu = buf; /* origin address can presented only in specific message types */ if (bvlc_function != BVLC_SC_CONNECT_REQUEST && bvlc_function != BVLC_SC_CONNECT_ACCEPT && bvlc_function != BVLC_SC_DISCONNECT_REQUEST && bvlc_function != BVLC_SC_DISCONNECT_ACK && bvlc_function != BVLC_SC_HEARTBEAT_REQUEST && bvlc_function != BVLC_SC_HEARTBEAT_ACK) { len = bvlc_sc_set_orig(&ppdu, pdu_size, &test); ret = bvlc_sc_decode_message( ppdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, &test, dest, dest_options_absent, data_options_absent, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); zassert_equal( memcmp(&test.address, message.hdr.origin, sizeof(test.address)), 0, NULL); } else { len = pdu_size; } memcpy(buf, pdu, pdu_size); ppdu = buf; len = bvlc_sc_remove_orig_and_dest(&ppdu, pdu_size); ret = bvlc_sc_decode_message( ppdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.origin, NULL, NULL); zassert_equal(message.hdr.dest, NULL, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, NULL, NULL, dest_options_absent, data_options_absent, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); } static void test_1_option_data( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; const char *err_desc = NULL; size_t optlen; size_t len; bool ret; int res; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, pdu_size, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, true, false, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.data_options_num, 1, NULL); zassert_equal( message.data_options[0].type, BVLC_SC_OPTION_TYPE_SECURE_PATH, NULL); zassert_equal(message.data_options[0].must_understand, true, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, true, false); } /* 3 options are added to pdu in total: 1 sc, 2 proprietary */ static void test_3_options_different_buffer_data( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t buf1[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf1, sizeof(buf1), buf, pdu_size, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf1, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf1, sizeof(buf1), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf1, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, true, false, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.data_options_num, 3, NULL); zassert_equal( message.data_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[0].must_understand, true, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[0].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.data_options[0].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.data_options[0].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.data_options[0].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal( message.data_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[1].must_understand, true, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[2].type, BVLC_SC_OPTION_TYPE_SECURE_PATH, NULL); zassert_equal(message.data_options[2].must_understand, true, NULL); zassert_equal( message.data_options[2].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.data_options[2].packed_header_marker & BVLC_SC_HEADER_DATA, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); } /* 3 options are added to pdu in total: 1 sc, 2 proprietary */ static void test_3_options_data( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, true, false, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.data_options_num, 3, NULL); zassert_equal( message.data_options[2].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[2].must_understand, true, NULL); zassert_equal( message.data_options[2].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.data_options[2].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[2].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.data_options[2].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.data_options[2].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.data_options[2].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal( message.data_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[1].must_understand, true, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[0].type, BVLC_SC_OPTION_TYPE_SECURE_PATH, NULL); zassert_equal(message.data_options[0].must_understand, true, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, true, false); } static void test_5_options_data( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len; bool ret; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; size_t i; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = pdu_size; for (i = 0; i < 5; i++) { len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); } ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_OUT_OF_MEMORY, NULL); zassert_equal(error_class, ERROR_CLASS_RESOURCES, NULL); } /* check message decoding when header option has incorrect more bit flag */ static void test_options_incorrect_more_bit_data( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[5]; size_t offs = 4; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); if (buf[1] & BVLC_SC_CONTROL_ORIG_VADDR) { offs += BVLC_SC_VMAC_SIZE; } if (buf[1] & BVLC_SC_CONTROL_DEST_VADDR) { offs += BVLC_SC_VMAC_SIZE; } buf[offs] &= ~(BVLC_SC_HEADER_MORE); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_UNEXPECTED_DATA, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } /* check message decoding when header option has incorrect more bit flag */ static void test_options_incorrect_data_bit_data( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; size_t offs = 4; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); if (buf[1] & BVLC_SC_CONTROL_ORIG_VADDR) { offs += BVLC_SC_VMAC_SIZE; } if (buf[1] & BVLC_SC_CONTROL_DEST_VADDR) { offs += BVLC_SC_VMAC_SIZE; } buf[offs] &= ~(BVLC_SC_HEADER_DATA); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } /* secure path option must not be in dest option headers. this test checks this case */ static void test_1_option_dest_incorrect( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len; bool ret; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, pdu_size, optbuf, optlen); zassert_equal(len, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, pdu_size, optbuf, optlen); zassert_not_equal(len, 0, NULL); buf[1] &= ~(BVLC_SC_CONTROL_DATA_OPTIONS); buf[1] |= BVLC_SC_CONTROL_DEST_OPTIONS; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } static void test_1_option_dest( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len; bool ret; int res; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, pdu_size, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, false, true, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.dest_options_num, 1, NULL); zassert_equal( message.dest_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[0].must_understand, true, NULL); zassert_equal( message.dest_options[0].specific.proprietary.vendor_id, vendor_id1, NULL); zassert_equal( message.dest_options[0].specific.proprietary.option_type, proprietary_option_type1, NULL); zassert_equal( message.dest_options[0].specific.proprietary.data_len, sizeof(proprietary_data1), NULL); res = memcmp( message.dest_options[0].specific.proprietary.data, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(res, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, false, true); } /* 3 proprietary options are added to pdu */ static void test_3_options_dest( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint16_t vendor_id3; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_option_type3; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; uint8_t proprietary_data3[43]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id3 = 0xF00D; proprietary_option_type3 = 0x08; memset(proprietary_data3, 0x55, sizeof(proprietary_data3)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id3, proprietary_option_type3, proprietary_data3, sizeof(proprietary_data3)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, false, true, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.dest_options_num, 3, NULL); zassert_equal( message.dest_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[0].must_understand, true, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[0].specific.proprietary.vendor_id, vendor_id3, NULL); zassert_equal( message.dest_options[0].specific.proprietary.option_type, proprietary_option_type3, NULL); zassert_equal( message.dest_options[0].specific.proprietary.data_len, sizeof(proprietary_data3), NULL); res = memcmp( message.dest_options[0].specific.proprietary.data, proprietary_data3, sizeof(proprietary_data3)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[1].must_understand, true, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[1].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.dest_options[1].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.dest_options[1].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.dest_options[1].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[2].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[2].must_understand, true, NULL); zassert_equal( message.dest_options[2].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.dest_options[2].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[2].specific.proprietary.vendor_id, vendor_id1, NULL); zassert_equal( message.dest_options[2].specific.proprietary.option_type, proprietary_option_type1, NULL); zassert_equal( message.dest_options[2].specific.proprietary.data_len, sizeof(proprietary_data1), NULL); res = memcmp( message.dest_options[2].specific.proprietary.data, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(res, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, false, true); } static void test_3_options_dest_different_buffer( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf1[256]; uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint16_t vendor_id3; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_option_type3; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; uint8_t proprietary_data3[43]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf1, sizeof(buf1), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf1, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id3 = 0xF00D; proprietary_option_type3 = 0x08; memset(proprietary_data3, 0x55, sizeof(proprietary_data3)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id3, proprietary_option_type3, proprietary_data3, sizeof(proprietary_data3)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf1, sizeof(buf1), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf1, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, false, true, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.dest_options_num, 3, NULL); zassert_equal( message.dest_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[0].must_understand, true, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[0].specific.proprietary.vendor_id, vendor_id3, NULL); zassert_equal( message.dest_options[0].specific.proprietary.option_type, proprietary_option_type3, NULL); zassert_equal( message.dest_options[0].specific.proprietary.data_len, sizeof(proprietary_data3), NULL); res = memcmp( message.dest_options[0].specific.proprietary.data, proprietary_data3, sizeof(proprietary_data3)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[1].must_understand, true, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[1].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.dest_options[1].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.dest_options[1].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.dest_options[1].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[2].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[2].must_understand, true, NULL); zassert_equal( message.dest_options[2].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.dest_options[2].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[2].specific.proprietary.vendor_id, vendor_id1, NULL); zassert_equal( message.dest_options[2].specific.proprietary.option_type, proprietary_option_type1, NULL); zassert_equal( message.dest_options[2].specific.proprietary.data_len, sizeof(proprietary_data1), NULL); res = memcmp( message.dest_options[2].specific.proprietary.data, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(res, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf1, len, bvlc_function, message_id, origin, dest, payload, payload_len, false, true); } static void test_5_options_dest( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; size_t i; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = pdu_size; for (i = 0; i < 5; i++) { len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); } ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_OUT_OF_MEMORY, NULL); zassert_equal(error_class, ERROR_CLASS_RESOURCES, NULL); } static void test_options_incorrect_data_bit_dest( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; int offs = 4; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); if (buf[1] & BVLC_SC_CONTROL_ORIG_VADDR) { offs += BVLC_SC_VMAC_SIZE; } if (buf[1] & BVLC_SC_CONTROL_DEST_VADDR) { offs += BVLC_SC_VMAC_SIZE; } buf[offs] &= ~(BVLC_SC_HEADER_DATA); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } static void test_options_incorrect_more_bit_dest( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[5]; size_t offs = 4; const char *err_desc = NULL; (void)bvlc_function; (void)message_id; (void)origin; (void)dest; (void)payload; (void)payload_len; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0x0; proprietary_option_type1 = 0x0; memset(proprietary_data1, 0x0, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); if (buf[1] & BVLC_SC_CONTROL_ORIG_VADDR) { offs += BVLC_SC_VMAC_SIZE; } if (buf[1] & BVLC_SC_CONTROL_DEST_VADDR) { offs += BVLC_SC_VMAC_SIZE; } buf[offs] &= ~(BVLC_SC_HEADER_MORE); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); if (error_code != ERROR_CODE_UNEXPECTED_DATA && error_code != ERROR_CODE_PARAMETER_OUT_OF_RANGE) { zassert_equal(1, 2, NULL); } zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } static void test_options_mixed_case1( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint16_t vendor_id3; uint16_t vendor_id4; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_option_type3; uint8_t proprietary_option_type4; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; uint8_t proprietary_data3[43]; uint8_t proprietary_data4[23]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id3 = 0xF00D; proprietary_option_type3 = 0x08; memset(proprietary_data3, 0x55, sizeof(proprietary_data3)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id3, proprietary_option_type3, proprietary_data3, sizeof(proprietary_data3)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id4 = 0xabcd; proprietary_option_type4 = 0x64; memset(proprietary_data4, 0x97, sizeof(proprietary_data4)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id4, proprietary_option_type4, proprietary_data4, sizeof(proprietary_data4)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, false, false, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.dest_options_num, 2, NULL); zassert_equal(message.hdr.data_options_num, 2, NULL); zassert_equal( message.dest_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[0].must_understand, true, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[0].specific.proprietary.vendor_id, vendor_id3, NULL); zassert_equal( message.dest_options[0].specific.proprietary.option_type, proprietary_option_type3, NULL); zassert_equal( message.dest_options[0].specific.proprietary.data_len, sizeof(proprietary_data3), NULL); res = memcmp( message.dest_options[0].specific.proprietary.data, proprietary_data3, sizeof(proprietary_data3)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[1].must_understand, true, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[1].specific.proprietary.vendor_id, vendor_id1, NULL); zassert_equal( message.dest_options[1].specific.proprietary.option_type, proprietary_option_type1, NULL); zassert_equal( message.dest_options[1].specific.proprietary.data_len, sizeof(proprietary_data1), NULL); res = memcmp( message.dest_options[1].specific.proprietary.data, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(res, 0, NULL); /* data options */ zassert_equal( message.data_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[0].must_understand, true, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[0].specific.proprietary.vendor_id, vendor_id4, NULL); zassert_equal( message.data_options[0].specific.proprietary.option_type, proprietary_option_type4, NULL); zassert_equal( message.data_options[0].specific.proprietary.data_len, sizeof(proprietary_data4), NULL); res = memcmp( message.data_options[0].specific.proprietary.data, proprietary_data4, sizeof(proprietary_data4)); zassert_equal(res, 0, NULL); zassert_equal( message.data_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[1].must_understand, true, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[1].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.data_options[1].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.data_options[1].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.data_options[1].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, false, false); } static void test_options_mixed_case2( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint16_t vendor_id3; uint16_t vendor_id4; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_option_type3; uint8_t proprietary_option_type4; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; uint8_t proprietary_data3[43]; uint8_t proprietary_data4[23]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id3 = 0xF00D; proprietary_option_type3 = 0x08; memset(proprietary_data3, 0x55, sizeof(proprietary_data3)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id3, proprietary_option_type3, proprietary_data3, sizeof(proprietary_data3)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id4 = 0xabcd; proprietary_option_type4 = 0x64; memset(proprietary_data4, 0x97, sizeof(proprietary_data4)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id4, proprietary_option_type4, proprietary_data4, sizeof(proprietary_data4)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, false, false, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.dest_options_num, 2, NULL); zassert_equal(message.hdr.data_options_num, 2, NULL); zassert_equal( message.dest_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[0].must_understand, true, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[0].specific.proprietary.vendor_id, vendor_id4, NULL); zassert_equal( message.dest_options[0].specific.proprietary.option_type, proprietary_option_type4, NULL); zassert_equal( message.dest_options[0].specific.proprietary.data_len, sizeof(proprietary_data4), NULL); res = memcmp( message.dest_options[0].specific.proprietary.data, proprietary_data4, sizeof(proprietary_data4)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[1].must_understand, true, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[1].specific.proprietary.vendor_id, vendor_id3, NULL); zassert_equal( message.dest_options[1].specific.proprietary.option_type, proprietary_option_type3, NULL); zassert_equal( message.dest_options[1].specific.proprietary.data_len, sizeof(proprietary_data3), NULL); res = memcmp( message.dest_options[1].specific.proprietary.data, proprietary_data3, sizeof(proprietary_data3)); zassert_equal(res, 0, NULL); /* data options */ zassert_equal( message.data_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[0].must_understand, true, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[0].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.data_options[0].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.data_options[0].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.data_options[0].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal( message.data_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[1].must_understand, true, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[1].specific.proprietary.vendor_id, vendor_id1, NULL); zassert_equal( message.data_options[1].specific.proprietary.option_type, proprietary_option_type1, NULL); zassert_equal( message.data_options[1].specific.proprietary.data_len, sizeof(proprietary_data1), NULL); res = memcmp( message.data_options[1].specific.proprietary.data, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(res, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, false, false); } static void test_options_mixed_case3( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, uint8_t *payload, size_t payload_len) { uint8_t buf[256]; uint8_t optbuf[256]; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; size_t optlen; size_t len = pdu_size; bool ret; uint16_t vendor_id1; uint16_t vendor_id2; uint16_t vendor_id3; uint16_t vendor_id4; uint8_t proprietary_option_type1; uint8_t proprietary_option_type2; uint8_t proprietary_option_type3; uint8_t proprietary_option_type4; uint8_t proprietary_data1[17]; uint8_t proprietary_data2[1]; uint8_t proprietary_data3[43]; uint8_t proprietary_data4[23]; int res; const char *err_desc = NULL; zassert_equal(true, sizeof(buf) >= pdu_size ? true : false, NULL); memcpy(buf, pdu, pdu_size); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id2 = 0xbeaf; proprietary_option_type2 = 0x33; memset(proprietary_data2, 0x11, sizeof(proprietary_data2)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id2, proprietary_option_type2, proprietary_data2, sizeof(proprietary_data2)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id3 = 0xF00D; proprietary_option_type3 = 0x08; memset(proprietary_data3, 0x55, sizeof(proprietary_data3)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id3, proprietary_option_type3, proprietary_data3, sizeof(proprietary_data3)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); vendor_id4 = 0xabcd; proprietary_option_type4 = 0x64; memset(proprietary_data4, 0x97, sizeof(proprietary_data4)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id4, proprietary_option_type4, proprietary_data4, sizeof(proprietary_data4)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, bvlc_function, message_id, origin, dest, false, false, payload_len); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.dest_options_num, 2, NULL); zassert_equal(message.hdr.data_options_num, 2, NULL); zassert_equal( message.dest_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[0].must_understand, true, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.dest_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[0].specific.proprietary.vendor_id, vendor_id2, NULL); zassert_equal( message.dest_options[0].specific.proprietary.option_type, proprietary_option_type2, NULL); zassert_equal( message.dest_options[0].specific.proprietary.data_len, sizeof(proprietary_data2), NULL); res = memcmp( message.dest_options[0].specific.proprietary.data, proprietary_data2, sizeof(proprietary_data2)); zassert_equal(res, 0, NULL); zassert_equal( message.dest_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.dest_options[1].must_understand, true, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.dest_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.dest_options[1].specific.proprietary.vendor_id, vendor_id1, NULL); zassert_equal( message.dest_options[1].specific.proprietary.option_type, proprietary_option_type1, NULL); zassert_equal( message.dest_options[1].specific.proprietary.data_len, sizeof(proprietary_data1), NULL); res = memcmp( message.dest_options[1].specific.proprietary.data, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(res, 0, NULL); /* data options */ zassert_equal( message.data_options[0].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[0].must_understand, true, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_MORE, BVLC_SC_HEADER_MORE, NULL); zassert_equal( message.data_options[0].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[0].specific.proprietary.vendor_id, vendor_id4, NULL); zassert_equal( message.data_options[0].specific.proprietary.option_type, proprietary_option_type4, NULL); zassert_equal( message.data_options[0].specific.proprietary.data_len, sizeof(proprietary_data4), NULL); res = memcmp( message.data_options[0].specific.proprietary.data, proprietary_data4, sizeof(proprietary_data4)); zassert_equal(res, 0, NULL); zassert_equal( message.data_options[1].type, BVLC_SC_OPTION_TYPE_PROPRIETARY, NULL); zassert_equal(message.data_options[1].must_understand, true, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_MORE, 0, NULL); zassert_equal( message.data_options[1].packed_header_marker & BVLC_SC_HEADER_DATA, BVLC_SC_HEADER_DATA, NULL); zassert_equal( message.data_options[1].specific.proprietary.vendor_id, vendor_id3, NULL); zassert_equal( message.data_options[1].specific.proprietary.option_type, proprietary_option_type3, NULL); zassert_equal( message.data_options[1].specific.proprietary.data_len, sizeof(proprietary_data3), NULL); res = memcmp( message.data_options[1].specific.proprietary.data, proprietary_data3, sizeof(proprietary_data3)); zassert_equal(res, 0, NULL); zassert_equal(message.hdr.payload_len, payload_len, NULL); res = memcmp(message.hdr.payload, payload, payload_len); zassert_equal(res, 0, NULL); test_header_modifications( buf, len, bvlc_function, message_id, origin, dest, payload, payload_len, false, false); } static void test_options( uint8_t *pdu, size_t pdu_size, uint8_t bvlc_function, uint16_t message_id, BACNET_SC_VMAC_ADDRESS *origin, BACNET_SC_VMAC_ADDRESS *dest, bool test_dest_option, bool test_data_option, uint8_t *payload, size_t payload_len, bool ignore_more_bit_test) { if (!test_dest_option && test_data_option) { test_1_option_data( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_3_options_data( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_3_options_different_buffer_data( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_5_options_data( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); if (!ignore_more_bit_test) { test_options_incorrect_more_bit_data( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); } test_options_incorrect_data_bit_data( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); } else if (test_dest_option && !test_data_option) { test_1_option_dest_incorrect( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_1_option_dest( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_3_options_dest( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_3_options_dest_different_buffer( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_5_options_dest( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); if (!ignore_more_bit_test) { test_options_incorrect_more_bit_dest( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); } test_options_incorrect_data_bit_dest( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); } else if (test_dest_option && test_data_option) { test_options_mixed_case1( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_options_mixed_case2( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); test_options_mixed_case3( pdu, pdu_size, bvlc_function, message_id, origin, dest, payload, payload_len); } } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_BVLC_RESULT) #else static void test_BVLC_RESULT(void) #endif { uint8_t sbuf[256 + BSC_PRE]; uint8_t *buf = &sbuf[BSC_PRE]; int buf_len = 256; size_t len; uint8_t optbuf[256]; size_t optlen; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS new_origin; BACNET_SC_VMAC_ADDRESS dest; BACNET_SC_VMAC_ADDRESS test_dest; uint16_t message_id = 0x7777; uint8_t result_bvlc_function = 3; bool ret; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint8_t error_header_marker = 0xcc; uint16_t test_error_class = 0xaa; uint16_t test_error_code = 0xdd; const char *error_details_string = "something bad has happened"; const char *err_desc = NULL; uint8_t *pdu; memset(origin.address, 0x23, BVLC_SC_VMAC_SIZE); memset(dest.address, 0x44, BVLC_SC_VMAC_SIZE); memset(new_origin.address, 0x93, BVLC_SC_VMAC_SIZE); /* origin and dest presented */ len = bvlc_sc_encode_result( buf, buf_len, message_id, &origin, &dest, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, &origin, &dest, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, &origin, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); ret = bvlc_sc_pdu_has_no_dest(buf, len); zassert_equal(ret, false, NULL); memset(&test_dest, 0, sizeof(test_dest)); ret = bvlc_sc_pdu_get_dest(buf, len, &test_dest); zassert_equal(ret, true, NULL); zassert_equal( 0, memcmp(&dest.address, &test_dest.address, sizeof(test_dest.address)), NULL); pdu = buf; len = bvlc_sc_set_orig(&pdu, len, &new_origin); ret = bvlc_sc_decode_message( pdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, &new_origin, &dest, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( pdu, len, BVLC_SC_RESULT, message_id, &new_origin, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); pdu = buf; len = bvlc_sc_remove_orig_and_dest(&pdu, len); ret = bvlc_sc_decode_message( pdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, NULL, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( pdu, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* origin presented */ len = bvlc_sc_encode_result( buf, buf_len, message_id, &origin, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_no_dest(buf, len); zassert_equal(ret, true, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, &origin, NULL, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, &origin, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); pdu = buf; len = bvlc_sc_remove_orig_and_dest(&pdu, len); ret = bvlc_sc_decode_message( pdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, NULL, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( pdu, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* dest presented */ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, &dest, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, &dest, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, NULL, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); ret = bvlc_sc_pdu_has_no_dest(buf, len); zassert_equal(ret, false, NULL); memset(&test_dest, 0, sizeof(test_dest)); ret = bvlc_sc_pdu_get_dest(buf, len, &test_dest); zassert_equal(ret, true, NULL); zassert_equal( 0, memcmp(&dest.address, &test_dest.address, sizeof(test_dest.address)), NULL); pdu = buf; len = bvlc_sc_set_orig(&pdu, len, &new_origin); ret = bvlc_sc_decode_message( pdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, &new_origin, &dest, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( pdu, len, BVLC_SC_RESULT, message_id, &new_origin, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, &dest, result_bvlc_function, 0, NULL, NULL, NULL, NULL); pdu = buf; len = bvlc_sc_remove_orig_and_dest(&pdu, len); ret = bvlc_sc_decode_message( pdu, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, NULL, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( pdu, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, &dest, result_bvlc_function, 0, NULL, NULL, NULL, NULL); bvlc_sc_remove_dest_set_orig(buf, len, &new_origin); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, &new_origin, NULL, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, &new_origin, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* dest and origin absent */ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_no_dest(buf, len); zassert_equal(ret, true, NULL); memset(&test_dest, 0, sizeof(test_dest)); ret = bvlc_sc_pdu_get_dest(buf, len, &test_dest); zassert_equal(ret, false, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, NULL, true, true, 2); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 0, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* nak, no details string */ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 1, &error_header_marker, &test_error_class, &test_error_code, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, NULL, true, true, 7); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 1, NULL); zassert_equal( message.payload.result.error_header_marker, error_header_marker, NULL); zassert_equal(message.payload.result.error_class, test_error_class, NULL); zassert_equal(message.payload.result.error_code, test_error_code, NULL); zassert_equal(message.payload.result.utf8_details_string, NULL, NULL); zassert_equal(message.payload.result.utf8_details_string_len, 0, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* nak , details string */ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 1, &error_header_marker, &test_error_class, &test_error_code, error_details_string); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, NULL, NULL, true, true, 7 + strlen(error_details_string)); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 1, NULL); zassert_equal( message.payload.result.error_header_marker, error_header_marker, NULL); zassert_equal(message.payload.result.error_class, test_error_class, NULL); zassert_equal(message.payload.result.error_code, test_error_code, NULL); zassert_equal( message.payload.result.utf8_details_string_len, strlen(error_details_string), NULL); ret = memcmp( message.payload.result.utf8_details_string, error_details_string, strlen(error_details_string)) == 0 ? true : false; zassert_equal(ret, true, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* dest and origin, nak , details string */ len = bvlc_sc_encode_result( buf, buf_len, message_id, &origin, &dest, result_bvlc_function, 1, &error_header_marker, &test_error_class, &test_error_code, error_details_string); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_RESULT, message_id, &origin, &dest, true, true, 7 + strlen(error_details_string)); zassert_equal(ret, true, NULL); zassert_equal( message.payload.result.bvlc_function, result_bvlc_function, NULL); zassert_equal(message.payload.result.result, 1, NULL); zassert_equal( message.payload.result.error_header_marker, error_header_marker, NULL); zassert_equal(message.payload.result.error_class, test_error_class, NULL); zassert_equal(message.payload.result.error_code, test_error_code, NULL); zassert_equal( message.payload.result.utf8_details_string_len, strlen(error_details_string), NULL); ret = memcmp( message.payload.result.utf8_details_string, error_details_string, strlen(error_details_string)) == 0 ? true : false; zassert_equal(ret, true, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, &origin, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 1, &error_header_marker, &test_error_class, &test_error_code, error_details_string); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); /* origin and dest absent, result ok*/ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); test_options( buf, len, BVLC_SC_RESULT, message_id, NULL, NULL, true, false, message.hdr.payload, 2, false); /* data option test */ memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, buf_len, buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* zero payload test */ memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* bad result code */ memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); buf[5] = 4; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PARAMETER_OUT_OF_RANGE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* utf-8 string with zero symbol inside */ len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 1, &error_header_marker, &test_error_class, &test_error_code, error_details_string); zassert_not_equal(len, 0, NULL); buf[13] = 0; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* bad payload case 1 */ memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 1, &error_header_marker, &test_error_class, &test_error_code, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 10, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* bad payload case 2 */ memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* bad payload case 3 */ memset(buf, 0, buf_len); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_result( buf, buf_len, message_id, NULL, NULL, result_bvlc_function, 0, NULL, NULL, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 7, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_UNEXPECTED_DATA, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_ENCAPSULATED_NPDU) #else static void test_ENCAPSULATED_NPDU(void) #endif { uint8_t buf[256]; size_t len; uint8_t npdu[256]; size_t npdulen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x1789; int res; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; bool ret; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); memset(&origin.address, 0x63, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0x24, BVLC_SC_VMAC_SIZE); memset(npdu, 0x99, sizeof(npdu)); npdulen = 50; /* dest and origin absent */ len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, NULL, NULL, npdu, npdulen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, NULL, true, true, npdulen); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, 0, NULL); zassert_equal(message.hdr.payload_len, npdulen, NULL); res = memcmp(message.hdr.payload, npdu, npdulen); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, NULL, true, false, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, NULL, false, true, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, NULL, true, true, npdu, npdulen, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is presented, dest is absent */ len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, &origin, NULL, npdu, npdulen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, NULL, true, true, npdulen); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, 0, NULL); zassert_equal(message.hdr.payload_len, npdulen, NULL); res = memcmp(message.hdr.payload, npdu, npdulen); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, NULL, true, false, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, NULL, false, true, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, NULL, true, true, npdu, npdulen, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is absent, dest is presented */ len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, NULL, &dest, npdu, npdulen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, &dest, true, true, npdulen); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, 0, NULL); zassert_equal(message.hdr.payload_len, npdulen, NULL); res = memcmp(message.hdr.payload, npdu, npdulen); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, &dest, true, false, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, &dest, false, true, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, NULL, &dest, true, true, npdu, npdulen, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* both dest and origin are presented */ len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, &origin, &dest, npdu, npdulen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, &dest, true, true, npdulen); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, 0, NULL); zassert_equal(message.hdr.payload_len, npdulen, NULL); res = memcmp(message.hdr.payload, npdu, npdulen); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, &dest, true, false, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, &dest, false, true, npdu, npdulen, true); test_options( buf, len, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, &dest, true, true, npdu, npdulen, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, &origin, &dest, npdu, npdulen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 4 */ ret = bvlc_sc_decode_message( buf, 16, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* zero payload test */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, &origin, &dest, npdu, 0); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* 1 byte payload test */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, &origin, &dest, npdu, 1); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ENCAPSULATED_NPDU, message_id, &origin, &dest, true, true, 1); zassert_equal(ret, true, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_ADDRESS_RESOLUTION) #else static void test_ADDRESS_RESOLUTION(void) #endif { uint8_t buf[256]; size_t len; uint8_t optbuf[256]; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x514a; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; bool ret; const char *err_desc = NULL; memset(&origin.address, 0x27, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0xaa, BVLC_SC_VMAC_SIZE); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* dest and origin absent */ len = bvlc_sc_encode_address_resolution( buf, sizeof(buf), message_id, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION, message_id, NULL, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION, message_id, NULL, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is presented, dest is absent */ len = bvlc_sc_encode_address_resolution( buf, sizeof(buf), message_id, &origin, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION, message_id, &origin, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION, message_id, &origin, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is absent, dest is presented */ len = bvlc_sc_encode_address_resolution( buf, sizeof(buf), message_id, NULL, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION, message_id, NULL, &dest, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION, message_id, NULL, &dest, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin and dest are presented */ len = bvlc_sc_encode_address_resolution( buf, sizeof(buf), message_id, &origin, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION, message_id, &origin, &dest, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION, message_id, &origin, &dest, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_address_resolution( buf, sizeof(buf), message_id, &origin, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* data options test */ optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_ADDRESS_RESOLUTION_ACK) #else static void test_ADDRESS_RESOLUTION_ACK(void) #endif { uint8_t buf[256]; size_t len; uint8_t optbuf[256]; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0xf1d3; int res; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; bool ret; char web_socket_uris[256]; const char *err_desc = NULL; web_socket_uris[0] = 0; sprintf(web_socket_uris, "%s %s", "web_socket_uri1", "web_socket_uri2"); memset(&origin.address, 0x91, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0xef, BVLC_SC_VMAC_SIZE); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* dest and origin absent */ len = bvlc_sc_encode_address_resolution_ack( buf, sizeof(buf), message_id, NULL, NULL, (uint8_t *)web_socket_uris, strlen(web_socket_uris)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, NULL, NULL, true, true, strlen(web_socket_uris)); zassert_equal(ret, true, NULL); res = memcmp(message.hdr.payload, web_socket_uris, strlen(web_socket_uris)); zassert_equal(res, 0, NULL); zassert_not_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string, NULL, NULL); zassert_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string_len, strlen(web_socket_uris), NULL); zassert_equal(message.hdr.payload_len, strlen(web_socket_uris), NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, NULL, NULL, true, false, (uint8_t *)web_socket_uris, strlen(web_socket_uris), true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is presented, dest is absent */ len = bvlc_sc_encode_address_resolution_ack( buf, sizeof(buf), message_id, &origin, NULL, (uint8_t *)web_socket_uris, strlen(web_socket_uris)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, &origin, NULL, true, true, strlen(web_socket_uris)); zassert_equal(ret, true, NULL); res = memcmp(message.hdr.payload, web_socket_uris, strlen(web_socket_uris)); zassert_equal(res, 0, NULL); zassert_not_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string, NULL, NULL); zassert_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string_len, strlen(web_socket_uris), NULL); zassert_equal(message.hdr.payload_len, strlen(web_socket_uris), NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, &origin, NULL, true, false, (uint8_t *)web_socket_uris, strlen(web_socket_uris), true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is absent, dest is presented */ len = bvlc_sc_encode_address_resolution_ack( buf, sizeof(buf), message_id, NULL, &dest, (uint8_t *)web_socket_uris, strlen(web_socket_uris)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, NULL, &dest, true, true, strlen(web_socket_uris)); zassert_equal(ret, true, NULL); res = memcmp(message.hdr.payload, web_socket_uris, strlen(web_socket_uris)); zassert_equal(res, 0, NULL); zassert_not_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string, NULL, NULL); zassert_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string_len, strlen(web_socket_uris), NULL); zassert_equal(message.hdr.payload_len, strlen(web_socket_uris), NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, NULL, &dest, true, false, (uint8_t *)web_socket_uris, strlen(web_socket_uris), true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin and dest are presented */ len = bvlc_sc_encode_address_resolution_ack( buf, sizeof(buf), message_id, &origin, &dest, (uint8_t *)web_socket_uris, strlen(web_socket_uris)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, &origin, &dest, true, true, strlen(web_socket_uris)); zassert_equal(ret, true, NULL); res = memcmp(message.hdr.payload, web_socket_uris, strlen(web_socket_uris)); zassert_equal(res, 0, NULL); zassert_not_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string, NULL, NULL); zassert_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string_len, strlen(web_socket_uris), NULL); zassert_equal(message.hdr.payload_len, strlen(web_socket_uris), NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, &origin, &dest, true, false, (uint8_t *)web_socket_uris, strlen(web_socket_uris), true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* zero payload test */ len = bvlc_sc_encode_address_resolution_ack( buf, sizeof(buf), message_id, &origin, &dest, NULL, 0); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, &origin, &dest, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string, NULL, NULL); zassert_equal( message.payload.address_resolution_ack.utf8_websocket_uri_string_len, 0, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADDRESS_RESOLUTION_ACK, message_id, &origin, &dest, true, false, NULL, 0, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_address_resolution_ack( buf, sizeof(buf), message_id, &origin, &dest, (uint8_t *)web_socket_uris, strlen(web_socket_uris)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 4 */ ret = bvlc_sc_decode_message( buf, 15, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* data options test */ optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_ADVERTISIMENT) #else static void test_ADVERTISIMENT(void) #endif { uint8_t buf[256]; size_t len; uint8_t optbuf[256]; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0xe2ad; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; bool ret; BACNET_SC_HUB_CONNECTOR_STATE hub_status = BACNET_SC_HUB_CONNECTOR_STATE_CONNECTED_TO_PRIMARY; BVLC_SC_DIRECT_CONNECTION_SUPPORT support = BVLC_SC_DIRECT_CONNECTION_ACCEPT_SUPPORTED; uint16_t max_bvlc_len = 567; uint16_t max_npdu_len = 1323; const char *err_desc = NULL; memset(&origin.address, 0xe1, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0x4f, BVLC_SC_VMAC_SIZE); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* dest and origin absent */ len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, NULL, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT, message_id, NULL, NULL, true, true, 6); zassert_equal(ret, true, NULL); zassert_equal(message.payload.advertisiment.hub_status, hub_status, NULL); zassert_equal(message.payload.advertisiment.support, support, NULL); zassert_equal( message.payload.advertisiment.max_bvlc_len, max_bvlc_len, NULL); zassert_equal( message.payload.advertisiment.max_npdu_len, max_npdu_len, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is presented, dest is absent */ len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, &origin, NULL, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT, message_id, &origin, NULL, true, true, 6); zassert_equal(ret, true, NULL); zassert_equal(message.payload.advertisiment.hub_status, hub_status, NULL); zassert_equal(message.payload.advertisiment.support, support, NULL); zassert_equal( message.payload.advertisiment.max_bvlc_len, max_bvlc_len, NULL); zassert_equal( message.payload.advertisiment.max_npdu_len, max_npdu_len, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT, message_id, &origin, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is absent, dest is presented */ len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, &dest, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT, message_id, NULL, &dest, true, true, 6); zassert_equal(ret, true, NULL); zassert_equal(message.payload.advertisiment.hub_status, hub_status, NULL); zassert_equal(message.payload.advertisiment.support, support, NULL); zassert_equal( message.payload.advertisiment.max_bvlc_len, max_bvlc_len, NULL); zassert_equal( message.payload.advertisiment.max_npdu_len, max_npdu_len, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT, message_id, NULL, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin and dest are presented */ len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, &origin, &dest, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT, message_id, &origin, &dest, true, true, 6); zassert_equal(ret, true, NULL); zassert_equal(message.payload.advertisiment.hub_status, hub_status, NULL); zassert_equal(message.payload.advertisiment.support, support, NULL); zassert_equal( message.payload.advertisiment.max_bvlc_len, max_bvlc_len, NULL); zassert_equal( message.payload.advertisiment.max_npdu_len, max_npdu_len, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT, message_id, &origin, &dest, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, &origin, &dest, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 4 */ ret = bvlc_sc_decode_message( buf, 15, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* bad hub connection param */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, NULL, 5, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PARAMETER_OUT_OF_RANGE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* bad support param */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, NULL, hub_status, 4, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PARAMETER_OUT_OF_RANGE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* payload len < 6 */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, NULL, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* zero payload test */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, NULL, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* data options presented */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_advertisiment( buf, sizeof(buf), message_id, NULL, NULL, hub_status, support, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_ADVERTISIMENT_SOLICITATION) #else static void test_ADVERTISIMENT_SOLICITATION(void) #endif { uint8_t buf[256]; size_t len; uint8_t optbuf[256]; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0xaf4a; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; bool ret; const char *err_desc = NULL; memset(&origin.address, 0x17, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0x1a, BVLC_SC_VMAC_SIZE); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* dest and origin absent */ len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), message_id, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, NULL, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, NULL, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is presented, dest is absent */ len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), message_id, &origin, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, &origin, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, &origin, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is absent, dest is presented */ len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), message_id, NULL, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, NULL, &dest, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, NULL, &dest, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin and dest are presented */ len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), message_id, &origin, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, &origin, &dest, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_ADVERTISIMENT_SOLICITATION, message_id, &origin, &dest, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), message_id, &origin, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* data options test */ optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_CONNECT_REQUEST) #else static void test_CONNECT_REQUEST(void) #endif { uint8_t buf[256]; size_t len; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x41af; int res; bool ret; uint16_t max_bvlc_len = 9997; uint16_t max_npdu_len = 3329; BACNET_SC_VMAC_ADDRESS local_vmac; BACNET_SC_UUID local_uuid; const char *err_desc = NULL; memset(&local_vmac, 0x88, sizeof(local_vmac)); memset(&local_uuid, 0x22, sizeof(local_uuid)); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_connect_request( buf, sizeof(buf), message_id, &local_vmac, &local_uuid, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_CONNECT_REQUEST, message_id, NULL, NULL, true, true, 26); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload_len, 26, NULL); res = memcmp( message.payload.connect_request.vmac, &local_vmac, BVLC_SC_VMAC_SIZE); zassert_equal(res, 0, NULL); res = memcmp( message.payload.connect_request.uuid, &local_uuid, BVLC_SC_VMAC_SIZE); zassert_equal(res, 0, NULL); zassert_equal( message.payload.connect_request.max_bvlc_len, max_bvlc_len, NULL); zassert_equal( message.payload.connect_request.max_npdu_len, max_npdu_len, NULL); test_options( buf, len, BVLC_SC_CONNECT_REQUEST, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_connect_request( buf, sizeof(buf), message_id, &local_vmac, &local_uuid, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* message has dest */ buf[1] |= BVLC_SC_CONTROL_DEST_VADDR; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* message has origin */ buf[1] |= BVLC_SC_CONTROL_ORIG_VADDR; buf[1] &= ~BVLC_SC_CONTROL_DEST_VADDR; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* message has both dest and orign */ buf[1] |= BVLC_SC_CONTROL_ORIG_VADDR; buf[1] |= BVLC_SC_CONTROL_DEST_VADDR; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_CONNECT_ACCEPT) #else static void test_CONNECT_ACCEPT(void) #endif { uint8_t buf[256]; size_t len; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; int res; bool ret; uint16_t max_bvlc_len = 1027; uint16_t max_npdu_len = 22; BACNET_SC_VMAC_ADDRESS local_vmac; BACNET_SC_UUID local_uuid; const char *err_desc = NULL; memset(&local_vmac, 0x33, sizeof(local_vmac)); memset(&local_uuid, 0x11, sizeof(local_uuid)); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_connect_accept( buf, sizeof(buf), message_id, &local_vmac, &local_uuid, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_CONNECT_ACCEPT, message_id, NULL, NULL, true, true, 26); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload_len, 26, NULL); res = memcmp( message.payload.connect_accept.vmac, &local_vmac, BVLC_SC_VMAC_SIZE); zassert_equal(res, 0, NULL); res = memcmp( message.payload.connect_accept.uuid, &local_uuid, BVLC_SC_VMAC_SIZE); zassert_equal(res, 0, NULL); zassert_equal( message.payload.connect_accept.max_bvlc_len, max_bvlc_len, NULL); zassert_equal( message.payload.connect_accept.max_npdu_len, max_npdu_len, NULL); test_options( buf, len, BVLC_SC_CONNECT_ACCEPT, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_connect_accept( buf, sizeof(buf), message_id, &local_vmac, &local_uuid, max_bvlc_len, max_npdu_len); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* message has dest */ buf[1] |= BVLC_SC_CONTROL_DEST_VADDR; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* message has origin */ buf[1] |= BVLC_SC_CONTROL_ORIG_VADDR; buf[1] &= ~BVLC_SC_CONTROL_DEST_VADDR; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* message has both dest and orign */ buf[1] |= BVLC_SC_CONTROL_ORIG_VADDR; buf[1] |= BVLC_SC_CONTROL_DEST_VADDR; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_DISCONNECT_REQUEST) #else static void test_DISCONNECT_REQUEST(void) #endif { uint8_t buf[256]; size_t len; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; bool ret; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_disconnect_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_DISCONNECT_REQUEST, message_id, NULL, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_DISCONNECT_REQUEST, message_id, NULL, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_disconnect_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_UNEXPECTED_DATA, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); ret = bvlc_sc_decode_message( buf, 3, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_DISCARD, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_DISCONNECT_ACK) #else static void test_DISCONNECT_ACK(void) #endif { uint8_t buf[256]; size_t len; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; bool ret; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_disconnect_ack(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_DISCONNECT_ACK, message_id, NULL, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_DISCONNECT_ACK, message_id, NULL, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_disconnect_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_UNEXPECTED_DATA, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); ret = bvlc_sc_decode_message( buf, 3, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_DISCARD, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_HEARTBEAT_REQUEST) #else static void test_HEARTBEAT_REQUEST(void) #endif { uint8_t buf[256]; size_t len; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; bool ret; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_HEARTBEAT_REQUEST, message_id, NULL, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_HEARTBEAT_REQUEST, message_id, NULL, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_disconnect_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_UNEXPECTED_DATA, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); ret = bvlc_sc_decode_message( buf, 3, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_DISCARD, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_HEARTBEAT_ACK) #else static void test_HEARTBEAT_ACK(void) #endif { uint8_t buf[256]; size_t len; uint8_t optbuf[256]; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; bool ret; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); len = bvlc_sc_encode_heartbeat_ack(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_HEARTBEAT_ACK, message_id, NULL, NULL, true, true, 0); zassert_equal(ret, true, NULL); zassert_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 0, NULL); test_options( buf, len, BVLC_SC_HEARTBEAT_ACK, message_id, NULL, NULL, true, false, NULL, 0, false); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_heartbeat_ack(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_UNEXPECTED_DATA, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); ret = bvlc_sc_decode_message( buf, 3, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_DISCARD, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* data options test */ optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_PROPRIETARY_MESSAGE) #else static void test_PROPRIETARY_MESSAGE(void) #endif { uint8_t buf[256]; size_t len; uint8_t optbuf[256]; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x4455; int res; bool ret; uint8_t proprietary_function = 0xea; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; uint16_t vendor_id = 0xaabb; uint8_t data[34]; const char *err_desc = NULL; memset(data, 0x66, sizeof(data)); memset(&origin.address, 0x2f, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0xf3, BVLC_SC_VMAC_SIZE); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* dest and origin absent */ len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), message_id, NULL, NULL, vendor_id, proprietary_function, data, sizeof(data)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_PROPRIETARY_MESSAGE, message_id, NULL, NULL, true, true, 3 + sizeof(data)); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 3 + sizeof(data), NULL); zassert_equal(message.payload.proprietary.vendor_id, vendor_id, NULL); zassert_equal( message.payload.proprietary.function, proprietary_function, NULL); zassert_equal(message.payload.proprietary.data_len, sizeof(data), NULL); res = memcmp(message.payload.proprietary.data, data, sizeof(data)); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_PROPRIETARY_MESSAGE, message_id, NULL, NULL, true, false, message.hdr.payload, message.hdr.payload_len, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is presented, dest is absent */ len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), message_id, &origin, NULL, vendor_id, proprietary_function, data, sizeof(data)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_PROPRIETARY_MESSAGE, message_id, &origin, NULL, true, true, 3 + sizeof(data)); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 3 + sizeof(data), NULL); zassert_equal(message.payload.proprietary.vendor_id, vendor_id, NULL); zassert_equal( message.payload.proprietary.function, proprietary_function, NULL); zassert_equal(message.payload.proprietary.data_len, sizeof(data), NULL); res = memcmp(message.payload.proprietary.data, data, sizeof(data)); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_PROPRIETARY_MESSAGE, message_id, &origin, NULL, true, false, message.hdr.payload, message.hdr.payload_len, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin is absent, dest is presented */ len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), message_id, NULL, &dest, vendor_id, proprietary_function, data, sizeof(data)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_PROPRIETARY_MESSAGE, message_id, NULL, &dest, true, true, 3 + sizeof(data)); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 3 + sizeof(data), NULL); zassert_equal(message.payload.proprietary.vendor_id, vendor_id, NULL); zassert_equal( message.payload.proprietary.function, proprietary_function, NULL); zassert_equal(message.payload.proprietary.data_len, sizeof(data), NULL); res = memcmp(message.payload.proprietary.data, data, sizeof(data)); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_PROPRIETARY_MESSAGE, message_id, NULL, &dest, true, false, message.hdr.payload, message.hdr.payload_len, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* origin and dest are presented */ len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), message_id, &origin, &dest, vendor_id, proprietary_function, data, sizeof(data)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = verify_bsc_bvll_header( &message.hdr, BVLC_SC_PROPRIETARY_MESSAGE, message_id, &origin, &dest, true, true, 3 + sizeof(data)); zassert_equal(ret, true, NULL); zassert_not_equal(message.hdr.payload, NULL, NULL); zassert_equal(message.hdr.payload_len, 3 + sizeof(data), NULL); zassert_equal(message.payload.proprietary.vendor_id, vendor_id, NULL); zassert_equal( message.payload.proprietary.function, proprietary_function, NULL); zassert_equal(message.payload.proprietary.data_len, sizeof(data), NULL); res = memcmp(message.payload.proprietary.data, data, sizeof(data)); zassert_equal(res, 0, NULL); test_options( buf, len, BVLC_SC_PROPRIETARY_MESSAGE, message_id, &origin, &dest, true, false, message.hdr.payload, message.hdr.payload_len, true); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), message_id, &origin, &dest, vendor_id, proprietary_function, data, sizeof(data)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 5, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 2 */ ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 3 */ ret = bvlc_sc_decode_message( buf, 13, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* truncated message, case 5 */ ret = bvlc_sc_decode_message( buf, 18, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* data options test */ optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_INCONSISTENT_PARAMETERS, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* zero payload test */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message, case 1 */ len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), message_id, NULL, NULL, vendor_id, proprietary_function, data, sizeof(data)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_PAYLOAD_EXPECTED, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* zero payload test */ ret = bvlc_sc_decode_message( buf, 7, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); zassert_equal(message.payload.proprietary.vendor_id, vendor_id, NULL); zassert_equal( message.payload.proprietary.function, proprietary_function, NULL); zassert_equal(message.payload.proprietary.data_len, 0, NULL); zassert_equal(message.payload.proprietary.data, NULL, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_BAD_HEADER_OPTIONS) #else static void test_BAD_HEADER_OPTIONS(void) #endif { uint8_t buf[256]; uint8_t optbuf[256]; uint8_t npdu[256]; uint16_t npdulen; size_t len; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; bool ret; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* form secure path option with data flag enabled (which is incorrect ) */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); buf[4] |= BVLC_SC_HEADER_DATA; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); /* form unknown header option */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); buf[4] |= 2; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* form unknown header option */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_secure_path_option(optbuf, sizeof(optbuf), true); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); buf[4] |= 2; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_HEADER_ENCODING_ERROR, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated proprietary option, case 1 */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); ret = bvlc_sc_decode_message( buf, 6, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated proprietary option, case 2 */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); ret = bvlc_sc_decode_message( buf, 9, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message with destination options */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, 4, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_MESSAGE_INCOMPLETE, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* call add option func with bad parameters */ vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_not_equal(optlen, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), NULL, len, optbuf, optlen); zassert_equal(len, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, 3, optbuf, optlen); zassert_equal(len, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, 64000, optbuf, 64000); zassert_equal(len, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, 100, buf, 120, optbuf, optlen); zassert_equal(len, 0, NULL); len = bvlc_sc_add_option_to_destination_options( buf, 101, buf, 100, optbuf, optlen); zassert_equal(len, 0, NULL); optbuf[0] |= BVLC_SC_HEADER_MORE; len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, 20, optbuf, optlen); zassert_equal(len, 0, NULL); optbuf[0] = 23; len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, 20, optbuf, optlen); zassert_equal(len, 0, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* truncated message with destination options */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_not_equal(len, 0, NULL); buf[4] = 23; len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_equal(len, 0, NULL); /* message with incorrect dest options */ len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), message_id); zassert_not_equal(len, 0, NULL); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); len = bvlc_sc_add_option_to_destination_options( buf, sizeof(buf), buf, len, optbuf, optlen); buf[4] = 23; len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, len, optbuf, optlen); zassert_equal(len, 0, NULL); /* one more incorrect call to add options */ memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); memset(&origin.address, 0x63, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0x24, BVLC_SC_VMAC_SIZE); memset(npdu, 0x99, sizeof(npdu)); npdulen = 50; len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, &origin, &dest, npdu, npdulen); optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); len = bvlc_sc_add_option_to_data_options( buf, sizeof(buf), buf, 4, optbuf, optlen); zassert_equal(len, 0, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_BAD_ENCODE_PARAMS) #else static void test_BAD_ENCODE_PARAMS(void) #endif { uint8_t buf[256]; uint8_t optbuf[256]; uint8_t npdu[256]; uint16_t npdulen; size_t len; size_t optlen; BVLC_SC_DECODED_MESSAGE message; uint16_t message_id = 0x0203; uint16_t vendor_id1; uint8_t proprietary_option_type1; uint8_t proprietary_data1[17]; BACNET_SC_VMAC_ADDRESS origin; BACNET_SC_VMAC_ADDRESS dest; uint8_t error_header_marker = 0xcc; uint16_t error_class = 0xaa; uint16_t error_code = 0xdd; const char *error_details_string = "something bad has happend"; BACNET_SC_VMAC_ADDRESS local_vmac; BACNET_SC_UUID local_uuid; uint8_t data[34]; uint8_t proprietary_function = 0xea; memset(data, 0x66, sizeof(data)); memset(&local_uuid, 0x22, sizeof(local_uuid)); memset(&local_vmac, 0x42, sizeof(local_vmac)); memset(&origin.address, 0x63, BVLC_SC_VMAC_SIZE); memset(&dest.address, 0x24, BVLC_SC_VMAC_SIZE); memset(npdu, 0x99, sizeof(npdu)); npdulen = 50; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); vendor_id1 = 0xdead; proprietary_option_type1 = 0x77; memset(proprietary_data1, 0x99, sizeof(proprietary_data1)); /* case 1 */ optlen = bvlc_sc_encode_proprietary_option( optbuf, sizeof(optbuf), true, vendor_id1, proprietary_option_type1, proprietary_data1, BVLC_SC_NPDU_SIZE - 3); zassert_equal(optlen, 0, NULL); /* case 2 */ optlen = bvlc_sc_encode_proprietary_option( optbuf, 3, true, vendor_id1, proprietary_option_type1, proprietary_data1, sizeof(proprietary_data1)); zassert_equal(optlen, 0, NULL); /* case 3 */ optlen = bvlc_sc_encode_secure_path_option(optbuf, 0, true); zassert_equal(optlen, 0, NULL); /* case 4 */ len = bvlc_sc_encode_heartbeat_request(buf, 3, message_id); zassert_equal(len, 0, NULL); /* case 5 */ len = bvlc_sc_encode_heartbeat_request(buf, 3, message_id); zassert_equal(len, 0, NULL); /* case 6 */ len = bvlc_sc_encode_encapsulated_npdu( buf, 5, message_id, &origin, NULL, npdu, npdulen); zassert_equal(len, 0, NULL); /* case 7 */ len = bvlc_sc_encode_encapsulated_npdu( buf, 6 + BVLC_SC_VMAC_SIZE, message_id, &origin, &dest, npdu, npdulen); zassert_equal(len, 0, NULL); /* case 8 */ len = bvlc_sc_encode_result( buf, sizeof(buf), message_id, &origin, &dest, 99, 0, NULL, NULL, NULL, NULL); zassert_equal(len, 0, NULL); /* case 9 */ len = bvlc_sc_encode_result( buf, sizeof(buf), message_id, &origin, &dest, 1, 4, NULL, NULL, NULL, NULL); zassert_equal(len, 0, NULL); /* case 9 */ len = bvlc_sc_encode_result( buf, sizeof(buf), message_id, &origin, &dest, 1, 1, NULL, NULL, NULL, NULL); zassert_equal(len, 0, NULL); /* case 10 */ len = bvlc_sc_encode_result( buf, 3, message_id, &origin, &dest, 1, 0, NULL, NULL, NULL, NULL); zassert_equal(len, 0, NULL); /* case 11 */ len = bvlc_sc_encode_result( buf, 5, message_id, NULL, NULL, 1, 0, NULL, NULL, NULL, NULL); zassert_equal(len, 0, NULL); /* case 12 */ len = bvlc_sc_encode_result( buf, 7, message_id, NULL, NULL, 1, 0, (uint8_t *)1, NULL, NULL, NULL); zassert_equal(len, 0, NULL); /* case 13 */ len = bvlc_sc_encode_result( buf, 7, message_id, NULL, NULL, 1, 1, &error_header_marker, &error_class, &error_code, error_details_string); zassert_equal(len, 0, NULL); /* case 13 */ len = bvlc_sc_encode_result( buf, 12, message_id, NULL, NULL, 1, 1, &error_header_marker, &error_class, &error_code, error_details_string); zassert_equal(len, 0, NULL); /* case 14 */ len = bvlc_sc_encode_encapsulated_npdu( buf, 3, message_id, NULL, NULL, npdu, npdulen); zassert_equal(len, 0, NULL); /* case 15 */ len = bvlc_sc_encode_encapsulated_npdu( buf, 6, message_id, NULL, NULL, npdu, npdulen); zassert_equal(len, 0, NULL); /* case 16 */ len = bvlc_sc_encode_address_resolution_ack( buf, 3, message_id, NULL, NULL, NULL, 0); zassert_equal(len, 0, NULL); /* case 17 */ len = bvlc_sc_encode_advertisiment( buf, 3, message_id, NULL, NULL, 1, 1, 1, 1); zassert_equal(len, 0, NULL); /* case 18 */ len = bvlc_sc_encode_connect_request( buf, sizeof(buf), message_id, NULL, NULL, 1, 1); zassert_equal(len, 0, NULL); /* case 19 */ len = bvlc_sc_encode_connect_request( buf, 3, message_id, &local_vmac, &local_uuid, 1, 1); zassert_equal(len, 0, NULL); /* case 20 */ len = bvlc_sc_encode_connect_request( buf, 5, message_id, &local_vmac, &local_uuid, 1, 1); zassert_equal(len, 0, NULL); /* case 21 */ len = bvlc_sc_encode_connect_accept( buf, sizeof(buf), message_id, NULL, NULL, 1, 1); zassert_equal(len, 0, NULL); /* case 22 */ len = bvlc_sc_encode_connect_accept( buf, 3, message_id, &local_vmac, &local_uuid, 1, 1); zassert_equal(len, 0, NULL); /* case 23 */ len = bvlc_sc_encode_connect_accept( buf, 5, message_id, &local_vmac, &local_uuid, 1, 1); zassert_equal(len, 0, NULL); /* case 24 */ len = bvlc_sc_encode_proprietary_message( buf, 3, message_id, NULL, NULL, vendor_id1, proprietary_function, data, sizeof(data)); zassert_equal(len, 0, NULL); /* case 25 */ len = bvlc_sc_encode_proprietary_message( buf, 5, message_id, NULL, NULL, vendor_id1, proprietary_function, data, sizeof(data)); zassert_equal(len, 0, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_BAD_DECODE_PARAMS) #else static void test_BAD_DECODE_PARAMS(void) #endif { uint8_t buf[256]; uint8_t npdu[256]; uint16_t npdulen = 50; size_t len; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; uint16_t message_id = 0x0203; bool ret; const char *err_desc = NULL; memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); /* case 1 */ len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), message_id, NULL, NULL, npdu, npdulen); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, NULL, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); /* case 2 */ buf[0] = 99; ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, false, NULL); zassert_equal(error_code, ERROR_CODE_BVLC_FUNCTION_UNKNOWN, NULL); zassert_equal(error_class, ERROR_CLASS_COMMUNICATION, NULL); memset(buf, 0, sizeof(buf)); memset(&message, 0, sizeof(message)); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST(bvlc_sc_tests, test_BROADCAST) #else static void test_BROADCAST(void) #endif { uint8_t buf[256]; size_t len; BACNET_SC_VMAC_ADDRESS dest; BACNET_SC_VMAC_ADDRESS orig; bool ret; uint8_t *pdu; BVLC_SC_DECODED_MESSAGE message; uint16_t error_code; uint16_t error_class; const char *err_desc = NULL; BACNET_SC_UUID uuid = { { 0x34 } }; memset(&dest.address, 0xFF, sizeof(dest.address)); memset(&orig.address, 0x12, sizeof(orig.address)); ret = bvlc_sc_is_vmac_broadcast(&dest); zassert_equal(ret, true, NULL); ret = bvlc_sc_is_vmac_broadcast(&orig); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, &orig, &orig); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_dest_broadcast(buf, len); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, &orig, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_dest_broadcast(buf, len); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_disconnect_ack(buf, sizeof(buf), 0xF00D); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_dest_broadcast(buf, len); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, NULL, &orig); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_dest_broadcast(buf, len); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, NULL, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_dest_broadcast(buf, len); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_pdu_has_dest_broadcast(buf, len); zassert_equal(ret, false, NULL); pdu = buf; len = bvlc_sc_set_orig(&pdu, len, &orig); zassert_equal(len, 4, NULL); len = bvlc_sc_remove_orig_and_dest(&pdu, len); zassert_equal(len, 4, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, NULL, &dest); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_connect_request( buf, sizeof(buf), 0xF00D, &orig, &uuid, 1000, 1000); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_connect_accept( buf, sizeof(buf), 0xF00D, &orig, &uuid, 1000, 1000); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_disconnect_request(buf, sizeof(buf), 0xF00D); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_encapsulated_npdu( buf, sizeof(buf), 0xF00D, NULL, NULL, (uint8_t *)&orig, sizeof(orig)); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_proprietary_message( buf, sizeof(buf), 0xF00D, NULL, NULL, 123, 123, NULL, 0); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, false, NULL); len = bvlc_sc_encode_heartbeat_request(buf, sizeof(buf), 0xF00D); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_address_resolution(buf, sizeof(buf), 0xF00D, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); len = bvlc_sc_encode_advertisiment_solicitation( buf, sizeof(buf), 0xF00D, NULL, NULL); zassert_not_equal(len, 0, NULL); ret = bvlc_sc_decode_message( buf, len, &message, &error_code, &error_class, &err_desc); zassert_equal(ret, true, NULL); ret = bvlc_sc_need_send_bvlc_result(&message); zassert_equal(ret, true, NULL); } #if defined(CONFIG_ZTEST_NEW_API) ZTEST_SUITE(bvlc_sc_tests, NULL, NULL, NULL, NULL, NULL); #else void test_main(void) { ztest_test_suite( bvlc_sc_tests, ztest_unit_test(test_BVLC_RESULT), ztest_unit_test(test_ENCAPSULATED_NPDU), ztest_unit_test(test_ADDRESS_RESOLUTION), ztest_unit_test(test_ADDRESS_RESOLUTION_ACK), ztest_unit_test(test_ADVERTISIMENT), ztest_unit_test(test_ADVERTISIMENT_SOLICITATION), ztest_unit_test(test_CONNECT_REQUEST), ztest_unit_test(test_CONNECT_ACCEPT), ztest_unit_test(test_DISCONNECT_REQUEST), ztest_unit_test(test_DISCONNECT_ACK), ztest_unit_test(test_HEARTBEAT_REQUEST), ztest_unit_test(test_HEARTBEAT_ACK), ztest_unit_test(test_PROPRIETARY_MESSAGE), ztest_unit_test(test_BAD_HEADER_OPTIONS), ztest_unit_test(test_BAD_ENCODE_PARAMS), ztest_unit_test(test_BAD_DECODE_PARAMS), ztest_unit_test(test_BROADCAST)); ztest_run_test_suite(bvlc_sc_tests); } #endif