mirror of
https://gitlab.eurecom.fr/oai/openairinterface5g.git
synced 2026-07-13 04:30:28 +00:00
Fix packing/unpacking procedures for DCI payload with inversion
Add unitary test for DCI payload pack/unpack with random length/data
This commit is contained in:
committed by
Rúben Soares Silva
parent
df1cb77000
commit
d35dbe6377
@@ -620,39 +620,59 @@ uint8_t unpackarray(uint8_t **ppReadPackedMsg,
|
||||
|
||||
uint32_t pack_dci_payload(uint8_t payload[], uint16_t payloadSizeBits, uint8_t **out, uint8_t *end)
|
||||
{
|
||||
// Helper vars for DCI Payload
|
||||
uint8_t dci_bytes_inverted[DCI_PAYLOAD_BYTE_LEN];
|
||||
uint8_t dci_byte_len = (payloadSizeBits + 7) / 8;
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
// Helper vars for DCI Payload
|
||||
uint8_t dci_bytes_inverted[DCI_PAYLOAD_BYTE_LEN] = {0};
|
||||
uint8_t payload_internal[DCI_PAYLOAD_BYTE_LEN] = {0}; // Used to not edit the "outside" pointer
|
||||
uint8_t rotation_bits = 0;
|
||||
// Align the dci payload bits to the left on the payload buffer
|
||||
uint64_t *dci_pdu = (uint64_t *)payload;
|
||||
if (payloadSizeBits % 8 != 0) {
|
||||
uint8_t rotation_bits = 8 - (payloadSizeBits % 8);
|
||||
*dci_pdu = (*dci_pdu << rotation_bits);
|
||||
rotation_bits = 8 - (payloadSizeBits % 8);
|
||||
// Bit shifting value ( << )
|
||||
uint64_t t = 0;
|
||||
memcpy(&t, payload, dci_byte_len);
|
||||
t = t << rotation_bits;
|
||||
memcpy(payload_internal, &t, dci_byte_len);
|
||||
} else {
|
||||
// No rotation needed
|
||||
memcpy(payload_internal, payload, dci_byte_len);
|
||||
}
|
||||
// Invert the byte order of the DCI Payload
|
||||
for (int j = 0; j < dci_byte_len; j++) {
|
||||
dci_bytes_inverted[j] = payload[(dci_byte_len - 1) - j];
|
||||
dci_bytes_inverted[j] = payload_internal[(dci_byte_len - 1) - j];
|
||||
}
|
||||
return pusharray8(dci_bytes_inverted, DCI_PAYLOAD_BYTE_LEN, dci_byte_len, out, end);
|
||||
#else
|
||||
return pusharray8(payload, DCI_PAYLOAD_BYTE_LEN, dci_byte_len, out, end);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t unpack_dci_payload(uint8_t payload[], uint16_t payloadSizeBits, uint8_t **in, uint8_t *end)
|
||||
{
|
||||
// Pull the inverted DCI and invert it back
|
||||
// Helper vars for DCI Payload
|
||||
uint8_t dci_bytes_inverted[DCI_PAYLOAD_BYTE_LEN];
|
||||
uint8_t dci_byte_len = (payloadSizeBits + 7) / 8;
|
||||
#ifdef FAPI_BYTE_ORDERING_BIG_ENDIAN
|
||||
uint8_t dci_bytes_inverted[DCI_PAYLOAD_BYTE_LEN] = {0};
|
||||
// Get DCI array inverted
|
||||
uint32_t pullresult = pullarray8(in, dci_bytes_inverted, DCI_PAYLOAD_BYTE_LEN, dci_byte_len, end);
|
||||
uint64_t *dci_pdu = (uint64_t *)payload;
|
||||
|
||||
// Reversing the byte order of the inverted DCI payload
|
||||
for (uint16_t j = 0; j < dci_byte_len; j++) {
|
||||
payload[j] = dci_bytes_inverted[(dci_byte_len - 1) - j];
|
||||
}
|
||||
|
||||
uint64_t t = 0;
|
||||
memcpy(&t, payload, dci_byte_len);
|
||||
if (payloadSizeBits % 8 != 0) {
|
||||
uint8_t rotation_bits = 8 - (payloadSizeBits % 8);
|
||||
*dci_pdu = (*dci_pdu >> rotation_bits);
|
||||
t = (t >> (uint64_t)rotation_bits);
|
||||
}
|
||||
memcpy(payload, &t, dci_byte_len);
|
||||
#else
|
||||
uint32_t pullresult = pullarray8(in, payload, DCI_PAYLOAD_BYTE_LEN, dci_byte_len, end);
|
||||
#endif
|
||||
return pullresult;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
if (ENABLE_TESTS)
|
||||
add_subdirectory(p5)
|
||||
add_subdirectory(p7)
|
||||
endif ()
|
||||
|
||||
16
nfapi/tests/p7/CMakeLists.txt
Normal file
16
nfapi/tests/p7/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
set(Test_Labels fapi p7)
|
||||
set(_fapi_p7_messages "dci_inversion")
|
||||
foreach (fapi_p7_message IN LISTS _fapi_p7_messages)
|
||||
add_executable(nr_fapi_${fapi_p7_message}_test nr_fapi_${fapi_p7_message}_test.c)
|
||||
target_link_libraries(nr_fapi_${fapi_p7_message}_test PUBLIC nr_fapi_p5)
|
||||
target_link_libraries(nr_fapi_${fapi_p7_message}_test PRIVATE pthread UTIL ${T_LIB} minimal_lib)
|
||||
add_dependencies(tests nr_fapi_${fapi_p7_message}_test)
|
||||
|
||||
add_test(nr_fapi_${fapi_p7_message}_test nr_fapi_${fapi_p7_message}_test)
|
||||
set_tests_properties(nr_fapi_${fapi_p7_message}_test PROPERTIES LABELS "${Test_Labels}")
|
||||
endforeach ()
|
||||
# Add the dci label for the dci payload test
|
||||
set(dci_labels dci ${Test_Labels})
|
||||
set_tests_properties(nr_fapi_dci_inversion_test PROPERTIES LABELS "dci ${Test_Labels}")
|
||||
# Add the FAPI_BYTE_ORDERING_BIG_ENDIAN preprocessor define in order to test the invert/uninvert dci payload functions
|
||||
target_compile_definitions(nfapi_common PRIVATE FAPI_BYTE_ORDERING_BIG_ENDIAN)
|
||||
146
nfapi/tests/p7/nr_fapi_dci_inversion_test.c
Normal file
146
nfapi/tests/p7/nr_fapi_dci_inversion_test.c
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The OpenAirInterface Software Alliance licenses this file to You under
|
||||
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.openairinterface.org/?page_id=698
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*-------------------------------------------------------------------------------
|
||||
* For more information about the OpenAirInterface (OAI) Software Alliance:
|
||||
* contact@openairinterface.org
|
||||
*/
|
||||
/*! \file nfapi/tests/p5/nr_fapi_param_request_test.c
|
||||
* \brief
|
||||
* \author Ruben S. Silva
|
||||
* \date 2024
|
||||
* \version 0.1
|
||||
* \company OpenAirInterface Software Alliance
|
||||
* \email: contact@openairinterface.org, rsilva@allbesmart.pt
|
||||
* \note
|
||||
* \warning
|
||||
*/
|
||||
#include "nfapi/tests/nr_fapi_test.h"
|
||||
#include "nr_fapi_p5.h"
|
||||
#include "nr_fapi.h"
|
||||
void printbits(uint64_t n, uint8_t numBytesToPrint)
|
||||
{
|
||||
uint64_t i;
|
||||
uint8_t counter = 0;
|
||||
if (numBytesToPrint == 0) {
|
||||
i = 1UL << (sizeof(n) * 8 - 1);
|
||||
} else {
|
||||
i = 1UL << (numBytesToPrint * 8 - 1);
|
||||
}
|
||||
while (i > 0) {
|
||||
if (n & i)
|
||||
printf("1");
|
||||
else
|
||||
printf("0");
|
||||
i >>= 1;
|
||||
counter++;
|
||||
if (counter % 8 == 0) {
|
||||
printf(" ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Drops unwanted bits from a byte array, leaving only a specified number of payload bits
|
||||
*
|
||||
* \param payloadSizeBits How many bits the payload is to have, from 1 to 64 (8 * DCI_PAYLOAD_BYTE_LEN)
|
||||
* \param payload[] A uint8_t array containing the payload bytes with random data
|
||||
* \details This function creates a bitmask of payloadSizeBits width to truncate the data in payload[] to only have the specified
|
||||
* number of payload bits\n
|
||||
* For example, a payload of 39 bits needs 5 bytes, but on the last byte, the last bit is unused, this function makes sure that
|
||||
* last bit is set to 0, allowing the payload to be then packed and unpacked and successfully compared with the original payload
|
||||
*/
|
||||
void truncate_unwanted_bits(uint8_t payloadSizeBits, uint8_t payload[])
|
||||
{
|
||||
uint8_t payloadSizeBytes = (payloadSizeBits + 7) / 8;
|
||||
printf("Original Value:\t");
|
||||
uint64_t t = 0;
|
||||
memcpy(&t, payload, payloadSizeBytes);
|
||||
printbits(t, payloadSizeBytes);
|
||||
printf("\n");
|
||||
uint64_t bitmask = 1;
|
||||
for (int i = 0; i < payloadSizeBits - 1; i++) {
|
||||
bitmask = bitmask << 1 | 1;
|
||||
}
|
||||
printf("Calculated Bitmask:\t");
|
||||
printbits(bitmask, payloadSizeBytes);
|
||||
printf("\n");
|
||||
t = t & bitmask;
|
||||
printf("Truncated Value:\t");
|
||||
printbits(t, payloadSizeBytes);
|
||||
printf("\n");
|
||||
memcpy(payload, &t, payloadSizeBytes);
|
||||
}
|
||||
|
||||
/*! \brief Generates a random payload payloadSizeBits long into payload[]
|
||||
*
|
||||
* \param payloadSizeBits How many bits the payload is to have, from 1 to 64 (8 * DCI_PAYLOAD_BYTE_LEN)
|
||||
* \param payload[] A uint8_t array to contain the generated payload
|
||||
* \details This function fills a uint8_t array with payloadSizeBits of random data, by first filling however many bytes are needed
|
||||
* to contain payloadSizeBits with random data, and then truncating the excess bits
|
||||
*/
|
||||
void generate_payload(uint8_t payloadSizeBits, uint8_t payload[])
|
||||
{
|
||||
for (int i = 0; i < (payloadSizeBits + 7) / 8; ++i) {
|
||||
payload[i] = rand8();
|
||||
}
|
||||
truncate_unwanted_bits(payloadSizeBits, payload);
|
||||
}
|
||||
|
||||
void test_pack_payload(uint8_t payloadSizeBits, uint8_t payload[])
|
||||
{
|
||||
uint8_t msg_buf[8192] = {0};
|
||||
uint8_t payloadSizeBytes = (payloadSizeBits + 7) / 8;
|
||||
uint8_t *pWritePackedMessage = msg_buf;
|
||||
uint8_t *pPackMessageEnd = msg_buf + sizeof(msg_buf);
|
||||
|
||||
pack_dci_payload(payload, payloadSizeBits, &pWritePackedMessage, pPackMessageEnd);
|
||||
|
||||
uint8_t *unpack_buf = calloc_or_fail(payloadSizeBytes, sizeof(uint8_t));
|
||||
pWritePackedMessage = msg_buf;
|
||||
unpack_dci_payload(unpack_buf, payloadSizeBits, &pWritePackedMessage, pPackMessageEnd);
|
||||
|
||||
printf("\nOriginal:\t");
|
||||
for (int j = payloadSizeBytes - 1; j >= 0; j--) {
|
||||
printbits(payload[j], 1);
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
printf("Unpacked:\t");
|
||||
for (int j = payloadSizeBytes - 1; j >= 0; j--) {
|
||||
printbits(unpack_buf[j], 1);
|
||||
printf(" ");
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
DevAssert(memcmp(payload, unpack_buf, payloadSizeBytes) == 0);
|
||||
// All tests successful!
|
||||
free(unpack_buf);
|
||||
}
|
||||
|
||||
int main(int n, char *v[])
|
||||
{
|
||||
fapi_test_init();
|
||||
uint8_t upper = 8 * DCI_PAYLOAD_BYTE_LEN;
|
||||
uint8_t lower = 1;
|
||||
uint8_t payloadSizeBits = (rand() % (upper - lower + 1)) + lower; // from 1 bit to DCI_PAYLOAD_BYTE_LEN, in bits
|
||||
printf("payloadSizeBits:%d\n", payloadSizeBits);
|
||||
uint8_t payload[(payloadSizeBits + 7) / 8];
|
||||
|
||||
generate_payload(payloadSizeBits, payload);
|
||||
test_pack_payload(payloadSizeBits, payload);
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user