diff --git a/openair2/F1AP/lib/CMakeLists.txt b/openair2/F1AP/lib/CMakeLists.txt index cb8d8b9712..0c6137dc30 100644 --- a/openair2/F1AP/lib/CMakeLists.txt +++ b/openair2/F1AP/lib/CMakeLists.txt @@ -8,3 +8,7 @@ target_include_directories(f1ap_lib PUBLIC ${CMAKE_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ) + +if(ENABLE_TESTS) + target_compile_definitions(f1ap_lib PRIVATE ENABLE_TESTS) +endif() diff --git a/openair2/F1AP/lib/f1ap_interface_management.c b/openair2/F1AP/lib/f1ap_interface_management.c index fe079faa4c..f067985a2d 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.c +++ b/openair2/F1AP/lib/f1ap_interface_management.c @@ -72,7 +72,7 @@ static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, /** * @brief F1AP Setup Request memory management */ -static void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info) +void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info) { if (sys_info) { free(sys_info->mib); @@ -83,72 +83,76 @@ static void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_d free(info->tac); } +/** + * @brief Encode NR Frequency Info (9.3.1.17 of 3GPP TS 38.473) + */ +static F1AP_NRFreqInfo_t encode_frequency_info(const f1ap_nr_frequency_info_t *info) +{ + F1AP_NRFreqInfo_t nrFreqInfo = {0}; + // NR ARFCN + nrFreqInfo.nRARFCN = info->arfcn; + int num_bands = 1; + // Frequency Band List + for (int j = 0; j < num_bands; j++) { + asn1cSequenceAdd(nrFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); + // NR Frequency Band + nr_freqBandNrItem->freqBandIndicatorNr = info->band; + } + return nrFreqInfo; +} + +/** + * @brief Encode Transmission Bandwidth (9.3.1.15 of 3GPP TS 38.473) + */ +static F1AP_Transmission_Bandwidth_t encode_tx_bandwidth(const f1ap_transmission_bandwidth_t *info) +{ + F1AP_Transmission_Bandwidth_t tb = {0}; + tb.nRSCS = info->scs; + tb.nRNRB = to_NRNRB(info->nrb); + return tb; +} + /** * @brief Encoding of Served Cell Information (9.3.1.10 of 3GPP TS 38.473) */ static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_cell_info_t *c) { F1AP_Served_Cell_Information_t scell_info = {0}; - // NR CGI + // NR CGI (M) MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &(scell_info.nRCGI.pLMN_Identity)); NR_CELL_ID_TO_BIT_STRING(c->nr_cellid, &(scell_info.nRCGI.nRCellIdentity)); - // NR PCI + // NR PCI (M) scell_info.nRPCI = c->nr_pci; // int 0..1007 - // 5GS TAC + // 5GS TAC (O) if (c->tac != NULL) { uint32_t tac = htonl(*c->tac); asn1cCalloc(scell_info.fiveGS_TAC, netOrder); OCTET_STRING_fromBuf(netOrder, ((char *)&tac) + 1, 3); } - // Served PLMNs + // Served PLMNs 1.. asn1cSequenceAdd(scell_info.servedPLMNs.list, F1AP_ServedPLMNs_Item_t, servedPLMN_item); + // PLMN Identity (M) MCC_MNC_TO_PLMNID(c->plmn.mcc, c->plmn.mnc, c->plmn.mnc_digit_length, &servedPLMN_item->pLMN_Identity); - // NR-Mode-Info + // NR-Mode-Info (M) F1AP_NR_Mode_Info_t *nR_Mode_Info = &scell_info.nR_Mode_Info; - if (c->mode == F1AP_MODE_FDD) { // FDD + if (c->mode == F1AP_MODE_FDD) { // FDD Info const f1ap_fdd_info_t *fdd = &c->fdd; nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_fDD; asn1cCalloc(nR_Mode_Info->choice.fDD, fDD_Info); - /* FDD.1.1 UL NRFreqInfo ARFCN */ - fDD_Info->uL_NRFreqInfo.nRARFCN = fdd->ul_freqinfo.arfcn; - /* FDD.1.3 freqBandListNr */ - int ul_band = 1; - for (int j = 0; j < ul_band; j++) { - asn1cSequenceAdd(fDD_Info->uL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); - /* FDD.1.3.1 freqBandIndicatorNr*/ - nr_freqBandNrItem->freqBandIndicatorNr = fdd->ul_freqinfo.band; - } - /* FDD.2.1 DL NRFreqInfo ARFCN */ - fDD_Info->dL_NRFreqInfo.nRARFCN = fdd->dl_freqinfo.arfcn; - /* FDD.2.3 freqBandListNr */ - int dl_bands = 1; - for (int j = 0; j < dl_bands; j++) { - asn1cSequenceAdd(fDD_Info->dL_NRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); - /* FDD.2.3.1 freqBandIndicatorNr*/ - nr_freqBandNrItem->freqBandIndicatorNr = fdd->dl_freqinfo.band; - } // for FDD : DL freq_Bands - /* FDD.3 UL Transmission Bandwidth */ - fDD_Info->uL_Transmission_Bandwidth.nRSCS = fdd->ul_tbw.scs; - fDD_Info->uL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->ul_tbw.nrb); - /* FDD.4 DL Transmission Bandwidth */ - fDD_Info->dL_Transmission_Bandwidth.nRSCS = fdd->dl_tbw.scs; - fDD_Info->dL_Transmission_Bandwidth.nRNRB = to_NRNRB(fdd->dl_tbw.nrb); - } else if (c->mode == F1AP_MODE_TDD) { + // NR Frequency Info + fDD_Info->uL_NRFreqInfo = encode_frequency_info(&fdd->ul_freqinfo); + fDD_Info->dL_NRFreqInfo = encode_frequency_info(&fdd->dl_freqinfo); + // Transmission Bandwidth + fDD_Info->uL_Transmission_Bandwidth = encode_tx_bandwidth(&fdd->ul_tbw); + fDD_Info->dL_Transmission_Bandwidth = encode_tx_bandwidth(&fdd->dl_tbw); + } else if (c->mode == F1AP_MODE_TDD) { // TDD Info const f1ap_tdd_info_t *tdd = &c->tdd; nR_Mode_Info->present = F1AP_NR_Mode_Info_PR_tDD; asn1cCalloc(nR_Mode_Info->choice.tDD, tDD_Info); - /* TDD.1.1 nRFreqInfo ARFCN */ - tDD_Info->nRFreqInfo.nRARFCN = tdd->freqinfo.arfcn; - /* TDD.1.3 freqBandListNr */ - int bands = 1; - for (int j = 0; j < bands; j++) { - asn1cSequenceAdd(tDD_Info->nRFreqInfo.freqBandListNr.list, F1AP_FreqBandNrItem_t, nr_freqBandNrItem); - /* TDD.1.3.1 freqBandIndicatorNr*/ - nr_freqBandNrItem->freqBandIndicatorNr = tdd->freqinfo.band; - } - /* TDD.2 transmission_Bandwidth */ - tDD_Info->transmission_Bandwidth.nRSCS = tdd->tbw.scs; - tDD_Info->transmission_Bandwidth.nRNRB = to_NRNRB(tdd->tbw.nrb); + // NR Frequency Info + tDD_Info->nRFreqInfo = encode_frequency_info(&tdd->freqinfo); + // Transmission Bandwidth + tDD_Info->transmission_Bandwidth = encode_tx_bandwidth(&tdd->tbw); } else { AssertFatal(false, "unknown duplex mode %d\n", c->mode); } @@ -530,16 +534,16 @@ bool decode_f1ap_setup_request(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_req_t *out return true; } -static void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *dest, const f1ap_served_cell_info_t *src) { +void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *dest, const f1ap_served_cell_info_t *src) +{ + // shallow copy *dest = *src; - dest->mode = src->mode; - dest->tdd = src->tdd; - dest->fdd = src->fdd; - dest->plmn = src->plmn; + // tac if (src->tac) { dest->tac = malloc_or_fail(sizeof(*dest->tac)); *dest->tac = *src->tac; } + // measurement timing config if (src->measurement_timing_config_len) { dest->measurement_timing_config = calloc_or_fail(src->measurement_timing_config_len, sizeof(*dest->measurement_timing_config)); memcpy(dest->measurement_timing_config, src->measurement_timing_config, src->measurement_timing_config_len); @@ -955,7 +959,7 @@ bool decode_f1ap_setup_failure(const F1AP_F1AP_PDU_t *pdu, f1ap_setup_failure_t */ bool eq_f1ap_setup_failure(const f1ap_setup_failure_t *a, const f1ap_setup_failure_t *b) { - _F1_EQ_CHECK_INT(a->transaction_id, b->transaction_id); + _F1_EQ_CHECK_LONG(a->transaction_id, b->transaction_id); return true; } diff --git a/openair2/F1AP/lib/f1ap_interface_management.h b/openair2/F1AP/lib/f1ap_interface_management.h index bdceee9a61..e483a74301 100644 --- a/openair2/F1AP/lib/f1ap_interface_management.h +++ b/openair2/F1AP/lib/f1ap_interface_management.h @@ -32,6 +32,8 @@ bool decode_f1ap_setup_request(const struct F1AP_F1AP_PDU *pdu, f1ap_setup_req_t f1ap_setup_req_t cp_f1ap_setup_request(const f1ap_setup_req_t *msg); bool eq_f1ap_setup_request(const f1ap_setup_req_t *a, const f1ap_setup_req_t *b); void free_f1ap_setup_request(const f1ap_setup_req_t *msg); +void copy_f1ap_served_cell_info(f1ap_served_cell_info_t *a, const f1ap_served_cell_info_t *b); +void free_f1ap_cell(const f1ap_served_cell_info_t *info, const f1ap_gnb_du_system_info_t *sys_info); /* F1 Setup Response */ struct F1AP_F1AP_PDU *encode_f1ap_setup_response(const f1ap_setup_resp_t *msg); diff --git a/openair2/F1AP/tests/f1ap_lib_test.c b/openair2/F1AP/tests/f1ap_lib_test.c index 71d2bea953..4c75aa944e 100644 --- a/openair2/F1AP/tests/f1ap_lib_test.c +++ b/openair2/F1AP/tests/f1ap_lib_test.c @@ -119,9 +119,8 @@ static void test_initial_ul_rrc_message_transfer(void) */ static void test_dl_rrc_message_transfer(void) { - uint8_t *rrc = calloc(strlen("RRC Container") + 1, sizeof(uint8_t)); - uint32_t *old_gNB_DU_ue_id = calloc(1, sizeof(uint32_t)); - AssertFatal(rrc != NULL && old_gNB_DU_ue_id != NULL, "out of memory\n"); + uint8_t *rrc = calloc_or_fail(strlen("RRC Container") + 1, sizeof(*rrc)); + uint32_t *old_gNB_DU_ue_id = calloc_or_fail(1, sizeof(*old_gNB_DU_ue_id)); memcpy((void *)rrc, "RRC Container", strlen("RRC Container") + 1); f1ap_dl_rrc_message_t orig = { @@ -194,12 +193,11 @@ static void test_f1ap_setup_request(void) { /* allocate memory */ /* gNB_DU_name */ - uint8_t *gNB_DU_name = calloc(strlen("OAI DU") + 1, sizeof(uint8_t)); - AssertFatal(gNB_DU_name != NULL, "out of memory\n"); + uint8_t *gNB_DU_name = calloc_or_fail(strlen("OAI DU") + 1, sizeof(*gNB_DU_name)); memcpy(gNB_DU_name, "OAI DU", strlen("OAI DU") + 1); /* sys_info */ - uint8_t *mib = calloc(3, sizeof(uint8_t)); - uint8_t *sib1 = calloc(3, sizeof(uint8_t)); + uint8_t *mib = calloc_or_fail(3, sizeof(*mib)); + uint8_t *sib1 = calloc_or_fail(3, sizeof(*sib1)); f1ap_gnb_du_system_info_t sys_info = { .mib_length = 3, .mib = mib, @@ -208,11 +206,10 @@ static void test_f1ap_setup_request(void) }; /* measurement_timing_information */ int measurement_timing_config_len = strlen("0") + 1; - uint8_t *measurement_timing_information = calloc(measurement_timing_config_len, sizeof(uint8_t)); - AssertFatal(measurement_timing_information != NULL, "out of memory\n"); + uint8_t *measurement_timing_information = calloc_or_fail(measurement_timing_config_len, sizeof(*measurement_timing_information)); memcpy((void *)measurement_timing_information, "0", measurement_timing_config_len); /* TAC */ - uint32_t *tac = calloc(1, sizeof(uint32_t)); + uint32_t *tac = calloc_or_fail(1, sizeof(*tac)); /* * TDD test */ @@ -245,7 +242,7 @@ static void test_f1ap_setup_request(void) .rrc_ver[2] = 56, .cell[0].info = info, }; - orig.cell[0].sys_info = calloc(1, sizeof(*orig.cell[0].sys_info)); + orig.cell[0].sys_info = calloc_or_fail(1, sizeof(*orig.cell[0].sys_info)); *orig.cell[0].sys_info = sys_info; // encode F1AP_F1AP_PDU_t *f1enc = encode_f1ap_setup_request(&orig); @@ -311,8 +308,7 @@ static void test_f1ap_setup_response(void) /* gNB_CU_name */ char *cu_name = "OAI-CU"; int len = strlen(cu_name) + 1; - uint8_t *gNB_CU_name = calloc(len, sizeof(uint8_t)); - AssertFatal(gNB_CU_name != NULL, "out of memory\n"); + uint8_t *gNB_CU_name = calloc_or_fail(len, sizeof(*gNB_CU_name)); memcpy((void *)gNB_CU_name, cu_name, len); /* create message */ f1ap_setup_resp_t orig = { @@ -393,8 +389,8 @@ static void test_f1ap_setup_failure(void) static void test_f1ap_du_configuration_update(void) { /* sys_info */ - uint8_t *mib = calloc(3, sizeof(uint8_t)); - uint8_t *sib1 = calloc(3, sizeof(uint8_t)); + uint8_t *mib = calloc_or_fail(3, sizeof(*mib)); + uint8_t *sib1 = calloc_or_fail(3, sizeof(*sib1)); f1ap_gnb_du_system_info_t sys_info = { .mib_length = 3, .mib = mib, @@ -404,12 +400,10 @@ static void test_f1ap_du_configuration_update(void) /* measurement_timing_information modify */ char *s = "1"; int measurement_timing_config_len = strlen(s) + 1; - uint8_t *measurement_timing_config_mod = calloc(measurement_timing_config_len, sizeof(uint8_t)); - AssertFatal(measurement_timing_config_mod != NULL, "out of memory\n"); + uint8_t *measurement_timing_config_mod = calloc_or_fail(measurement_timing_config_len, sizeof(*measurement_timing_config_mod)); memcpy((void *)measurement_timing_config_mod, s, measurement_timing_config_len); /* TAC modify */ - uint32_t *tac = calloc(1, sizeof(uint32_t)); - AssertFatal(tac != NULL, "out of memory\n"); + uint32_t *tac = calloc_or_fail(1, sizeof(*tac)); *tac = 456; /* info modify */ f1ap_served_cell_info_t info = { @@ -437,8 +431,7 @@ static void test_f1ap_du_configuration_update(void) .cell_to_delete[0].plmn.mnc = 1, .cell_to_delete[0].plmn.mnc_digit_length = 3, }; - orig.cell_to_modify[0].sys_info = calloc(1, sizeof(*orig.cell_to_modify[0].sys_info)); - AssertFatal(orig.cell_to_modify[0].sys_info != NULL, "out of memory\n"); + orig.cell_to_modify[0].sys_info = calloc_or_fail(1, sizeof(*orig.cell_to_modify[0].sys_info)); *orig.cell_to_modify[0].sys_info = sys_info; F1AP_F1AP_PDU_t *f1enc = encode_f1ap_du_configuration_update(&orig); diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 639c279d4d..bc3c564516 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -446,19 +446,9 @@ static void update_cell_info(nr_rrc_du_container_t *du, const f1ap_served_cell_i AssertFatal(du->setup_req->num_cells_available == 1, "expected 1 cell for DU, but has %d\n", du->setup_req->num_cells_available); f1ap_served_cell_info_t *ci = &du->setup_req->cell[0].info; - - ci->nr_cellid = new_ci->nr_cellid; - ci->nr_pci = new_ci->nr_pci; - if (new_ci->tac != NULL) - *ci->tac = *new_ci->tac; - ci->num_ssi = new_ci->num_ssi; - for (int s = 0; s < new_ci->num_ssi; ++s) - ci->nssai[s] = new_ci->nssai[s]; - ci->mode = new_ci->mode; - if (ci->mode == F1AP_MODE_TDD) - ci->tdd = new_ci->tdd; - else - ci->fdd = new_ci->fdd; + // make sure no memory is allocated + free_f1ap_cell(ci, NULL); + copy_f1ap_served_cell_info(ci, new_ci); NR_MeasurementTimingConfiguration_t *new_mtc = extract_mtc(new_ci->measurement_timing_config, new_ci->measurement_timing_config_len);