diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 26399fae85..8ec4613327 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -129,10 +129,9 @@ typedef struct f1ap_served_cell_info_t { /* Tracking area code */ uint32_t *tac; - // Number of slide support items (max 16, could be increased to as much as 1024) + // Number of slice support items (max 16, could be increased to as much as 1024) uint16_t num_ssi; - uint8_t sst; - uint8_t sd; + nssai_t nssai[16]; f1ap_mode_t mode; union { diff --git a/openair2/F1AP/f1ap_cu_interface_management.c b/openair2/F1AP/f1ap_cu_interface_management.c index ed8403c492..92c1840350 100644 --- a/openair2/F1AP/f1ap_cu_interface_management.c +++ b/openair2/F1AP/f1ap_cu_interface_management.c @@ -76,6 +76,32 @@ static uint8_t *cp_octet_string(const OCTET_STRING_t *os, int *len) return buf; } +static int read_slice_info(const F1AP_ServedPLMNs_Item_t *plmn, nssai_t *nssai, int max_nssai) +{ + if (plmn->iE_Extensions == NULL) + return 0; + + const F1AP_ProtocolExtensionContainer_10696P34_t *p = (F1AP_ProtocolExtensionContainer_10696P34_t *)plmn->iE_Extensions; + if (p->list.count == 0) + return 0; + + const F1AP_ServedPLMNs_ItemExtIEs_t *splmn = p->list.array[0]; + DevAssert(splmn->id == F1AP_ProtocolIE_ID_id_TAISliceSupportList); + DevAssert(splmn->extensionValue.present == F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList); + const F1AP_SliceSupportList_t *ssl = &splmn->extensionValue.choice.SliceSupportList; + AssertFatal(ssl->list.count <= max_nssai, "cannot handle more than 16 slices\n"); + for (int s = 0; s < ssl->list.count; ++s) { + const F1AP_SliceSupportItem_t *sl = ssl->list.array[s]; + nssai_t *n = &nssai[s]; + OCTET_STRING_TO_INT8(&sl->sNSSAI.sST, n->sst); + n->sd = 0xffffff; + if (sl->sNSSAI.sD != NULL) + OCTET_STRING_TO_INT24(sl->sNSSAI.sD, n->sd); + } + + return ssl->list.count; +} + /* F1 Setup */ @@ -152,6 +178,9 @@ int CU_handle_F1_SETUP_REQUEST(instance_t instance, sctp_assoc_t assoc_id, uint3 req->cell[i].info.nr_pci = servedCellInformation->nRPCI; LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell[i].info.nr_pci); + AssertFatal(servedCellInformation->servedPLMNs.list.count == 1, "only one PLMN handled\n"); + req->cell[i].info.num_ssi = read_slice_info(servedCellInformation->servedPLMNs.list.array[0], req->cell[i].info.nssai, 16); + // FDD Cells if (servedCellInformation->nR_Mode_Info.present==F1AP_NR_Mode_Info_PR_fDD) { req->cell[i].info.mode = F1AP_MODE_FDD; @@ -507,6 +536,10 @@ int CU_handle_gNB_DU_CONFIGURATION_UPDATE(instance_t instance, sctp_assoc_t asso req->cell_to_add[i].info.nr_pci = servedCellInformation->nRPCI; LOG_D(F1AP, "req->nr_pci[%d] %d \n", i, req->cell_to_add[i].info.nr_pci); + AssertFatal(servedCellInformation->servedPLMNs.list.count == 1, "only one PLMN handled\n"); + req->cell_to_add[i].info.num_ssi = + read_slice_info(servedCellInformation->servedPLMNs.list.array[0], req->cell_to_add[i].info.nssai, 16); + // FDD Cells if (servedCellInformation->nR_Mode_Info.present == F1AP_NR_Mode_Info_PR_fDD) { req->cell_to_add[i].info.mode = F1AP_MODE_FDD; diff --git a/openair2/F1AP/f1ap_du_interface_management.c b/openair2/F1AP/f1ap_du_interface_management.c index 23af0ea3e6..7ea710a0b4 100644 --- a/openair2/F1AP/f1ap_du_interface_management.c +++ b/openair2/F1AP/f1ap_du_interface_management.c @@ -119,13 +119,13 @@ static F1AP_Served_Cell_Information_t encode_served_cell_info(const f1ap_served_ served_plmns_itemExtIEs->extensionValue.present = F1AP_ServedPLMNs_ItemExtIEs__extensionValue_PR_SliceSupportList; F1AP_SliceSupportList_t *slice_support_list = &served_plmns_itemExtIEs->extensionValue.choice.SliceSupportList; - AssertFatal(c->num_ssi == 1, "can only encode one slice\n"); for (int s = 0; s < c->num_ssi; s++) { asn1cSequenceAdd(slice_support_list->list, F1AP_SliceSupportItem_t, slice); - INT8_TO_OCTET_STRING(c->sst, &slice->sNSSAI.sST); - if (c->sd != 0xffffff) { + const nssai_t *nssai = &c->nssai[s]; + INT8_TO_OCTET_STRING(nssai->sst, &slice->sNSSAI.sST); + if (nssai->sd != 0xffffff) { asn1cCalloc(slice->sNSSAI.sD, tmp); - INT24_TO_OCTET_STRING(c->sd, tmp); + INT24_TO_OCTET_STRING(nssai->sd, tmp); } } } diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 64a40e4a83..2b9e6ce56c 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1075,6 +1075,8 @@ static int read_du_cell_info(configmodule_interface_t *cfg, PLMNParams[I].chkPptr = &(config_check_PLMNParams[I]); paramlist_def_t PLMNParamList = {GNB_CONFIG_STRING_PLMN_LIST, NULL, 0}; config_getlist(cfg, &PLMNParamList, PLMNParams, sizeof(PLMNParams) / sizeof(paramdef_t), aprefix); + AssertFatal(PLMNParamList.numelt > 0, "need to have a PLMN in PLMN section\n"); + AssertFatal(PLMNParamList.numelt == 1, "cannot have more than one PLMN\n"); // if fronthaul is F1, require gNB_DU_ID, else use gNB_ID if (separate_du) { @@ -1099,8 +1101,20 @@ static int read_du_cell_info(configmodule_interface_t *cfg, info->plmn.mnc_digit_length); info->nr_cellid = (uint64_t) * (GNBParamList.paramarray[0][GNB_NRCELLID_IDX].u64ptr); - LOG_W(GNB_APP, "no slices transported via F1 Setup Request!\n"); - info->num_ssi = 0; + paramdef_t SNSSAIParams[] = GNBSNSSAIPARAMS_DESC; + paramlist_def_t SNSSAIParamList = {GNB_CONFIG_STRING_SNSSAI_LIST, NULL, 0}; + checkedparam_t config_check_SNSSAIParams[] = SNSSAIPARAMS_CHECK; + for (int J = 0; J < sizeofArray(SNSSAIParams); ++J) + SNSSAIParams[J].chkPptr = &(config_check_SNSSAIParams[J]); + char snssaistr[MAX_OPTNAME_SIZE * 2 + 8]; + sprintf(snssaistr, "%s.[0].%s.[0]", GNB_CONFIG_STRING_GNB_LIST, GNB_CONFIG_STRING_PLMN_LIST); + config_getlist(config_get_if(), &SNSSAIParamList, SNSSAIParams, sizeofArray(SNSSAIParams), snssaistr); + info->num_ssi = SNSSAIParamList.numelt; + for (int s = 0; s < info->num_ssi; ++s) { + info->nssai[s].sst = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + info->nssai[s].sd = *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr; + AssertFatal(info->nssai[s].sd <= 0xffffff, "SD cannot be bigger than 0xffffff, but is %d\n", info->nssai[s].sd); + } return 1; } diff --git a/openair2/RRC/NR/rrc_gNB_du.c b/openair2/RRC/NR/rrc_gNB_du.c index 58b5dc6e7d..3bce7964b0 100644 --- a/openair2/RRC/NR/rrc_gNB_du.c +++ b/openair2/RRC/NR/rrc_gNB_du.c @@ -258,8 +258,8 @@ static void update_cell_info(nr_rrc_du_container_t *du, const f1ap_served_cell_i if (new_ci->tac != NULL) *ci->tac = *new_ci->tac; ci->num_ssi = new_ci->num_ssi; - ci->sst = new_ci->sst; - ci->sd = new_ci->sd; + 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;