Commit df17a8dd authored by wujing's avatar wujing Committed by masayuki.harada

merge NNSF feature based on v1.0.2

(cherry picked from commit b9e93a16379cf261502d9451b60bd787c07da64e)
parent 63a5c693
...@@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ( ...@@ -782,21 +782,37 @@ rrc_eNB_send_S1AP_NAS_FIRST_REQ(
S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei; S1AP_NAS_FIRST_REQ (message_p).ue_identity.presenceMask |= UE_IDENTITIES_gummei;
if (r_mme->plmn_Identity != NULL) { if (r_mme->plmn_Identity != NULL) {
if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count > 0)) { if ((r_mme->plmn_Identity->mcc != NULL) && (r_mme->plmn_Identity->mcc->list.count == 3))
/* 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]; 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", LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MCC %u ue %x\n",
ctxt_pP->module_id, ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc, S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mcc,
ue_context_pP->ue_context.rnti); ue_context_pP->ue_context.rnti);
} }
if(r_mme->plmn_Identity->mnc.list.count == 3)
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[0] & 0xf) * 100 +
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc = *r_mme->plmn_Identity->mnc.list.array[selected_plmn_identity]; (*r_mme->plmn_Identity->mnc.list.array[1] & 0xf) * 10 +
LOG_I(S1AP, "[eNB %d] Build S1AP_NAS_FIRST_REQ adding in s_TMSI: GUMMEI MNC %u ue %x\n", (*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, ctxt_pP->module_id,
S1AP_NAS_FIRST_REQ (message_p).ue_identity.gummei.mnc, 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); ue_context_pP->ue_context.rnti);
} }
} else { // end if plmn_Identity != NULL } else { // end if plmn_Identity != NULL
......
...@@ -164,6 +164,8 @@ typedef struct s1ap_eNB_mme_data_s { ...@@ -164,6 +164,8 @@ typedef struct s1ap_eNB_mme_data_s {
/* Only meaningfull in virtual mode */ /* Only meaningfull in virtual mode */
struct s1ap_eNB_instance_s *s1ap_eNB_instance; struct s1ap_eNB_instance_s *s1ap_eNB_instance;
uint32_t nb_calls;
} s1ap_eNB_mme_data_t; } s1ap_eNB_mme_data_t;
typedef struct s1ap_eNB_instance_s { typedef struct s1ap_eNB_instance_s {
......
...@@ -138,8 +138,9 @@ int s1ap_eNB_handle_nas_first_req( ...@@ -138,8 +138,9 @@ int s1ap_eNB_handle_nas_first_req(
* identity, selects the MME with the highest capacity. * identity, selects the MME with the highest capacity.
*/ */
mme_desc_p = s1ap_eNB_nnsf_select_mme( mme_desc_p = s1ap_eNB_nnsf_select_mme(
instance_p, instance_p,
s1ap_nas_first_req_p->establishment_cause); s1ap_nas_first_req_p->establishment_cause,
s1ap_nas_first_req_p->selected_plmn_identity);
if (mme_desc_p) { if (mme_desc_p) {
S1AP_INFO("[eNB %d] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", 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( ...@@ -232,9 +233,9 @@ int s1ap_eNB_handle_nas_first_req(
MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id, MACRO_ENB_ID_TO_CELL_IDENTITY(instance_p->eNB_id,
0, // Cell ID 0, // Cell ID
&ie->value.choice.EUTRAN_CGI.cell_ID); &ie->value.choice.EUTRAN_CGI.cell_ID);
MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity], MCC_MNC_TO_TBCD(instance_p->mcc[mme_desc_p->broadcast_plmn_index[0]],
instance_p->mnc[ue_desc_p->selected_plmn_identity], instance_p->mnc[mme_desc_p->broadcast_plmn_index[0]],
instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity], instance_p->mnc_digit_length[mme_desc_p->broadcast_plmn_index[0]],
&ie->value.choice.EUTRAN_CGI.pLMNidentity); &ie->value.choice.EUTRAN_CGI.pLMNidentity);
ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie);
/* Set the establishment cause according to those provided by RRC */ /* 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_ ...@@ -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->criticality = S1AP_Criticality_ignore;
ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI; ie->value.present = S1AP_UplinkNASTransport_IEs__value_PR_EUTRAN_CGI;
MCC_MNC_TO_PLMNID( MCC_MNC_TO_PLMNID(
s1ap_eNB_instance_p->mcc[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->selected_plmn_identity], s1ap_eNB_instance_p->mnc[ue_context_p->mme_ref->broadcast_plmn_index[0]],
s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->selected_plmn_identity], s1ap_eNB_instance_p->mnc_digit_length[ue_context_p->mme_ref->broadcast_plmn_index[0]],
&ie->value.choice.EUTRAN_CGI.pLMNidentity); &ie->value.choice.EUTRAN_CGI.pLMNidentity);
//#warning "TODO get cell id from RRC" //#warning "TODO get cell id from RRC"
MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id, MACRO_ENB_ID_TO_CELL_IDENTITY(s1ap_eNB_instance_p->eNB_id,
......
...@@ -38,13 +38,27 @@ ...@@ -38,13 +38,27 @@
struct s1ap_eNB_mme_data_s * struct s1ap_eNB_mme_data_s *
s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, 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_data_p = NULL;
struct s1ap_eNB_mme_data_s *mme_highest_capacity_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) { 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) { if (mme_data_p->state != S1AP_ENB_STATE_CONNECTED) {
/* The association between MME and eNB is not ready for the moment, /* The association between MME and eNB is not ready for the moment,
* go to the next known MME. * go to the next known MME.
...@@ -79,11 +93,55 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, ...@@ -79,11 +93,55 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
} }
} }
if (current_capacity < mme_data_p->relative_mme_capacity) { gummei_p = mme_data_p->served_gummei.stqh_first;
/* We find a better MME, keep a reference to it */ if( gummei_p != NULL )
current_capacity = mme_data_p->relative_mme_capacity; {
mme_highest_capacity_p = mme_data_p; 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; return mme_highest_capacity_p;
......
...@@ -24,7 +24,8 @@ ...@@ -24,7 +24,8 @@
struct s1ap_eNB_mme_data_s * struct s1ap_eNB_mme_data_s *
s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, 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 * struct s1ap_eNB_mme_data_s *
s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
......
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