Monitoring Netconf connectivity feature
[sim/o1-interface.git] / ntsimulator / ntsim-ng / core / app / nf_oran_ru_supervision.c
diff --git a/ntsimulator/ntsim-ng/core/app/nf_oran_ru_supervision.c b/ntsimulator/ntsim-ng/core/app/nf_oran_ru_supervision.c
new file mode 100644 (file)
index 0000000..7d12fce
--- /dev/null
@@ -0,0 +1,159 @@
+/*************************************************************************
+*
+* Copyright 2021 highstreet technologies GmbH and others
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+***************************************************************************/
+
+#define _GNU_SOURCE
+
+#include "nf_oran_ru_supervision.h"
+#include "utils/log_utils.h"
+#include "utils/sys_utils.h"
+#include "utils/nts_utils.h"
+#include "utils/rand_utils.h"
+#include "utils/http_client.h"
+#include <stdio.h>
+#include <pthread.h>
+#include <assert.h>
+
+#include <sysrepo.h>
+#include <sysrepo/values.h>
+#include <libnetconf2/netconf.h>
+#include <libyang/libyang.h>
+#include <errno.h>
+#include <pthread.h>
+#include <signal.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#include "core/framework.h"
+#include "core/context.h"
+#include "core/session.h"
+#include "core/xpath.h"
+
+int notification_timer_seconds=60;
+int supervision_timer_seconds=10;
+
+static pthread_t o_ran_supervision_thread = NULL;
+static void *o_ran_supervision_thread_routine(void *arg);
+
+static int
+supervision_watchdog_reset_rpc_cb(sr_session_ctx_t *session, const char *path, const sr_val_t *input, const size_t input_cnt,
+        sr_event_t event, uint32_t request_id, sr_val_t **output, size_t *output_cnt, void *private_data)
+{
+    size_t i;
+
+    (void)session;
+    (void)event;
+    (void)request_id;
+    (void)private_data;
+
+    bool notification_default = true;
+    bool supervision_default = true;
+
+    for (i = 0; i < input_cnt; ++i) {
+        if (!strcmp(input[i].xpath, "/o-ran-supervision:supervision-watchdog-reset/supervision-notification-interval")) {
+            notification_timer_seconds = input[i].data.uint16_val;
+            notification_default = false;
+        }
+        else if (!strcmp(input[i].xpath, "/o-ran-supervision:supervision-watchdog-reset/guard-timer-overhead")) {
+            supervision_timer_seconds = input[i].data.uint16_val;
+            supervision_default = false;
+        }
+    }
+
+    if (notification_default) {
+        notification_timer_seconds = 60;
+    }
+    if (supervision_default) {
+        supervision_timer_seconds = 10;
+    }
+
+    if (!strcmp(path, "/o-ran-supervision:supervision-watchdog-reset")) {
+        *output = malloc(sizeof **output);
+        *output_cnt = 1;
+
+        (*output)[0].xpath = strdup("/o-ran-supervision:supervision-watchdog-reset/next-update-at");
+        (*output)[0].type = SR_STRING_T;
+        (*output)[0].dflt = 0;
+        (*output)[0].data.string_val = get_current_date_and_time_delay_seconds(notification_timer_seconds);
+    }
+
+    if (o_ran_supervision_thread != NULL) {
+        pthread_cancel(o_ran_supervision_thread);
+        o_ran_supervision_thread = NULL;
+    }
+
+    if(pthread_create(&o_ran_supervision_thread, 0, o_ran_supervision_thread_routine, 0)) {
+        log_error("could not create thread for o-ran-supervision\n");
+        return NTS_ERR_FAILED;
+    }
+
+    return NTS_ERR_OK;
+}
+
+int nf_oran_ru_supervision_init(void) {
+    int rc;
+
+    rc = sr_rpc_subscribe(session_running, O_RAN_SUPERVISION_WATCHDOG_RESET_RPC_SCHEMA_XPATH, supervision_watchdog_reset_rpc_cb, NULL, 0, 0, &session_subscription);
+    if (rc != SR_ERR_OK) {
+        log_add_verbose(1, "Subscribing for RPC \"%s\" failed.\n", O_RAN_SUPERVISION_WATCHDOG_RESET_RPC_SCHEMA_XPATH);
+        return NTS_ERR_FAILED;
+    }
+
+    if(pthread_create(&o_ran_supervision_thread, 0, o_ran_supervision_thread_routine, 0)) {
+        log_error("could not create thread for o-ran-supervision\n");
+        return NTS_ERR_FAILED;
+    }
+
+    return NTS_ERR_OK;
+}
+
+static void *o_ran_supervision_thread_routine(void *arg) {
+    int notification_counter = notification_timer_seconds;
+    int supervision_counter = notification_timer_seconds + supervision_timer_seconds;
+    int rc;
+
+    log_add_verbose(1, "Starting thread for o-ran-supervision...\n");
+
+    struct lyd_node *notif = NULL;
+    notif = lyd_new_path(NULL, session_context, O_RAN_SUPERVISION_NOTIFICATION_SCHEMA_XPATH, NULL, 0, 0);
+    if (!notif) {
+        log_error("Creating notification \"%s\" failed.\n", O_RAN_SUPERVISION_NOTIFICATION_SCHEMA_XPATH);
+        return NTS_ERR_FAILED;
+    }
+
+    while (supervision_counter > 0) {
+        sleep(1);
+        supervision_counter--;
+        notification_counter--;
+
+        if (notification_counter == 0) {
+            log_add_verbose(1, "Sending o-ran-supervision supervision-notification..\n");
+            rc = sr_event_notif_send_tree(session_running, notif);
+            if (rc != SR_ERR_OK) {
+                lyd_free(notif);
+                return NTS_ERR_FAILED;
+            }
+        }
+    }
+
+    log_add_verbose(1, "Failed to receive watchdog reset, terminating supervision timer for o-ran-supervision...\n");
+    pthread_exit((void *)1);
+}
+
+void nf_oran_ru_supervision_free(void) {
+
+}
+