diff --git a/src/cfg.c b/src/cfg.c index 9bb05bb2d..06dec81e6 100644 --- a/src/cfg.c +++ b/src/cfg.c @@ -5,62 +5,169 @@ * @copyright 2014, Institute for Automation of Complex Power Systems, EONERC */ +#include +#include +#include #include -#include "config.h" +#include "cfg.h" #include "utils.h" -int config_parse(config_t *cfg, const char *filename, struct path *paths, struct node *nodes) +int config_parse(config_t *cfg, struct config *g) { - if (!config_read_file(cfg, filename)) { - logger(ERROR, "Failed to parse configuration: %s in %s:%d", - config_error_text(cfg), config_error_file(cfg), config_error_line(cfg)); - exit(EXIT_FAILURE); + config_setting_t *cfg_nodes, *cfg_paths, *cfg_root; + + if (!config_read_file(cfg, g->filename)) { + error("Failed to parse configuration: %s in %s:%d", + config_error_text(cfg), + config_error_file(cfg), + config_error_line(cfg) + ); } - config_setting_t *cfg_root = config_root_setting(cfg); + cfg_root = config_root_setting(cfg); - // read global settings - int debug; - if (config_setting_lookup_int(cfg_root, "debug", &debug)) - logger(DEBUG, "Setting debug level to %u", debug); + /* Read global settings */ + config_parse_global(cfg_root, g); - // read nodes - config_setting_t *cfg_nodes = config_setting_get_member(cfg_root, "nodes"); - if (cfg_nodes) { - for (int i=0; i < config_setting_length(cfg_nodes); i++) { - config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i); - config_parse_node(cfg_node, nodes); + /* Allocate memory for paths and nodes */ + cfg_nodes = config_setting_get_member(cfg_root, "nodes"); + if (!cfg_nodes || !config_setting_is_group(cfg_nodes)) + error("Missing node section in config"); + + cfg_paths = config_setting_get_member(cfg_root, "paths"); + if (!cfg_paths || !config_setting_is_list(cfg_paths)) + error("Missing path section in config"); + + int node_count = config_setting_length(cfg_nodes); + int path_count = config_setting_length(cfg_paths); + + g->nodes = malloc(node_count * sizeof(struct node)); + if (!g->nodes) + error("Failed to allocate memory for nodes"); + + g->paths = malloc(path_count * sizeof(struct path)); + if (!g->paths) + error("Failed to allocate memory for paths"); + + + /* Parse nodes */ + for (int i=0; i < node_count; i++) { + config_parse_node(config_setting_get_elem(cfg_nodes, i), g); + } + + /* Parse paths */ + for (int i=0; i < path_count; i++) { + config_parse_path(config_setting_get_elem(cfg_paths, i), g); + } + + return CONFIG_TRUE; +} + +int config_parse_global(config_setting_t *c, struct config *g) +{ + if (!config_setting_lookup_string(c, "name", &g->name)) + cerror(c, "Missing node name"); + + config_setting_lookup_int(c, "debug", &g->debug); + config_setting_lookup_int(c, "affinity", &g->affinity); + config_setting_lookup_int(c, "nice", &g->nice); + config_setting_lookup_int(c, "protocol", &g->protocol); + + return CONFIG_TRUE; +} + +int config_parse_path(config_setting_t *c, struct config *g) +{ + struct node *in, *out; + const char *in_str = NULL; + const char *out_str = NULL; + int enabled = 1; + int reverse = 0; + + /* Optional settings */ + config_setting_lookup_bool(c, "enabled", &enabled); + config_setting_lookup_bool(c, "reverse", &reverse); + + /* Required settings */ + if (!config_setting_lookup_string(c, "in", &in_str)) + cerror(c, "Missing input node for path"); + + if (!config_setting_lookup_string(c, "out", &out_str)) + cerror(c, "Missing output node for path"); + + if (!config_setting_lookup_int) + + info("Loading path from '%s' to '%s'", in_str, out_str); + + in = node_lookup_name(in_str, g->nodes, g->node_count); + if (!in) + cerror(c, "Invalid input node '%s'"); + + out = node_lookup_name(out_str, g->nodes, g->node_count); + if (!out) + cerror(c, "Invalid output node '%s'", out_str); + + if (enabled) { + if (path_create(&g->paths[g->path_count], in, out)) + cerror(c, "Failed to parse path"); + + g->path_count++; + + if (reverse) { + if (path_create(&g->paths[g->path_count], out, in)) + cerror(c, "Failed to parse path"); + + g->path_count++; } } - - // read paths - config_setting_t *cfg_paths = config_setting_get_member(cfg_root, "paths"); - if (cfg_paths) { - for (int i=0; i < config_setting_length(cfg_paths); i++) { - for (int i=0; i < config_setting_length(cfg_paths); i++) { - config_setting_t *cfg_path = config_setting_get_elem(cfg_paths, i); - config_parse_path(cfg_path, &paths[i]); - } - } - } - - return CONFIG_TRUE; + else + warn(" Path is not enabled"); } -int config_parse_path(config_setting_t *c, struct path *p) +int config_parse_node(config_setting_t *c, struct config *g) { + const char *name = NULL; + const char *type_str = NULL; + const char *remote_str = NULL; + const char *local_str = NULL; - return CONFIG_TRUE; -} - -int config_parse_node(config_setting_t *c, struct node *n) -{ - config_setting_lookup_string(c, "name", (const char **) &n->name); - - - logger(DEBUG, "Found node: %s", n->name); - - return CONFIG_TRUE; + struct sockaddr_in local; + struct sockaddr_in remote; + enum node_type type; + + /* Optional settings */ + + /* Required settings */ + name = config_setting_name(c); + if (!name) + cerror(c, "Missing node name"); + + if (!config_setting_lookup_string(c, "type", &type_str)) + cerror(c, "Missing node type"); + + if (!config_setting_lookup_string(c, "remote", &remote_str)) + cerror(c, "Missing node remote address"); + + if (!config_setting_lookup_string(c, "local", &local_str)) + cerror(c, "Missing node local address"); + + type = node_lookup_type(type_str); + if (type == NODE_INVALID) + cerror(c, "Invalid node type '%s'", type); + + + info("Loading %s node '%s'", type_str, name); + + if (resolve(local_str, &local, 0)) + cerror(c, "Failed to resolve local address '%s' of node '%s'", local_str, name); + + if (resolve(remote_str, &remote, 0)) + cerror(c, "Failed to resolve remote address '%s' of node '%s'", remote_str, name); + + if (node_create(&g->nodes[g->node_count], name, type, local, remote)) + cerror(c, "Failed to parse node"); + + g->node_count++; } diff --git a/src/server.c b/src/server.c index 2e1d589b6..23b01b9bd 100644 --- a/src/server.c +++ b/src/server.c @@ -12,51 +12,35 @@ #include #include +#include "config.h" +#include "cfg.h" #include "msg.h" #include "utils.h" -#include "config.h" #include "path.h" #include "node.h" -static struct node *nodes[MAX_NODES] = { NULL }; -static struct path *paths[MAX_PATHS] = { NULL }; - -int dumper(struct msg *m) -{ - msg_fprint(stdout, m); -} - -/** - * Do your configuration here - */ -void init() -{ - nodes[0] = node_create("test", SERVER, "*:10201", "localhost:10200"); - //nodes[1] = node_create("sintef", SERVER, "localhost", 10201); - - paths[0] = path_create(nodes[0], nodes[0]); - - path_start(paths[0]); - paths[0]->hooks[0] = dumper; - - //paths[1] = path_create(nodes[1], &nodes[0], 1); - - //for (int i = 0; i < MAX_PATHS && paths[i]; i++) { - // path_start(paths[i]); - //} -} +/// Global settings +struct config config; void quit() { - for (int i = 0; i < MAX_PATHS && paths[i]; i++) { - path_stop(paths[i]); - path_destroy(paths[i]); + for (int i = 0; i < config.path_count; i++) { + struct path *p = &config.paths[i]; + + path_stop(p); + + + path_destroy(p); } - for (int i = 0; i < MAX_NODES && nodes[i]; i++) - node_destroy(nodes[i]); + for (int i = 0; i < config.node_count; i++) { + node_destroy(&config.nodes[i]); + } + + free(config.paths); + free(config.nodes); + config_destroy(&config.obj); - debug(1, "Goodbye!"); _exit(EXIT_SUCCESS); } @@ -64,23 +48,40 @@ int main(int argc, char *argv[]) { atexit(&quit); - if (argc != 1) { - printf("Usage: %s [config]\n", argv[0]); - printf(" config is an optional path to a configuration file\n\n"); + if (argc != 2) { + printf("Usage: %s CONFIG\n", argv[0]); + printf(" CONFIG is a required path to a configuration file\n\n"); printf("Simulator2Simulator Server %s (%s %s)\n", VERSION, __DATE__, __TIME__); printf(" Copyright 2014, Institute for Automation of Complex Power Systems, EONERC\n"); printf(" Steffen Vogel \n\n"); exit(EXIT_FAILURE); } - debug(1, "Good morning! This is s2ss %s", VERSION); + info("This is s2ss %s", VERSION); - init(); /* Setup paths and nodes manually */ + // Default settings + config.filename = argv[1]; + config.debug = 0; + config.nice = 0; + config.affinity = 0xC0; + config.protocol = 0; + + config_init(&config.obj); + config_parse(&config.obj, &config); + + if (config.path_count) + info("Parsed %u nodes and %u paths", config.node_count, config.path_count); + else + error("No paths found. Terminating..."); + + for (int i = 0; i < config.path_count; i++) { + path_start(&config.paths[i]); + } signal(SIGINT, quit); pause(); - info("Good night!"); + quit(); return 0; }