Refactor (F1AP/RRC): convert SIB containers to byte_array_t

Unify SIB container handling by introducing a typed SIB enum and storing
SIB payloads as byte_array_t across common NR types, F1AP helpers, MAC,
and RRC DU setup code.

Changes:
- Include byte_array support in nr_common.h, add nr_sib_type_t (NR_SIB_1–NR_SIB_21),
  and change nr_SIBs_t to hold only nr_sib_type_t SIB_type.
- Switch f1ap_sib_msg_t in f1ap_messages_types.h to use a byte_array_t SI_container
  instead of raw pointer and length fields.
- Update F1AP encode/decode, equality, copy, and free helpers in
  f1ap_interface_management.c to work on SI_container.buf / SI_container.len and
  use eq_byte_array, copy_byte_array, and free_byte_array.
- Adapt F1AP tests in f1ap_lib_test.c to build and inspect SIB containers via
  SI_container.buf and SI_container.len.
- Replace magic SIB numbers with nr_sib_type_t values in gnb_config.c
  (get_sys_info and fill_du_sibs) to validate and configure DU SIBs.
- Rework nr_mac_configure_other_sib in NR_MAC_gNB/config.c to decode SIB2
  from a byte_array_t container, fix freeing by releasing the decoded sib2 on
  failure, and use NR_SIB_2 / NR_SIB_19 for CU/DU SIB selection.
- Add an add_si_msg helper in rrc_gNB_du.c and refactor the SIB2 branch of
  rrc_gNB_process_f1_setup_req to populate cell->SI_msg from encoded local
  byte array while iterating SIBs with FOR_EACH_SEQ_ARR.
