merge NNSF feature based on v1.0.2
(cherry picked from commit b9e93a16379cf261502d9451b60bd787c07da64e)
This commit is contained in:
@@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei;
|
||||
|
||||
if (r_mme->plmn_Identity != NULL) {
|
||||
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) {
|
||||
/* Use first indicated PLMN MCC if it is defined */
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = *r_mme->plmn_Identity->mcc->list.array[selected_plmn_identity];
|
||||
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3))
|
||||
{
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc = (*r_mme->plmn_Identity->mcc->list.array[0] & 0xf) * 100 +
|
||||
(*r_mme->plmn_Identity->mcc->list.array[1] & 0xf) * 10 +
|
||||
(*r_mme->plmn_Identity->mcc->list.array[2] & 0xf);
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
|
||||
if (r_mme->plmn_Identity->mnc.list.count > 0) {
|
||||
/* Use first indicated PLMN MNC if it is defined */
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity];
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n",
|
||||
if(r_mme->plmn_Identity->mnc.list.count == 3)
|
||||
{
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 100 +
|
||||
(*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 +
|
||||
(*r_mme->plmn_Identity->mnc.list.array[2] & 0xf);
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 3;
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
else if(r_mme->plmn_Identity->mnc.list.count == 2)
|
||||
{
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = (*r_mme->plmn_Identity->mnc.list.array[0] & 0xf) * 10 +
|
||||
(*r_mme->plmn_Identity->mnc.list.array[1] & 0xf);
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len = 2;
|
||||
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u %udigit ue %x\n",
|
||||
ctxt_pP->module_id,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc,
|
||||
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc_len,
|
||||
ue_context_pP->ue_context.rnti);
|
||||
}
|
||||
} else { // end if plmn_Identity != NULL
|
||||
|
||||
@@ -164,6 +164,8 @@ typedef struct s1ap_eNB_mme_data_s {
|
||||
|
||||
/* Only meaningfull in virtual mode */
|
||||
struct s1ap_eNB_instance_s *s1ap_eNB_instance;
|
||||
|
||||
uint32_t nb_calls;
|
||||
} s1ap_eNB_mme_data_t;
|
||||
|
||||
typedef struct s1ap_eNB_instance_s {
|
||||
|
||||
@@ -138,8 +138,9 @@ int s1ap_eNB_handle_nas_first_req(
|
||||
* identity, selects the MME with the highest capacity.
|
||||
*/
|
||||
mme_desc_p = s1ap_eNB_nnsf_select_mme(
|
||||
instance_p,
|
||||
s1ap_nas_first_req_p->establishment_cause);
|
||||
instance_p,
|
||||
s1ap_nas_first_req_p->establishment_cause,
|
||||
s1ap_nas_first_req_p->selected_plmn_identity);
|
||||
|
||||
if (mme_desc_p) {
|
||||
S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n",
|
||||
@@ -232,9 +233,9 @@ int s1ap_eNB_handle_nas_first_req(
|
||||
MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,
|
||||
0, // Cell ID
|
||||
&ie->value.choice.EUTRAN_CGI.cell_ID);
|
||||
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->mcc[mme_desc_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc[mme_desc_p->broadcast_plmn_index[0]],
|
||||
instance_p->mnc_digit_length[mme_desc_p->broadcast_plmn_index[0]],
|
||||
&ie->value.choice.EUTRAN_CGI.pLMNidentity);
|
||||
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
|
||||
/* Set the establishment cause according to those provided by RRC */
|
||||
@@ -494,9 +495,9 @@ int s1ap_eNB_nas_uplink(instance_t instance, s1ap_uplink_nas_t *s1ap_uplink_nas_
|
||||
ie->criticality = S1AP_Criticality_ignore;
|
||||
ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI;
|
||||
MCC_MNC_TO_PLMNID(
|
||||
s1ap_eNB_instance_p->mcc[ue_context_p->selected_plmn_identity],
|
||||
s1ap_eNB_instance_p->mnc[ue_context_p->selected_plmn_identity],
|
||||
s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity],
|
||||
s1ap_eNB_instance_p->mcc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
|
||||
s1ap_eNB_instance_p->mnc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
|
||||
s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->mme_ref->broadcast_plmn_index[0]],
|
||||
&ie->value.choice.EUTRAN_CGI.pLMNidentity);
|
||||
//#warning "TODO get cell id from RRC"
|
||||
MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id,
|
||||
|
||||
@@ -38,13 +38,27 @@
|
||||
|
||||
struct s1ap_eNB_mme_data_s *
|
||||
s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause)
|
||||
rrc_establishment_cause_t cause,
|
||||
uint32_t plmn_id)
|
||||
{
|
||||
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;
|
||||
typedef struct MME_nnsf_inf {
|
||||
struct s1ap_eNB_mme_data_s *mme_p;
|
||||
uint64_t weight;
|
||||
} MME_nnsf_inf_t;
|
||||
|
||||
uint16_t capacity_sum = 0;
|
||||
MME_nnsf_inf_t mme_inf[10];
|
||||
int cnt;
|
||||
int nb_mme = 0;
|
||||
uint64_t weight = 0;
|
||||
|
||||
memset(mme_inf, 0, sizeof(mme_inf));
|
||||
|
||||
RB_FOREACH(mme_data_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
|
||||
struct served_gummei_s *gummei_p = NULL;
|
||||
capacity_sum = capacity_sum + mme_data_p->relative_mme_capacity;
|
||||
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.
|
||||
@@ -79,12 +93,56 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
gummei_p = mme_data_p->served_gummei.stqh_first;
|
||||
if( gummei_p != NULL )
|
||||
{
|
||||
struct plmn_identity_s *served_plmns_p = NULL;
|
||||
|
||||
served_plmns_p = gummei_p->served_plmns.stqh_first;
|
||||
if( served_plmns_p != 0 )
|
||||
for( cnt = 0 ; cnt < 8 ; cnt++)
|
||||
{
|
||||
if ( (served_plmns_p->mcc == instance_p->mcc[plmn_id]) &&
|
||||
(served_plmns_p->mnc == instance_p->mnc[plmn_id]) )
|
||||
{
|
||||
mme_inf[nb_mme].mme_p = mme_data_p;
|
||||
nb_mme++;
|
||||
break;
|
||||
}
|
||||
if( served_plmns_p->next.stqe_next == 0 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
served_plmns_p = served_plmns_p->next.stqe_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if( nb_mme != 0 )
|
||||
{
|
||||
for( cnt = 0 ; cnt < nb_mme ; cnt++ )
|
||||
{
|
||||
mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity;
|
||||
mme_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1);
|
||||
}
|
||||
mme_highest_capacity_p = mme_inf[0].mme_p;
|
||||
weight = mme_inf[0].weight;
|
||||
for( cnt = 1 ; cnt < nb_mme ; cnt++ )
|
||||
{
|
||||
if( weight > mme_inf[cnt].weight )
|
||||
{
|
||||
mme_highest_capacity_p = mme_inf[cnt].mme_p;
|
||||
weight = mme_inf[cnt].weight;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mme_highest_capacity_p = NULL;
|
||||
}
|
||||
if( mme_highest_capacity_p != NULL )
|
||||
{
|
||||
mme_highest_capacity_p->nb_calls++;
|
||||
}
|
||||
|
||||
return mme_highest_capacity_p;
|
||||
}
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
struct s1ap_eNB_mme_data_s *
|
||||
s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
|
||||
rrc_establishment_cause_t cause);
|
||||
rrc_establishment_cause_t cause,
|
||||
uint32_t plmn_id);
|
||||
|
||||
struct s1ap_eNB_mme_data_s *
|
||||
s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
|
||||
|
||||
Reference in New Issue
Block a user