From d9e3725a21d992405a12cfcff68953279f68c36e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=BAben=20Soares=20Silva?= Date: Thu, 6 Mar 2025 11:37:17 +0000 Subject: [PATCH] Unpack SRS report TLV not expecting padding to be present Add a function pullx32 to pull x amount of bytes into uint32_t Change the unpacking to pull only the needed bytes, and skip over the padding, when not Aerial Change SRS.indication dumping function to also print the report TLV contents Change SRS.indication unitary test to fill the last 4 byte block of the report TLV according to the length, with padding --- nfapi/oai_integration/aerial/fapi_vnf_p7.c | 7 ++--- nfapi/open-nFAPI/common/public_inc/nfapi.h | 12 +++++++++ nfapi/open-nFAPI/common/src/nfapi.c | 25 +++++++++++++++++ nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h | 1 + nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c | 28 +++++++++++++++++--- nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c | 14 +++++++++- nfapi/tests/p7/nr_fapi_srs_indication_test.c | 9 ++++--- 7 files changed, 83 insertions(+), 13 deletions(-) diff --git a/nfapi/oai_integration/aerial/fapi_vnf_p7.c b/nfapi/oai_integration/aerial/fapi_vnf_p7.c index 263df7bd8a..cb8fa4550f 100644 --- a/nfapi/oai_integration/aerial/fapi_vnf_p7.c +++ b/nfapi/oai_integration/aerial/fapi_vnf_p7.c @@ -309,11 +309,8 @@ uint8_t aerial_unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, nfapi_nr_srs_indication_t *srs_ind = (nfapi_nr_srs_indication_t *)msg; for (uint8_t pdu_idx = 0; pdu_idx < srs_ind->number_of_pdus; pdu_idx++) { nfapi_nr_srs_indication_pdu_t *pdu = &srs_ind->pdu_list[pdu_idx]; - nfapi_srs_report_tlv_t *report_tlv = &pdu->report_tlv; - for (int i = 0; i < (report_tlv->length + 3) / 4; i++) { - if (!pull32(pDataMsg, &report_tlv->value[i], data_end)) { - return 0; - } + if (!unpack_nr_srs_report_tlv_value(&pdu->report_tlv, pDataMsg, data_end)) { + return 0; } } return retval; diff --git a/nfapi/open-nFAPI/common/public_inc/nfapi.h b/nfapi/open-nFAPI/common/public_inc/nfapi.h index 99c7d7ec7e..2cb9cee996 100644 --- a/nfapi/open-nFAPI/common/public_inc/nfapi.h +++ b/nfapi/open-nFAPI/common/public_inc/nfapi.h @@ -36,6 +36,18 @@ uint8_t pull8(uint8_t **in, uint8_t *out, uint8_t *end); uint8_t pulls8(uint8_t **in, int8_t *out, uint8_t *end); uint8_t pull16(uint8_t **in, uint16_t *out, uint8_t *end); uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end); + + /*! \brief Pull an arbitrary amount of bytes ( 0 to 4 ) into an uint32_t + * \param length the amount of bytes to pull + * \param in the buffer from where to pull the bytes + * \param out a pointer to the destination uint32_t + * \param end a pointer to the end of the buffer in + * + * This function is used to pull `length` amount of bytes from `in` into `out`. + * Used where pulling the full 32 bits would cause the `in` pointer to go over `end`. + * It's currently used to pull the last bytes of a payload where the buffer does not contain padding at the end. + */ +uint8_t pullx32(uint8_t length, uint8_t **in, uint32_t *out, uint8_t *end); uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end); uint8_t pulls32(uint8_t **in, int32_t *out, uint8_t *end); diff --git a/nfapi/open-nFAPI/common/src/nfapi.c b/nfapi/open-nFAPI/common/src/nfapi.c index 97352b98f7..716387ae7d 100644 --- a/nfapi/open-nFAPI/common/src/nfapi.c +++ b/nfapi/open-nFAPI/common/src/nfapi.c @@ -259,6 +259,31 @@ uint8_t pulls16(uint8_t **in, int16_t *out, uint8_t *end) } } +uint8_t pullx32(uint8_t length, uint8_t **in, uint32_t *out, uint8_t *end) +{ + uint8_t *pIn = *in; + if (length > 4) { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s Can't pull more than 4 bytes (%d) into a uint32_t\n", __FUNCTION__, length); + on_error(); + return 0; + } + if ((end - pIn) >= length) { + for (int i = 0; i < length; i++) { +#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN + *out |= ((uint32_t)pIn[i] << (8 * i)); +#else + *out = ((uint32_t)pIn[i] << (8 * (length - 1 - i))); +#endif + } + (*in) += length; + return length; + } else { + NFAPI_TRACE(NFAPI_TRACE_ERROR, "%s no space in buffer\n", __FUNCTION__); + on_error(); + return 0; + } +} + uint8_t pull32(uint8_t **in, uint32_t *out, uint8_t *end) { uint8_t *pIn = *in; diff --git a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h index 76e2043f2d..c2701acb5f 100644 --- a/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h +++ b/nfapi/open-nFAPI/fapi/inc/nr_fapi_p7.h @@ -50,6 +50,7 @@ uint8_t pack_nr_uci_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e uint8_t unpack_nr_uci_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config); uint8_t unpack_nr_srs_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); +uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end); uint8_t pack_nr_rach_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *end, nfapi_p7_codec_config_t *config); uint8_t unpack_nr_rach_indication(uint8_t **ppReadPackedMsg, uint8_t *end, void *msg, nfapi_p7_codec_config_t *config); #endif // OPENAIRINTERFACE_NR_FAPI_P7_H diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c index a247541315..7b840fc126 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7.c @@ -2300,6 +2300,28 @@ uint8_t pack_nr_srs_indication(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e return 1; } +uint8_t unpack_nr_srs_report_tlv_value(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) +{ +#ifndef ENABLE_AERIAL + for (int i = 0; i < (report_tlv->length + 3) / 4; i++) { + if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) { + return 0; + } + } +#else + const uint16_t last_idx = ((report_tlv->length + 3) / 4) - 1; + for (int i = 0; i < last_idx; i++) { + if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) { + return 0; + } + } + // Pull last bytes according to how much padding it would need to be 32-bit aligned + const uint8_t padding = get_tlv_padding(report_tlv->length); + pullx32(4 - padding, ppReadPackedMsg, &report_tlv->value[last_idx], end); +#endif + return 1; +} + static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint8_t **ppReadPackedMsg, uint8_t *end) { if(!(pull16(ppReadPackedMsg, &report_tlv->tag, end) && @@ -2307,10 +2329,8 @@ static uint8_t unpack_nr_srs_report_tlv(nfapi_srs_report_tlv_t *report_tlv, uint return 0; } #ifndef ENABLE_AERIAL - for (int i = 0; i < (report_tlv->length + 3) / 4; i++) { - if (!pull32(ppReadPackedMsg, &report_tlv->value[i], end)) { - return 0; - } + if (!unpack_nr_srs_report_tlv_value(report_tlv, ppReadPackedMsg, end)) { + return 0; } #endif return 1; diff --git a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c index c753cbcb1c..9939a6f535 100644 --- a/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c +++ b/nfapi/open-nFAPI/fapi/src/nr_fapi_p7_utils.c @@ -2684,6 +2684,18 @@ void dump_uci_indication(const nfapi_nr_uci_indication_t *msg) } } +static void dump_srs_report_tlv(const nfapi_srs_report_tlv_t* tlv, int depth) +{ + depth++; + INDENTED_PRINTF("TAG = 0x%02x\n", tlv->tag); + INDENTED_PRINTF("LENGTH = 0x%02x\n", tlv->length); + INDENTED_PRINTF("VALUE = "); + for (int i = 0; i < ((tlv->length + 3) / 4); ++i) { + printf("0x%04x ", tlv->value[i]); + } + printf("\n"); +} + void dump_srs_indication(const nfapi_nr_srs_indication_t *msg) { int depth = 0; @@ -2704,7 +2716,7 @@ void dump_srs_indication(const nfapi_nr_srs_indication_t *msg) INDENTED_PRINTF("Timing advance offset in nanoseconds = 0x%02x\n", pdu->timing_advance_offset_nsec); INDENTED_PRINTF("SRS usage = 0x%02x\n", pdu->srs_usage); INDENTED_PRINTF("Report Type = 0x%02x\n", pdu->report_type); - /* call to dump_srs_report_tlv */ + dump_srs_report_tlv(&pdu->report_tlv, depth); depth--; } } diff --git a/nfapi/tests/p7/nr_fapi_srs_indication_test.c b/nfapi/tests/p7/nr_fapi_srs_indication_test.c index 49b73fd8f5..1271606b77 100644 --- a/nfapi/tests/p7/nr_fapi_srs_indication_test.c +++ b/nfapi/tests/p7/nr_fapi_srs_indication_test.c @@ -24,11 +24,14 @@ static void fil_srs_indication_report_tlv(nfapi_srs_report_tlv_t *tlv) { - tlv->tag = rand16_range(0,3); - tlv->length = rand32_range(0,sizeof(tlv->value)); - for (int i = 0; i < (tlv->length + 3) / 4; ++i) { + tlv->tag = rand16_range(0, 3); + tlv->length = rand32_range(1, sizeof(tlv->value)); + const uint16_t last_idx = ((tlv->length + 3) / 4) - 1; + for (int i = 0; i < last_idx; ++i) { tlv->value[i] = rand32(); } + const uint8_t num_bytes = 4 - get_tlv_padding(tlv->length); + tlv->value[last_idx] = rand32_range(0, 1 << (8 * num_bytes)); } static void fill_srs_indication_PDU(nfapi_nr_srs_indication_pdu_t *pdu)