diff --git a/src/bacnet/hostnport.c b/src/bacnet/hostnport.c index 08dca1e7..a8fb8199 100644 --- a/src/bacnet/hostnport.c +++ b/src/bacnet/hostnport.c @@ -245,6 +245,59 @@ int host_n_port_decode(uint8_t *apdu, return apdu_len; } +/** + * @brief Decode a context encoded BACnetHostNPort complex data + * @param apdu - the APDU buffer + * @param apdu_size - the APDU buffer length + * @param tag_number - context tag number to be decoded + * @param error_code - error or reject or abort when error occurs + * @param address - IP address and port number + * @return length of the APDU buffer decoded, or ERROR, REJECT, or ABORT + */ +int host_n_port_context_decode(uint8_t *apdu, + uint32_t apdu_size, + uint8_t tag_number, + BACNET_ERROR_CODE *error_code, + BACNET_HOST_N_PORT *address) +{ + int len = 0; + int apdu_len = 0; + + /* default reject code */ + if (error_code) { + *error_code = ERROR_CODE_REJECT_MISSING_REQUIRED_PARAMETER; + } + if (!bacnet_is_opening_tag_number( + &apdu[apdu_len], apdu_size - apdu_len, tag_number, &len)) { + if (error_code) { + *error_code = ERROR_CODE_REJECT_INVALID_TAG; + } + + return BACNET_STATUS_REJECT; + } + apdu_len += len; + len = host_n_port_decode(&apdu[apdu_len], apdu_size - apdu_len, + error_code, address); + if (len > 0) { + apdu_len += len; + } else { + if (error_code) { + *error_code = ERROR_CODE_REJECT_OTHER; + } + return BACNET_STATUS_REJECT; + } + if (!bacnet_is_closing_tag_number( + &apdu[apdu_len], apdu_size - apdu_len, tag_number, &len)) { + if (error_code) { + *error_code = ERROR_CODE_REJECT_INVALID_TAG; + } + return BACNET_STATUS_REJECT; + } + apdu_len += len; + + return apdu_len; +} + /** * @brief Copy the BACnetHostNPort complex data from src to dst * @param dst - destination structure diff --git a/src/bacnet/hostnport.h b/src/bacnet/hostnport.h index e4ab9617..29f83ff0 100644 --- a/src/bacnet/hostnport.h +++ b/src/bacnet/hostnport.h @@ -61,6 +61,12 @@ extern "C" { BACNET_ERROR_CODE *error_code, BACNET_HOST_N_PORT *address); BACNET_STACK_EXPORT + int host_n_port_context_decode(uint8_t *apdu, + uint32_t apdu_size, + uint8_t tag_number, + BACNET_ERROR_CODE *error_code, + BACNET_HOST_N_PORT *address); + BACNET_STACK_EXPORT bool host_n_port_copy( BACNET_HOST_N_PORT * dst, BACNET_HOST_N_PORT * src); diff --git a/test/bacnet/hostnport/src/main.c b/test/bacnet/hostnport/src/main.c index 502ebd7d..1ffbbefd 100644 --- a/test/bacnet/hostnport/src/main.c +++ b/test/bacnet/hostnport/src/main.c @@ -41,19 +41,14 @@ static void test_HostNPortCodec(BACNET_HOST_N_PORT *data) zassert_equal(apdu_len, null_len, NULL); zassert_true(apdu_len != BACNET_STATUS_ERROR, NULL); - status = bacnet_is_opening_tag_number(apdu, apdu_len, tag_number, &len); - zassert_true(status, NULL); - zassert_true(len > 0, "len=%d", len); - - null_len = host_n_port_decode(&apdu[len], apdu_len-len, NULL, NULL); - test_len = host_n_port_decode(&apdu[len], apdu_len-len, &error_code, &test_data); + null_len = host_n_port_context_decode(apdu, apdu_len, tag_number, + &error_code, NULL); + test_len = host_n_port_context_decode(apdu, apdu_len, tag_number, + &error_code, &test_data); zassert_equal(test_len, null_len, NULL); zassert_true(test_len > 0, "test_len=%d", len); - len += test_len; - - status = bacnet_is_closing_tag_number(&apdu[len], apdu_len-len, tag_number, &len); + status = host_n_port_same(&test_data, data); zassert_true(status, NULL); - zassert_true(len > 0, "len=%d", len); status = host_n_port_copy(&test_data, data); zassert_true(status, NULL);