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
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,36 +267,28 @@ 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{
......@@ -305,8 +296,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
}
}
}
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;
......@@ -423,7 +397,7 @@ 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)
timer_has_expired_t *msg_p)
{
uint32_t timer_kind = 0;
int16_t line_ind = 0;
......@@ -433,17 +407,14 @@ void s1ap_eNB_timer_expired(
long timer_id = S1AP_TIMERID_INIT;
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);
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);
if(mme_desc_p != NULL)
{
if( timer_id == mme_desc_p->timer_id )
{
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;
......@@ -452,12 +423,9 @@ void s1ap_eNB_timer_expired(
case S1_SETRSP_WAIT:
{
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 );
}
else
{
} else {
S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
}
break;
......@@ -465,12 +433,9 @@ void s1ap_eNB_timer_expired(
case S1_SETREQ_WAIT:
{
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 );
}
else
{
} else {
S1AP_ERROR("Retransmission count exceeded of S1 SETUP REQUEST : MME=%d\n",line_ind);
}
break;
......@@ -478,12 +443,9 @@ void s1ap_eNB_timer_expired(
case SCTP_REQ_WAIT:
{
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 );
}
else
{
} else {
S1AP_ERROR("Retransmission count exceeded of SCTP : MME=%d\n",line_ind);
}
break;
......@@ -494,29 +456,21 @@ void s1ap_eNB_timer_expired(
break;
}
}
}
else
{
} else {
S1AP_DEBUG("Unmatch timer id\n");
return;
}
}
else
{
} else {
S1AP_WARN("Not applicable MME detected : connection id = %d\n", line_ind);
return;
}
}
else
{
}
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;
......@@ -790,7 +744,7 @@ static int s1ap_sctp_req(s1ap_eNB_instance_t *instance_p,
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->port = S1AP_PORT_NUMBER;
sctp_new_association_req_p->ppid = S1AP_SCTP_PPID;
......@@ -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->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,
&s1ap_mme_data_p->mme_ip_address,
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,
&instance_p->enb_ip_address,
sizeof(net_ip_address_t));
}
else
{
} else {
S1AP_ERROR("Invalid IP Address Format V4(MME):V6\n");
return -1;
}
}
else
{
} 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 )
{
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
{
} else {
S1AP_ERROR("Invalid IP Address Format V6(MME):V4\n");
return -1;
}
......
......@@ -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,15 +344,11 @@ 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
{
} 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;
}
......@@ -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);
}
/* 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);
......
......@@ -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;
}
}
......
......@@ -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 */
......
......@@ -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];
......@@ -57,7 +58,6 @@ s1ap_eNB_nnsf_select_mme(s1ap_eNB_instance_t *instance_p,
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,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_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;
......@@ -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;
}
......
......@@ -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,
......
......@@ -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;
}
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