Add supoprt for D release use-case.
[sim/o1-interface.git] / ntsimulator / ntsim-ng / features / ves_heartbeat / ves_heartbeat.c
index 4bfc075..74f7f62 100644 (file)
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <unistd.h>
 #include <pthread.h>
+#include <signal.h>
 
 #include "core/session.h"
 #include "core/framework.h"
@@ -50,41 +51,74 @@ static void *ves_heartbeat_thread_routine(void *arg);
 static cJSON* ves_create_heartbeat_fields(int heartbeat_period);
 static int heartbeat_change_cb(sr_session_ctx_t *session, const char *module_name, const char *xpath, sr_event_t event, uint32_t request_id, void *private_data);
 
+static volatile sig_atomic_t ves_heartbeat_stopsig;
+static sr_subscription_ctx_t *ves_heartbeat_subscription = 0;
+
+int ves_heartbeat_feature_get_status(void) {
+    return (ves_heartbeat_subscription != 0);
+}
+
 int ves_heartbeat_feature_start(sr_session_ctx_t *current_session) {
     assert_session();
+    assert(current_session);
 
-    sr_val_t *value = 0;
-    if(pthread_mutex_init(&ves_heartbeat_lock, NULL) != 0) { 
-        log_error("mutex init has failed"); 
-        return NTS_ERR_FAILED; 
-    }
+    if(ves_heartbeat_subscription == 0) {
+        sr_val_t *value = 0;
+        if(pthread_mutex_init(&ves_heartbeat_lock, NULL) != 0) { 
+            log_error("mutex init has failed\n");
+            return NTS_ERR_FAILED; 
+        }
 
-    ves_heartbeat_period = 0;
-    ves_sequence_number = 0;
+        ves_heartbeat_stopsig = 0;
+        ves_heartbeat_period = 0;
+        ves_sequence_number = 0;
 
-    int rc = sr_get_item(current_session, HEARTBEAT_SCHEMA_XPATH, 0, &value);
-    if(rc == SR_ERR_OK) {
-        ves_heartbeat_period_set(value->data.uint16_val);
-        sr_free_val(value);
-    }
-    else if(rc != SR_ERR_NOT_FOUND) {
-        log_error("sr_get_item failed");
-    }
+        int rc = sr_get_item(current_session, HEARTBEAT_SCHEMA_XPATH, 0, &value);
+        if(rc == SR_ERR_OK) {
+            ves_heartbeat_period_set(value->data.uint16_val);
+            sr_free_val(value);
+        }
+        else if(rc != SR_ERR_NOT_FOUND) {
+            log_error("sr_get_item failed\n");
+        }
 
-    rc = sr_module_change_subscribe(current_session, "nts-network-function", HEARTBEAT_SCHEMA_XPATH, heartbeat_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &session_subscription);
-    if(rc != SR_ERR_OK) {
-        log_error("could not subscribe to heartbeat");
-        return NTS_ERR_FAILED;
+        rc = sr_module_change_subscribe(current_session, "nts-network-function", HEARTBEAT_SCHEMA_XPATH, heartbeat_change_cb, NULL, 0, SR_SUBSCR_CTX_REUSE, &ves_heartbeat_subscription);
+        if(rc != SR_ERR_OK) {
+            log_error("could not subscribe to heartbeat\n");
+            return NTS_ERR_FAILED;
+        }
+
+        if(pthread_create(&ves_heartbeat_thread, 0, ves_heartbeat_thread_routine, 0)) {
+            log_error("could not create thread for heartbeat\n");
+            return NTS_ERR_FAILED;
+        }
     }
 
-    if(pthread_create(&ves_heartbeat_thread, 0, ves_heartbeat_thread_routine, 0)) {
-        log_error("could not create thread for heartbeat");
-        return NTS_ERR_FAILED;
+    return NTS_ERR_OK;
+}
+
+int ves_heartbeat_feature_stop(void) {
+    assert_session();
+
+    if(ves_heartbeat_subscription) {
+        int rc = sr_unsubscribe(ves_heartbeat_subscription);
+        if(rc != SR_ERR_OK) {
+            log_error("could not subscribe to heartbeat\n");
+            return NTS_ERR_FAILED;
+        }
+
+        void *status;
+        ves_heartbeat_stopsig = 1;
+        pthread_join(ves_heartbeat_thread, &status);
+        pthread_mutex_destroy(&ves_heartbeat_lock);
+
+        ves_heartbeat_subscription = 0;
     }
 
     return NTS_ERR_OK;
 }
 
+
 static int ves_heartbeat_period_get(void) {
     pthread_mutex_lock(&ves_heartbeat_lock);
     int ret = ves_heartbeat_period;
@@ -99,48 +133,48 @@ static void ves_heartbeat_period_set(int new_period) {
 }
 
 static int ves_heartbeat_send_ves_message(void) {
-    char *hostname_string = framework_environment.hostname;
+    char *hostname_string = framework_environment.settings.hostname;
     cJSON *post_data_json = cJSON_CreateObject();
     if(post_data_json == 0) {
-        log_error("cJSON_CreateObject failed");
+        log_error("cJSON_CreateObject failed\n");
         return NTS_ERR_FAILED;
     }
 
     cJSON *event = cJSON_CreateObject();
     if(event == 0) {
-        log_error("cJSON_CreateObject failed");
+        log_error("cJSON_CreateObject failed\n");
         cJSON_Delete(post_data_json);
         return NTS_ERR_FAILED;
     }
     
     if(cJSON_AddItemToObject(post_data_json, "event", event) == 0) {
-        log_error("cJOSN_AddItemToObject failed");
+        log_error("cJOSN_AddItemToObject failed\n");
         cJSON_Delete(post_data_json);
         return NTS_ERR_FAILED;
     }
 
     cJSON *common_event_header = ves_create_common_event_header("heartbeat", "Controller", hostname_string, "Low", ves_sequence_number++);
     if(common_event_header == 0) {
-        log_error("ves_create_common_event_header failed");
+        log_error("ves_create_common_event_header failed\n");
         cJSON_Delete(post_data_json);
         return NTS_ERR_FAILED;
     }
     
     if(cJSON_AddItemToObject(event, "commonEventHeader", common_event_header) == 0) {
-        log_error("cJOSN_AddItemToObject failed");
+        log_error("cJOSN_AddItemToObject failed\n");
         cJSON_Delete(post_data_json);
         return NTS_ERR_FAILED;
     }
 
     cJSON *heartbeat_fields = ves_create_heartbeat_fields(ves_heartbeat_period_get());
     if(heartbeat_fields == 0) {
-        log_error("ves_create_heartbeat_fields failed");
+        log_error("ves_create_heartbeat_fields failed\n");
         cJSON_Delete(post_data_json);
         return NTS_ERR_FAILED;
     }
     
     if(cJSON_AddItemToObject(event, "heartbeatFields", heartbeat_fields) == 0) {
-        log_error("cJOSN_AddItemToObject failed");
+        log_error("cJOSN_AddItemToObject failed\n");
         cJSON_Delete(post_data_json);
         return NTS_ERR_FAILED;
     }
@@ -148,13 +182,13 @@ static int ves_heartbeat_send_ves_message(void) {
     char *post_data = cJSON_PrintUnformatted(post_data_json);
     cJSON_Delete(post_data_json);
     if(post_data == 0) {
-        log_error("cJSON_PrintUnformatted failed");
+        log_error("cJSON_PrintUnformatted failed\n");
         return NTS_ERR_FAILED;
     }
 
     ves_details_t *ves_details = ves_endpoint_details_get(0);
     if(!ves_details) {
-        log_error("ves_endpoint_details_get failed");
+        log_error("ves_endpoint_details_get failed\n");
         free(post_data);
         return NTS_ERR_FAILED;
     }
@@ -164,7 +198,7 @@ static int ves_heartbeat_send_ves_message(void) {
     free(post_data);
     
     if(rc != NTS_ERR_OK) {
-        log_error("http_request failed");
+        log_error("http_request failed\n");
         return NTS_ERR_FAILED;
     }
 
@@ -175,7 +209,7 @@ static void *ves_heartbeat_thread_routine(void *arg) {
     int current_heartbeat_period = 0;
     unsigned int timer_counter = 0;
 
-    while(!framework_sigint) {
+    while((!framework_sigint) && (!ves_heartbeat_stopsig)) {
         current_heartbeat_period = ves_heartbeat_period_get();
         timer_counter++;
 
@@ -184,7 +218,7 @@ static void *ves_heartbeat_thread_routine(void *arg) {
 
             int rc = ves_heartbeat_send_ves_message();
             if(rc != NTS_ERR_FAILED) {
-                log_error("could not send VES heartbeat");
+                log_error("could not send VES heartbeat\n");
             }
         }
 
@@ -197,45 +231,45 @@ static void *ves_heartbeat_thread_routine(void *arg) {
 static cJSON* ves_create_heartbeat_fields(int heartbeat_period) {
     cJSON *heartbeat_fields = cJSON_CreateObject();
     if(heartbeat_fields == 0) {
-        log_error("could not create JSON object");
+        log_error("could not create JSON object\n");
         return 0;
     }
 
     if(cJSON_AddStringToObject(heartbeat_fields, "heartbeatFieldsVersion", "3.0") == 0) {
-        log_error("cJSON_Add*ToObject failed");
+        log_error("cJSON_Add*ToObject failed\n");
         cJSON_Delete(heartbeat_fields);
         return 0;
     }
 
     if(cJSON_AddNumberToObject(heartbeat_fields, "heartbeatInterval", (double)(heartbeat_period)) == 0) {
-        log_error("cJSON_Add*ToObject failed");
+        log_error("cJSON_Add*ToObject failed\n");
         cJSON_Delete(heartbeat_fields);
         return 0;
     }
 
     cJSON *additional_fields = cJSON_CreateObject();
     if(additional_fields == 0) {
-        log_error("could not create JSON object");
-        log_error("cJSON_Add*ToObject failed");
+        log_error("could not create JSON object\n");
+        log_error("cJSON_Add*ToObject failed\n");
         cJSON_Delete(heartbeat_fields);
         return 0;
     }
     
     if(cJSON_AddItemToObject(heartbeat_fields, "additionalFields", additional_fields) == 0) {
-        log_error("cJSON_Add*ToObject failed");
+        log_error("cJSON_Add*ToObject failed\n");
         cJSON_Delete(heartbeat_fields);
         return 0;
     }
 
     char *current_date_and_time = get_current_date_and_time();
     if(current_date_and_time == 0) {
-        log_error("get_current_date_and_time failed");
+        log_error("get_current_date_and_time failed\n");
         cJSON_Delete(heartbeat_fields);
         return 0;
     }
 
     if(cJSON_AddStringToObject(additional_fields, "eventTime", current_date_and_time) == 0) {
-        log_error("cJSON_Add*ToObject failed");
+        log_error("cJSON_Add*ToObject failed\n");
         cJSON_Delete(heartbeat_fields);
         free(current_date_and_time);
         return 0;
@@ -255,7 +289,7 @@ static int heartbeat_change_cb(sr_session_ctx_t *session, const char *module_nam
     if(event == SR_EV_DONE) {
         rc = sr_get_changes_iter(session, HEARTBEAT_SCHEMA_XPATH, &it);
         if(rc != SR_ERR_OK) {
-            log_error("sr_get_changes_iter failed");
+            log_error("sr_get_changes_iter failed\n");
             return SR_ERR_VALIDATION_FAILED;
         }