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