diff --git a/openair2/COMMON/e1ap_messages_types.h b/openair2/COMMON/e1ap_messages_types.h index f98058b85c..c50efd337f 100644 --- a/openair2/COMMON/e1ap_messages_types.h +++ b/openair2/COMMON/e1ap_messages_types.h @@ -59,10 +59,7 @@ typedef struct PLMN_ID_s { int mnc_digit_length; } PLMN_ID_t; -typedef struct e1ap_nssai_t { - uint8_t sst; - uint32_t sd; // optional: "No SD" is 0xffffff, see 23.003 Sec 28.4.2 -} e1ap_nssai_t; +typedef nssai_t e1ap_nssai_t; typedef struct e1ap_net_config_t { net_ip_address_t CUUP_e1_ip_address; diff --git a/openair2/COMMON/f1ap_messages_types.h b/openair2/COMMON/f1ap_messages_types.h index 8f8a047ee5..d7d46f3bef 100644 --- a/openair2/COMMON/f1ap_messages_types.h +++ b/openair2/COMMON/f1ap_messages_types.h @@ -26,6 +26,7 @@ #include #include "rlc.h" #include "s1ap_messages_types.h" +#include "ngap_messages_types.h" //-------------------------------------------------------------------------------------------// // Defines to access message fields. @@ -290,6 +291,7 @@ typedef struct f1ap_drb_to_be_setup_s { f1ap_up_tnl_t up_dl_tnl[2]; uint8_t up_dl_tnl_length; rlc_mode_t rlc_mode; + nssai_t nssai; } f1ap_drb_to_be_setup_t; typedef struct f1ap_srb_to_be_setup_s { diff --git a/openair2/COMMON/ngap_messages_types.h b/openair2/COMMON/ngap_messages_types.h index a03a9d88b6..25889468f2 100644 --- a/openair2/COMMON/ngap_messages_types.h +++ b/openair2/COMMON/ngap_messages_types.h @@ -194,6 +194,11 @@ typedef enum ngap_rrc_establishment_cause_e { NGAP_RRC_CAUSE_LAST } ngap_rrc_establishment_cause_t; +typedef struct nssai_s { + uint8_t sst; + uint32_t sd; +} nssai_t; + typedef struct pdusession_level_qos_parameter_s { uint8_t qfi; uint64_t fiveQI; @@ -210,12 +215,6 @@ typedef struct ngap_guami_s { uint8_t amf_pointer; } ngap_guami_t; -typedef struct ngap_allowed_NSSAI_s{ - uint8_t sST; - uint8_t sD_flag; - uint8_t sD[3]; -}ngap_allowed_NSSAI_t; - typedef struct fiveg_s_tmsi_s { uint16_t amf_set_id; uint8_t amf_pointer; @@ -282,6 +281,7 @@ typedef struct pdusession_s { transport_layer_addr_t gNB_addr_N3; uint32_t UPF_teid_N3; transport_layer_addr_t UPF_addr_N3; + nssai_t nssai; } pdusession_t; typedef enum pdusession_qosflow_mapping_ind_e{ @@ -423,6 +423,14 @@ typedef enum ngap_paging_ind_present_s { NGAP_PAGING_IND_PAGING_PRIORITY = (1 << 1), } ngap_paging_ind_present_t; +typedef struct { + uint16_t mcc; + uint16_t mnc; + uint8_t mnc_digit_length; + uint8_t num_nssai; + nssai_t s_nssai[8]; +} ngap_plmn_t; + //-------------------------------------------------------------------------------------------// // gNB application layer -> NGAP messages typedef struct ngap_register_gnb_req_s { @@ -447,13 +455,8 @@ typedef struct ngap_register_gnb_req_s { /* Mobile Country Code * Mobile Network Code */ - uint16_t mcc[PLMN_LIST_MAX_SIZE]; - uint16_t mnc[PLMN_LIST_MAX_SIZE]; - uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; uint8_t num_plmn; - - uint16_t num_nssai[PLMN_LIST_MAX_SIZE]; - ngap_allowed_NSSAI_t s_nssai[PLMN_LIST_MAX_SIZE][8]; + ngap_plmn_t plmn[PLMN_LIST_MAX_SIZE]; /* Default Paging DRX of the gNB as defined in TS 38.304 */ ngap_paging_drx_t default_drx; @@ -601,7 +604,7 @@ typedef struct ngap_initial_context_setup_req_s { /* allowed nssai */ uint8_t nb_allowed_nssais; - ngap_allowed_NSSAI_t allowed_nssai[8]; + nssai_t allowed_nssai[8]; /* Security algorithms */ ngap_security_capabilities_t security_capabilities; @@ -662,7 +665,7 @@ typedef struct ngap_pdusession_setup_req_s { /* S-NSSAI */ // Fixme: illogical, nssai is part of each pdu session - ngap_allowed_NSSAI_t allowed_nssai[8]; + nssai_t allowed_nssai[8]; /* Number of pdusession to be setup in the list */ uint8_t nb_pdusessions_tosetup; diff --git a/openair2/F1AP/f1ap_cu_ue_context_management.c b/openair2/F1AP/f1ap_cu_ue_context_management.c index 876cd1e3a9..ff82cd3840 100644 --- a/openair2/F1AP/f1ap_cu_ue_context_management.c +++ b/openair2/F1AP/f1ap_cu_ue_context_management.c @@ -398,15 +398,12 @@ int CU_send_UE_CONTEXT_SETUP_REQUEST(instance_t instance, /* 12.1.2.2 sNSSAI */ { /* sST */ - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); + OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sst, 1); /* OPTIONAL */ - /* sD */ - if (0) { - asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } + const uint32_t sd = (f1ap_ue_context_setup_req->drbs_to_be_setup[i].nssai.sd & 0xffffff); + if (sd != 0xffffff) + OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3); } /* OPTIONAL */ @@ -1313,16 +1310,12 @@ int CU_send_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, f1ap_ue_context /* 12.1.2.2 sNSSAI */ { /* sST */ - - OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, "1", 1); + OCTET_STRING_fromBuf(&DRB_Information->sNSSAI.sST, (char *)&f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sst, 1); /* OPTIONAL */ - /* sD */ - if (0) { - asn1cCalloc(DRB_Information->sNSSAI.sD, tmp); - OCTET_STRING_fromBuf(tmp, "asdsa1d32sa1d31asd31as", - strlen("asdsa1d32sa1d31asd31as")); - } + const uint32_t sd = (f1ap_ue_context_modification_req->drbs_to_be_setup[i].nssai.sd & 0xffffff); + if (sd != 0xffffff) + OCTET_STRING_fromBuf(DRB_Information->sNSSAI.sD, (char *)&sd, 3); } /* OPTIONAL */ diff --git a/openair2/F1AP/f1ap_du_ue_context_management.c b/openair2/F1AP/f1ap_du_ue_context_management.c index 91cb157c9d..49e19f7697 100644 --- a/openair2/F1AP/f1ap_du_ue_context_management.c +++ b/openair2/F1AP/f1ap_du_ue_context_management.c @@ -879,6 +879,27 @@ int DU_handle_UE_CONTEXT_MODIFICATION_REQUEST(instance_t instance, sctp_assoc_t drb_p->rlc_mode = RLC_MODE_TM; break; } + + if (drbs_tobesetupmod_item_p->qoSInformation.present == F1AP_QoSInformation_PR_eUTRANQoS) { + AssertFatal(false, "Decode of eUTRANQoS is not implemented yet"); + } // EUTRAN QoS Information + else { + /* 12.1.2 DRB_Information */ + if (drbs_tobesetupmod_item_p->qoSInformation.present == F1AP_QoSInformation_PR_choice_extension) { + F1AP_QoSInformation_ExtIEs_t *ie = + (F1AP_QoSInformation_ExtIEs_t *)drbs_tobesetupmod_item_p->qoSInformation.choice.choice_extension; + if (ie->id == F1AP_ProtocolIE_ID_id_DRB_Information && ie->criticality == F1AP_Criticality_reject + && ie->value.present == F1AP_QoSInformation_ExtIEs__value_PR_DRB_Information) { + F1AP_DRB_Information_t *DRB_Information = &ie->value.choice.DRB_Information; + /* S-NSSAI */ + OCTET_STRING_TO_INT8(&DRB_Information->sNSSAI.sST, drb_p->nssai.sst); + if (DRB_Information->sNSSAI.sD != NULL) + memcpy((uint8_t *)&drb_p->nssai.sd, DRB_Information->sNSSAI.sD->buf, 3); + else + drb_p->nssai.sd = 0xffffff; + } + } + } } } diff --git a/openair2/GNB_APP/gnb_config.c b/openair2/GNB_APP/gnb_config.c index 2368e5ab6b..9fc93bf045 100644 --- a/openair2/GNB_APP/gnb_config.c +++ b/openair2/GNB_APP/gnb_config.c @@ -1750,27 +1750,23 @@ int RCconfig_NR_NG(MessageDef *msg_p, uint32_t i) { sprintf(snssaistr, "%s.[%i].%s.[%i]", GNB_CONFIG_STRING_GNB_LIST, k, GNB_CONFIG_STRING_PLMN_LIST, l); config_getlist(&SNSSAIParamList, SNSSAIParams, sizeof(SNSSAIParams)/sizeof(paramdef_t), snssaistr); - NGAP_REGISTER_GNB_REQ (msg_p).mcc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; - NGAP_REGISTER_GNB_REQ (msg_p).mnc[l] = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; - NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].mcc = *PLMNParamList.paramarray[l][GNB_MOBILE_COUNTRY_CODE_IDX].uptr; + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].mnc = *PLMNParamList.paramarray[l][GNB_MOBILE_NETWORK_CODE_IDX].uptr; + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].mnc_digit_length = *PLMNParamList.paramarray[l][GNB_MNC_DIGIT_LENGTH].u8ptr; NGAP_REGISTER_GNB_REQ (msg_p).default_drx = 0; - AssertFatal((NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] == 2) || - (NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l] == 3), + AssertFatal((NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].mnc_digit_length == 2) + || (NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].mnc_digit_length == 3), "BAD MNC DIGIT LENGTH %d", - NGAP_REGISTER_GNB_REQ (msg_p).mnc_digit_length[l]); - - NGAP_REGISTER_GNB_REQ (msg_p).num_nssai[l] = SNSSAIParamList.numelt; + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].mnc_digit_length); + + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].num_nssai = SNSSAIParamList.numelt; for (int s = 0; s < SNSSAIParamList.numelt; ++s) { - - NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sST = *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; - NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD_flag = 0; - if(SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr != 0 // SD is optional - && *SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr != 0xffffff) { // 0xffffff is "no SD", see 23.003 Sec 28.4.2 - NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD_flag = 1; - NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[0] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0xFF0000) >> 16; - NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[1] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0x00FF00) >> 8; - NGAP_REGISTER_GNB_REQ (msg_p).s_nssai[l][s].sD[2] = (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0x0000FF); - } + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].s_nssai[s].sst = + *SNSSAIParamList.paramarray[s][GNB_SLICE_SERVICE_TYPE_IDX].uptr; + // SD is optional + // 0xffffff is "no SD", see 23.003 Sec 28.4.2 + NGAP_REGISTER_GNB_REQ(msg_p).plmn[l].s_nssai[s].sd = + (*SNSSAIParamList.paramarray[s][GNB_SLICE_DIFFERENTIATOR_IDX].uptr & 0xffffff); } } sprintf(aprefix,"%s.[%i]",GNB_CONFIG_STRING_GNB_LIST,k); diff --git a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c index ea0d08e152..9eda0ceaf1 100644 --- a/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c +++ b/openair2/LAYER2/NR_MAC_gNB/mac_rrc_dl_handler.c @@ -30,6 +30,16 @@ #include "uper_decoder.h" #include "uper_encoder.h" +static long get_lcid_from_drbid(int drb_id) +{ + return drb_id + 3; /* LCID is DRB + 3 */ +} + +static long get_lcid_from_srbid(int srb_id) +{ + return srb_id; +} + static bool check_plmn_identity(const f1ap_plmn_t *check_plmn, const f1ap_plmn_t *plmn) { return plmn->mcc == check_plmn->mcc && plmn->mnc_digit_length == check_plmn->mnc_digit_length && plmn->mnc == check_plmn->mnc; @@ -78,7 +88,7 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_srb(const f1ap_srb_to_be_set long priority = srb->srb_id; // high priority for SRB e_NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration bucket = NR_LogicalChannelConfig__ul_SpecificParameters__bucketSizeDuration_ms5; - return get_SRB_RLC_BearerConfig(srb->srb_id, priority, bucket); + return get_SRB_RLC_BearerConfig(get_lcid_from_srbid(srb->srb_id), priority, bucket); } static int handle_ue_context_srbs_setup(int rnti, @@ -108,7 +118,7 @@ static NR_RLC_BearerConfig_t *get_bearerconfig_from_drb(const f1ap_drb_to_be_set { const NR_RLC_Config_PR rlc_conf = drb->rlc_mode == RLC_MODE_UM ? NR_RLC_Config_PR_um_Bi_Directional : NR_RLC_Config_PR_am; long priority = 13; // hardcoded for the moment - return get_DRB_RLC_BearerConfig(3 + drb->drb_id, drb->drb_id, rlc_conf, priority); + return get_DRB_RLC_BearerConfig(get_lcid_from_drbid(drb->drb_id), drb->drb_id, rlc_conf, priority); } static int handle_ue_context_drbs_setup(int rnti, @@ -153,7 +163,7 @@ static int handle_ue_context_drbs_release(int rnti, for (int i = 0; i < drbs_len; i++) { const f1ap_drb_to_be_released_t *drb = &req_drbs[i]; - long lcid = drb->rb_id + 3; /* LCID is DRB + 3 */ + long lcid = get_lcid_from_drbid(drb->rb_id); int idx = 0; while (idx < cellGroupConfig->rlc_BearerToAddModList->list.count) { const NR_RLC_BearerConfig_t *bc = cellGroupConfig->rlc_BearerToAddModList->list.array[idx]; @@ -222,6 +232,17 @@ static NR_CellGroupConfig_t *clone_CellGroupConfig(const NR_CellGroupConfig_t *o return cloned; } +static void set_nssaiConfig(const int drb_len, const f1ap_drb_to_be_setup_t *req_drbs, NR_UE_sched_ctrl_t *sched_ctrl) +{ + for (int i = 0; i < drb_len; i++) { + const f1ap_drb_to_be_setup_t *drb = &req_drbs[i]; + + long lcid = get_lcid_from_drbid(drb->drb_id); + sched_ctrl->dl_lc_nssai[lcid] = drb->nssai; + LOG_I(NR_MAC, "Setting NSSAI sst: %d, sd: %d for DRB: %ld\n", drb->nssai.sst, drb->nssai.sd, drb->drb_id); + } +} + void ue_context_setup_request(const f1ap_ue_context_setup_t *req) { gNB_MAC_INST *mac = RC.nrmac[0]; @@ -288,6 +309,9 @@ void ue_context_setup_request(const f1ap_ue_context_setup_t *req) /* TODO: need to apply after UE context reconfiguration confirmed? */ nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); + /* Set NSSAI config in MAC for each active DRB */ + set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl); + NR_SCHED_UNLOCK(&mac->sched_lock); /* some sanity checks, since we use the same type for request and response */ @@ -384,6 +408,9 @@ void ue_context_modification_request(const f1ap_ue_context_modif_req_t *req) resp.du_to_cu_rrc_information->cellGroupConfig_length = (enc_rval.encoded + 7) >> 3; nr_mac_prepare_cellgroup_update(mac, UE, new_CellGroup); + + /* Set NSSAI config in MAC for each active DRB */ + set_nssaiConfig(req->drbs_to_be_setup_length, req->drbs_to_be_setup, &UE->UE_sched_ctrl); } else { ASN_STRUCT_FREE(asn_DEF_NR_CellGroupConfig, new_CellGroup); // we actually don't need it } diff --git a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h index 89f1dabc34..0060df1c10 100644 --- a/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h +++ b/openair2/LAYER2/NR_MAC_gNB/nr_mac_gNB.h @@ -639,6 +639,7 @@ typedef struct { /// sri, ul_ri and tpmi based on SRS nr_srs_feedback_t srs_feedback; + nssai_t dl_lc_nssai[NR_MAX_NUM_LCID]; } NR_UE_sched_ctrl_t; typedef struct { diff --git a/openair2/RRC/NR/rrc_gNB.c b/openair2/RRC/NR/rrc_gNB.c index 027fc69862..6c3de095e5 100644 --- a/openair2/RRC/NR/rrc_gNB.c +++ b/openair2/RRC/NR/rrc_gNB.c @@ -2346,6 +2346,8 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp /* Instruction towards the DU for DRB configuration and tunnel creation */ int nb_drb = resp->pduSession[0].numDRBSetup; f1ap_drb_to_be_setup_t drbs[nb_drb]; + rrc_pdu_session_param_t *RRC_pduSession = find_pduSession(UE, resp->pduSession[0].id, false); + DevAssert(RRC_pduSession); for (int i = 0; i < nb_drb; i++) { drbs[i].drb_id = resp->pduSession[0].DRBnGRanList[i].id; drbs[i].rlc_mode = rrc->configuration.um_on_default_drb ? RLC_MODE_UM : RLC_MODE_AM; @@ -2353,6 +2355,8 @@ void rrc_gNB_process_e1_bearer_context_setup_resp(e1ap_bearer_setup_resp_t *resp drbs[i].up_ul_tnl[0].port = rrc->eth_params_s.my_portd; drbs[i].up_ul_tnl[0].teid = resp->pduSession[0].DRBnGRanList[i].UpParamList[0].teId; drbs[i].up_ul_tnl_length = 1; + /* pass NSSAI info to MAC */ + drbs[i].nssai = RRC_pduSession->param.nssai; } /* Instruction towards the DU for SRB2 configuration */ diff --git a/openair2/RRC/NR/rrc_gNB_NGAP.c b/openair2/RRC/NR/rrc_gNB_NGAP.c index 49d3ccad99..d60586e2c9 100644 --- a/openair2/RRC/NR/rrc_gNB_NGAP.c +++ b/openair2/RRC/NR/rrc_gNB_NGAP.c @@ -766,11 +766,12 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins for (int i = 0; i < msg->nb_pdusessions_tosetup; i++) { rrc_pdu_session_param_t *pduSession = find_pduSession(UE, msg->pdusession_setup_params[i].pdusession_id, true); pdusession_t *session = &pduSession->param; - LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions); session->pdusession_id = msg->pdusession_setup_params[i].pdusession_id; + LOG_I(NR_RRC, "Adding pdusession %d, total nb of sessions %d\n", session->pdusession_id, UE->nb_of_pdusessions); session->pdu_session_type = msg->pdusession_setup_params[i].pdu_session_type; session->nas_pdu = msg->pdusession_setup_params[i].nas_pdu; session->pdusessionTransfer = msg->pdusession_setup_params[i].pdusessionTransfer; + session->nssai = msg->pdusession_setup_params[i].nssai; decodePDUSessionResourceSetup(session); bearer_req.gNB_cu_cp_ue_id = msg->gNB_ue_ngap_id; bearer_req.cipheringAlgorithm = UE->ciphering_algorithm; @@ -781,11 +782,9 @@ void rrc_gNB_process_NGAP_PDUSESSION_SETUP_REQ(MessageDef *msg_p, instance_t ins pdu_session_to_setup_t *pdu = bearer_req.pduSession + bearer_req.numPDUSessions; bearer_req.numPDUSessions++; pdu->sessionId = session->pdusession_id; - ngap_allowed_NSSAI_t *nssai = &msg->allowed_nssai[i]; - pdu->nssai.sst = nssai->sST; - pdu->nssai.sd = 0xffffff; - if (nssai->sD_flag) - pdu->nssai.sd = nssai->sD[0] << 16 | nssai->sD[1] << 8 | nssai->sD[2]; + nssai_t *nssai = &msg->allowed_nssai[i]; + pdu->nssai.sst = nssai->sst; + pdu->nssai.sd = nssai->sd; if (cuup_nssai.sst == 0) cuup_nssai = pdu->nssai; /* for CU-UP selection below */ pdu->integrityProtectionIndication = rrc->security.do_drb_integrity ? E1AP_IntegrityProtectionIndication_required : E1AP_IntegrityProtectionIndication_not_needed; diff --git a/openair3/NGAP/ngap_gNB.c b/openair3/NGAP/ngap_gNB.c index 09dc9321a1..45183407a3 100644 --- a/openair3/NGAP/ngap_gNB.c +++ b/openair3/NGAP/ngap_gNB.c @@ -156,9 +156,14 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t * DevCheck(new_instance->tac == ngap_register_gNB->tac, new_instance->tac, ngap_register_gNB->tac, 0); for (int i = 0; i < new_instance->num_plmn; i++) { - DevCheck(new_instance->mcc[i] == ngap_register_gNB->mcc[i], new_instance->mcc[i], ngap_register_gNB->mcc[i], 0); - DevCheck(new_instance->mnc[i] == ngap_register_gNB->mnc[i], new_instance->mnc[i], ngap_register_gNB->mnc[i], 0); - DevCheck(new_instance->mnc_digit_length[i] == ngap_register_gNB->mnc_digit_length[i], new_instance->mnc_digit_length[i], ngap_register_gNB->mnc_digit_length[i], 0); + ngap_plmn_t *exist_plmn = &new_instance->plmn[i]; + ngap_plmn_t *new_plmn = &ngap_register_gNB->plmn[i]; + DevCheck(exist_plmn->mcc == new_plmn->mcc, exist_plmn->mcc, new_plmn->mcc, 0); + DevCheck(exist_plmn->mnc == new_plmn->mnc, exist_plmn->mnc, new_plmn->mnc, 0); + DevCheck(exist_plmn->mnc_digit_length == new_plmn->mnc_digit_length, + exist_plmn->mnc_digit_length, + new_plmn->mnc_digit_length, + 0); } DevCheck(new_instance->default_drx == ngap_register_gNB->default_drx, new_instance->default_drx, ngap_register_gNB->default_drx, 0); @@ -178,18 +183,17 @@ void ngap_gNB_handle_register_gNB(instance_t instance, ngap_register_gnb_req_t * sizeof(ngap_register_gNB->gnb_ip_address)); for (int i = 0; i < ngap_register_gNB->num_plmn; i++) { - new_instance->mcc[i] = ngap_register_gNB->mcc[i]; - new_instance->mnc[i] = ngap_register_gNB->mnc[i]; - new_instance->mnc_digit_length[i] = ngap_register_gNB->mnc_digit_length[i]; - - new_instance->num_nssai[i] = ngap_register_gNB->num_nssai[i]; + new_instance->plmn[i].mcc = ngap_register_gNB->plmn[i].mcc; + new_instance->plmn[i].mnc = ngap_register_gNB->plmn[i].mnc; + new_instance->plmn[i].mnc_digit_length = ngap_register_gNB->plmn[i].mnc_digit_length; + + new_instance->plmn[i].num_nssai = ngap_register_gNB->plmn[i].num_nssai; + memcpy(&new_instance->plmn[i].s_nssai, &ngap_register_gNB->plmn[i].s_nssai, sizeof(ngap_register_gNB->plmn[i].s_nssai)); } new_instance->num_plmn = ngap_register_gNB->num_plmn; new_instance->default_drx = ngap_register_gNB->default_drx; - memcpy(new_instance->s_nssai, ngap_register_gNB->s_nssai, sizeof(ngap_register_gNB->s_nssai)); - /* Add the new instance to the list of gNB (meaningfull in virtual mode) */ ngap_gNB_insert_new_instance(new_instance); NGAP_INFO("Registered new gNB[%ld] and %s gNB id %u\n", @@ -410,9 +414,9 @@ static int ngap_gNB_generate_ng_setup_request( ie->value.present = NGAP_NGSetupRequestIEs__value_PR_GlobalRANNodeID; ie->value.choice.GlobalRANNodeID.present = NGAP_GlobalRANNodeID_PR_globalGNB_ID; ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID = CALLOC(1, sizeof(struct NGAP_GlobalGNB_ID)); - MCC_MNC_TO_PLMNID(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[0]], - instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[0]], - instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[0]], + MCC_MNC_TO_PLMNID(instance_p->plmn[ngap_amf_data_p->broadcast_plmn_index[0]].mcc, + instance_p->plmn[ngap_amf_data_p->broadcast_plmn_index[0]].mnc, + instance_p->plmn[ngap_amf_data_p->broadcast_plmn_index[0]].mnc_digit_length, &(ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->pLMNIdentity)); ie->value.choice.GlobalRANNodeID.choice.globalGNB_ID->gNB_ID.present = NGAP_GNB_ID_PR_gNB_ID; MACRO_GNB_ID_TO_BIT_STRING(instance_p->gNB_id, @@ -446,28 +450,26 @@ static int ngap_gNB_generate_ng_setup_request( { for (int i = 0; i < ngap_amf_data_p->broadcast_plmn_num; ++i) { plmn = (NGAP_BroadcastPLMNItem_t *)calloc(1, sizeof(NGAP_BroadcastPLMNItem_t)); - MCC_MNC_TO_TBCD(instance_p->mcc[ngap_amf_data_p->broadcast_plmn_index[i]], - instance_p->mnc[ngap_amf_data_p->broadcast_plmn_index[i]], - instance_p->mnc_digit_length[ngap_amf_data_p->broadcast_plmn_index[i]], - &plmn->pLMNIdentity); + ngap_plmn_t *plmn_req = &instance_p->plmn[ngap_amf_data_p->broadcast_plmn_index[i]]; + MCC_MNC_TO_TBCD(plmn_req->mcc, plmn_req->mnc, plmn_req->mnc_digit_length, &plmn->pLMNIdentity); - for(int si = 0; si < instance_p->num_nssai[i]; si++) { + for (int si = 0; si < plmn_req->num_nssai; si++) { ssi = (NGAP_SliceSupportItem_t *)calloc(1, sizeof(NGAP_SliceSupportItem_t)); - INT8_TO_OCTET_STRING(instance_p->s_nssai[i][si].sST, &ssi->s_NSSAI.sST); + INT8_TO_OCTET_STRING(plmn_req->s_nssai[si].sst, &ssi->s_NSSAI.sST); - if (instance_p->s_nssai[i][si].sD_flag) { + const uint32_t sd = plmn_req->s_nssai[si].sd; + if (sd != 0xffffff) { ssi->s_NSSAI.sD = calloc(1, sizeof(NGAP_SD_t)); ssi->s_NSSAI.sD->buf = calloc(3, sizeof(uint8_t)); ssi->s_NSSAI.sD->size = 3; - ssi->s_NSSAI.sD->buf[0] = instance_p->s_nssai[i][si].sD[0]; - ssi->s_NSSAI.sD->buf[1] = instance_p->s_nssai[i][si].sD[1]; - ssi->s_NSSAI.sD->buf[2] = instance_p->s_nssai[i][si].sD[2]; + ssi->s_NSSAI.sD->buf[0] = (sd & 0xff0000) >> 16; + ssi->s_NSSAI.sD->buf[1] = (sd & 0x00ff00) >> 8; + ssi->s_NSSAI.sD->buf[2] = (sd & 0x0000ff); } - asn1cSeqAdd(&plmn->tAISliceSupportList.list, ssi); } - + asn1cSeqAdd(&ta->broadcastPLMNList.list, plmn); } } diff --git a/openair3/NGAP/ngap_gNB_defs.h b/openair3/NGAP/ngap_gNB_defs.h index c93d448723..1a1e5768ff 100644 --- a/openair3/NGAP/ngap_gNB_defs.h +++ b/openair3/NGAP/ngap_gNB_defs.h @@ -31,6 +31,7 @@ #include "queue.h" #include "tree.h" +#include "openair2/COMMON/ngap_messages_types.h" #ifndef NGAP_GNB_DEFS_H_ #define NGAP_GNB_DEFS_H_ @@ -215,12 +216,6 @@ typedef struct ngap_gNB_amf_data_s { struct ngap_gNB_instance_s *ngap_gNB_instance; } ngap_gNB_amf_data_t; -typedef struct ngap_gNB_NSSAI_s{ - uint8_t sST; - uint8_t sD_flag; - uint8_t sD[3]; -}ngap_gNB_NSSAI_t; - typedef struct ngap_gNB_instance_s { /* Next ngap gNB association. * Only used for virtual mode. @@ -259,14 +254,9 @@ typedef struct ngap_gNB_instance_s { /* Mobile Country Code * Mobile Network Code */ - uint16_t mcc[PLMN_LIST_MAX_SIZE]; - uint16_t mnc[PLMN_LIST_MAX_SIZE]; - uint8_t mnc_digit_length[PLMN_LIST_MAX_SIZE]; - uint8_t num_plmn; + uint8_t num_plmn; + ngap_plmn_t plmn[PLMN_LIST_MAX_SIZE]; - uint16_t num_nssai[PLMN_LIST_MAX_SIZE]; - ngap_gNB_NSSAI_t s_nssai[PLMN_LIST_MAX_SIZE][8]; - /* Default Paging DRX of the gNB as defined in TS 38.304 */ ngap_paging_drx_t default_drx; } ngap_gNB_instance_t; diff --git a/openair3/NGAP/ngap_gNB_handlers.c b/openair3/NGAP/ngap_gNB_handlers.c index 1835b51cb6..0fb9fd0dbc 100644 --- a/openair3/NGAP/ngap_gNB_handlers.c +++ b/openair3/NGAP/ngap_gNB_handlers.c @@ -780,12 +780,13 @@ static int ngap_gNB_handle_initial_context_request(sctp_assoc_t assoc_id, uint32 for(i = 0; i < ie->value.choice.AllowedNSSAI.list.count; i++) { allow_nssai_item_p = ie->value.choice.AllowedNSSAI.list.array[i]; - - OCTET_STRING_TO_INT8(&allow_nssai_item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST); + + OCTET_STRING_TO_INT8(&allow_nssai_item_p->s_NSSAI.sST, msg->allowed_nssai[i].sst); if(allow_nssai_item_p->s_NSSAI.sD != NULL) { - msg->allowed_nssai[i].sD_flag = 1; - memcpy(msg->allowed_nssai[i].sD, allow_nssai_item_p->s_NSSAI.sD, sizeof(msg->allowed_nssai[i].sD)); + memcpy(&msg->allowed_nssai[i].sd, allow_nssai_item_p->s_NSSAI.sD, 3); + } else { + msg->allowed_nssai[i].sd = 0xffffff; } } @@ -961,12 +962,14 @@ static int ngap_gNB_handle_pdusession_setup_request(sctp_assoc_t assoc_id, uint3 msg->pdusession_setup_params[i].pdusession_id = item_p->pDUSessionID; // S-NSSAI - OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->allowed_nssai[i].sST); + OCTET_STRING_TO_INT8(&item_p->s_NSSAI.sST, msg->pdusession_setup_params[i].nssai.sst); if (item_p->s_NSSAI.sD != NULL) { - msg->allowed_nssai[i].sD_flag = 1; - msg->allowed_nssai[i].sD[0] = item_p->s_NSSAI.sD->buf[0]; - msg->allowed_nssai[i].sD[1] = item_p->s_NSSAI.sD->buf[1]; - msg->allowed_nssai[i].sD[2] = item_p->s_NSSAI.sD->buf[2]; + uint8_t *sd_p = (uint8_t *)&msg->pdusession_setup_params[i].nssai.sd; + sd_p[0] = item_p->s_NSSAI.sD->buf[0]; + sd_p[1] = item_p->s_NSSAI.sD->buf[1]; + sd_p[2] = item_p->s_NSSAI.sD->buf[2]; + } else { + msg->pdusession_setup_params[i].nssai.sd = 0xffffff; } allocCopy(&msg->pdusession_setup_params[i].nas_pdu, *item_p->pDUSessionNAS_PDU); diff --git a/openair3/NGAP/ngap_gNB_nas_procedures.c b/openair3/NGAP/ngap_gNB_nas_procedures.c index 690e603042..6d67920bcb 100644 --- a/openair3/NGAP/ngap_gNB_nas_procedures.c +++ b/openair3/NGAP/ngap_gNB_nas_procedures.c @@ -114,14 +114,15 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf amf_desc_p = ngap_gNB_nnsf_select_amf_by_amf_setid(instance_p, UEfirstReq->establishment_cause, UEfirstReq->selected_plmn_identity, UEfirstReq->ue_identity.s_tmsi.amf_set_id); if (amf_desc_p) { - NGAP_INFO("[gNB %ld] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", - instance, - amf_desc_p->amf_name, - amf_desc_p->assoc_id, - UEfirstReq->ue_identity.s_tmsi.amf_set_id, - UEfirstReq->selected_plmn_identity, - instance_p->mcc[UEfirstReq->selected_plmn_identity], - instance_p->mnc[UEfirstReq->selected_plmn_identity]); + NGAP_INFO( + "[gNB %ld] Chose AMF '%s' (assoc_id %d) through S-TMSI AMFSI %d and selected PLMN Identity index %d MCC %d MNC %d\n", + instance, + amf_desc_p->amf_name, + amf_desc_p->assoc_id, + UEfirstReq->ue_identity.s_tmsi.amf_set_id, + UEfirstReq->selected_plmn_identity, + instance_p->plmn[UEfirstReq->selected_plmn_identity].mcc, + instance_p->plmn[UEfirstReq->selected_plmn_identity].mnc); } } } @@ -138,8 +139,8 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf amf_desc_p->amf_name, amf_desc_p->assoc_id, UEfirstReq->selected_plmn_identity, - instance_p->mcc[UEfirstReq->selected_plmn_identity], - instance_p->mnc[UEfirstReq->selected_plmn_identity]); + instance_p->plmn[UEfirstReq->selected_plmn_identity].mcc, + instance_p->plmn[UEfirstReq->selected_plmn_identity].mnc); } } @@ -212,16 +213,16 @@ int ngap_gNB_handle_nas_first_req(instance_t instance, ngap_nas_first_req_t *UEf MACRO_GNB_ID_TO_CELL_IDENTITY(instance_p->gNB_id, 0, // Cell ID &userinfo_nr_p->nR_CGI.nRCellIdentity); - MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + MCC_MNC_TO_TBCD(instance_p->plmn[ue_desc_p->selected_plmn_identity].mcc, + instance_p->plmn[ue_desc_p->selected_plmn_identity].mnc, + instance_p->plmn[ue_desc_p->selected_plmn_identity].mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity); /* Set TAI */ INT24_TO_OCTET_STRING(instance_p->tac, &userinfo_nr_p->tAI.tAC); - MCC_MNC_TO_PLMNID(instance_p->mcc[ue_desc_p->selected_plmn_identity], - instance_p->mnc[ue_desc_p->selected_plmn_identity], - instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], + MCC_MNC_TO_PLMNID(instance_p->plmn[ue_desc_p->selected_plmn_identity].mcc, + instance_p->plmn[ue_desc_p->selected_plmn_identity].mnc, + instance_p->plmn[ue_desc_p->selected_plmn_identity].mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity); } @@ -444,16 +445,16 @@ int ngap_gNB_nas_uplink(instance_t instance, ngap_uplink_nas_t *ngap_uplink_nas_ MACRO_GNB_ID_TO_CELL_IDENTITY(ngap_gNB_instance_p->gNB_id, 0, // Cell ID &userinfo_nr_p->nR_CGI.nRCellIdentity); - MCC_MNC_TO_TBCD(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + MCC_MNC_TO_TBCD(ngap_gNB_instance_p->plmn[ue_context_p->selected_plmn_identity].mcc, + ngap_gNB_instance_p->plmn[ue_context_p->selected_plmn_identity].mnc, + ngap_gNB_instance_p->plmn[ue_context_p->selected_plmn_identity].mnc_digit_length, &userinfo_nr_p->nR_CGI.pLMNIdentity); /* Set TAI */ INT24_TO_OCTET_STRING(ngap_gNB_instance_p->tac, &userinfo_nr_p->tAI.tAC); - MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->mcc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc[ue_context_p->selected_plmn_identity], - ngap_gNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], + MCC_MNC_TO_PLMNID(ngap_gNB_instance_p->plmn[ue_context_p->selected_plmn_identity].mcc, + ngap_gNB_instance_p->plmn[ue_context_p->selected_plmn_identity].mnc, + ngap_gNB_instance_p->plmn[ue_context_p->selected_plmn_identity].mnc_digit_length, &userinfo_nr_p->tAI.pLMNIdentity); } if (ngap_gNB_encode_pdu(&pdu, &buffer, &length) < 0) { diff --git a/openair3/NGAP/ngap_gNB_nnsf.c b/openair3/NGAP/ngap_gNB_nnsf.c index e9ec66b1b4..0d002e9836 100644 --- a/openair3/NGAP/ngap_gNB_nnsf.c +++ b/openair3/NGAP/ngap_gNB_nnsf.c @@ -139,8 +139,8 @@ ngap_gNB_nnsf_select_amf_by_plmn_id(ngap_gNB_instance_t *instance_p, /* Looking for served GUAMI PLMN Identity selected matching the one provided by the UE */ STAILQ_FOREACH(guami_p, &amf_data_p->served_guami, next) { STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { - if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && - (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + if ((served_plmn_p->mcc == instance_p->plmn[selected_plmn_identity].mcc) + && (served_plmn_p->mnc == instance_p->plmn[selected_plmn_identity].mnc)) { break; } } @@ -211,8 +211,8 @@ ngap_gNB_nnsf_select_amf_by_amf_setid(ngap_gNB_instance_t *instance_p, struct plmn_identity_s *served_plmn_p = NULL; STAILQ_FOREACH(served_plmn_p, &guami_p->served_plmns, next) { - if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && - (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { + if ((served_plmn_p->mcc == instance_p->plmn[selected_plmn_identity].mcc) + && (served_plmn_p->mnc == instance_p->plmn[selected_plmn_identity].mnc)) { break; } }