Commit 969425f6 authored by masayuki.harada's avatar masayuki.harada

Replace to itti timer.

Fix nnsf selection.
Fix indentation and opening brace.
parent ff994453
This diff is collapsed.
...@@ -290,8 +290,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, ...@@ -290,8 +290,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_Cause,true); S1AP_ProtocolIE_ID_id_Cause,true);
if(ie == NULL) if(ie == NULL) {
{
return -1; return -1;
} }
...@@ -302,19 +301,16 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, ...@@ -302,19 +301,16 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n"); S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
} }
if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) if( mme_desc_p->timer_id != S1AP_TIMERID_INIT ) {
{
s1ap_timer_remove( mme_desc_p->timer_id ); s1ap_timer_remove( mme_desc_p->timer_id );
mme_desc_p->timer_id = S1AP_TIMERID_INIT; mme_desc_p->timer_id = S1AP_TIMERID_INIT;
} }
instance_p = mme_desc_p->s1ap_eNB_instance; instance_p = mme_desc_p->s1ap_eNB_instance;
if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || if( ( instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) ||
( instance_p->s1_setupreq_count == 0xffff) ) ( instance_p->s1_setupreq_count == 0xffff) ) {
{
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupFailureIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_TimeToWait, false); S1AP_ProtocolIE_ID_id_TimeToWait, false);
if( ie != NULL ) if( ie != NULL ) {
{
switch(ie->value.choice.TimeToWait) switch(ie->value.choice.TimeToWait)
{ {
case S1AP_TimeToWait_v1s: case S1AP_TimeToWait_v1s:
...@@ -339,9 +335,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, ...@@ -339,9 +335,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
interval_sec = instance_p->s1_setupreq_wait_timer; interval_sec = instance_p->s1_setupreq_wait_timer;
break; break;
} }
} } else {
else
{
interval_sec = instance_p->s1_setupreq_wait_timer; interval_sec = instance_p->s1_setupreq_wait_timer;
} }
...@@ -350,16 +344,12 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, ...@@ -350,16 +344,12 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id,
timer_kind = timer_kind | S1_SETREQ_WAIT; timer_kind = timer_kind | S1_SETREQ_WAIT;
if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT, if( s1ap_timer_setup(interval_sec, 0, TASK_S1AP, instance_p->instance, timer_kind, S1AP_TIMER_ONE_SHOT,
NULL, &mme_desc_p->timer_id) < 0 ) NULL, &mme_desc_p->timer_id) < 0 ) {
{
S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id); S1AP_ERROR("Timer Start NG(S1 Setup Request) : MME=%d\n",mme_desc_p->cnx_id);
s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p ); s1ap_eNB_snd_s1_setup_request( instance_p, mme_desc_p );
} }
} } else {
else S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id);
{
S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id);
} }
return 0; return 0;
} }
...@@ -391,16 +381,14 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, ...@@ -391,16 +381,14 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
/* Set the capacity of this MME */ /* Set the capacity of this MME */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
if(ie == NULL) if(ie == NULL) {
{
return -1; return -1;
} }
mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true); S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true);
if(ie == NULL) if(ie == NULL) {
{
return -1; return -1;
} }
...@@ -462,13 +450,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, ...@@ -462,13 +450,7 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next); STAILQ_INSERT_TAIL(&mme_desc_p->served_gummei, new_gummei_p, next);
} }
/* Set the capacity of this MME */
// S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
// S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true);
//
// mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity;
//
/* Optionaly set the mme name */ /* Optionaly set the mme name */
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container,
S1AP_ProtocolIE_ID_id_MMEname, false); S1AP_ProtocolIE_ID_id_MMEname, false);
...@@ -486,7 +468,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, ...@@ -486,7 +468,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id,
*/ */
mme_desc_p->state = S1AP_ENB_STATE_CONNECTED; mme_desc_p->state = S1AP_ENB_STATE_CONNECTED;
mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++; mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb ++;
// s1ap_handle_s1_setup_message(mme_desc_p, 0);
return 0; return 0;
} }
...@@ -819,8 +800,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, ...@@ -819,8 +800,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id,
S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false);
if (ie) { if (ie) {
if( ie->value.choice.CriticalityDiagnostics.procedureCode ) if( ie->value.choice.CriticalityDiagnostics.procedureCode ) {
{
S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode); S1AP_WARN("Received S1 Error indication CriticalityDiagnostics procedureCode = %ld\n", *ie->value.choice.CriticalityDiagnostics.procedureCode);
} }
// TODO continue // TODO continue
...@@ -1023,8 +1003,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, ...@@ -1023,8 +1003,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container, S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_UEContextReleaseCommand_IEs_t, ie, container,
S1AP_ProtocolIE_ID_id_Cause, true); S1AP_ProtocolIE_ID_id_Cause, true);
if( ie == NULL ) if( ie == NULL ) {
{
S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" ); S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" );
return -1; return -1;
} }
...@@ -1076,9 +1055,6 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, ...@@ -1076,9 +1055,6 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
//#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?" //#warning "TODO mapping mme_ue_s1ap_id enb_ue_s1ap_id?"
case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID: case S1AP_UE_S1AP_IDs_PR_mME_UE_S1AP_ID:
// mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.uE_S1AP_ID_pair.mME_UE_S1AP_ID;
// S1AP_ERROR("TO DO mapping mme_ue_s1ap_id enb_ue_s1ap_id");
// (void)mme_ue_s1ap_id; /* TODO: remove - it's to remove gcc warning about unused var */
mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID; mme_ue_s1ap_id = ie->value.choice.UE_S1AP_IDs.choice.mME_UE_S1AP_ID;
RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head) RB_FOREACH(ue_desc_p, s1ap_ue_map, &mme_desc_p->s1ap_eNB_instance->s1ap_ue_head)
...@@ -1087,7 +1063,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id, ...@@ -1087,7 +1063,7 @@ int s1ap_eNB_handle_ue_context_release_command(uint32_t assoc_id,
{ {
enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id; enb_ue_s1ap_id = ue_desc_p->eNB_ue_s1ap_id;
message_p = itti_alloc_new_message(TASK_S1AP, S1AP_UE_CONTEXT_RELEASE_COMMAND); message_p = itti_alloc_new_message(TASK_S1AP, 0, S1AP_UE_CONTEXT_RELEASE_COMMAND);
S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id; S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = enb_ue_s1ap_id;
itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p);
......
...@@ -102,8 +102,7 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( ...@@ -102,8 +102,7 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
temp.assoc_id = assoc_id; temp.assoc_id = assoc_id;
temp.cnx_id = cnx_id; temp.cnx_id = cnx_id;
if( cnx_id != 0 ) if( cnx_id != 0 ) {
{
if (instance_p == NULL) { if (instance_p == NULL) {
STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
s1ap_eNB_entries) { s1ap_eNB_entries) {
...@@ -116,29 +115,19 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( ...@@ -116,29 +115,19 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME(
} else { } else {
return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp);
} }
} } else {
else if (instance_p == NULL) {
{
if (instance_p == NULL)
{
STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head,
s1ap_eNB_entries) s1ap_eNB_entries) {
{ RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) if( mme_p->assoc_id == assoc_id ) {
{
if( mme_p->assoc_id == assoc_id )
{
return mme_p; return mme_p;
} }
} }
} }
} } else {
else RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) {
{ if( mme_p->assoc_id == assoc_id ) {
RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head)
{
if( mme_p->assoc_id == assoc_id )
{
return mme_p; return mme_p;
} }
} }
......
...@@ -139,8 +139,7 @@ int s1ap_eNB_handle_nas_first_req( ...@@ -139,8 +139,7 @@ int s1ap_eNB_handle_nas_first_req(
*/ */
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 %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n", S1AP_INFO("[eNB %ld] Chose MME '%s' (assoc_id %d) through highest relative capacity\n",
...@@ -233,9 +232,9 @@ int s1ap_eNB_handle_nas_first_req( ...@@ -233,9 +232,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[mme_desc_p->broadcast_plmn_index[0]], MCC_MNC_TO_TBCD(instance_p->mcc[ue_desc_p->selected_plmn_identity],
instance_p->mnc[mme_desc_p->broadcast_plmn_index[0]], instance_p->mnc[ue_desc_p->selected_plmn_identity],
instance_p->mnc_digit_length[mme_desc_p->broadcast_plmn_index[0]], instance_p->mnc_digit_length[ue_desc_p->selected_plmn_identity],
&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 */
......
...@@ -36,17 +36,18 @@ ...@@ -36,17 +36,18 @@
#include "s1ap_eNB_defs.h" #include "s1ap_eNB_defs.h"
#include "s1ap_eNB_nnsf.h" #include "s1ap_eNB_nnsf.h"
typedef struct MME_nnsf_inf {
struct s1ap_eNB_mme_data_s *mme_p;
uint64_t weight;
} MME_nnsf_inf_t;
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;
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; uint16_t capacity_sum = 0;
MME_nnsf_inf_t mme_inf[10]; MME_nnsf_inf_t mme_inf[10];
...@@ -55,9 +56,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, ...@@ -55,9 +56,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
uint64_t weight = 0; uint64_t weight = 0;
memset(mme_inf, 0, sizeof(mme_inf)); 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; 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,
...@@ -83,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, ...@@ -83,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
|| (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) {
continue; continue;
} }
mme_inf[nb_mme].mme_p = mme_data_p;
nb_mme++;
/* At this point, the RRC establishment can be handled by the MME /* At this point, the RRC establishment can be handled by the MME
* even if it is in overload state. * even if it is in overload state.
*/ */
...@@ -92,58 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, ...@@ -92,58 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
continue; continue;
} }
} }
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 )
{ if( nb_mme != 0 ) {
for( cnt = 0 ; cnt < nb_mme ; cnt++ ) 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 = (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_inf[cnt].weight = (mme_inf[cnt].weight)*(mme_inf[cnt].mme_p->nb_calls + 1);
} }
mme_highest_capacity_p = mme_inf[0].mme_p; mme_highest_capacity_p = mme_inf[0].mme_p;
weight = mme_inf[0].weight; weight = mme_inf[0].weight;
for( cnt = 1 ; cnt < nb_mme ; cnt++ ) for( cnt = 1 ; cnt < nb_mme ; cnt++ ) {
{ if( weight > mme_inf[cnt].weight ) {
if( weight > mme_inf[cnt].weight )
{
mme_highest_capacity_p = mme_inf[cnt].mme_p; mme_highest_capacity_p = mme_inf[cnt].mme_p;
weight = mme_inf[cnt].weight; weight = mme_inf[cnt].weight;
} }
} }
} } else {
else
{
mme_highest_capacity_p = NULL; mme_highest_capacity_p = NULL;
} }
if( mme_highest_capacity_p != NULL ) if( mme_highest_capacity_p != NULL ) {
{
mme_highest_capacity_p->nb_calls++; mme_highest_capacity_p->nb_calls++;
} }
return mme_highest_capacity_p; return mme_highest_capacity_p;
} }
...@@ -154,8 +124,15 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, ...@@ -154,8 +124,15 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
{ {
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;
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; struct served_gummei_s *gummei_p = NULL;
struct plmn_identity_s *served_plmn_p = NULL; struct plmn_identity_s *served_plmn_p = NULL;
...@@ -198,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, ...@@ -198,6 +175,8 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) { STAILQ_FOREACH(served_plmn_p, &gummei_p->served_plmns, next) {
if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) && if ((served_plmn_p->mcc == instance_p->mcc[selected_plmn_identity]) &&
(served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) { (served_plmn_p->mnc == instance_p->mnc[selected_plmn_identity])) {
mme_inf[nb_mme].mme_p = mme_data_p;
nb_mme++;
break; break;
} }
} }
...@@ -206,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, ...@@ -206,14 +185,27 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p,
} }
/* if we didn't find such a served PLMN, go on with the next MME */ /* if we didn't find such a served PLMN, go on with the next MME */
if (!served_plmn_p) continue; if (!served_plmn_p) continue;
}
if (current_capacity < mme_data_p->relative_mme_capacity) { if( nb_mme != 0 ) {
/* We find a better MME, keep a reference to it */ for( cnt = 0 ; cnt < nb_mme ; cnt++ ) {
current_capacity = mme_data_p->relative_mme_capacity; mme_inf[cnt].weight = (capacity_sum*10)/mme_inf[cnt].mme_p->relative_mme_capacity;
mme_highest_capacity_p = mme_data_p; 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,8 +24,7 @@ ...@@ -24,8 +24,7 @@
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,
......
...@@ -36,91 +36,6 @@ ...@@ -36,91 +36,6 @@
#include "queue.h" #include "queue.h"
#include "s1ap_common.h" #include "s1ap_common.h"
struct s1ap_timer_elm_s {
task_id_t task_id; ///< Task ID which has requested the timer
int32_t instance; ///< Instance of the task which has requested the timer
uint32_t timer_kind; ///< Instance of the task which has requested the timer
timer_t timer; ///< Unique timer id
timer_type_t type; ///< Timer type
void *timer_arg; ///< Optional argument that will be passed when timer expires
STAILQ_ENTRY(s1ap_timer_elm_s) entries; ///< Pointer to next element
};
typedef struct timer_desc_s {
STAILQ_HEAD(timer_list_head, s1ap_timer_elm_s) timer_queue;
pthread_mutex_t timer_list_mutex;
struct timespec timeout;
} timer_desc_t;
static timer_desc_t timer_desc;
#define TIMER_SEARCH(vAR, tIMERfIELD, tIMERvALUE, tIMERqUEUE) \
do { \
STAILQ_FOREACH(vAR, tIMERqUEUE, entries) { \
if (((vAR)->tIMERfIELD == tIMERvALUE)) \
break; \
} \
} while(0)
int s1ap_timer_timeout(sigval_t info)
{
struct s1ap_timer_elm_s *timer_p;
MessageDef *message_p;
s1ap_timer_has_expired_t *timer_expired_p;
task_id_t task_id;
int32_t instance;
uint32_t timer_kind;
timer_kind = info.sival_int;
if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex lock timeout=%x\n", timer_kind);
return -1;
}
TIMER_SEARCH(timer_p, timer_kind, timer_kind, &timer_desc.timer_queue);
if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex unlock timeout=0x%x\n", timer_kind);
}
if (timer_p == NULL)
{
S1AP_ERROR("Didn't find timer 0x%x in list\n", timer_kind);
return -1;
}
S1AP_DEBUG("Timer kind 0x%x has expired\n", timer_kind);
task_id = timer_p->task_id;
instance = timer_p->instance;
message_p = itti_alloc_new_message(TASK_UNKNOWN, TIMER_HAS_EXPIRED);
timer_expired_p = (s1ap_timer_has_expired_t *)(&message_p->ittiMsg.timer_has_expired);
timer_expired_p->timer_id = (long)timer_p->timer;
timer_expired_p->timer_kind = timer_p->timer_kind;
timer_expired_p->arg = timer_p->timer_arg;
/* Timer is a one shot timer, remove it */
if( (int)timer_p->type == (int)S1AP_TIMER_ONE_SHOT )
{
if( s1ap_timer_remove((long)timer_p->timer) != 0 )
{
S1AP_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
}
}
/* Notify task of timer expiry */
if( itti_send_msg_to_task(task_id, instance, message_p) < 0 )
{
S1AP_ERROR("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id);
free(message_p);
return -1;
}
return 0;
}
int s1ap_timer_setup( int s1ap_timer_setup(
uint32_t interval_sec, uint32_t interval_sec,
...@@ -132,169 +47,24 @@ int s1ap_timer_setup( ...@@ -132,169 +47,24 @@ int s1ap_timer_setup(
void *timer_arg, void *timer_arg,
long *timer_id) long *timer_id)
{ {
struct sigevent evp; uint32_t *timeoutArg=NULL;
struct itimerspec its; int ret=0;
struct s1ap_timer_elm_s *timer_p; timeoutArg=malloc(sizeof(uint32_t));
timer_t timer; *timeoutArg=timer_kind;
ret=timer_setup(interval_sec,
if( timer_id == NULL ) interval_us,
{ task_id,
S1AP_ERROR("Invalid timer_id\n"); instance,
return -1; type,
} (void*)timeoutArg,
timer_id);
if( (int)type >= (int)S1AP_TIMER_TYPE_MAX ) return ret;
{
S1AP_ERROR("Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX);
return -1;
}
if( *timer_id != S1AP_TIMERID_INIT )
{
if( s1ap_timer_remove(*timer_id) != 0 )
{
S1AP_ERROR("Failed to delete timer when the timer start 0x%lx\n", *timer_id);
}
}
/* Allocate new timer list element */
timer_p = malloc(sizeof(struct s1ap_timer_elm_s));
if( timer_p == NULL )
{
S1AP_ERROR("Failed to create new timer element\n");
return -1;
}
memset(&timer, 0, sizeof(timer_t));
memset(&evp, 0, sizeof(evp));
timer_p->task_id = task_id;
timer_p->instance = instance;
timer_p->timer_kind = timer_kind;
timer_p->type = type;
timer_p->timer_arg = timer_arg;
evp.sigev_notify = (int)SIGEV_THREAD;
evp.sigev_notify_function = (void *)s1ap_timer_timeout;
evp.sigev_signo = SIGRTMIN;
evp.sigev_notify_attributes = NULL;
evp.sigev_value.sival_int = timer_kind;
/* At the timer creation, the timer structure will be filled in with timer_id,
* which is unique for this process. This id is allocated by kernel and the
* value might be used to distinguish timers.
*/
if( timer_create(CLOCK_REALTIME, &evp, &timer) < 0 )
{
S1AP_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno);
free(timer_p);
return -1;
}
/* Fill in the first expiration value. */
its.it_value.tv_sec = interval_sec;
its.it_value.tv_nsec = interval_us * 1000;
if( (int)type == (int)S1AP_TIMER_PERIODIC )
{
/* Asked for periodic timer. We set the interval time */
its.it_interval.tv_sec = interval_sec;
its.it_interval.tv_nsec = interval_us * 1000;
}
else
{
/* Asked for one-shot timer. Do not set the interval field */
its.it_interval.tv_sec = 0;
its.it_interval.tv_nsec = 0;
}
if( timer_settime(timer, 0, &its, NULL) )
{
S1AP_ERROR("Failed to Settimer: (%s:%d)\n", strerror(errno), errno);
free(timer_p);
return -1;
}
/* Simply set the timer_id argument. so it can be used by caller */
*timer_id = (long)timer;
timer_p->timer = timer;
/* Lock the queue and insert the timer at the tail */
if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex lock\n");
if( timer_delete(timer_p->timer) < 0 )
{
S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
}
free(timer_p);
timer_p = NULL;
return -1;
}
STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries);
if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex unlock\n");
}
return 0;
} }
int s1ap_timer_remove(long timer_id) int s1ap_timer_remove(long timer_id)
{ {
int rc = 0; int ret;
struct s1ap_timer_elm_s *timer_p; ret=timer_remove(timer_id);
return ret;
if( pthread_mutex_lock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex lock\n");
if( timer_delete((timer_t)timer_id) < 0 )
{
S1AP_ERROR("Failed to delete timer 0x%lx\n", (long)timer_id);
}
return -1;
}
TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue);
/* We didn't find the timer in list */
if (timer_p == NULL)
{
S1AP_ERROR("Didn't find timer 0x%lx in list\n", timer_id);
if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex unlock\n");
}
return -1;
}
timer_delete(timer_p->timer);
STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, s1ap_timer_elm_s, entries);
if( pthread_mutex_unlock(&timer_desc.timer_list_mutex) != 0 )
{
S1AP_ERROR("Failed to mutex unlock\n");
}
free(timer_p);
timer_p = NULL;
return rc;
} }
int s1ap_timer_init(void)
{
memset(&timer_desc, 0, sizeof(timer_desc_t));
STAILQ_INIT(&timer_desc.timer_queue);
pthread_mutex_init(&timer_desc.timer_list_mutex, NULL);
return 0;
}
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