This commit is contained in:
Guido Casati
2026-04-10 10:22:50 +02:00
parent 7606a93f57
commit e27f8c24cf
7 changed files with 78 additions and 58 deletions
+26 -3
View File
@@ -13,6 +13,7 @@
#include <stdlib.h>
#include "assertions.h"
#include "common/utils/utils.h"
#include "common/utils/ds/byte_array.h"
#define MAX_SI_GROUPS 3
#define NR_MAX_PDSCH_TBS 3824
@@ -79,10 +80,32 @@ static inline const char *rnti_types(nr_rnti_type_t rr)
// the total shift is 2 * 15, in dB scale thats 10log10(2^(15*2))
#define SQ15_SQUARED_NORM_FACTOR_DB 90.3089986992
typedef enum {
NR_SIB_1 = 1,
NR_SIB_2,
NR_SIB_3,
NR_SIB_4,
NR_SIB_5,
NR_SIB_6,
NR_SIB_7,
NR_SIB_8,
NR_SIB_9,
NR_SIB_10,
NR_SIB_11,
NR_SIB_12,
NR_SIB_13,
NR_SIB_14,
NR_SIB_15,
NR_SIB_16,
NR_SIB_17,
NR_SIB_18,
NR_SIB_19,
NR_SIB_20,
NR_SIB_21,
} nr_sib_type_t;
typedef struct {
uint8_t *SIB_buffer;
int SIB_size;
int SIB_type;
nr_sib_type_t SIB_type;
} nr_SIBs_t;
typedef struct nr_bandentry_s {
+1 -2
View File
@@ -161,8 +161,7 @@ typedef struct f1ap_du_register_req_s {
typedef struct f1ap_sib_msg_s {
/// RRC container with system information owned by gNB-CU
uint8_t *SI_container;
int SI_container_length;
byte_array_t SI_container;
/// SIB block type, e.g. 2 for sibType2
int SI_type;
} f1ap_sib_msg_t;
+15 -24
View File
@@ -627,10 +627,10 @@ static void encode_cells_to_activate(const served_cells_to_activate_t *cell, F1A
F1AP_GNB_CUSystemInformation_t *gNB_CUSystemInformation =
&cells_to_be_activated_itemExtIEs->extensionValue.choice.GNB_CUSystemInformation;
const f1ap_sib_msg_t *SI_msg = &cell->SI_msg[n];
if (SI_msg->SI_container != NULL) {
if (SI_msg->SI_container.buf != NULL) {
asn1cSequenceAdd(gNB_CUSystemInformation->sibtypetobeupdatedlist.list, F1AP_SibtypetobeupdatedListItem_t, sib_item);
sib_item->sIBtype = SI_msg->SI_type;
OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container, SI_msg->SI_container_length);
OCTET_STRING_fromBuf(&sib_item->sIBmessage, (const char *)SI_msg->SI_container.buf, SI_msg->SI_container.len);
}
}
}
@@ -670,7 +670,7 @@ static bool decode_cells_to_activate(served_cells_to_activate_t *out, const F1AP
F1AP_SibtypetobeupdatedListItem_t *sib_item = gNB_CUSystemInformation->sibtypetobeupdatedlist.list.array[s];
/* SI container */
f1ap_sib_msg_t *SI_msg = &out->SI_msg[s];
SI_msg->SI_container = cp_octet_string(&sib_item->sIBmessage, &SI_msg->SI_container_length);
SI_msg->SI_container.buf = cp_octet_string(&sib_item->sIBmessage, (int *)&SI_msg->SI_container.len);
/* SIB type */
SI_msg->SI_type = sib_item->sIBtype;
}
@@ -1163,8 +1163,8 @@ bool eq_f1ap_setup_response(const f1ap_setup_resp_t *a, const f1ap_setup_resp_t
for (int j = 0; j < b->cells_to_activate[i].num_SI; j++) {
const f1ap_sib_msg_t *a_SI_msg = &a->cells_to_activate[i].SI_msg[j];
const f1ap_sib_msg_t *b_SI_msg = &b->cells_to_activate[i].SI_msg[j];
_EQ_CHECK_INT(*a_SI_msg->SI_container, *b_SI_msg->SI_container);
_EQ_CHECK_INT(a_SI_msg->SI_container_length, b_SI_msg->SI_container_length);
if (!eq_byte_array(&a_SI_msg->SI_container, &b_SI_msg->SI_container))
return false;
_EQ_CHECK_INT(a_SI_msg->SI_type, b_SI_msg->SI_type);
}
}
@@ -1201,9 +1201,7 @@ f1ap_setup_resp_t cp_f1ap_setup_response(const f1ap_setup_resp_t *msg)
for (int j = 0; j < cp_cell->num_SI; j++) {
f1ap_sib_msg_t *cp_SI_msg = &cp_cell->SI_msg[j];
const f1ap_sib_msg_t *b_SI_msg = &msg_cell->SI_msg[j];
cp_SI_msg->SI_container_length = b_SI_msg->SI_container_length;
cp_SI_msg->SI_container = malloc_or_fail(cp_SI_msg->SI_container_length);
memcpy(cp_SI_msg->SI_container, b_SI_msg->SI_container, b_SI_msg->SI_container_length);
cp_SI_msg->SI_container = copy_byte_array(b_SI_msg->SI_container);
cp_SI_msg->SI_type = b_SI_msg->SI_type;
}
}
@@ -1221,8 +1219,7 @@ void free_f1ap_setup_response(const f1ap_setup_resp_t *msg)
free(msg->gNB_CU_name);
for (int i = 0; i < msg->num_cells_to_activate; i++)
for (int j = 0; j < msg->cells_to_activate[i].num_SI; j++)
if (msg->cells_to_activate[i].SI_msg[j].SI_container_length > 0)
free(msg->cells_to_activate[i].SI_msg[j].SI_container);
free_byte_array(msg->cells_to_activate[i].SI_msg[j].SI_container);
free(msg->cells_to_activate);
}
@@ -1798,7 +1795,7 @@ void free_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t
{
for (int i = 0; i < msg->num_cells_to_activate; i++)
for (int j = 0; j < msg->cells_to_activate[i].num_SI; j++)
free(msg->cells_to_activate[i].SI_msg[j].SI_container);
free_byte_array(msg->cells_to_activate[i].SI_msg[j].SI_container);
free(msg->cells_to_activate);
}
@@ -1819,8 +1816,8 @@ bool eq_f1ap_cu_configuration_update(const f1ap_gnb_cu_configuration_update_t *a
for (int s = 0; s < a->cells_to_activate[i].num_SI; s++) {
f1ap_sib_msg_t *a_sib_msg = &a->cells_to_activate[i].SI_msg[s];
f1ap_sib_msg_t *b_sib_msg = &b->cells_to_activate[i].SI_msg[s];
_EQ_CHECK_INT(*a_sib_msg->SI_container, *b_sib_msg->SI_container);
_EQ_CHECK_INT(a_sib_msg->SI_container_length, b_sib_msg->SI_container_length);
if (!eq_byte_array(&a_sib_msg->SI_container, &b_sib_msg->SI_container))
return false;
_EQ_CHECK_INT(a_sib_msg->SI_type, b_sib_msg->SI_type);
}
}
@@ -1842,9 +1839,7 @@ f1ap_gnb_cu_configuration_update_t cp_f1ap_cu_configuration_update(const f1ap_gn
for (int s = 0; s < cp.cells_to_activate[i].num_SI; s++) {
cp.cells_to_activate[i].SI_msg[s] = msg->cells_to_activate[i].SI_msg[s];
f1ap_sib_msg_t *SI_msg = &cp.cells_to_activate[i].SI_msg[s];
SI_msg->SI_container = calloc_or_fail(SI_msg->SI_container_length, sizeof(*SI_msg->SI_container));
for (int j = 0; j < SI_msg->SI_container_length; j++)
SI_msg->SI_container[j] = msg->cells_to_activate[i].SI_msg[s].SI_container[j];
SI_msg->SI_container = copy_byte_array(msg->cells_to_activate[i].SI_msg[s].SI_container);
}
}
return cp;
@@ -2153,8 +2148,8 @@ bool eq_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configuration
return false;
_EQ_CHECK_INT(a->cells_to_activate[i].num_SI, b->cells_to_activate[i].num_SI);
for (int s = 0; s < a->cells_to_activate[i].num_SI; s++) {
_EQ_CHECK_INT(*a->cells_to_activate[i].SI_msg[s].SI_container, *b->cells_to_activate[i].SI_msg[s].SI_container);
_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_container_length, b->cells_to_activate[i].SI_msg[s].SI_container_length);
if (!eq_byte_array(&a->cells_to_activate[i].SI_msg[s].SI_container, &b->cells_to_activate[i].SI_msg[s].SI_container))
return false;
_EQ_CHECK_INT(a->cells_to_activate[i].SI_msg[s].SI_type, b->cells_to_activate[i].SI_msg[s].SI_type);
}
}
@@ -2180,9 +2175,7 @@ f1ap_gnb_du_configuration_update_acknowledge_t cp_f1ap_du_configuration_update_a
f1ap_sib_msg_t *cp_sib = &cp.cells_to_activate[i].SI_msg[s];
const f1ap_sib_msg_t *msg_sib = &msg->cells_to_activate[i].SI_msg[s];
cp_sib->SI_type = msg_sib->SI_type;
cp_sib->SI_container_length = msg_sib->SI_container_length;
cp_sib->SI_container = calloc_or_fail(cp_sib->SI_container_length, sizeof(*cp_sib->SI_container));
memcpy(cp_sib->SI_container, msg_sib->SI_container, cp_sib->SI_container_length);
cp_sib->SI_container = copy_byte_array(msg_sib->SI_container);
}
}
return cp;
@@ -2196,9 +2189,7 @@ void free_f1ap_du_configuration_update_acknowledge(const f1ap_gnb_du_configurati
// SI_container
for (int i = 0; i < msg->num_cells_to_activate; i++) {
for (int j = 0; j < msg->cells_to_activate[i].num_SI; j++) {
if (msg->cells_to_activate[i].SI_msg[j].SI_container) {
free(msg->cells_to_activate[i].SI_msg[j].SI_container);
}
free_byte_array(msg->cells_to_activate[i].SI_msg[j].SI_container);
}
}
free(msg->cells_to_activate);
+9 -9
View File
@@ -313,9 +313,9 @@ static void test_f1ap_setup_response(void)
int SI_container_length = strlen(s) + 1;
orig.cells_to_activate[0].num_SI = 1;
f1ap_sib_msg_t *SI_msg = &orig.cells_to_activate[0].SI_msg[0];
SI_msg->SI_container = malloc_or_fail(SI_container_length);
memcpy(SI_msg->SI_container, (uint8_t *)s, SI_container_length);
SI_msg->SI_container_length = SI_container_length;
SI_msg->SI_container.buf = malloc_or_fail(SI_container_length);
memcpy(SI_msg->SI_container.buf, s, SI_container_length);
SI_msg->SI_container.len = SI_container_length;
SI_msg->SI_type = 7;
}
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_response(&orig);
@@ -609,10 +609,10 @@ static void test_f1ap_du_configuration_update_acknowledge(void)
orig.cells_to_activate[0].plmn.mnc_digit_length = 2;
orig.cells_to_activate[0].num_SI = 1;
orig.cells_to_activate[0].SI_msg[0].SI_type = 7;
orig.cells_to_activate[0].SI_msg[0].SI_container_length = 10;
orig.cells_to_activate[0].SI_msg[0].SI_container = malloc(sizeof(uint8_t) * 10);
for (int i = 0; i < orig.cells_to_activate[0].SI_msg[0].SI_container_length; i++) {
orig.cells_to_activate[0].SI_msg[0].SI_container[i] = i;
orig.cells_to_activate[0].SI_msg[0].SI_container.len = 10;
orig.cells_to_activate[0].SI_msg[0].SI_container.buf = malloc(sizeof(uint8_t) * 10);
for (int i = 0; i < (int)orig.cells_to_activate[0].SI_msg[0].SI_container.len; i++) {
orig.cells_to_activate[0].SI_msg[0].SI_container.buf[i] = i;
}
// ASN.1 enc/dec
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update_acknowledge(&orig);
@@ -655,8 +655,8 @@ static void test_f1ap_cu_configuration_update(void)
orig.cells_to_activate[0].plmn.mnc_digit_length = 2;
orig.cells_to_activate[0].num_SI = 1;
orig.cells_to_activate[0].SI_msg[0].SI_type = 7;
orig.cells_to_activate[0].SI_msg[0].SI_container_length = 10;
orig.cells_to_activate[0].SI_msg[0].SI_container = malloc(sizeof(uint8_t) * 10);
orig.cells_to_activate[0].SI_msg[0].SI_container.len = 10;
orig.cells_to_activate[0].SI_msg[0].SI_container.buf = malloc(sizeof(uint8_t) * 10);
F1AP_F1AP_PDU_t *f1enc = encode_f1ap_cu_configuration_update(&orig);
F1AP_F1AP_PDU_t *f1dec = f1ap_encode_decode(f1enc);
f1ap_msg_free(f1enc);
+2 -2
View File
@@ -1083,7 +1083,7 @@ f1ap_gnb_du_system_info_t *get_sys_info(NR_BCCH_BCH_Message_t *mib, const NR_BCC
nr_SIBs_t *si = (nr_SIBs_t *)seq_arr_at(du_SIBs, i);
// other SIB in gNB-DU System Information not implemented yet
// only DU SIB not included in this message is SIB19
AssertFatal(si->SIB_type == 19, "Cannot handle SIB%d in gNB-DU System Information\n", si->SIB_type);
AssertFatal(si->SIB_type == NR_SIB_19, "Cannot handle SIB%d in gNB-DU System Information\n", (int)si->SIB_type);
}
}
return sys_info;
@@ -1243,7 +1243,7 @@ static seq_arr_t *fill_du_sibs(paramdef_t *GNBparamarray)
int sib_value = GNBparamarray[GNB_DU_SIBS_IDX].iptr[i];
// SIB10, SIB12, SIB13, SIB14, SIB15, SIB17, SIB18, SIB19 and SIB20 are generated by the DU
// all the rest in the DU
AssertFatal((sib_value > 9 && sib_value < 21) && sib_value != 11 && sib_value != 16,
AssertFatal((sib_value > NR_SIB_9 && sib_value < NR_SIB_21) && sib_value != NR_SIB_11 && sib_value != NR_SIB_16,
"SIB%d is not a DU SIB, to be configured in DU section\n",
sib_value);
nr_SIBs_t *du_sib = calloc_or_fail(1, sizeof(nr_SIBs_t));
+9 -10
View File
@@ -988,22 +988,21 @@ bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_
NR_SystemInformation_IEs_t *sysInfov17 = calloc(1, sizeof(*sysInfov17)); // for othersibs
for (int i = 0; i < num_cu_sib; i++) {
config_sibs[i] = cu_sib[i].SI_type;
const byte_array_t *container = &cu_sib[i].SI_container;
if (!container->buf || container->len == 0) {
LOG_W(NR_MAC, "SIB%d container is invalid (ptr=%p len=%zu), skipping\n", config_sibs[i], container->buf, container->len);
continue;
}
switch (config_sibs[i]) {
case 2: {
case NR_SIB_2: {
struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type = calloc(1, sizeof(*type));
type->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib2;
// SIB2 coming from CU need to decode it
NR_SIB2_t *sib2 = NULL;
asn_dec_rval_t dec_rval = uper_decode(NULL,
&asn_DEF_NR_SIB2,
(void **)&sib2,
cu_sib[i].SI_container,
cu_sib[i].SI_container_length,
0,
0);
asn_dec_rval_t dec_rval = uper_decode(NULL, &asn_DEF_NR_SIB2, (void **)&sib2, container->buf, container->len, 0, 0);
if (dec_rval.code != RC_OK) {
LOG_E(NR_MAC, "cannot decode SIB%d from CU\n", config_sibs[i]);
ASN_STRUCT_FREE(asn_DEF_NR_SIB2, cu_sib[i].SI_container);
ASN_STRUCT_FREE(asn_DEF_NR_SIB2, sib2);
}
type->choice.sib2 = sib2;
add_sib_to_systeminformation(sysInfo, type);
@@ -1019,7 +1018,7 @@ bool nr_mac_configure_other_sib(gNB_MAC_INST *nrmac, int num_cu_sib, const f1ap_
int sib_idx = i + num_cu_sib;
config_sibs[sib_idx] = si->SIB_type;
switch (config_sibs[sib_idx]) {
case 19: {
case NR_SIB_19: {
struct NR_SystemInformation_IEs__sib_TypeAndInfo__Member *type_du = calloc(1, sizeof(*type_du));
type_du->present = NR_SystemInformation_IEs__sib_TypeAndInfo__Member_PR_sib19_v1700;
NR_SIB19_r17_t *sib19 = get_SIB19_NR(cc->ServingCellConfigCommon);
+16 -8
View File
@@ -297,6 +297,17 @@ static void cp_f1_served_cell_info_to_cell(nr_rrc_cell_container_t *dst, const f
}
}
static void add_si_msg(served_cells_to_activate_t *cell, int sib_type, const byte_array_t *enc)
{
AssertFatal(cell->num_SI < F1AP_MAX_NO_SIB_TYPES,
"Too many SI messages (%u), max supported is %u\n",
cell->num_SI,
F1AP_MAX_NO_SIB_TYPES);
cell->SI_msg[cell->num_SI].SI_container = copy_byte_array(*enc);
cell->SI_msg[cell->num_SI].SI_type = sib_type;
cell->num_SI++;
}
void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
{
AssertFatal(assoc_id != 0, "illegal assoc_id == 0: should be -1 (monolithic) or >0 (split)\n");
@@ -425,16 +436,13 @@ void rrc_gNB_process_f1_setup_req(f1ap_setup_req_t *req, sctp_assoc_t assoc_id)
// Encode CU SIBs and configure setup response with sysinfo
seq_arr_t *sibs = rrc->SIBs;
if (sibs) {
for (int i = 0; i < sibs->size; i++) {
nr_SIBs_t *sib = (nr_SIBs_t *)seq_arr_at(sibs, i);
FOR_EACH_SEQ_ARR (nr_SIBs_t *, sib, sibs) {
switch (sib->SIB_type) {
case 2: {
case NR_SIB_2: {
NR_SSB_MTC_t *ssbmtc = get_ssb_mtc(new->mtc);
sib->SIB_size = do_SIB2_NR(&sib->SIB_buffer, ssbmtc);
cell.SI_msg[cell.num_SI].SI_container = sib->SIB_buffer;
cell.SI_msg[cell.num_SI].SI_container_length = sib->SIB_size;
cell.SI_msg[cell.num_SI].SI_type = sib->SIB_type;
cell.num_SI++;
byte_array_t ba = {0};
ba.len = do_SIB2_NR(&ba.buf, ssbmtc);
add_si_msg(&cell, sib->SIB_type, &ba);
} break;
default:
AssertFatal(false, "SIB%d not handled yet\n", sib->SIB_type);