From 969425f6a8a5cec22d8b70e26683cc2a3954c4f0 Mon Sep 17 00:00:00 2001 From: "masayuki.harada" <masayuki.harada@jp.fujitsu.com> Date: Tue, 9 Mar 2021 03:25:00 +0900 Subject: [PATCH] Replace to itti timer. Fix nnsf selection. Fix indentation and opening brace. --- openair3/S1AP/s1ap_eNB.c | 327 ++++++++---------- openair3/S1AP/s1ap_eNB_handlers.c | 52 +-- .../S1AP/s1ap_eNB_management_procedures.c | 29 +- openair3/S1AP/s1ap_eNB_nas_procedures.c | 9 +- openair3/S1AP/s1ap_eNB_nnsf.c | 100 +++--- openair3/S1AP/s1ap_eNB_nnsf.h | 3 +- openair3/S1AP/s1ap_eNB_timer.c | 260 +------------- 7 files changed, 225 insertions(+), 555 deletions(-) diff --git a/openair3/S1AP/s1ap_eNB.c b/openair3/S1AP/s1ap_eNB.c index c40cc7cea9..6cb82de8d3 100644 --- a/openair3/S1AP/s1ap_eNB.c +++ b/openair3/S1AP/s1ap_eNB.c @@ -78,7 +78,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p); void s1ap_eNB_timer_expired(instance_t instance, - s1ap_timer_has_expired_t *msg_p); + timer_has_expired_t *msg_p); uint32_t s1ap_generate_eNB_id(void) { char *out; @@ -157,7 +157,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * uint8_t index; DevAssert(s1ap_register_eNB != NULL); /* Look if the provided instance already exists */ - s1ap_timer_init(); new_instance = s1ap_eNB_get_instance(instance); if (new_instance != NULL) { @@ -268,45 +267,36 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa sctp_new_association_resp->ulp_cnx_id); DevAssert(s1ap_mme_data_p != NULL); memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) ); - if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) - { + if( s1ap_mme_data_p->timer_id != S1AP_TIMERID_INIT ) { s1ap_timer_remove( s1ap_mme_data_p->timer_id ); s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; } - if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) - { - RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) - { - if( ue_p->mme_ref == s1ap_mme_data_p ) - { - if(cnt < NUMBER_OF_UE_MAX){ + if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) { + RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) { + if( ue_p->mme_ref == s1ap_mme_data_p ) { + if(cnt < NUMBER_OF_UE_MAX) { enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; cnt++; message_p = NULL; - 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); - if( message_p != NULL ) - { + if( message_p != NULL ) { S1AP_UE_CONTEXT_RELEASE_COMMAND(message_p).eNB_ue_s1ap_id = ue_p->eNB_ue_s1ap_id; - if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) - { + if( itti_send_msg_to_task(TASK_RRC_ENB, ue_p->eNB_instance->instance, message_p) < 0 ) { S1AP_ERROR("UE Context Release Command Transmission Failure: eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } - } - else - { + } else { S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id); } }else{ - S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); + S1AP_ERROR("s1ap_eNB_handle_sctp_association_resp: cnt %d > max\n", cnt); } } } - for( ; cnt > 0 ; ) - { + for( ; cnt > 0 ; ) { cnt--; struct s1ap_eNB_ue_context_s *ue_context_p = NULL; struct s1ap_eNB_ue_context_s *s1ap_ue_context_p = NULL; @@ -323,25 +313,21 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa s1ap_mme_data_p->out_streams = 0; s1ap_mme_data_p->assoc_id = -1; - while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) - { + while (!STAILQ_EMPTY(&s1ap_mme_data_p->served_gummei)) { gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei); STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->served_gummei, next); - while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) - { + while (!STAILQ_EMPTY(&gummeiInfo->served_plmns)) { plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns); STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next); free(plmnInfo); } - while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) - { + while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) { groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids); STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next); free(groupInfo); } - while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) - { + while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) { mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes); STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next); free(mmeCode); @@ -351,45 +337,33 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa STAILQ_INIT(&s1ap_mme_data_p->served_gummei); - if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) - { + if( s1ap_mme_data_p->state == S1AP_ENB_STATE_DISCONNECTED ) { if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || - (instance_p->sctp_req_count == 0xffff) ) - { + (instance_p->sctp_req_count == 0xffff) ) { timer_kind = s1ap_mme_data_p->cnx_id; timer_kind = timer_kind | S1AP_MMEIND; timer_kind = timer_kind | SCTP_REQ_WAIT; if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance, - timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) - { + timer_kind, S1AP_TIMER_ONE_SHOT, NULL, &s1ap_mme_data_p->timer_id) < 0 ) { S1AP_ERROR("Timer Start NG(SCTP retransmission wait timer) : MME=%d\n",s1ap_mme_data_p->cnx_id); s1ap_sctp_req( instance_p, s1ap_mme_data_p ); } - } - else - { + } else { S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); } - } - else - { + } else { S1AP_ERROR("SCTP disconnection reception : MME = %d\n",s1ap_mme_data_p->cnx_id); if( (s1ap_mme_data_p->sctp_req_cnt <= instance_p->sctp_req_count) || - (instance_p->sctp_req_count == 0xffff) ) - { + (instance_p->sctp_req_count == 0xffff) ) { s1ap_sctp_req( instance_p, s1ap_mme_data_p ); - } - else - { + } else { S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id); } s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; } - } - else - { + } else { /* Update parameters */ s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; @@ -422,101 +396,81 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { } void s1ap_eNB_timer_expired( - instance_t instance, - s1ap_timer_has_expired_t *msg_p) + instance_t instance, + timer_has_expired_t *msg_p) { - uint32_t timer_kind = 0; - int16_t line_ind = 0; - s1ap_eNB_mme_data_t *mme_desc_p = NULL; - uint32_t timer_ind = 0; - s1ap_eNB_instance_t *instance_p = NULL; - long timer_id = S1AP_TIMERID_INIT; - - instance_p = s1ap_eNB_get_instance(instance); - timer_kind = msg_p->timer_kind; - line_ind = (int16_t)(timer_kind & S1AP_LINEIND); - timer_id = msg_p->timer_id; - - if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) - { - mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); - if(mme_desc_p != NULL) + uint32_t timer_kind = 0; + int16_t line_ind = 0; + s1ap_eNB_mme_data_t *mme_desc_p = NULL; + uint32_t timer_ind = 0; + s1ap_eNB_instance_t *instance_p = NULL; + long timer_id = S1AP_TIMERID_INIT; + + instance_p = s1ap_eNB_get_instance(instance); + timer_kind = *((uint32_t*)msg_p->arg); + line_ind = (int16_t)(timer_kind & S1AP_LINEIND); + timer_id = msg_p->timer_id; + + if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) { + mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); + if(mme_desc_p != NULL) { + if( timer_id == mme_desc_p->timer_id ) { + mme_desc_p->timer_id = S1AP_TIMERID_INIT; + timer_ind = timer_kind & S1AP_TIMERIND; + + switch(timer_ind) { - if( timer_id == mme_desc_p->timer_id ) - { - mme_desc_p->timer_id = S1AP_TIMERID_INIT; - timer_ind = timer_kind & S1AP_TIMERIND; - - switch(timer_ind) - { - case S1_SETRSP_WAIT: - { - if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || - (instance_p->s1_setupreq_count == 0xffff) ) - { - s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); - } - else - { - S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); - } - break; - } - case S1_SETREQ_WAIT: - { - if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || - (instance_p->s1_setupreq_count == 0xffff) ) - { - s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); - } - else - { - S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); - } - break; - } - case SCTP_REQ_WAIT: - { - if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || - (instance_p->sctp_req_count == 0xffff) ) - { - s1ap_sctp_req( instance_p, mme_desc_p ); - } - else - { - S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); - } - break; - } - default: - { - S1AP_WARN("Invalid Timer indication\n"); - break; - } - } + case S1_SETRSP_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); } - else - { - S1AP_DEBUG("Unmatch timer id\n"); - return; + break; + } + case S1_SETREQ_WAIT: + { + if( (instance_p->s1_setupreq_count >= mme_desc_p->s1_setupreq_cnt) || + (instance_p->s1_setupreq_count == 0xffff) ) { + s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); } + break; + } + case SCTP_REQ_WAIT: + { + if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || + (instance_p->sctp_req_count == 0xffff) ) { + s1ap_sctp_req( instance_p, mme_desc_p ); + } else { + S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); + } + break; + } + default: + { + S1AP_WARN("Invalid Timer indication\n"); + break; + } } - else - { - S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); - return; - } - } - else - { + } else { + S1AP_DEBUG("Unmatch timer id\n"); + return; + } + } else { + S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); + return; } - return; + } + return; } void s1ap_eNB_init(void) { S1AP_DEBUG("Starting S1AP layer\n"); s1ap_eNB_prepare_internal_data(); - s1ap_timer_init(); itti_mark_task_ready(TASK_S1AP); MSC_START_USE(); } @@ -639,8 +593,8 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { case TIMER_HAS_EXPIRED: { - s1ap_eNB_timer_expired(ITTI_MESSAGE_GET_INSTANCE(received_msg), - (s1ap_timer_has_expired_t *) &TIMER_HAS_EXPIRED(received_msg)); + s1ap_eNB_timer_expired(ITTI_MSG_DESTINATION_INSTANCE(received_msg), + &received_msg->ittiMsg.timer_has_expired); } break; @@ -781,61 +735,52 @@ static int s1ap_eNB_generate_s1_setup_request( static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, s1ap_eNB_mme_data_t *s1ap_mme_data_p) { - MessageDef *message_p = NULL; - sctp_new_association_req_t *sctp_new_association_req_p = NULL; - - if( instance_p == NULL ) - { - S1AP_ERROR("Invalid instance_p\n"); - return -1; - } - - message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); - sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; - sctp_new_association_req_p->port = S1AP_PORT_NUMBER; - sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; - sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams; - sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams; - sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; - - if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) - { - memcpy(&sctp_new_association_req_p->remote_address, - &s1ap_mme_data_p->mme_ip_address, - sizeof(net_ip_address_t)); - if( instance_p->enb_ip_address.ipv4 != 0 ) - { - memcpy(&sctp_new_association_req_p->local_address, - &instance_p->enb_ip_address, - sizeof(net_ip_address_t)); - } - else - { - S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); - return -1; - } + MessageDef *message_p = NULL; + sctp_new_association_req_t *sctp_new_association_req_p = NULL; + + if( instance_p == NULL ) + { + S1AP_ERROR("Invalid instance_p\n"); + return -1; + } + + message_p = itti_alloc_new_message(TASK_S1AP, 0, SCTP_NEW_ASSOCIATION_REQ); + sctp_new_association_req_p = &message_p->ittiMsg.sctp_new_association_req; + sctp_new_association_req_p->port = S1AP_PORT_NUMBER; + sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; + sctp_new_association_req_p->in_streams = instance_p->sctp_in_streams; + sctp_new_association_req_p->out_streams = instance_p->sctp_out_streams; + sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id; + + if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv4 != 0 ) { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } else { + S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); + return -1; } - else - { - memcpy(&sctp_new_association_req_p->remote_address, - &s1ap_mme_data_p->mme_ip_address, - sizeof(net_ip_address_t)); - if( instance_p->enb_ip_address.ipv6 != 0 ) - { - memcpy(&sctp_new_association_req_p->local_address, - &instance_p->enb_ip_address, - sizeof(net_ip_address_t)); - } - else - { - S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); - return -1; - } + } else { + memcpy(&sctp_new_association_req_p->remote_address, + &s1ap_mme_data_p->mme_ip_address, + sizeof(net_ip_address_t)); + if( instance_p->enb_ip_address.ipv6 != 0 ) { + memcpy(&sctp_new_association_req_p->local_address, + &instance_p->enb_ip_address, + sizeof(net_ip_address_t)); + } else { + S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); + return -1; } - - itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); - - s1ap_mme_data_p->sctp_req_cnt++; - - return 0; + } + + itti_send_msg_to_task(TASK_SCTP, instance_p->instance, message_p); + + s1ap_mme_data_p->sctp_req_cnt++; + + return 0; } diff --git a/openair3/S1AP/s1ap_eNB_handlers.c b/openair3/S1AP/s1ap_eNB_handlers.c index ce9e2ce302..7c611b0fbf 100644 --- a/openair3/S1AP/s1ap_eNB_handlers.c +++ b/openair3/S1AP/s1ap_eNB_handlers.c @@ -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_ProtocolIE_ID_id_Cause,true); - if(ie == NULL) - { + if(ie == NULL) { return -1; } @@ -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"); } - 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 ); mme_desc_p->timer_id = S1AP_TIMERID_INIT; } instance_p = mme_desc_p->s1ap_eNB_instance; 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_ProtocolIE_ID_id_TimeToWait, false); - if( ie != NULL ) - { + if( ie != NULL ) { switch(ie->value.choice.TimeToWait) { case S1AP_TimeToWait_v1s: @@ -339,9 +335,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, interval_sec = instance_p->s1_setupreq_wait_timer; break; } - } - else - { + } else { interval_sec = instance_p->s1_setupreq_wait_timer; } @@ -350,16 +344,12 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, 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, - 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_eNB_snd_s1_setup_request( instance_p, mme_desc_p ); } - } - else - { - S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id); + } else { + S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",mme_desc_p->cnx_id); } return 0; } @@ -391,16 +381,14 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, /* Set the capacity of this MME */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_RelativeMMECapacity, true); - if(ie == NULL) - { + if(ie == NULL) { return -1; } mme_desc_p->relative_mme_capacity = ie->value.choice.RelativeMMECapacity; S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_ServedGUMMEIs, true); - if(ie == NULL) - { + if(ie == NULL) { return -1; } @@ -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); } - - /* 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 */ S1AP_FIND_PROTOCOLIE_BY_ID(S1AP_S1SetupResponseIEs_t, ie, container, S1AP_ProtocolIE_ID_id_MMEname, false); @@ -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->s1ap_eNB_instance->s1ap_mme_associated_nb ++; -// s1ap_handle_s1_setup_message(mme_desc_p, 0); return 0; } @@ -819,8 +800,7 @@ int s1ap_eNB_handle_error_indication(uint32_t assoc_id, S1AP_ProtocolIE_ID_id_CriticalityDiagnostics, false); 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); } // TODO continue @@ -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_ProtocolIE_ID_id_Cause, true); - if( ie == NULL ) - { + if( ie == NULL ) { S1AP_ERROR( "Mandatory Element Nothing : UEContextReleaseCommand(Cause)\n" ); return -1; } @@ -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?" 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; 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, { 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; itti_send_msg_to_task(TASK_RRC_ENB, ue_desc_p->eNB_instance->instance, message_p); diff --git a/openair3/S1AP/s1ap_eNB_management_procedures.c b/openair3/S1AP/s1ap_eNB_management_procedures.c index 1fdc09664b..a870e975a2 100644 --- a/openair3/S1AP/s1ap_eNB_management_procedures.c +++ b/openair3/S1AP/s1ap_eNB_management_procedures.c @@ -102,8 +102,7 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( temp.assoc_id = assoc_id; temp.cnx_id = cnx_id; - if( cnx_id != 0 ) - { + if( cnx_id != 0 ) { if (instance_p == NULL) { STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, s1ap_eNB_entries) { @@ -116,29 +115,19 @@ struct s1ap_eNB_mme_data_s *s1ap_eNB_get_MME( } else { return RB_FIND(s1ap_mme_map, &instance_p->s1ap_mme_head, &temp); } - } - else - { - if (instance_p == NULL) - { + } else { + if (instance_p == NULL) { STAILQ_FOREACH(instance_p, &s1ap_eNB_internal_data.s1ap_eNB_instances_head, - s1ap_eNB_entries) - { - RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) - { - if( mme_p->assoc_id == assoc_id ) - { + s1ap_eNB_entries) { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + if( mme_p->assoc_id == assoc_id ) { return mme_p; } } } - } - else - { - RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) - { - if( mme_p->assoc_id == assoc_id ) - { + } else { + RB_FOREACH(mme_p, s1ap_mme_map, &instance_p->s1ap_mme_head) { + if( mme_p->assoc_id == assoc_id ) { return mme_p; } } diff --git a/openair3/S1AP/s1ap_eNB_nas_procedures.c b/openair3/S1AP/s1ap_eNB_nas_procedures.c index 206201089d..b55bc06e11 100644 --- a/openair3/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair3/S1AP/s1ap_eNB_nas_procedures.c @@ -139,8 +139,7 @@ int s1ap_eNB_handle_nas_first_req( */ mme_desc_p = s1ap_eNB_nnsf_select_mme( instance_p, - s1ap_nas_first_req_p->establishment_cause, - s1ap_nas_first_req_p->selected_plmn_identity); + s1ap_nas_first_req_p->establishment_cause); if (mme_desc_p) { 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( 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[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]], + 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], &ie->value.choice.EUTRAN_CGI.pLMNidentity); ASN_SEQUENCE_ADD(&out->protocolIEs.list, ie); /* Set the establishment cause according to those provided by RRC */ diff --git a/openair3/S1AP/s1ap_eNB_nnsf.c b/openair3/S1AP/s1ap_eNB_nnsf.c index 6577b8f10b..a5a4e74734 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.c +++ b/openair3/S1AP/s1ap_eNB_nnsf.c @@ -36,17 +36,18 @@ #include "s1ap_eNB_defs.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 * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause, - uint32_t plmn_id) + rrc_establishment_cause_t cause) { struct s1ap_eNB_mme_data_s *mme_data_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; MME_nnsf_inf_t mme_inf[10]; @@ -55,9 +56,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, 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, @@ -83,7 +83,8 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, || (cause == RRC_CAUSE_HIGH_PRIO_ACCESS))) { continue; } - + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; /* At this point, the RRC establishment can be handled by the MME * even if it is in overload state. */ @@ -92,58 +93,27 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, 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 ) - { - for( cnt = 0 ; cnt < nb_mme ; cnt++ ) - { + + 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 ) - { + 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 - { + } else { mme_highest_capacity_p = NULL; } - if( mme_highest_capacity_p != NULL ) - { + if( mme_highest_capacity_p != NULL ) { mme_highest_capacity_p->nb_calls++; } - return mme_highest_capacity_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_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) { struct served_gummei_s *gummei_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, 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])) { + mme_inf[nb_mme].mme_p = mme_data_p; + nb_mme++; break; } } @@ -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 (!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; + 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; } diff --git a/openair3/S1AP/s1ap_eNB_nnsf.h b/openair3/S1AP/s1ap_eNB_nnsf.h index de039b7d30..d5f080649b 100644 --- a/openair3/S1AP/s1ap_eNB_nnsf.h +++ b/openair3/S1AP/s1ap_eNB_nnsf.h @@ -24,8 +24,7 @@ struct s1ap_eNB_mme_data_s * s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, - rrc_establishment_cause_t cause, - uint32_t plmn_id); + 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, diff --git a/openair3/S1AP/s1ap_eNB_timer.c b/openair3/S1AP/s1ap_eNB_timer.c index ccb294cb54..3014f961a9 100644 --- a/openair3/S1AP/s1ap_eNB_timer.c +++ b/openair3/S1AP/s1ap_eNB_timer.c @@ -36,91 +36,6 @@ #include "queue.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( uint32_t interval_sec, @@ -132,169 +47,24 @@ int s1ap_timer_setup( void *timer_arg, long *timer_id) { - struct sigevent evp; - struct itimerspec its; - struct s1ap_timer_elm_s *timer_p; - timer_t timer; - - if( timer_id == NULL ) - { - S1AP_ERROR("Invalid timer_id\n"); - return -1; - } - - if( (int)type >= (int)S1AP_TIMER_TYPE_MAX ) - { - 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; + uint32_t *timeoutArg=NULL; + int ret=0; + timeoutArg=malloc(sizeof(uint32_t)); + *timeoutArg=timer_kind; + ret=timer_setup(interval_sec, + interval_us, + task_id, + instance, + type, + (void*)timeoutArg, + timer_id); + return ret; } int s1ap_timer_remove(long timer_id) { - int rc = 0; - struct s1ap_timer_elm_s *timer_p; - - - 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 ret; + ret=timer_remove(timer_id); + return ret; } -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; -} -- 2.26.2