From bad4a6eb64017b03abc9c0053ab1dfbe7d1b6467 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 7 Feb 2025 14:35:28 +0100 Subject: [PATCH 1/3] nFAPI: msg length/offset is 32bit 5G nFAPI headers specify 32 bits for the length field, so use it here as well. --- nfapi/open-nFAPI/pnf/src/pnf_p7.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 81de4d7acc..4fdb4ae01f 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -2378,7 +2378,7 @@ void pnf_nr_handle_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, if (rx_msg->num_segments_received == rx_msg->num_segments_expected) { // send the buffer on uint16_t i = 0; - uint16_t length = 0; + uint32_t length = 0; for (i = 0; i < rx_msg->num_segments_expected; ++i) { length += rx_msg->segments[i].length - (i > 0 ? NFAPI_NR_P7_HEADER_LENGTH : 0); } @@ -2400,7 +2400,7 @@ void pnf_nr_handle_p7_message(void* pRecvMsg, int recvMsgLen, pnf_p7_t* pnf_p7, pnf_p7->reassemby_buffer_size = length; } - uint16_t offset = 0; + uint32_t offset = 0; for (i = 0; i < rx_msg->num_segments_expected; ++i) { if (i == 0) { memcpy(pnf_p7->reassemby_buffer, rx_msg->segments[i].buffer, rx_msg->segments[i].length); From 2067831e7aa0cf7abb1771e4301fa71635f25d54 Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 7 Feb 2025 16:55:12 +0100 Subject: [PATCH 2/3] nFAPI/VNF: Correctly set message length when segmenting The 5G nFAPI message length is 32bits. In particular tx_data.requests can be longer than 64kB. When segmenting, we should correctly write the message of the current segment (across all 32bits), because the length would interpreted wrongly otherwise. This fixes a bug in which tx_data.requests were discarded for 4-layer DL MIMO on 100 MHz with this message: P7 unpack message length is greater than the message buffer Further, increase the type of various (segment-related) variables to 32 bits. Currently, the maximum segment size is sxt to 65000 bytes (and in will likely remain, because the maximum UDP size is 65536); nevertheless, increase it in case we will ever go beyond this. See also commit dee68e63198f ("nFAPI: increase maximum segment size to 65000") --- nfapi/open-nFAPI/vnf/inc/vnf_p7.h | 2 +- nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h | 4 ++-- nfapi/open-nFAPI/vnf/src/vnf_p7.c | 8 +++++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h index 3684997c22..92623b41b8 100644 --- a/nfapi/open-nFAPI/vnf/inc/vnf_p7.h +++ b/nfapi/open-nFAPI/vnf/inc/vnf_p7.h @@ -27,7 +27,7 @@ typedef struct { uint8_t* buffer; - uint16_t length; + uint32_t length; } vnf_p7_rx_message_segment_t; typedef struct vnf_p7_rx_message vnf_p7_rx_message_t; diff --git a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h index 77f0358e40..6fd7d733eb 100644 --- a/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h +++ b/nfapi/open-nFAPI/vnf/public_inc/nfapi_vnf_interface.h @@ -669,8 +669,8 @@ typedef struct nfapi_vnf_p7_config uint8_t checksum_enabled; /*! The maxium size of a P7 segement. If a message is large that this it - * will be segemented */ - uint16_t segment_size; + * will be segmented. Note: u32 to cover 4G and 5G. */ + uint32_t segment_size; uint16_t max_num_segments; /*! Configuration option for the p7 pack unpack functions*/ diff --git a/nfapi/open-nFAPI/vnf/src/vnf_p7.c b/nfapi/open-nFAPI/vnf/src/vnf_p7.c index 0caebd2130..3d2975d03c 100644 --- a/nfapi/open-nFAPI/vnf/src/vnf_p7.c +++ b/nfapi/open-nFAPI/vnf/src/vnf_p7.c @@ -501,7 +501,7 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_ // segmenting the transmit int msg_body_len = len - NFAPI_NR_P7_HEADER_LENGTH ; - int seg_body_len = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH ; + uint32_t seg_body_len = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH ; int segment_count = (msg_body_len / (seg_body_len)) + ((msg_body_len % seg_body_len) ? 1 : 0); int segment = 0; @@ -511,19 +511,21 @@ int vnf_nr_p7_pack_and_send_p7_msg(vnf_p7_t* vnf_p7, nfapi_nr_p7_message_header_ for(segment = 0; segment < segment_count; ++segment) { uint8_t last = 0; - uint16_t size = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH; + uint32_t size = vnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH; if(segment + 1 == segment_count) { last = 1; size = (msg_body_len) - (seg_body_len * segment); } - uint16_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH; + uint32_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH; // Update the header with the m and segement memcpy(&tx_buffer[0], buffer, NFAPI_NR_P7_HEADER_LENGTH); // set the segment length + tx_buffer[4] = (segment_size & 0xFF000000) >> 24; + tx_buffer[5] = (segment_size & 0xFF0000) >> 16; tx_buffer[6] = (segment_size & 0xFF00) >> 8; tx_buffer[7] = (segment_size & 0xFF); From 609969f46d018bc4bb7b39c038cc40162ff2bdec Mon Sep 17 00:00:00 2001 From: Robert Schmidt Date: Fri, 7 Feb 2025 17:38:12 +0100 Subject: [PATCH 3/3] nFAPI/PNF: Correctly set message length when segmenting Make the same change as in parent commit, i.e., write the full 32-bit segment size. I could not test this, as we do not reach these rx_data.indication length. It's based on the fix in the parent commit, and to avoid future bad surprises. --- nfapi/open-nFAPI/pnf/inc/pnf_p7.h | 2 +- nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h | 4 ++-- nfapi/open-nFAPI/pnf/src/pnf_p7.c | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h index 0c14fcebef..0325c8c242 100644 --- a/nfapi/open-nFAPI/pnf/inc/pnf_p7.h +++ b/nfapi/open-nFAPI/pnf/inc/pnf_p7.h @@ -57,7 +57,7 @@ typedef struct { typedef struct { uint8_t* buffer; - uint16_t length; + uint32_t length; } pnf_p7_rx_message_segment_t; typedef struct pnf_p7_rx_message pnf_p7_rx_message_t; diff --git a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h index 5e964f10fa..7403bd7169 100644 --- a/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h +++ b/nfapi/open-nFAPI/pnf/public_inc/nfapi_pnf_interface.h @@ -629,8 +629,8 @@ typedef struct nfapi_pnf_p7_config uint8_t checksum_enabled; /*! The maxium size of a P7 segement. If a message is large that this it - * will be segemented */ - uint16_t segment_size; + * will be segmented. Note: u32 to cover 4G and 5G */ + uint32_t segment_size; /*! The dummy subframe buffer structure that should be used in case there * are no 'valid' subframe messages */ diff --git a/nfapi/open-nFAPI/pnf/src/pnf_p7.c b/nfapi/open-nFAPI/pnf/src/pnf_p7.c index 4fdb4ae01f..bdc1634ef5 100644 --- a/nfapi/open-nFAPI/pnf/src/pnf_p7.c +++ b/nfapi/open-nFAPI/pnf/src/pnf_p7.c @@ -602,18 +602,20 @@ int pnf_nr_p7_pack_and_send_p7_message(pnf_p7_t* pnf_p7, nfapi_nr_p7_message_hea uint8_t buffer[pnf_p7->_public.segment_size]; for (segment = 0; segment < segment_count; ++segment) { uint8_t last = 0; - uint16_t size = pnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH; + uint32_t size = pnf_p7->_public.segment_size - NFAPI_NR_P7_HEADER_LENGTH; if (segment + 1 == segment_count) { last = 1; size = (msg_body_len) - (seg_body_len * segment); } - uint16_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH; + uint32_t segment_size = size + NFAPI_NR_P7_HEADER_LENGTH; // Update the header with the m and segement memcpy(&buffer[0], tx_buf, NFAPI_NR_P7_HEADER_LENGTH); // set the segment length + buffer[4] = (segment_size & 0xFF000000) >> 24; + buffer[5] = (segment_size & 0xFF0000) >> 16; buffer[6] = (segment_size & 0xFF00) >> 8; buffer[7] = (segment_size & 0xFF);