From e8630ed685766cf043d3d74543a1900c8fae0fc6 Mon Sep 17 00:00:00 2001
From: winckel <winckel@eurecom.fr>
Date: Thu, 5 Dec 2013 13:15:05 +0000
Subject: [PATCH] Modified handling of MME shutdown in S1AP to avoid stopping
 eNB. !!! No recovering mechanism for this situation !!!

git-svn-id: http://svn.eurecom.fr/openair4G/trunk@4609 818b1a75-f10b-46b9-bf7c-635c3b92a50f
---
 openair-cn/S1AP/s1ap_eNB.c          |  2 +-
 openair-cn/S1AP/s1ap_eNB_handlers.c | 58 +++++++++++++++++++++--------
 openair-cn/S1AP/s1ap_eNB_handlers.h |  2 +-
 openair2/ENB_APP/enb_app.c          |  7 ++++
 4 files changed, 51 insertions(+), 18 deletions(-)

diff --git a/openair-cn/S1AP/s1ap_eNB.c b/openair-cn/S1AP/s1ap_eNB.c
index 6a74c6e24db..5ff4624e715 100644
--- a/openair-cn/S1AP/s1ap_eNB.c
+++ b/openair-cn/S1AP/s1ap_eNB.c
@@ -208,7 +208,7 @@ void s1ap_eNB_handle_sctp_association_resp(instance_t instance, sctp_new_associa
                   instance,
                   sctp_new_association_resp->ulp_cnx_id);
 
-        s1ap_handle_s1_setup_message(s1ap_mme_data_p);
+        s1ap_handle_s1_setup_message(s1ap_mme_data_p, sctp_new_association_resp->sctp_state == SCTP_STATE_SHUTDOWN);
 
         return;
     }
diff --git a/openair-cn/S1AP/s1ap_eNB_handlers.c b/openair-cn/S1AP/s1ap_eNB_handlers.c
index c24cb96cc52..72f7e88d1b2 100644
--- a/openair-cn/S1AP/s1ap_eNB_handlers.c
+++ b/openair-cn/S1AP/s1ap_eNB_handlers.c
@@ -133,21 +133,47 @@ static const char *direction2String[] = {
     "UnSuccessfull outcome", /* successfull outcome */
 };
 
-void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p) {
-    /* Check that at least one setup message is pending */
-    DevCheck(mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0, mme_desc_p->s1ap_eNB_instance->instance,
-             mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb, 0);
-    /* Decrease pending messages number */
-    mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --;
-
-    /* If there are no more pending messages, inform eNB app */
-    if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0)
-    {
-      MessageDef                 *message_p;
+void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown) {
+    if (sctp_shutdown) {
+        /* A previously connected MME has been shutdown */
+
+        /* TODO check if it was used by some eNB and send a message to inform these eNB if there is no more associated MME */
+        if (mme_desc_p->state == S1AP_ENB_STATE_CONNECTED)
+        {
+            mme_desc_p->state = S1AP_ENB_STATE_DISCONNECTED;
+
+            if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb > 0) {
+                /* Decrease associated MME number */
+                mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb --;
+            }
+
+            /* If there are no more associated MME, inform eNB app */
+            if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb == 0) {
+              MessageDef                 *message_p;
 
-      message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF);
-      S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb;
-      itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
+              message_p = itti_alloc_new_message(TASK_S1AP, S1AP_DEREGISTERED_ENB_IND);
+              S1AP_DEREGISTERED_ENB_IND(message_p).nb_mme = 0;
+              itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
+            }
+        }
+    } else {
+        /* Check that at least one setup message is pending */
+        DevCheck(mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0, mme_desc_p->s1ap_eNB_instance->instance,
+                 mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb, 0);
+
+        if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb > 0) {
+            /* Decrease pending messages number */
+            mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb --;
+        }
+
+        /* If there are no more pending messages, inform eNB app */
+        if (mme_desc_p->s1ap_eNB_instance->s1ap_mme_pending_nb == 0) {
+          MessageDef                 *message_p;
+
+          message_p = itti_alloc_new_message(TASK_S1AP, S1AP_REGISTER_ENB_CNF);
+          S1AP_REGISTER_ENB_CNF(message_p).nb_mme = mme_desc_p->s1ap_eNB_instance->s1ap_mme_associated_nb;
+          itti_send_msg_to_task(TASK_ENB_APP, mme_desc_p->s1ap_eNB_instance->instance, message_p);
+        }
     }
 }
 
@@ -209,7 +235,7 @@ int s1ap_eNB_handle_s1_setup_failure(uint32_t               assoc_id,
     S1AP_ERROR("Received s1 setup failure for MME... please check your parameters\n");
 
     mme_desc_p->state = S1AP_ENB_STATE_WAITING;
-    s1ap_handle_s1_setup_message(mme_desc_p);
+    s1ap_handle_s1_setup_message(mme_desc_p, 0);
 
     return 0;
 }
@@ -310,7 +336,7 @@ 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);
+    s1ap_handle_s1_setup_message(mme_desc_p, 0);
 
 #if 0
     /* We call back our self
diff --git a/openair-cn/S1AP/s1ap_eNB_handlers.h b/openair-cn/S1AP/s1ap_eNB_handlers.h
index c708517b73a..06a15213d10 100644
--- a/openair-cn/S1AP/s1ap_eNB_handlers.h
+++ b/openair-cn/S1AP/s1ap_eNB_handlers.h
@@ -31,7 +31,7 @@
 #ifndef S1AP_ENB_HANDLERS_H_
 #define S1AP_ENB_HANDLERS_H_
 
-void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p);
+void s1ap_handle_s1_setup_message(s1ap_eNB_mme_data_t *mme_desc_p, int sctp_shutdown);
 
 int s1ap_eNB_handle_message(uint32_t assoc_id, int32_t stream,
                             const uint8_t * const data, const uint32_t data_length);
diff --git a/openair2/ENB_APP/enb_app.c b/openair2/ENB_APP/enb_app.c
index 89102b7b25f..09b8b48fa80 100644
--- a/openair2/ENB_APP/enb_app.c
+++ b/openair2/ENB_APP/enb_app.c
@@ -226,6 +226,13 @@ void *eNB_app_task(void *args_p)
                 }
                 break;
 
+            case S1AP_DEREGISTERED_ENB_IND:
+                LOG_W(ENB_APP, "[eNB %d] Received %s: associated MME %d\n", instance, msg_name,
+                      S1AP_DEREGISTERED_ENB_IND(msg_p).nb_mme);
+
+                /* TODO handle recovering of registration */
+                break;
+
             case TIMER_HAS_EXPIRED:
                 LOG_I(ENB_APP, " Received %s: timer_id %d\n", msg_name, TIMER_HAS_EXPIRED(msg_p).timer_id);
 
-- 
GitLab