Merge remote-tracking branch 'origin/nfapi-fixes' into integration_2025_w04 (!2999)

Repair nFAPI in 5G

Add 5G nFAPI in OAI/Make it it work.

Many commits in this branch are basically bug fixes of things that don't work
properly, such as

- check for correct conditions (e.g. instance numbers in the RAN context)
- remove artificial limitation (e.g. only one PUCCH per TDD period in the PNF)
- improve performance (reduce big mallocs, make some static buffers such as a
  global ring buffer for nFAPI messages in the PNF)
- fix bugs in nFAPI (e.g., increase maximum message size to ~64kB instead of
  1500 bytes, because the latter is way too small for many TX_data.requests in
  5G, and it will delay message arrival unduly)
- fix bugs in message enc/dec (e.g., handle FDD in config.request)
- adjust the L1 such that the condition "we run monolithic" is not necessery
  (e.g., some message numbers in nFAPI struct where reset in MAC, instead of
  L1, and this breaks when running the PNF)

There are instructions that explain how to set it up. Two CI tests have been
added, one with COTS UE and MIMO in DL+UL in TDD numerology 1 (30kHz), and a
second test with FDD mu=0 (15kHZ) in RFsimulator.

These were some old to-dos that have been addressed.

- test with COTS UE - 4x4 pipeline works good in DL, UL now also work
- test in RFsim
- make PNF status message
- make FDD in u0 work
This commit is contained in:
Jaroslava Fiedlerova
2025-01-27 15:46:19 +01:00
80 changed files with 2104 additions and 21998 deletions
+28 -34
View File
@@ -714,16 +714,7 @@ uint8_t unpack_nr_param_response(uint8_t **ppReadPackedMsg, uint8_t *end, void *
{NFAPI_NR_NFAPI_TIMING_INFO_MODE_TAG, &pNfapiMsg->nfapi_config.timing_info_mode, &unpack_uint8_tlv_value},
{NFAPI_NR_NFAPI_TIMING_INFO_PERIOD_TAG, &pNfapiMsg->nfapi_config.timing_info_period, &unpack_uint8_tlv_value},
};
// print ppReadPackedMsg
uint8_t *ptr = *ppReadPackedMsg;
printf("\n Read message unpack_param_response: ");
while (ptr < end) {
printf(" 0x%02x", *ptr);
ptr++;
}
printf("\n");
return (pull8(ppReadPackedMsg, &pNfapiMsg->error_code, end) && pull8(ppReadPackedMsg, &pNfapiMsg->num_tlv, end)
&& unpack_nr_tlv_list(unpack_fns,
sizeof(unpack_fns) / sizeof(unpack_tlv_t),
@@ -1017,22 +1008,24 @@ uint8_t pack_nr_config_request(void *msg, uint8_t **ppWritePackedMsg, uint8_t *e
// END SSB Table
// START TDD Table
retval &=
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
numTLVs++;
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
&pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
if (pNfapiMsg->cell_config.frame_duplex_type.value == 1 /* TDD */) {
retval &=
pack_nr_tlv(NFAPI_NR_CONFIG_TDD_PERIOD_TAG, &(pNfapiMsg->tdd_table.tdd_period), ppWritePackedMsg, end, &pack_uint8_tlv_value);
numTLVs++;
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
retval &= pack_nr_tlv(NFAPI_NR_CONFIG_SLOT_CONFIG_TAG,
&pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
ppWritePackedMsg,
end,
&pack_uint8_tlv_value);
numTLVs++;
}
}
}
@@ -1232,27 +1225,28 @@ uint8_t unpack_nr_config_request(uint8_t **ppReadPackedMsg, uint8_t *end, void *
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.tag = generic_tl.tag;
pNfapiMsg->prach_config.num_prach_fd_occasions.tl.length = generic_tl.length;
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->prach_config.num_prach_fd_occasions, ppReadPackedMsg, end);
pNfapiMsg->prach_config.num_prach_fd_occasions_list = (nfapi_nr_num_prach_fd_occasions_t *)malloc(
pNfapiMsg->prach_config.num_prach_fd_occasions.value * sizeof(nfapi_nr_num_prach_fd_occasions_t));
pNfapiMsg->prach_config.num_prach_fd_occasions_list = calloc(pNfapiMsg->prach_config.num_prach_fd_occasions.value, sizeof(nfapi_nr_num_prach_fd_occasions_t));
prach_root_seq_idx = 0;
break;
case NFAPI_NR_CONFIG_SCS_COMMON_TAG:
pNfapiMsg->ssb_config.scs_common.tl.tag = generic_tl.tag;
pNfapiMsg->ssb_config.scs_common.tl.length = generic_tl.length;
result = (*unpack_fns[idx].unpack_func)(&pNfapiMsg->ssb_config.scs_common, ppReadPackedMsg, end);
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
pNfapiMsg->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(
slotsperframe[pNfapiMsg->ssb_config.scs_common.value] * sizeof(nfapi_nr_max_tdd_periodicity_t));
if (pNfapiMsg->cell_config.frame_duplex_type.value == 1 /* TDD */) {
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
int n = slotsperframe[pNfapiMsg->ssb_config.scs_common.value];
pNfapiMsg->tdd_table.max_tdd_periodicity_list = calloc(n, sizeof(nfapi_nr_max_tdd_periodicity_t));
for (int i = 0; i < slotsperframe[pNfapiMsg->ssb_config.scs_common.value]; i++) {
pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
(nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot
* sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
for (int i = 0; i < n; i++) {
pNfapiMsg->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
calloc(number_of_symbols_per_slot, sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
}
}
break;
case NFAPI_NR_CONFIG_PRACH_ROOT_SEQUENCE_INDEX_TAG:
+30 -26
View File
@@ -240,18 +240,20 @@ bool eq_config_request(const nfapi_nr_config_request_scf_t *unpacked_req, const
EQ_TLV(unpacked_req->ssb_table.ssb_beam_id_list[i].beam_id, req->ssb_table.ssb_beam_id_list[i].beam_id);
}
EQ_TLV(unpacked_req->tdd_table.tdd_period, req->tdd_table.tdd_period);
if (req->cell_config.frame_duplex_type.value == 1 /* TDD */) {
EQ_TLV(unpacked_req->tdd_table.tdd_period, req->tdd_table.tdd_period);
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
for (int i = 0; i < slotsperframe[unpacked_req->ssb_config.scs_common.value]; i++) {
for (int k = 0; k < number_of_symbols_per_slot; k++) {
EQ_TLV(unpacked_req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
for (int i = 0; i < slotsperframe[unpacked_req->ssb_config.scs_common.value]; i++) {
for (int k = 0; k < number_of_symbols_per_slot; k++) {
EQ_TLV(unpacked_req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
req->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
}
}
}
@@ -768,24 +770,26 @@ void copy_config_request(const nfapi_nr_config_request_scf_t *src, nfapi_nr_conf
COPY_TLV(dst->ssb_table.ssb_beam_id_list[i].beam_id, src->ssb_table.ssb_beam_id_list[i].beam_id);
}
COPY_TLV(dst->tdd_table.tdd_period, src->tdd_table.tdd_period);
if (src->cell_config.frame_duplex_type.value == 1 /* TDD */) {
COPY_TLV(dst->tdd_table.tdd_period, src->tdd_table.tdd_period);
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
dst->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(slotsperframe[dst->ssb_config.scs_common.value]
* sizeof(nfapi_nr_max_tdd_periodicity_t));
const uint8_t slotsperframe[5] = {10, 20, 40, 80, 160};
// Assuming always CP_Normal, because Cyclic prefix is not included in CONFIG.request 10.02, but is present in 10.04
uint8_t cyclicprefix = 1;
// 3GPP 38.211 Table 4.3.2.1 & Table 4.3.2.2
uint8_t number_of_symbols_per_slot = cyclicprefix ? 14 : 12;
dst->tdd_table.max_tdd_periodicity_list = (nfapi_nr_max_tdd_periodicity_t *)malloc(slotsperframe[dst->ssb_config.scs_common.value]
* sizeof(nfapi_nr_max_tdd_periodicity_t));
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) {
dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
(nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
}
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
COPY_TLV(dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
src->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) {
dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list =
(nfapi_nr_max_num_of_symbol_per_slot_t *)malloc(number_of_symbols_per_slot * sizeof(nfapi_nr_max_num_of_symbol_per_slot_t));
}
for (int i = 0; i < slotsperframe[dst->ssb_config.scs_common.value]; i++) { // TODO check right number of slots
for (int k = 0; k < number_of_symbols_per_slot; k++) { // TODO can change?
COPY_TLV(dst->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config,
src->tdd_table.max_tdd_periodicity_list[i].max_num_of_symbol_per_slot_list[k].slot_config);
}
}
}