X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?a=blobdiff_plain;f=ntsimulator%2Fntsim-ng%2Fcore%2Fcontext.c;fp=ntsimulator%2Fntsim-ng%2Fcore%2Fcontext.c;h=9bc57f24a1b6250229e6ebd0f04d297efeeeeea3;hb=f1d5c9198acde7a7ce296490087cad37e008f688;hp=0000000000000000000000000000000000000000;hpb=f2d8f1002fa93848c80a88e5658db4816cba3020;p=sim%2Fo1-interface.git diff --git a/ntsimulator/ntsim-ng/core/context.c b/ntsimulator/ntsim-ng/core/context.c new file mode 100644 index 0000000..9bc57f2 --- /dev/null +++ b/ntsimulator/ntsim-ng/core/context.c @@ -0,0 +1,370 @@ +/************************************************************************* +* +* Copyright 2020 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 "context.h" +#include "utils/log_utils.h" +#include "utils/sys_utils.h" +#include +#include "core/session.h" +#include +#include +#include + +//private variables for context state +struct lys_ident_with_childcount { + struct lys_ident *ident; + int children; +}; +static struct lys_ident_with_childcount *identities; +static int identities_size; //number of found identities + +struct features_with_info { + char *name; + bool enabled; +}; +static struct features_with_info *features; +static int features_size; + + +//private functions +static bool check_identity_of_type(const struct lys_ident *ident, const struct lys_ident *type); +static int identity_get_id(const struct lys_ident *ident); + +int context_init(const struct ly_ctx *ly_ctx) { + log_message(2, "context_init() begin\n"); + + identities = 0; + identities_size = 0; + + features = 0; + features_size = 0; + + log_message(2, "loading modules\n"); + uint32_t idx = 0; + struct lys_module *module; + while((module = (struct lys_module *)ly_ctx_get_module_iter(ly_ctx, &idx)) != 0) { + log_message(2, "MODULE %s\n", module->name); + log_message(2, " prefix: %s\n", module->prefix); + log_message(2, " namespace: %s\n", module->ns); + log_message(2, " imports [%d]", module->imp_size); + if(module->imp_size) { + log_message(2, ": "); + for(int i = 0; i < module->imp_size; i++) { + log_message(2, "%s(%s), ", module->imp[i].module->name, module->imp[i].module->prefix); + } + } + log_message(2, "\n"); + log_message(2, " implemented: %d\n", module->implemented); + + if(module->implemented) { + log_message(2, " IDENT count: %d\n", module->ident_size); + if(module->ident_size) { + //add to list of identities + identities = (struct lys_ident_with_childcount *)realloc(identities, sizeof(struct lys_ident_with_childcount) * (identities_size + module->ident_size)); + if(!identities) { + log_error("bad realloc"); + return 1; + } + + for(int i = 0; i < module->ident_size; i++) { + identities[identities_size].ident = &module->ident[i]; + identities[identities_size].children = 0; + identities_size++; + + if(module->ident[i].base_size) { + log_message(2, " IDENT[%d] %s with base %s:%s\n", i, module->ident[i].name, module->ident[i].base[0]->module->name, module->ident[i].base[0]->name); + int id = identity_get_id(module->ident[i].base[0]); + if(id != -1) { + identities[id].children++; + } + } + else { + log_message(2, " IDENT[%d] %s as base\n", i, module->ident[i].name); + } + } + } + + + log_message(2, " FEATURES count: %d\n", module->features_size); + if(module->features_size) { + //add to list of features + features = (struct features_with_info *)realloc(features, sizeof(struct features_with_info) * (features_size + module->features_size)); + if(!features) { + log_error("bad realloc"); + return 1; + } + + for(int i = 0; i < module->features_size; i++) { + asprintf(&features[features_size].name, "%s:%s", module->name, module->features[i].name); + features[features_size].enabled = (lys_features_state(module, module->features[i].name) == 1); + log_message(2, " FEATURE[%d] %s iffeature_size=%d enabled=%d\n", i, module->features[i].name, module->features[i].iffeature_size, features[features_size].enabled); + features_size++; + } + } + } + else { + log_message(2, "Module not implemented, skipping...\n"); + } + + log_message(2, " ----\n"); + } + + log_message(2, "context_init() finished\n"); + + return 0; +} + +void context_free(void) { + log_message(2, "context_free()... "); + free(identities); + identities_size = 0; + + for(int i = 0; i < features_size; i++) { + free(features[i].name); + } + free(features); + log_message(2, "done\n"); +} + +int context_get_identity_leafs_of_type(const struct lys_ident *ident, struct lys_ident ***found) { + + *found = (struct lys_ident **)malloc(sizeof(struct lys_ident *) * identities_size); + if(!*found) { + log_error("bad malloc"); + } + + int count = 0; + for(int i = 0; i < identities_size; i++) { + if(check_identity_of_type(identities[i].ident, ident)) { + if(identities[i].children == 0) { + (*found)[count] = identities[i].ident; + count++; + } + } + } + + if(count == 0) { + log_error("no identities found"); + } + else { + *found = (struct lys_ident **)realloc(*found, sizeof(struct lys_ident *) * count); + } + + return count; +} + +int context_get_features(char ***found_features) { + char **ftrs = (char **)malloc(sizeof(char *) * features_size); + if(!ftrs) { + log_error("could not alloc"); + return 0; + } + + for(int i = 0; i < features_size; i++) { + ftrs[i] = (char *)malloc(sizeof(char) * (strlen(features[i].name) + 1)); + if(!ftrs) { + log_error("could not alloc"); + return 0; + } + + strcpy(ftrs[i], features[i].name); + } + + *found_features = ftrs; + return features_size; +} + +bool context_get_feature_enabled(const char *feature) { + for(int i = 0; i < features_size; i++) { + if(strcmp(feature, features[i].name) == 0) { + return features[i].enabled; + } + } + return false; +} + +bool context_feature_enable(const char *feature) { + assert(feature); + + char mod[96]; + char feat[96]; + + mod[0] = 0; + feat[0] = 0; + + int i = 0; + int j = 0; + while((i < strlen(feature)) && (feature[i] != ':')) { + mod[j] = feature[i]; + j++; + i++; + } + mod[j] = 0; + + i++; + j = 0; + while(i < strlen(feature)) { + feat[j] = feature[i]; + j++; + i++; + } + feat[j] = 0; + + int rc; + if((rc = sr_enable_module_feature(session_connection, mod, feat)) != SR_ERR_OK) { + return false; + } + + return true; +} + +bool context_module_install(const char *name, const char *path) { + assert(name); + assert(path); + + char *searchpath = strdup(path); + int rc = sr_install_module(session_connection, path, dirname(searchpath), 0, 0); + free(searchpath); + if(rc != SR_ERR_OK) { + /* succeed if the module is already installed */ + if(rc != SR_ERR_EXISTS) { + return false; + } + } + + char *data_path = str_replace(path, ".yang", ".xml"); + if(file_exists(data_path)) { + rc = sr_install_module_data(session_connection, name, 0, data_path, LYD_XML); + if(rc != SR_ERR_OK) { + log_message(1, " xml error "); + sr_remove_module(session_connection, name); + context_apply_changes(); + return false; + } + } + free(data_path); + + //apply changes + if(!context_apply_changes()) { + sr_remove_module(session_connection, name); + context_apply_changes(); + return false; + } + + return true; +} + +bool context_module_set_access(const char *module_name) { + assert(module_name); + + if(sr_set_module_access(session_connection, module_name, "root", "root", 0666) != SR_ERR_OK) { + return false; + } + + return true; +} + +bool context_apply_changes(void) { + int rc; + uint32_t connection_count = 0; + + session_context = 0; + sr_disconnect(session_connection); + session_connection = 0; + + /* get connection count */ + if((rc = sr_connection_count(&connection_count)) != SR_ERR_OK) { + log_error("sr_connection_count() failed to get connection count"); + return false; + } + + if(connection_count) { + log_error("cannot apply changes because of existing connections"); + return false; + } + + if((rc = sr_connect(SR_CONN_ERR_ON_SCHED_FAIL, &session_connection)) != SR_ERR_OK) { + if((rc = sr_connect(0, &session_connection)) != SR_ERR_OK) { + log_error("failed to reconnect to sysrepo"); + } + return false; + } + + /* get context */ + session_context = (struct ly_ctx *)sr_get_context(session_connection); + if(session_context == 0) { + log_error("sr_get_context failed"); + return false; + } + + return true; +} + +bool context_yang_is_module(const char *path) { + assert(path); + + bool ret = false; + struct ly_ctx *ctx = ly_ctx_new(0, 0); + if(!ctx) { + log_error("ly_ctx_new failed"); + } + + char *searchpath = strdup(path); + ly_ctx_set_searchdir(ctx, dirname(searchpath)); + const struct lys_module *mod = lys_parse_path(ctx, path, LYS_YANG); + if((!mod) && (ly_vecode(ctx) == LYVE_SUBMODULE)) { + ret = true; + } + + free(searchpath); + ly_ctx_destroy(ctx, 0); + return ret; +} + + +static bool check_identity_of_type(const struct lys_ident *ident, const struct lys_ident *type) { + assert(type); + + if((ident->name == type->name) && (ident->module->name == type->module->name)) { + return true; + } + else if(ident->base_size != 0) { + bool result = false; + for(int i = 0; i < ident->base_size; i++) { + result |= check_identity_of_type(ident->base[i], type); + } + return result; + } + else { + return false; + } + +} + +static int identity_get_id(const struct lys_ident *ident) { + assert(ident); + + for(int i = 0; i < identities_size; i++) { + if((ident->name == identities[i].ident->name) && (ident->module->name == identities[i].ident->module->name)) { + return i; + } + } + + return -1; +}