Add NNSF by selected PLMN Identity
This commit is contained in:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user