From 02d09453061f5dea6d94712708bdc35f73c565c0 Mon Sep 17 00:00:00 2001 From: Robert Schmidt <robert.schmidt@eurecom.fr> Date: Wed, 4 Jul 2018 16:45:32 +0200 Subject: [PATCH] Add NNSF by selected PLMN Identity --- openair3/S1AP/s1ap_eNB_nas_procedures.c | 13 ++++- openair3/S1AP/s1ap_eNB_nnsf.c | 70 +++++++++++++++++++++++++ openair3/S1AP/s1ap_eNB_nnsf.h | 5 ++ 3 files changed, 86 insertions(+), 2 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 91d3da4745..750bcd02fc 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -94,10 +94,19 @@ int s1ap_eNB_handle_nas_first_req( } } + if (mme_desc_p == NULL) { + /* Select MME based on the selected PLMN identity, received through RRC + * Connection Setup Complete */ + mme_desc_p = s1ap_eNB_nnsf_select_mme_by_plmn_id( + instance_p, + s1ap_nas_first_req_p->establishment_cause, + s1ap_nas_first_req_p->selected_plmn_identity); + } + if (mme_desc_p == NULL) { /* - * If no MME corresponds to the GUMMEI or the s-TMSI, selects the MME with the - * highest capacity. + * If no MME corresponds to the GUMMEI, the s-TMSI, or the selected PLMN + * identity, selects the MME with the highest capacity. */ mme_desc_p = s1ap_eNB_nnsf_select_mme( instance_p, diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 0d5519149c..63dc92b5e2 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -89,6 +89,76 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, return mme_highest_capacity_p; } +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity) +{ + struct s1ap_eNB_mme_data_s *mme_data_p = NULL; + struct s1ap_eNB_mme_data_s *mme_highest_capacity_p = NULL; + uint8_t current_capacity = 0; + + RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + struct served_gummei_s *gummei_p = NULL; + struct plmn_identity_s *served_plmn_p = NULL; + if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) { + /* The association between MME and eNB is not ready for the moment, + * go to the next known MME. + */ + if (mme_data_p->state == S1AP_ENB_OVERLOAD) { + /* MME is overloaded. We have to check the RRC establishment + * cause and take decision to the select this MME depending on + * the overload state. + */ + if ((cause == RRC_CAUSE_MO_DATA) + && (mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_MO_DATA)) { + continue; + } + + if ((mme_data_p->overload_state == S1AP_OVERLOAD_REJECT_ALL_SIGNALLING) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA))) { + continue; + } + + if ((mme_data_p->overload_state == S1AP_OVERLOAD_ONLY_EMERGENCY_AND_MT) + && ((cause == RRC_CAUSE_MO_SIGNALLING) || (cause == RRC_CAUSE_MO_DATA) + || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { + continue; + } + + /* At this point, the RRC establishment can be handled by the MME + * even if it is in overload state. + */ + } else { + /* The MME is not overloaded, association is simply not ready. */ + continue; + } + } + + /* Looking for served GUMMEI PLMN Identity selected matching the one provided by the UE */ + STAILQ_FOREACH(gummei_p, &mme_data_p->served_gummei, next) { + STAILQ_FOREACH(served_plmn_p, &gummei_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])) { + break; + } + } + /* if found, we can stop the outer loop, too */ + if (served_plmn_p) break; + } + /* if we didn't find such a served PLMN, go on with the next MME */ + if (!served_plmn_p) continue; + + if (current_capacity < mme_data_p->relative_mme_capacity) { + /* We find a better MME, keep a reference to it */ + current_capacity = mme_data_p->relative_mme_capacity; + mme_highest_capacity_p = mme_data_p; + } + } + + return mme_highest_capacity_p; +} + struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index 5a3d44416f..706f3ada6f 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -26,6 +26,11 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause); +struct s1ap_eNB_mme_data_s * +s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, + rrc_establishment_cause_t cause, + int selected_plmn_identity); + struct s1ap_eNB_mme_data_s* s1ap_eNB_nnsf_select_mme_by_mme_code(s1ap_eNB_instance_t *instance_p, rrc_establishment_cause_t cause, -- GitLab