diff --git a/common/utils/nr/nr_common.h b/common/utils/nr/nr_common.h index 8580a0491b..228e51feb2 100644 --- a/common/utils/nr/nr_common.h +++ b/common/utils/nr/nr_common.h @@ -13,6 +13,7 @@ #include #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 { diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 37c4a7ee83..2df2c783bf 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -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; diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index bb2015b33e..815a9f1b82 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -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); diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 8f315ff8ae..1140e3c39b 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -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); diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 0c38993487..edbaae1735 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -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)); diff --git a/openair2/LAYER2/NR_MAC_gNB/config.c b/openair2/LAYER2/NR_MAC_gNB/config.c index 202590f9fc..18d5bbb4a8 100644 --- a/openair2/LAYER2/NR_MAC_gNB/config.c +++ b/openair2/LAYER2/NR_MAC_gNB/config.c @@ -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); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 71da3f3d1b..495ad92c82 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -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);