From efcd582b09993e8345184cceda67022ec0fac7ab Mon Sep 17 00:00:00 2001 From: Lionel Gauthier <lionel.gauthier@eurecom.fr> Date: Tue, 9 Dec 2014 19:43:47 +0000 Subject: [PATCH] UE_CONTEXT_RELEASE_COMPLETE git-svn-id: http://svn.eurecom.fr/openair4G/trunk@6223 818b1a75-f10b-46b9-bf7c-635c3b92a50f --- openair-cn/S1AP/s1ap_eNB.c | 4 ++ openair-cn/S1AP/s1ap_eNB_encoder.c | 76 ++++++++++++++++++----- openair-cn/S1AP/s1ap_eNB_itti_messaging.c | 13 ++++ openair-cn/S1AP/s1ap_eNB_itti_messaging.h | 4 ++ openair-cn/S1AP/s1ap_eNB_nas_procedures.c | 72 +++++++++++++++++++++ openair-cn/S1AP/s1ap_eNB_nas_procedures.h | 4 ++ openair-cn/S1AP/s1ap_eNB_ue_context.h | 3 + 7 files changed, 161 insertions(+), 15 deletions(-) diff --git a/openair-cn/S1AP/s1ap_eNB.c b/openair-cn/S1AP/s1ap_eNB.c index e0d0629ff6..18137475be 100644 --- a/openair-cn/S1AP/s1ap_eNB.c +++ b/openair-cn/S1AP/s1ap_eNB.c @@ -296,6 +296,10 @@ void *s1ap_eNB_task(void *arg) s1ap_eNB_nas_non_delivery_ind(ITTI_MESSAGE_GET_INSTANCE(received_msg), &S1AP_NAS_NON_DELIVERY_IND(received_msg)); } break; + case S1AP_UE_CONTEXT_RELEASE_COMPLETE: { + s1ap_ue_context_release_complete(ITTI_MESSAGE_GET_INSTANCE(received_msg), + &S1AP_UE_CONTEXT_RELEASE_COMPLETE(received_msg)); + } break; default: S1AP_ERROR("Received unhandled message: %d:%s\n", ITTI_MSG_ID(received_msg), ITTI_MSG_NAME(received_msg)); diff --git a/openair-cn/S1AP/s1ap_eNB_encoder.c b/openair-cn/S1AP/s1ap_eNB_encoder.c index c8d4cc9618..821f791747 100644 --- a/openair-cn/S1AP/s1ap_eNB_encoder.c +++ b/openair-cn/S1AP/s1ap_eNB_encoder.c @@ -89,6 +89,13 @@ int s1ap_eNB_encode_nas_non_delivery( uint8_t **buffer, uint32_t *length); +static inline +int s1ap_eNB_encode_ue_context_release_complete( + S1ap_UEContextReleaseCompleteIEs_t *s1ap_UEContextReleaseCompleteIEs, + uint8_t **buffer, + uint32_t *length); + + int s1ap_eNB_encode_pdu(s1ap_message *message, uint8_t **buffer, uint32_t *len) { DevAssert(message != NULL); @@ -198,14 +205,34 @@ int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p, message_string = calloc(10000, sizeof(char)); s1ap_string_total_size = 0; + message_string_size = strlen(message_string); + switch(s1ap_message_p->procedureCode) { - case S1ap_ProcedureCode_id_InitialContextSetup: - ret = s1ap_eNB_encode_initial_context_setup_response( - &s1ap_message_p->msg.s1ap_InitialContextSetupResponseIEs, buffer, len); - s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, s1ap_message_p); - message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG; - break; + case S1ap_ProcedureCode_id_InitialContextSetup: + ret = s1ap_eNB_encode_initial_context_setup_response( + &s1ap_message_p->msg.s1ap_InitialContextSetupResponseIEs, buffer, len); + + s1ap_xer_print_s1ap_initialcontextsetupresponse(s1ap_xer__print2sp, message_string, s1ap_message_p); + message_id = S1AP_INITIAL_CONTEXT_SETUP_LOG; + message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.s1ap_initial_context_setup_log.size = message_string_size; + memcpy(&message_p->ittiMsg.s1ap_initial_context_setup_log.text, message_string, message_string_size); + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + free(message_string); + break; + + case S1ap_ProcedureCode_id_UEContextRelease: + ret = s1ap_eNB_encode_ue_context_release_complete( + &s1ap_message_p->msg.s1ap_UEContextReleaseCompleteIEs, buffer, len); + s1ap_xer_print_s1ap_uecontextreleasecomplete(s1ap_xer__print2sp, message_string, s1ap_message_p); + message_id = S1AP_UE_CONTEXT_RELEASE_COMPLETE_LOG; + message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText)); + message_p->ittiMsg.s1ap_ue_context_release_complete_log.size = message_string_size; + memcpy(&message_p->ittiMsg.s1ap_ue_context_release_complete_log.text, message_string, message_string_size); + itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); + free(message_string); + break; default: S1AP_DEBUG("Unknown procedure ID (%d) for successfull outcome message\n", @@ -214,15 +241,6 @@ int s1ap_eNB_encode_successfull_outcome(s1ap_message *s1ap_message_p, break; } - message_string_size = strlen(message_string); - - message_p = itti_alloc_new_message_sized(TASK_S1AP, message_id, message_string_size + sizeof (IttiMsgText)); - message_p->ittiMsg.s1ap_initial_context_setup_log.size = message_string_size; - memcpy(&message_p->ittiMsg.s1ap_initial_context_setup_log.text, message_string, message_string_size); - - itti_send_msg_to_task(TASK_UNKNOWN, INSTANCE_DEFAULT, message_p); - - free(message_string); return ret; } @@ -445,3 +463,31 @@ int s1ap_eNB_encode_initial_context_setup_response( &asn_DEF_S1ap_InitialContextSetupResponse, initial_context_setup_response_p); } + +static inline +int s1ap_eNB_encode_ue_context_release_complete( + S1ap_UEContextReleaseCompleteIEs_t *s1ap_UEContextReleaseCompleteIEs, + uint8_t **buffer, + uint32_t *length) +{ + S1ap_UEContextReleaseComplete_t ue_context_release_complete; + S1ap_UEContextReleaseComplete_t *ue_context_release_complete_p = + &ue_context_release_complete; + + memset((void *)ue_context_release_complete_p, 0, + sizeof(ue_context_release_complete)); + + if (s1ap_encode_s1ap_uecontextreleasecompleteies( + ue_context_release_complete_p, s1ap_UEContextReleaseCompleteIEs) < 0) + { + return -1; + } + + return s1ap_generate_successfull_outcome(buffer, + length, + S1ap_ProcedureCode_id_UEContextRelease, + S1ap_Criticality_reject, + &asn_DEF_S1ap_UEContextReleaseComplete, + ue_context_release_complete_p); +} + diff --git a/openair-cn/S1AP/s1ap_eNB_itti_messaging.c b/openair-cn/S1AP/s1ap_eNB_itti_messaging.c index 8cb4e98f54..2eb9011e94 100644 --- a/openair-cn/S1AP/s1ap_eNB_itti_messaging.c +++ b/openair-cn/S1AP/s1ap_eNB_itti_messaging.c @@ -40,3 +40,16 @@ void s1ap_eNB_itti_send_nas_downlink_ind(instance_t instance, itti_send_msg_to_task(TASK_RRC_ENB, instance, message_p); } + +void s1ap_eNB_itti_send_sctp_close_association(instance_t instance, int32_t assoc_id) +{ + MessageDef *message_p = NULL; + sctp_close_association_t *sctp_close_association_p = NULL; + + message_p = itti_alloc_new_message(TASK_S1AP, SCTP_CLOSE_ASSOCIATION); + sctp_close_association_p = &message_p->ittiMsg.sctp_close_association; + sctp_close_association_p->assoc_id = assoc_id; + + itti_send_msg_to_task(TASK_SCTP, instance, message_p); +} + diff --git a/openair-cn/S1AP/s1ap_eNB_itti_messaging.h b/openair-cn/S1AP/s1ap_eNB_itti_messaging.h index 2d9ac3ce0e..8a16d7aad2 100644 --- a/openair-cn/S1AP/s1ap_eNB_itti_messaging.h +++ b/openair-cn/S1AP/s1ap_eNB_itti_messaging.h @@ -38,4 +38,8 @@ void s1ap_eNB_itti_send_nas_downlink_ind(instance_t instance, uint8_t *nas_pdu, uint32_t nas_pdu_length); +void s1ap_eNB_itti_send_sctp_close_association(instance_t instance, + int32_t assoc_id); + + #endif /* S1AP_ENB_ITTI_MESSAGING_H_ */ diff --git a/openair-cn/S1AP/s1ap_eNB_nas_procedures.c b/openair-cn/S1AP/s1ap_eNB_nas_procedures.c index 608addc19a..49a9bf0109 100644 --- a/openair-cn/S1AP/s1ap_eNB_nas_procedures.c +++ b/openair-cn/S1AP/s1ap_eNB_nas_procedures.c @@ -572,3 +572,75 @@ int s1ap_eNB_ue_capabilities(instance_t instance, return ret; } + +int s1ap_ue_context_release_complete(instance_t instance, + s1ap_ue_release_complete_t *ue_release_complete_p) +{ + s1ap_eNB_instance_t *s1ap_eNB_instance_p = NULL; + struct s1ap_eNB_ue_context_s *ue_context_p = NULL; + + S1ap_UEContextReleaseCompleteIEs_t *ue_ctxt_release_complete_ies_p = NULL; + + s1ap_message message; + + uint8_t *buffer; + uint32_t length; + int ret = -1; + + /* Retrieve the S1AP eNB instance associated with Mod_id */ + s1ap_eNB_instance_p = s1ap_eNB_get_instance(instance); + + DevAssert(ue_release_complete_p != NULL); + DevAssert(s1ap_eNB_instance_p != NULL); + + if ((ue_context_p = s1ap_eNB_get_ue_context(s1ap_eNB_instance_p, + ue_release_complete_p->eNB_ue_s1ap_id)) == NULL) + { + /* The context for this eNB ue s1ap id doesn't exist in the map of eNB UEs */ + S1AP_WARN("Failed to find ue context associated with eNB ue s1ap id: %u\n", + ue_release_complete_p->eNB_ue_s1ap_id); + return -1; + } + + /* Prepare the S1AP message to encode */ + memset(&message, 0, sizeof(s1ap_message)); + + message.direction = S1AP_PDU_PR_successfulOutcome; + message.procedureCode = S1ap_ProcedureCode_id_UEContextRelease; + //message.criticality = S1ap_Criticality_reject; + message.direction = S1AP_PDU_PR_successfulOutcome; + + ue_ctxt_release_complete_ies_p = &message.msg.s1ap_UEContextReleaseCompleteIEs; + + ue_ctxt_release_complete_ies_p->eNB_UE_S1AP_ID = ue_release_complete_p->eNB_ue_s1ap_id; + ue_ctxt_release_complete_ies_p->mme_ue_s1ap_id = ue_context_p->mme_ue_s1ap_id; + //ue_ctxt_release_complete_ies_p->criticalityDiagnostics + //ue_ctxt_release_complete_ies_p->presenceMask + + if (s1ap_eNB_encode_pdu(&message, &buffer, &length) < 0) { + /* Encode procedure has failed... */ + S1AP_ERROR("Failed to encode UE context release complete\n"); + return -1; + } + + /* UE associated signalling -> use the allocated stream */ + s1ap_eNB_itti_send_sctp_data_req(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id, buffer, + length, ue_context_p->stream); + + + s1ap_eNB_itti_send_sctp_close_association(s1ap_eNB_instance_p->instance, + ue_context_p->mme_ref->assoc_id); + + + + // release UE context + struct s1ap_eNB_ue_context_s *ue_context2_p = NULL; + if ((ue_context2_p = RB_REMOVE(s1ap_ue_map, &s1ap_eNB_instance_p->s1ap_ue_head, ue_context_p)) + == NULL) + { + s1ap_eNB_free_ue_context(ue_context2_p); + } + return ret; +} + diff --git a/openair-cn/S1AP/s1ap_eNB_nas_procedures.h b/openair-cn/S1AP/s1ap_eNB_nas_procedures.h index 2e68cf2e12..04d31b0f2a 100644 --- a/openair-cn/S1AP/s1ap_eNB_nas_procedures.h +++ b/openair-cn/S1AP/s1ap_eNB_nas_procedures.h @@ -49,4 +49,8 @@ int s1ap_eNB_initial_ctxt_resp( int s1ap_eNB_ue_capabilities(instance_t instance, s1ap_ue_cap_info_ind_t *ue_cap_info_ind_p); +int s1ap_ue_context_release_complete(instance_t instance, + s1ap_ue_release_complete_t *ue_release_complete_p); + + #endif /* S1AP_ENB_NAS_PROCEDURES_H_ */ diff --git a/openair-cn/S1AP/s1ap_eNB_ue_context.h b/openair-cn/S1AP/s1ap_eNB_ue_context.h index 51dcb4d897..8e4906d05e 100644 --- a/openair-cn/S1AP/s1ap_eNB_ue_context.h +++ b/openair-cn/S1AP/s1ap_eNB_ue_context.h @@ -91,4 +91,7 @@ struct s1ap_eNB_ue_context_s *s1ap_eNB_get_ue_context( s1ap_eNB_instance_t *instance_p, uint32_t eNB_ue_s1ap_id); +void s1ap_eNB_free_ue_context(struct s1ap_eNB_ue_context_s *ue_context_p); + + #endif /* S1AP_ENB_UE_CONTEXT_H_ */ -- GitLab