Commit 02d09453 authored by Robert Schmidt's avatar Robert Schmidt

Add NNSF by selected PLMN Identity

parent 067f6e7a
......@@ -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,
......
......@@ -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,
......
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment