/************************************************************************* * * 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 #include #include #include #include #include #include #include #include #include #include #include #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) { }