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

Replace to itti timer.

Fix nnsf selection.
Fix indentation and opening brace.
parent ff994453
...@@ -78,7 +78,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa ...@@ -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, static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
s1ap_eNB_mme_data_t *s1ap_mme_data_p); s1ap_eNB_mme_data_t *s1ap_mme_data_p);
void s1ap_eNB_timer_expired(instance_t instance, 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) { uint32_t s1ap_generate_eNB_id(void) {
char *out; char *out;
...@@ -157,7 +157,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t * ...@@ -157,7 +157,6 @@ void s1ap_eNB_handle_register_eNB(instance_t instance, s1ap_register_enb_req_t *
uint8_t index; uint8_t index;
DevAssert(s1ap_register_eNB != NULL); DevAssert(s1ap_register_eNB != NULL);
/* Look if the provided instance already exists */ /* Look if the provided instance already exists */
s1ap_timer_init();
new_instance = s1ap_eNB_get_instance(instance); new_instance = s1ap_eNB_get_instance(instance);
if (new_instance != NULL) { if (new_instance != NULL) {
...@@ -268,36 +267,28 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa ...@@ -268,36 +267,28 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
sctp_new_association_resp->ulp_cnx_id); sctp_new_association_resp->ulp_cnx_id);
DevAssert(s1ap_mme_data_p != NULL); DevAssert(s1ap_mme_data_p != NULL);
memset(enb_s1ap_id, 0, sizeof(enb_s1ap_id) ); 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_timer_remove( s1ap_mme_data_p->timer_id );
s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT; s1ap_mme_data_p->timer_id = S1AP_TIMERID_INIT;
} }
if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) if( sctp_new_association_resp->sctp_state != SCTP_STATE_ESTABLISHED ) {
{ RB_FOREACH(ue_p, s1ap_ue_map, &instance_p->s1ap_ue_head) {
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( ue_p->mme_ref == s1ap_mme_data_p )
{
if(cnt < NUMBER_OF_UE_MAX){
enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id; enb_s1ap_id[cnt] = ue_p->eNB_ue_s1ap_id;
cnt++; cnt++;
message_p = NULL; 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; 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); 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); S1AP_ERROR("Invalid message_p : eNB_ue_s1ap_id=%u\n", ue_p->eNB_ue_s1ap_id);
} }
}else{ }else{
...@@ -305,8 +296,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa ...@@ -305,8 +296,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
} }
} }
} }
for( ; cnt > 0 ; ) for( ; cnt > 0 ; ) {
{
cnt--; cnt--;
struct s1ap_eNB_ue_context_s *ue_context_p = NULL; struct s1ap_eNB_ue_context_s *ue_context_p = NULL;
struct s1ap_eNB_ue_context_s *s1ap_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 ...@@ -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->out_streams = 0;
s1ap_mme_data_p->assoc_id = -1; 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); gummeiInfo = STAILQ_FIRST(&s1ap_mme_data_p->served_gummei);
STAILQ_REMOVE_HEAD(&s1ap_mme_data_p->served_gummei, next); 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); plmnInfo = STAILQ_FIRST(&gummeiInfo->served_plmns);
STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next); STAILQ_REMOVE_HEAD(&gummeiInfo->served_plmns, next);
free(plmnInfo); free(plmnInfo);
} }
while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) while (!STAILQ_EMPTY(&gummeiInfo->served_group_ids)) {
{
groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids); groupInfo = STAILQ_FIRST(&gummeiInfo->served_group_ids);
STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next); STAILQ_REMOVE_HEAD(&gummeiInfo->served_group_ids, next);
free(groupInfo); free(groupInfo);
} }
while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) while (!STAILQ_EMPTY(&gummeiInfo->mme_codes)) {
{
mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes); mmeCode = STAILQ_FIRST(&gummeiInfo->mme_codes);
STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next); STAILQ_REMOVE_HEAD(&gummeiInfo->mme_codes, next);
free(mmeCode); free(mmeCode);
...@@ -351,45 +337,33 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa ...@@ -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); 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) || 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 = s1ap_mme_data_p->cnx_id;
timer_kind = timer_kind | S1AP_MMEIND; timer_kind = timer_kind | S1AP_MMEIND;
timer_kind = timer_kind | SCTP_REQ_WAIT; timer_kind = timer_kind | SCTP_REQ_WAIT;
if( s1ap_timer_setup( instance_p->sctp_req_timer, 0, TASK_S1AP, instance_p->instance, 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_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 ); 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_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); 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) || 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 ); 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_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",s1ap_mme_data_p->cnx_id);
} }
s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED; s1ap_mme_data_p->state = S1AP_ENB_STATE_DISCONNECTED;
} }
} } else {
else
{
/* Update parameters */ /* Update parameters */
s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id; s1ap_mme_data_p->assoc_id = sctp_new_association_resp->assoc_id;
s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams; s1ap_mme_data_p->in_streams = sctp_new_association_resp->in_streams;
...@@ -423,7 +397,7 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) { ...@@ -423,7 +397,7 @@ void s1ap_eNB_handle_sctp_data_ind(sctp_data_ind_t *sctp_data_ind) {
void s1ap_eNB_timer_expired( void s1ap_eNB_timer_expired(
instance_t instance, instance_t instance,
s1ap_timer_has_expired_t *msg_p) timer_has_expired_t *msg_p)
{ {
uint32_t timer_kind = 0; uint32_t timer_kind = 0;
int16_t line_ind = 0; int16_t line_ind = 0;
...@@ -433,17 +407,14 @@ void s1ap_eNB_timer_expired( ...@@ -433,17 +407,14 @@ void s1ap_eNB_timer_expired(
long timer_id = S1AP_TIMERID_INIT; long timer_id = S1AP_TIMERID_INIT;
instance_p = s1ap_eNB_get_instance(instance); instance_p = s1ap_eNB_get_instance(instance);
timer_kind = msg_p->timer_kind; timer_kind = *((uint32_t*)msg_p->arg);
line_ind = (int16_t)(timer_kind & S1AP_LINEIND); line_ind = (int16_t)(timer_kind & S1AP_LINEIND);
timer_id = msg_p->timer_id; timer_id = msg_p->timer_id;
if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) if( (timer_kind & S1AP_MMEIND) == S1AP_MMEIND ) {
{
mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind); mme_desc_p = s1ap_eNB_get_MME(instance_p, -1, line_ind);
if(mme_desc_p != NULL) if(mme_desc_p != NULL) {
{ if( timer_id == mme_desc_p->timer_id ) {
if( timer_id == mme_desc_p->timer_id )
{
mme_desc_p->timer_id = S1AP_TIMERID_INIT; mme_desc_p->timer_id = S1AP_TIMERID_INIT;
timer_ind = timer_kind & S1AP_TIMERIND; timer_ind = timer_kind & S1AP_TIMERIND;
...@@ -452,12 +423,9 @@ void s1ap_eNB_timer_expired( ...@@ -452,12 +423,9 @@ void s1ap_eNB_timer_expired(
case S1_SETRSP_WAIT: case S1_SETRSP_WAIT:
{ {
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_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p );
} } else {
else
{
S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
} }
break; break;
...@@ -465,12 +433,9 @@ void s1ap_eNB_timer_expired( ...@@ -465,12 +433,9 @@ void s1ap_eNB_timer_expired(
case S1_SETREQ_WAIT: case S1_SETREQ_WAIT:
{ {
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_eNB_generate_s1_setup_request( instance_p, mme_desc_p ); s1ap_eNB_generate_s1_setup_request( instance_p, mme_desc_p );
} } else {
else
{
S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind); S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
} }
break; break;
...@@ -478,12 +443,9 @@ void s1ap_eNB_timer_expired( ...@@ -478,12 +443,9 @@ void s1ap_eNB_timer_expired(
case SCTP_REQ_WAIT: case SCTP_REQ_WAIT:
{ {
if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) || if( (instance_p->sctp_req_count >= mme_desc_p->sctp_req_cnt) ||
(instance_p->sctp_req_count == 0xffff) ) (instance_p->sctp_req_count == 0xffff) ) {
{
s1ap_sctp_req( instance_p, mme_desc_p ); s1ap_sctp_req( instance_p, mme_desc_p );
} } else {
else
{
S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind); S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind);
} }
break; break;
...@@ -494,29 +456,21 @@ void s1ap_eNB_timer_expired( ...@@ -494,29 +456,21 @@ void s1ap_eNB_timer_expired(
break; break;
} }
} }
} } else {
else
{
S1AP_DEBUG("Unmatch timer id\n"); S1AP_DEBUG("Unmatch timer id\n");
return; return;
} }
} } else {
else
{
S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind); S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind);
return; return;
} }
} }
else
{
}
return; return;
} }
void s1ap_eNB_init(void) { void s1ap_eNB_init(void) {
S1AP_DEBUG("Starting S1AP layer\n"); S1AP_DEBUG("Starting S1AP layer\n");
s1ap_eNB_prepare_internal_data(); s1ap_eNB_prepare_internal_data();
s1ap_timer_init();
itti_mark_task_ready(TASK_S1AP); itti_mark_task_ready(TASK_S1AP);
MSC_START_USE(); MSC_START_USE();
} }
...@@ -639,8 +593,8 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) { ...@@ -639,8 +593,8 @@ void *s1ap_eNB_process_itti_msg(void *notUsed) {
case TIMER_HAS_EXPIRED: case TIMER_HAS_EXPIRED:
{ {
s1ap_eNB_timer_expired(ITTI_MESSAGE_GET_INSTANCE(received_msg), s1ap_eNB_timer_expired(ITTI_MSG_DESTINATION_INSTANCE(received_msg),
(s1ap_timer_has_expired_t *) &TIMER_HAS_EXPIRED(received_msg)); &received_msg->ittiMsg.timer_has_expired);
} }
break; break;
...@@ -790,7 +744,7 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, ...@@ -790,7 +744,7 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
return -1; return -1;
} }
message_p = itti_alloc_new_message(TASK_S1AP, SCTP_NEW_ASSOCIATION_REQ); 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 = &message_p->ittiMsg.sctp_new_association_req;
sctp_new_association_req_p->port = S1AP_PORT_NUMBER; sctp_new_association_req_p->port = S1AP_PORT_NUMBER;
sctp_new_association_req_p->ppid = S1AP_SCTP_PPID; sctp_new_association_req_p->ppid = S1AP_SCTP_PPID;
...@@ -798,36 +752,27 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p, ...@@ -798,36 +752,27 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
sctp_new_association_req_p->out_streams = instance_p->sctp_out_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; sctp_new_association_req_p->ulp_cnx_id = s1ap_mme_data_p->cnx_id;
if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) if( s1ap_mme_data_p->mme_ip_address.ipv4 != 0 ) {
{
memcpy(&sctp_new_association_req_p->remote_address, memcpy(&sctp_new_association_req_p->remote_address,
&s1ap_mme_data_p->mme_ip_address, &s1ap_mme_data_p->mme_ip_address,
sizeof(net_ip_address_t)); sizeof(net_ip_address_t));
if( instance_p->enb_ip_address.ipv4 != 0 ) if( instance_p->enb_ip_address.ipv4 != 0 ) {
{
memcpy(&sctp_new_association_req_p->local_address, memcpy(&sctp_new_association_req_p->local_address,
&instance_p->enb_ip_address, &instance_p->enb_ip_address,
sizeof(net_ip_address_t)); sizeof(net_ip_address_t));
} } else {
else
{
S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n"); S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n");
return -1; return -1;
} }
} } else {
else
{
memcpy(&sctp_new_association_req_p->remote_address, memcpy(&sctp_new_association_req_p->remote_address,
&s1ap_mme_data_p->mme_ip_address, &s1ap_mme_data_p->mme_ip_address,
sizeof(net_ip_address_t)); sizeof(net_ip_address_t));
if( instance_p->enb_ip_address.ipv6 != 0 ) if( instance_p->enb_ip_address.ipv6 != 0 ) {
{
memcpy(&sctp_new_association_req_p->local_address, memcpy(&sctp_new_association_req_p->local_address,
&instance_p->enb_ip_address, &instance_p->enb_ip_address,
sizeof(net_ip_address_t)); sizeof(net_ip_address_t));
} } else {
else
{
S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n"); S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n");
return -1; return -1;
} }
......
...@@ -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,15 +344,11 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t assoc_id, ...@@ -350,15 +344,11 @@ 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;
} }
...@@ -463,12 +451,6 @@ int s1ap_eNB_handle_s1_setup_response(uint32_t assoc_id, ...@@ -463,12 +451,6 @@ 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];
...@@ -57,7 +58,6 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p, ...@@ -57,7 +58,6 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
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,7 +124,14 @@ s1ap_eNB_nnsf_select_mme_by_plmn_id(s1ap_eNB_instance_t *instance_p, ...@@ -154,7 +124,14 @@ 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;
...@@ -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