diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 39df8bed..73ca170f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,19 +21,19 @@ jobs: - uses: actions/checkout@v3 - name: Install cmocka - run: sudo apt-get install -y --no-install-recommends libyaml-dev libcmocka-dev + run: sudo apt update; sudo apt-get install -y --no-install-recommends libyaml-dev libcmocka-dev - name: Build libbidib run: git clone --depth 1 https://github.com/uniba-swt/libbidib.git; cd libbidib; mkdir bin; cd bin; cmake ..; make -j; sudo make -j install - name: Install pam, gnutls - run: sudo apt-get install -y --no-install-recommends libpam0g-dev libgnutls28-dev + run: sudo apt update; sudo apt-get install -y --no-install-recommends libpam0g-dev libgnutls28-dev - name: Build libonion run: git clone --depth 1 https://github.com/uniba-swt/onion.git; cd onion; mkdir bin; cd bin; cmake -DONION_EXAMPLES=false -DONION_USE_TESTS=false ..; make -j onion; make -j onion_static; sudo make -j install - name: Install flex-dev, graphviz - run: sudo apt-get install -y libfl-dev graphviz + run: sudo apt update; sudo apt-get install -y libfl-dev graphviz - name: Install forecc run: git clone --depth 1 https://github.com/PRETgroup/ForeC.git; cd ForeC/ForeC\ Compiler; make -j; echo "FOREC_COMPILER_PATH=`pwd`" >> $GITHUB_ENV diff --git a/README.md b/README.md index 98bf742f..1da7c5ec 100644 --- a/README.md +++ b/README.md @@ -213,3 +213,29 @@ When is a grab-id reset? is not the same as the one at the server * If the user issues `swtbahn admin shutdown` and the system was running * If the user issues `swtbahn config` + +## Logging Format Notes +We try to use a consistent logging format in all request handlers. General workflow of how request handlers generate log messages: +1. Parse form data. +2. Validate form data. If validation fails, make a log on `ERROR` level and stop processing. +3. Make a log on log level `NOTICE` that represents the start of processing, with ` - start` at the end of the log. +4. Process request. If processing causes an error, make a log on the `ERROR` or `WARNING` log level with ` - abort` at the end of the log and stop processing. +5. Processing concluded. Indicate this by printing the log message of Step 3 again, on the same log level, with ` - finish` instead of ` - start` at the end. + +For request handlers that barely do any "processing" at all; e.g. where only a status variable is updated, they only generate one log message that ends with ` - done`. +Request handlers that only return information (getters) also use the ` - done` pattern instead of `start` and `finish`, and use the log level `INFO` for the ` - done` log. + +As an example, when a request is made to set point10 to the normal state, the request handler (`handler_set_point`) generates the following log messages when the processing is successful: +> LOG_NOTICE: `Request: Set point - point: point10 state: normal - start` +> _Intervening log messages from internal processing_ +> LOG_NOTICE: `Request: Set point - point: point10 state: normal - finish` + +If the above request was instead made with an unsupported state, e.g., `foobar`, then the request handler would generate the following log messages to say that the processing was stopped because of invalid parameters: + +> LOG_NOTICE: `Request: Set point - point: point10 state: foobar - start` +> _Intervening log messages from internal processing_ +> LOG_ERR: `Request: Set point - point: point10 state: foobar - invalid parameters - abort` + +If the above request forgot to specify the state, i.e., the state parameter is `null`, then the request handler would only generate the following log message to say that the parameter validation failed: + +> LOG_ERR: `Request: Set point - invalid parameters` \ No newline at end of file diff --git a/server/src/bahn_data_util.c b/server/src/bahn_data_util.c index c9da3ed2..d56e1057 100644 --- a/server/src/bahn_data_util.c +++ b/server/src/bahn_data_util.c @@ -563,13 +563,16 @@ bool config_set_scalar_string_value(const char *type, const char *id, const char t_interlocking_route *route = (t_interlocking_route *) obj; route->train = strdup(value); if (value != NULL && route->train == NULL) { - syslog_server(LOG_ERR, "config set scalar string value: unable to allocate memory for route->train"); + syslog_server(LOG_ERR, + "config set scalar string value: unable to allocate memory for route->train"); } result = true; } } - syslog_server(LOG_DEBUG, "Set scalar string: %s %s.%s = %s => %s", type, id, prop_name, value, result ? "true" : "false"); + syslog_server(LOG_DEBUG, + "Set scalar string: %s %s.%s = %s => %s", + type, id, prop_name, value, result ? "true" : "false"); return result; } diff --git a/server/src/dyn_containers_interface.c b/server/src/dyn_containers_interface.c index e56c3c74..cc07351a 100644 --- a/server/src/dyn_containers_interface.c +++ b/server/src/dyn_containers_interface.c @@ -146,11 +146,13 @@ static void *dyn_containers_actuate(void *_) { ? engine_instance->output_nominal_speed : -engine_instance->output_nominal_speed, grabbed_trains[i].track_output)) { - syslog_server(LOG_ERR, "Request: Set train speed - train: %s: bad parameter values", + syslog_server(LOG_ERR, + "Dyn containers actuate - train: %s - invalid parameters", grabbed_trains[i].name->str); } else { bidib_flush(); - syslog_server(LOG_NOTICE, "Request: Set train speed - train: %s speed: %d", + syslog_server(LOG_NOTICE, + "Dyn containers actuate - train: %s speed: %d - set train speed", grabbed_trains[i].name->str, engine_instance->output_nominal_forwards ? engine_instance->output_nominal_speed diff --git a/server/src/handler_admin.c b/server/src/handler_admin.c index e4f44a2d..2d73e078 100644 --- a/server/src/handler_admin.c +++ b/server/src/handler_admin.c @@ -25,19 +25,16 @@ * */ -#include #include #include -#include -#include #include +#include +#include "handler_admin.h" #include "server.h" -#include "param_verification.h" #include "handler_upload.h" #include "handler_driver.h" #include "handler_controller.h" -#include "interlocking.h" #include "dyn_containers_interface.h" #include "param_verification.h" #include "bahn_data_util.h" @@ -78,35 +75,35 @@ static void *poll_bidib_messages(void *_) { } // Must be called with start_stop_mutex already acquired -static bool start_bidib(void) { +static bool startup_server(void) { const int err_serial = bidib_start_serial(serial_device, config_directory, 0); if (err_serial) { - syslog_server(LOG_ERR, "Request: Start - Could not start BiDiB serial connection"); + syslog_server(LOG_ERR, "Startup server - Could not start BiDiB serial connection"); return false; } const int succ_clear_dir = clear_engine_dir() + clear_interlocker_dir(); if (!succ_clear_dir) { syslog_server(LOG_ERR, - "Request: Start - Could not clear the engine and interlocker directories"); + "Startup server - Could not clear the engine and interlocker directories"); return false; } const int succ_config = bahn_data_util_initialise_config(config_directory); if (!succ_config) { - syslog_server(LOG_ERR, "Request: Start - Could not initialise interlocking tables"); + syslog_server(LOG_ERR, "Startup server - Could not initialise interlocking tables"); return false; } const int err_dyn_containers = dyn_containers_start(); if (err_dyn_containers) { - syslog_server(LOG_ERR, "Request: Start - Could not start shared library containers"); + syslog_server(LOG_ERR, "Startup server - Could not start shared library containers"); return false; } const int err_interlocker = load_default_interlocker_instance(); if (err_interlocker) { - syslog_server(LOG_ERR, "Request: Start - Could not load default interlocker instance"); + syslog_server(LOG_ERR, "Startup server - Could not load default interlocker instance"); return false; } @@ -115,53 +112,68 @@ static bool start_bidib(void) { return true; } -void stop_bidib(void) { +void shutdown_server(void) { session_id = 0; - syslog_server(LOG_NOTICE, "Request: Stop"); + syslog_server(LOG_NOTICE, "Shutdown server"); release_all_grabbed_trains(); + syslog_server(LOG_INFO, "Shutdown server - Released all grabbed trains"); release_all_interlockers(); + syslog_server(LOG_INFO, "Shutdown server - Released all interlockers"); running = false; dyn_containers_stop(); + syslog_server(LOG_INFO, "Shutdown server - Stopped dyn containers"); bahn_data_util_free_config(); + syslog_server(LOG_INFO, "Shutdown server - Released interlocking config and table data"); pthread_join(poll_bidib_messages_thread, NULL); + syslog_server(LOG_NOTICE, + "Shutdown server - BiDiB message poll thread joined, now stopping BiDiB and closing log"); bidib_stop(); } -onion_connection_status handler_startup(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_startup(void *_, onion_request *req, onion_response *res) { build_response_header(res); int retval = OCS_NOT_IMPLEMENTED; pthread_mutex_lock(&start_stop_mutex); if (!running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { // Necessary when restarting the server because libbidib closes syslog on exit - openlog("swtbahn", 0, LOG_LOCAL0); + openlog("swtbahn", 0, LOG_LOCAL0); session_id = time(NULL); - syslog_server(LOG_NOTICE, "Request: Start, session id: %ld", session_id); + syslog_server(LOG_NOTICE, "Request: Startup server - session id: %ld - start", session_id); - if (start_bidib()) { + if (startup_server()) { retval = OCS_PROCESSED; + syslog_server(LOG_NOTICE, + "Request: Startup server - session id: %ld - finish", + session_id); + } else { + syslog_server(LOG_ERR, + "Request: Startup server - session id: %ld - unable to start BiDiB - abort", + session_id); } } else { - syslog_server(LOG_ERR, "Request: Start - BiDiB system is already running"); + syslog_server(LOG_ERR, + "Request: Startup server - BiDiB system is already running or wrong request type"); } pthread_mutex_unlock(&start_stop_mutex); return retval; } -onion_connection_status handler_shutdown(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_shutdown(void *_, onion_request *req, onion_response *res) { build_response_header(res); int retval = OCS_NOT_IMPLEMENTED; pthread_mutex_lock(&start_stop_mutex); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { - stop_bidib(); + syslog_server(LOG_NOTICE, "Request: Shutdown server - start"); + shutdown_server(); + // Can't log "finished" here since bidib closes the syslog when stopping retval = OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Stop - BiDiB system is not running"); + syslog_server(LOG_ERR, + "Request: Shutdown server - BiDiB system is not running or wrong request type"); retval = OCS_NOT_IMPLEMENTED; } pthread_mutex_unlock(&start_stop_mutex); @@ -169,21 +181,20 @@ onion_connection_status handler_shutdown(void *_, onion_request *req, return retval; } -onion_connection_status handler_set_track_output(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_set_track_output(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { char *end; const char *data_state = onion_request_get_post(req, "state"); long int state = strtol(data_state, &end, 10); - if (data_state == NULL || (state == LONG_MAX || state == LONG_MIN) || - *end != '\0') { + if (data_state == NULL || (state == LONG_MAX || state == LONG_MIN) || *end != '\0') { syslog_server(LOG_ERR, "Request: Set track output - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Set track output - state: 0x%02x", state); + syslog_server(LOG_NOTICE, "Request: Set track output - state: 0x%02x - start", state); bidib_set_track_output_state_all(state); bidib_flush(); + syslog_server(LOG_NOTICE, "Request: Set track output - state: 0x%02x - finish", state); return OCS_PROCESSED; } } else { @@ -198,12 +209,19 @@ onion_connection_status handler_set_verification_option(void *_, onion_request * build_response_header(res); if ((onion_request_get_flags(req) & OR_METHODS) == OR_POST) { const char *data_verification_option = onion_request_get_post(req, "verification-option"); - if (data_verification_option == NULL || !params_check_is_bool_string(data_verification_option)) { + if (!params_check_is_bool_string(data_verification_option)) { syslog_server(LOG_ERR, "Request: Set verification option - invalid parameters"); return OCS_NOT_IMPLEMENTED; } - verification_enabled = params_check_verification_option(data_verification_option); - syslog_server(LOG_NOTICE, "Request: Set verification option - state: %s", + if (strcmp("true", data_verification_option) == 0 + || strcmp("True", data_verification_option) == 0 + || strcmp("TRUE", data_verification_option) == 0) { + verification_enabled = true; + } else { + verification_enabled = false; + } + syslog_server(LOG_NOTICE, + "Request: Set verification option - new state: %s - done", verification_enabled ? "enabled" : "disabled"); return OCS_PROCESSED; } else { @@ -218,15 +236,16 @@ onion_connection_status handler_set_verification_url(void *_, onion_request *req if ((onion_request_get_flags(req) & OR_METHODS) == OR_POST) { const char *data_verification_url = onion_request_get_post(req, "verification-url"); if (data_verification_url == NULL) { - syslog_server(LOG_ERR, "Request: Set verification url - invalid parameters"); + syslog_server(LOG_ERR, "Request: Set verification URL - invalid parameters"); return OCS_NOT_IMPLEMENTED; } set_verifier_url(data_verification_url); - syslog_server(LOG_NOTICE, "Request: Set verification url - url: %s", + syslog_server(LOG_NOTICE, + "Request: Set verification URL - new URL: %s - done", data_verification_url); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Set verification url - wrong request type"); + syslog_server(LOG_ERR, "Request: Set verification URL - wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -234,48 +253,44 @@ onion_connection_status handler_set_verification_url(void *_, onion_request *req onion_connection_status handler_admin_release_train(void *_, onion_request *req, onion_response *res) { build_response_header(res); - if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { + if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_train = onion_request_get_post(req, "train"); const int grab_id = train_get_grab_id(data_train); pthread_mutex_lock(&grabbed_trains_mutex); if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Admin release train - invalid train id " - "or train not grabbed (%s)", + syslog_server(LOG_ERR, + "Request: Admin release train - invalid train id or train %s not grabbed", data_train); return OCS_NOT_IMPLEMENTED; } + syslog_server(LOG_NOTICE, "Request: Admin release train - train: %s - start", data_train); // Ensure that the train has stopped moving const int engine_instance = grabbed_trains[grab_id].dyn_containers_engine_instance; dyn_containers_set_train_engine_instance_inputs(engine_instance, 0, true); - char *train_id = strdup(grabbed_trains[grab_id].name->str); pthread_mutex_unlock(&grabbed_trains_mutex); - if (train_id == NULL) { - syslog_server(LOG_ERR, - "Request: Admin release train - failed to allocate memory for train_id"); - return OCS_NOT_IMPLEMENTED; - } - t_bidib_train_state_query train_state_query = bidib_get_train_state(train_id); + t_bidib_train_state_query train_state_query = bidib_get_train_state(data_train); while (train_state_query.data.set_speed_step != 0) { bidib_free_train_state_query(train_state_query); - ///TODO: Change to TRAIN_DRIVE_TIME_STEP like in handler_driver - usleep(10000); // 0.01 s (TRAIN_DRIVE_TIME_STEP) - train_state_query = bidib_get_train_state(train_id); + usleep(TRAIN_DRIVE_TIME_STEP); // 0.01 s + train_state_query = bidib_get_train_state(data_train); } bidib_free_train_state_query(train_state_query); if (!release_train(grab_id)) { - syslog_server(LOG_ERR, "Request: Admin release train %s - invalid grab id", train_id); - free(train_id); + syslog_server(LOG_ERR, + "Request: Admin release train - train: %s - invalid grab id - abort", + data_train); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Admin release train %s", train_id); - free(train_id); + syslog_server(LOG_NOTICE, + "Request: Admin release train - train: %s - finish", + data_train); return OCS_PROCESSED; } } else { @@ -293,21 +308,31 @@ onion_connection_status handler_admin_set_dcc_train_speed(void *_, onion_request const char *data_speed = onion_request_get_post(req, "speed"); const char *data_track_output = onion_request_get_post(req, "track-output"); int speed = params_check_speed(data_speed); + if (speed == 999) { - syslog_server(LOG_ERR, "Request: Admin set train speed - bad speed"); + syslog_server(LOG_ERR, + "Request: Admin set dcc train speed - train: %s speed: %d - invalid speed", + data_train, speed); return OCS_NOT_IMPLEMENTED; } else if (data_track_output == NULL) { - syslog_server(LOG_ERR, "Request: Admin set train speed - bad track output"); + syslog_server(LOG_ERR, + "Request: Admin set dcc train speed - train: %s speed: %d - invalid track output", + data_train, speed); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, + "Request: Admin set dcc train speed - train: %s speed: %d - start", + data_train, speed); pthread_mutex_lock(&grabbed_trains_mutex); if (bidib_set_train_speed(data_train, speed, data_track_output)) { syslog_server(LOG_ERR, - "Request: Admin set train speed - train: %s: bad parameter values", - data_train); + "Request: Admin set dcc train speed - train: %s speed: %d - " + "invalid parameters - abort", + data_train, speed); } else { bidib_flush(); - syslog_server(LOG_NOTICE, "Request: Admin set train speed - train: %s speed: %d", + syslog_server(LOG_NOTICE, + "Request: Admin set dcc train speed - train: %s speed: %d - finish", data_train, speed); } pthread_mutex_unlock(&grabbed_trains_mutex); @@ -315,7 +340,7 @@ onion_connection_status handler_admin_set_dcc_train_speed(void *_, onion_request } } else { syslog_server(LOG_ERR, - "Request: Admin set train speed - system not running or wrong request type"); + "Request: Admin set dcc train speed - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } diff --git a/server/src/handler_admin.h b/server/src/handler_admin.h index e35276f7..8209df52 100644 --- a/server/src/handler_admin.h +++ b/server/src/handler_admin.h @@ -30,9 +30,7 @@ #include -#include - -void stop_bidib(void); +void shutdown_server(void); onion_connection_status handler_startup(void *_, onion_request *req, onion_response *res); diff --git a/server/src/handler_controller.c b/server/src/handler_controller.c index c0af7857..89749b7f 100644 --- a/server/src/handler_controller.c +++ b/server/src/handler_controller.c @@ -23,16 +23,17 @@ * * - Nicolas Gross * - Tri Nguyen + * - Bernhard Luedtke * */ -#include -#include #include #include -#include #include +#include +#include +#include "handler_controller.h" #include "server.h" #include "dyn_containers_interface.h" #include "param_verification.h" @@ -60,10 +61,9 @@ const int set_interlocker(const char *interlocker_name) { pthread_mutex_lock(&interlocker_mutex); for (size_t i = 0; i < INTERLOCKER_INSTANCE_COUNT_MAX; i++) { if (!interlocker_instances[i].is_valid) { - if (dyn_containers_set_interlocker_instance( - &interlocker_instances[i], interlocker_name) - ) { - syslog_server(LOG_ERR, "Interlocker %s could not be used in instance %d", + if (dyn_containers_set_interlocker_instance(&interlocker_instances[i], interlocker_name)) { + syslog_server(LOG_ERR, + "Set interlocker - interlocker: %s - could not be used in instance %d", interlocker_name, i); } else { selected_interlocker_name = g_string_new(interlocker_name); @@ -126,19 +126,26 @@ void release_all_interlockers(void) { // get_granted_route_conflicts, but using direct implementation of sectional-style checker GArray *get_granted_route_conflicts_sectional(const char *route_id) { + if (route_id == NULL) { + return NULL; + } GArray* conflict_route_ids = g_array_new(FALSE, FALSE, sizeof(char *)); - - char *conflict_routes[1024]; - const size_t conflict_routes_len = config_get_array_string_value("route", route_id, "conflicts", conflict_routes); + + const unsigned int route_count = MAX(interlocking_table_get_size(), 1024); + char *conflict_routes[route_count]; + const size_t conflict_routes_len = + config_get_array_string_value("route", route_id, "conflicts", conflict_routes); + for (size_t i = 0; i < conflict_routes_len; i++) { t_interlocking_route *conflict_route = get_route(conflict_routes[i]); if (conflict_route->train != NULL) { if (!is_route_conflict_safe_sectional(conflict_routes[i],route_id)) { - const size_t conflict_route_id_string_len = strlen(conflict_route->id) + strlen(conflict_route->train) + 3 + 1; + const size_t conflict_route_id_string_len = strlen(conflict_route->id) + + strlen(conflict_route->train) + 3 + 1; char *conflict_route_id_string = malloc(sizeof(char) * conflict_route_id_string_len); if (conflict_route_id_string == NULL) { syslog_server(LOG_ERR, - "get_granted_route_conflicts_sectional: Failed to allocate memory" + "get_granted_route_conflicts_sectional - failed to allocate memory" " for conflict_route_id_string"); g_array_free(conflict_route_ids, true); return NULL; @@ -153,6 +160,9 @@ GArray *get_granted_route_conflicts_sectional(const char *route_id) { } GArray *get_granted_route_conflicts(const char *route_id) { + if (route_id == NULL) { + return NULL; + } GArray* conflict_route_ids = g_array_new(FALSE, FALSE, sizeof(char *)); // When a sectional interlocker is in use, use the sectional checker to @@ -161,17 +171,20 @@ GArray *get_granted_route_conflicts(const char *route_id) { // Use native implementation of sectional checker return get_granted_route_conflicts_sectional(route_id); } - - char *conflict_routes[1024]; - const size_t conflict_routes_len = config_get_array_string_value("route", route_id, "conflicts", conflict_routes); + + const unsigned int route_count = MAX(interlocking_table_get_size(), 1024); + char *conflict_routes[route_count]; + const size_t conflict_routes_len = + config_get_array_string_value("route", route_id, "conflicts", conflict_routes); for (size_t i = 0; i < conflict_routes_len; i++) { t_interlocking_route *conflict_route = get_route(conflict_routes[i]); if (conflict_route->train != NULL) { - const size_t conflict_route_id_string_len = strlen(conflict_route->id) + strlen(conflict_route->train) + 3 + 1; + const size_t conflict_route_id_string_len = strlen(conflict_route->id) + + strlen(conflict_route->train) + 3 + 1; char *conflict_route_id_string = malloc(sizeof(char) * conflict_route_id_string_len); if (conflict_route_id_string == NULL) { syslog_server(LOG_ERR, - "get_granted_route_conflicts: Failed to allocate memory" + "get_granted_route_conflicts - failed to allocate memory" " for conflict_route_id_string"); g_array_free(conflict_route_ids, true); return NULL; @@ -186,11 +199,15 @@ GArray *get_granted_route_conflicts(const char *route_id) { } const bool get_route_is_clear(const char *route_id) { + if (route_id == NULL) { + return false; + } bahn_data_util_init_cached_track_state(); // Check that all route signals are in the Stop aspect char *signal_ids[1024]; - const size_t signal_ids_len = config_get_array_string_value("route", route_id, "route_signals", signal_ids); + const size_t signal_ids_len = config_get_array_string_value("route", route_id, + "route_signals", signal_ids); for (size_t i = 0; i < signal_ids_len; i++) { char *signal_state = track_state_get_value(signal_ids[i]); if (strcmp(signal_state, "stop")) { @@ -214,20 +231,28 @@ const bool get_route_is_clear(const char *route_id) { } GString *grant_route(const char *train_id, const char *source_id, const char *destination_id) { + if (train_id == NULL || source_id == NULL || destination_id == NULL) { + syslog_server(LOG_ERR, "Grant route - invalid (NULL) parameter(s)"); + return g_string_new("not_grantable"); + } + + + pthread_mutex_lock(&interlocker_mutex); if (selected_interlocker_instance == -1) { - syslog_server(LOG_ERR, "Grant route: No interlocker has been set"); + pthread_mutex_unlock(&interlocker_mutex); + syslog_server(LOG_ERR, + "Grant route - train: %s from: %s to: %s - no interlocker has been set", + train_id, source_id, destination_id); return g_string_new("no_interlocker"); } - pthread_mutex_lock(&interlocker_mutex); - bahn_data_util_init_cached_track_state(); // Ask the interlocker to grant requested route. // May take multiple ticks to process the request. dyn_containers_set_interlocker_instance_inputs(&interlocker_instances[selected_interlocker_instance], - source_id, destination_id, - train_id); + source_id, destination_id, + train_id); struct t_interlocker_instance_io interlocker_instance_io; do { @@ -246,68 +271,89 @@ GString *grant_route(const char *train_id, const char *source_id, const char *de } while (!interlocker_instance_io.output_terminated); // Return the result - const char *route_id = interlocker_instance_io.output_route_id; - if (route_id != NULL && params_check_is_number(route_id)) { - syslog_server(LOG_NOTICE, "Grant route: Route %s has been granted", route_id); - - syslog_server(LOG_NOTICE, "Grant route: Set points and signals for route id \"%s\" - interlocker type %d", - interlocker_instance_io.output_route_id, - interlocker_instance_io.output_interlocker_type); - } else { - if (strcmp(route_id, "no_routes") == 0) { - syslog_server(LOG_ERR, "Grant route: No routes possible from %s to %s", source_id, destination_id); - } else if (strcmp(route_id, "not_grantable") == 0) { - syslog_server(LOG_ERR, "Grant route: Conflicting routes are in use"); - } else if (strcmp(route_id, "not_clear") == 0) { - syslog_server(LOG_ERR, "Grant route: Route found has occupied blocks or source signal is not stop"); - } else { - syslog_server(LOG_ERR, "Grant route: Route could not be granted (%s)", route_id); - } - } - GString *route_id_copy = g_string_new(route_id); + GString *g_route_id_copy = g_string_new(interlocker_instance_io.output_route_id); bahn_data_util_free_cached_track_state(); - pthread_mutex_unlock(&interlocker_mutex); - return route_id_copy; + + if (g_route_id_copy->str != NULL && params_check_is_number(g_route_id_copy->str)) { + syslog_server(LOG_NOTICE, + "Grant route - train: %s from: %s to: %s - route %s has been granted", + train_id, source_id, destination_id, g_route_id_copy->str); + } else if (strcmp(g_route_id_copy->str, "no_routes") == 0) { + syslog_server(LOG_WARNING, + "Grant route - train: %s from: %s to: %s - no route possible", + train_id, source_id, destination_id); + } else if (strcmp(g_route_id_copy->str, "not_grantable") == 0) { + syslog_server(LOG_WARNING, + "Grant route - train: %s from: %s to: %s - conflicting routes in use", + train_id, source_id, destination_id); + } else if (strcmp(g_route_id_copy->str, "not_clear") == 0) { + syslog_server(LOG_WARNING, + "Grant route - train: %s from: %s to: %s - route blocked or source signal not stop", + train_id, source_id, destination_id); + } else { + syslog_server(LOG_WARNING, + "Grant route - train: %s from: %s to: %s - route could not be granted (message: %s)", + train_id, source_id, destination_id, g_route_id_copy->str); + } + return g_route_id_copy; } const char *grant_route_id(const char *train_id, const char *route_id) { + if (train_id == NULL || route_id == NULL) { + syslog_server(LOG_ERR, "Grant route id - invalid (NULL) parameter(s)"); + return "not_grantable"; + } pthread_mutex_lock(&interlocker_mutex); - // Check whether the route can be granted t_interlocking_route * const route = get_route(route_id); GArray * const granted_conflicts = get_granted_route_conflicts(route_id); if (granted_conflicts == NULL) { - syslog_server(LOG_ERR, "grant_route_id: granted_conflicts is NULL"); pthread_mutex_unlock(&interlocker_mutex); + syslog_server(LOG_WARNING, + "Grant route id - train: %s route: %s - search for conflicting routes failed", + train_id, route_id); return "not_grantable"; } const bool hasGrantedConflicts = (granted_conflicts->len > 0); g_array_free(granted_conflicts, true); if (route->train != NULL || hasGrantedConflicts) { pthread_mutex_unlock(&interlocker_mutex); + syslog_server(LOG_WARNING, + "Grant route id - train: %s route: %s - route already granted " + "or conflicting routes are in use", + train_id, route_id); return "not_grantable"; } // Check whether the route is physically available if (!get_route_is_clear(route_id)) { pthread_mutex_unlock(&interlocker_mutex); + syslog_server(LOG_WARNING, + "Grant route id - train: %s route: %s - route is not clear", + train_id, route_id); return "not_clear"; } - // Grant the route to the train and mark it unavailable + // Grant the route to the train + + syslog_server(LOG_INFO, + "Grant route id - train: %s route: %s - checks passed, now grant route", + train_id, route_id); + route->train = strdup(train_id); if (route->train == NULL) { - syslog_server(LOG_ERR, "grant_route_id: Unable to allocate memory for route->train"); pthread_mutex_unlock(&interlocker_mutex); + syslog_server(LOG_ERR, + "Grant route id - train: %s route: %s - unable to allocate memory for route->train", + train_id, route_id); return "not_grantable"; } // Set the points to their required positions for (size_t i = 0; i < route->points->len; i++) { - const t_interlocking_point point = - g_array_index(route->points, t_interlocking_point, i); + const t_interlocking_point point = g_array_index(route->points, t_interlocking_point, i); const char *position = (point.position == NORMAL) ? "normal" : "reverse"; bidib_switch_point(point.id, position); bidib_flush(); @@ -321,31 +367,49 @@ const char *grant_route_id(const char *train_id, const char *route_id) { bidib_set_signal(signal, signal_aspect); bidib_flush(); } + + syslog_server(LOG_NOTICE, + "Grant route id - train: %s route: %s - route granted", + train_id, route_id); pthread_mutex_unlock(&interlocker_mutex); return "granted"; } +///TODO: This should not unconditionally set all route signals to stop, because that would +// prevent sectional route release from working correctly! void release_route(const char *route_id) { + if (route_id == NULL) { + syslog_server(LOG_ERR, "Release route - invalid parameter, route_id is null"); + return; + } pthread_mutex_lock(&interlocker_mutex); t_interlocking_route *route = get_route(route_id); - if (route->train != NULL) { + if (route != NULL && route->train != NULL) { + syslog_server(LOG_INFO, + "Release route - route: %s - currently granted to train %s, " + "now setting all route signals to aspect_stop", + route_id, route->train); + const char *signal_aspect = "aspect_stop"; - - const int signal_count = route->signals->len; - for (int signal_index = 0; signal_index < signal_count; signal_index++) { - // Get each signal along the route + for (int signal_index = 0; signal_index < route->signals->len; signal_index++) { const char *signal_id = g_array_index(route->signals, char *, signal_index); if (bidib_set_signal(signal_id, signal_aspect)) { - syslog_server(LOG_ERR, "Release route: Unable to set signal to aspect %s", signal_aspect); + syslog_server(LOG_ERR, + "Release route - route: %s - unable to set signal to aspect %s", + route_id, signal_aspect); } bidib_flush(); } free(route->train); route->train = NULL; - syslog_server(LOG_NOTICE, "Release route: route %s released", route_id); + syslog_server(LOG_NOTICE, "Release route - route: %s - released", route_id); + } else if (route == NULL) { + syslog_server(LOG_ERR, "Release route - route: %s - does not exist", route_id); + } else { + syslog_server(LOG_ERR, "Release route - route: %s - is not granted to any train", route_id); } pthread_mutex_unlock(&interlocker_mutex); @@ -384,8 +448,7 @@ const bool reversers_state_update(void) { return !error; } -onion_connection_status handler_release_route(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_release_route(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_route_id = onion_request_get_post(req, "route-id"); @@ -394,8 +457,9 @@ onion_connection_status handler_release_route(void *_, onion_request *req, syslog_server(LOG_ERR, "Request: Release route - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, "Request: Release route - route: %s - start", route_id); release_route(route_id); - syslog_server(LOG_NOTICE, "Request: Release route - route: %s", route_id); + syslog_server(LOG_NOTICE, "Request: Release route - route: %s - finish", route_id); return OCS_PROCESSED; } } else { @@ -404,8 +468,7 @@ onion_connection_status handler_release_route(void *_, onion_request *req, } } -onion_connection_status handler_set_point(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_set_point(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_point = onion_request_get_post(req, "point"); @@ -414,14 +477,19 @@ onion_connection_status handler_set_point(void *_, onion_request *req, syslog_server(LOG_ERR, "Request: Set point - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, + "Request: Set point - point: %s state: %s - start", + data_point, data_state); if (bidib_switch_point(data_point, data_state)) { - syslog_server(LOG_ERR, "Request: Set point - invalid parameters"); - bidib_flush(); + syslog_server(LOG_ERR, + "Request: Set point - point: %s state: %s - invalid parameters - abort", + data_point, data_state); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Set point - point: %s state: %s", - data_point, data_state); bidib_flush(); + syslog_server(LOG_NOTICE, + "Request: Set point - point: %s state: %s - finish", + data_point, data_state); return OCS_PROCESSED; } } @@ -431,8 +499,7 @@ onion_connection_status handler_set_point(void *_, onion_request *req, } } -onion_connection_status handler_set_signal(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_set_signal(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_signal = onion_request_get_post(req, "signal"); @@ -441,13 +508,20 @@ onion_connection_status handler_set_signal(void *_, onion_request *req, syslog_server(LOG_ERR, "Request: Set signal - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, + "Request: Set signal - signal: %s state: %s - start", + data_signal, data_state); if (bidib_set_signal(data_signal, data_state)) { - syslog_server(LOG_ERR, "Request: Set signal - invalid parameters"); + syslog_server(LOG_ERR, + "Request: Set signal - signal: %s state: %s - " + "invalid parameters - abort", + data_signal, data_state); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Set signal - signal: %s state: %s", - data_signal, data_state); bidib_flush(); + syslog_server(LOG_NOTICE, + "Request: Set signal - signal: %s state: %s - finish", + data_signal, data_state); return OCS_PROCESSED; } } @@ -457,8 +531,7 @@ onion_connection_status handler_set_signal(void *_, onion_request *req, } } -onion_connection_status handler_set_peripheral(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_set_peripheral(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_peripheral = onion_request_get_post(req, "peripheral"); @@ -467,13 +540,20 @@ onion_connection_status handler_set_peripheral(void *_, onion_request *req, syslog_server(LOG_ERR, "Request: Set peripheral - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, + "Request: Set peripheral - peripheral: %s state: %s - start", + data_peripheral, data_state); if (bidib_set_peripheral(data_peripheral, data_state)) { - syslog_server(LOG_ERR, "Request: Set peripheral - invalid parameters"); + syslog_server(LOG_ERR, + "Request: Set peripheral - peripheral: %s state: %s - " + "invalid parameters - abort", + data_peripheral, data_state); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Set peripheral - peripheral: %s state: %s", - data_peripheral, data_state); bidib_flush(); + syslog_server(LOG_NOTICE, + "Request: Set peripheral - peripheral: %s state: %s - finish", + data_peripheral, data_state); return OCS_PROCESSED; } } @@ -483,15 +563,15 @@ onion_connection_status handler_set_peripheral(void *_, onion_request *req, } } -onion_connection_status handler_get_interlocker(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_interlocker(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { - if (selected_interlocker_instance != -1) { + if (selected_interlocker_instance != -1 && selected_interlocker_name != NULL) { onion_response_printf(res, "%s", selected_interlocker_name->str); + syslog_server(LOG_INFO, "Request: Get interlocker - done"); return OCS_PROCESSED; } else { - syslog_server(LOG_NOTICE, "Request: Get interlocker - none selected"); + syslog_server(LOG_ERR, "Request: Get interlocker - none selected"); return OCS_NOT_IMPLEMENTED; } } else { @@ -500,8 +580,7 @@ onion_connection_status handler_get_interlocker(void *_, onion_request *req, } } -onion_connection_status handler_set_interlocker(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_set_interlocker(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_interlocker = onion_request_get_post(req, "interlocker"); @@ -509,20 +588,29 @@ onion_connection_status handler_set_interlocker(void *_, onion_request *req, syslog_server(LOG_ERR, "Request: Set interlocker - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, + "Request: Set interlocker - interlocker: %s - start", + data_interlocker); if (selected_interlocker_instance != -1) { - syslog_server(LOG_ERR, "Request: Set interlocker - another interlocker instance already set"); + syslog_server(LOG_ERR, + "Request: Set interlocker - interlocker: %s - another " + "interlocker instance is already set - abort", + data_interlocker); return OCS_NOT_IMPLEMENTED; } set_interlocker(data_interlocker); if (selected_interlocker_instance == -1) { - syslog_server(LOG_ERR, "Request: Set interlocker - invalid parameters or " - "no more interlocker instances can be loaded"); + syslog_server(LOG_ERR, + "Request: Set interlocker - interlocker: %s - invalid " + "parameters or no more interlocker instances can be loaded - abort", + data_interlocker); return OCS_NOT_IMPLEMENTED; } else { onion_response_printf(res, "%s", selected_interlocker_name->str); - syslog_server(LOG_NOTICE, "Request: Set interlocker - %s", - selected_interlocker_name->str); + syslog_server(LOG_NOTICE, + "Request: Set interlocker - interlocker: %s - finish", + data_interlocker); return OCS_PROCESSED; } } @@ -532,8 +620,7 @@ onion_connection_status handler_set_interlocker(void *_, onion_request *req, } } -onion_connection_status handler_unset_interlocker(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_unset_interlocker(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_interlocker = onion_request_get_post(req, "interlocker"); @@ -541,17 +628,26 @@ onion_connection_status handler_unset_interlocker(void *_, onion_request *req, syslog_server(LOG_ERR, "Request: Unset interlocker - invalid parameters"); return OCS_NOT_IMPLEMENTED; } else { + syslog_server(LOG_NOTICE, "Request: Unset interlocker - interlocker: %s - start", + data_interlocker); if (selected_interlocker_instance == -1) { - syslog_server(LOG_ERR, "Request: Unset interlocker - no interlocker instance to unset"); + syslog_server(LOG_ERR, + "Request: Unset interlocker - interlocker: %s - " + "no interlocker instance to unset - abort", + data_interlocker); return OCS_NOT_IMPLEMENTED; } unset_interlocker(data_interlocker); if (selected_interlocker_instance != -1) { - syslog_server(LOG_ERR, "Request: Unset interlocker - invalid parameters"); + syslog_server(LOG_ERR, + "Request: Unset interlocker - interlocker: %s - " + "invalid parameters - abort", + data_interlocker); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Unset interlocker - %s", + syslog_server(LOG_NOTICE, + "Request: Unset interlocker - interlocker: %s - finish", data_interlocker); return OCS_PROCESSED; } diff --git a/server/src/handler_controller.h b/server/src/handler_controller.h index 98eabbdf..fb7a65d2 100644 --- a/server/src/handler_controller.h +++ b/server/src/handler_controller.h @@ -29,17 +29,12 @@ #ifndef HANDLER_CONTROLLER_H #define HANDLER_CONTROLLER_H -#include -#include +#include #include - #define INTERLOCKER_COUNT_MAX 4 #define INTERLOCKER_INSTANCE_COUNT_MAX 4 -#include -#include - extern pthread_mutex_t interlocker_mutex; typedef struct { diff --git a/server/src/handler_driver.c b/server/src/handler_driver.c index 0471c99e..d8b024b1 100644 --- a/server/src/handler_driver.c +++ b/server/src/handler_driver.c @@ -26,27 +26,22 @@ * */ -#include #include #include #include +#include #include -#include -#include -#include #include -#include +#include +#include "handler_driver.h" #include "server.h" -#include "dyn_containers_interface.h" #include "handler_controller.h" -#include "interlocking.h" +#include "dyn_containers_interface.h" #include "param_verification.h" +#include "interlocking.h" #include "bahn_data_util.h" -#define MICROSECOND 1 -#define TRAIN_DRIVE_TIME_STEP 10000 * MICROSECOND // 0.01 seconds - pthread_mutex_t grabbed_trains_mutex = PTHREAD_MUTEX_INITIALIZER; static unsigned int DRIVING_SPEED_SLOW = 40; @@ -100,8 +95,7 @@ const int train_get_grab_id(const char *train) { pthread_mutex_lock(&grabbed_trains_mutex); int grab_id = -1; for (size_t i = 0; i < TRAIN_ENGINE_INSTANCE_COUNT_MAX; i++) { - if (grabbed_trains[i].is_valid - && strcmp(grabbed_trains[i].name->str, train) == 0) { + if (grabbed_trains[i].is_valid && strcmp(grabbed_trains[i].name->str, train) == 0) { grab_id = i; break; } @@ -139,8 +133,7 @@ static bool train_position_is_at(const char *train_id, const char *segment) { return false; } -static const bool is_forward_driving(const t_interlocking_route *route, - const char *train_id) { +static const bool is_forward_driving(const t_interlocking_route *route, const char *train_id) { t_bidib_train_position_query train_position_query = bidib_get_train_position(train_id); const bool train_is_left = train_position_query.orientation_is_left; @@ -160,8 +153,9 @@ static const bool is_forward_driving(const t_interlocking_route *route, bidib_free_train_position_query(train_position_query); if (block_id == NULL) { - syslog_server(LOG_ERR, "Driving is forwards: %s - current block of train: %s is unknown", - is_forwards ? "yes" : "no", train_id); + syslog_server(LOG_ERR, + "Is forward driving - train: %s driving: %s - current block of train is unknown", + train_id, is_forwards ? "forwards" : "backwards"); return is_forwards; } @@ -175,12 +169,10 @@ static const bool is_forward_driving(const t_interlocking_route *route, if (strcmp(block_id, reverser_block) == 0) { const bool succ = reversers_state_update(); - t_bidib_reverser_state_query rev_state_query = - bidib_get_reverser_state(reverser_id); + t_bidib_reverser_state_query rev_state_query = bidib_get_reverser_state(reverser_id); // 3. Check the reverser's state if (succ && rev_state_query.available) { - electrically_reversed = - (rev_state_query.data.state_value == BIDIB_REV_EXEC_STATE_ON); + electrically_reversed = (rev_state_query.data.state_value == BIDIB_REV_EXEC_STATE_ON); } break; } @@ -190,14 +182,20 @@ static const bool is_forward_driving(const t_interlocking_route *route, const bool requested_forwards = electrically_reversed ? !is_forwards : is_forwards; - syslog_server(LOG_NOTICE, "Driving is forwards: %s", - requested_forwards ? "yes" : "no"); + syslog_server(LOG_NOTICE, + "Is forward driving - train: %s driving: %s", + train_id, is_forwards ? "forwards" : "backwards"); return requested_forwards; } static bool drive_route_params_valid(const char *train_id, t_interlocking_route *route) { + if (train_id == NULL || route == NULL) { + syslog_server(LOG_ERR, "Check drive route params - invalid (NULL) parameter(s)"); + return false; + } if ((route->train == NULL) || strcmp(train_id, route->train) != 0) { - syslog_server(LOG_NOTICE, "Check drive route params: Route %s not granted to train %s", + syslog_server(LOG_WARNING, + "Check drive route params - route %s not granted to train %s", route->id, train_id); return false; } @@ -216,7 +214,8 @@ static bool validate_interlocking_route_members_not_null(const t_interlocking_ro static void log_signal_info(int priority, const t_route_signal_info *sig_info) { if (sig_info != NULL) { - syslog_server(priority, "Drive route signal info: id - %s, %s source, %s destination, path index - %d", + syslog_server(priority, + "Drive route signal info - id: %s, source: %s, destination: %s, path index: %d", sig_info->id != NULL ? sig_info->id : "NULL", sig_info->is_source_signal ? "is" : "not", sig_info->is_destination_signal ? "is" : "not", @@ -226,13 +225,13 @@ static void log_signal_info(int priority, const t_route_signal_info *sig_info) { __attribute__ ((unused)) static void log_signal_info_array(int priority, const t_route_signal_info_array *sig_info_array) { - syslog_server(priority, "Drive route signal info array: Begin"); + syslog_server(priority, "log route signal info array - start"); if (sig_info_array != NULL) { for (size_t i = 0; i < sig_info_array->len; ++i) { log_signal_info(priority, sig_info_array->data_ptr[i]); } } - syslog_server(priority, "Drive route signal info array: End"); + syslog_server(priority, "log route signal info array - end"); } static void free_route_signal_info_array(t_route_signal_info_array *route_signal_info_array) { @@ -268,16 +267,17 @@ static bool add_signal_info_for_signal(t_route_signal_info_array *signal_info_ar size_t number_of_signal_infos) { if (signal_info_array == NULL || signal_info_array->data_ptr == NULL) { syslog_server(LOG_ERR, - "Add signal-info to signal_info_array: " - "Signal info array or signal info array data pointer is NULL"); + "Add signal-info to signal_info_array - " + "signal info array or signal info array data pointer is NULL"); return false; } const size_t i = index_in_info_array; // A. Return without adding signal-info if signal from route->signals is NULL if (signal_id_item == NULL) { syslog_server(LOG_WARNING, - "Add signal-info to signal_info_array: " - "Skipping NULL signal at index %d of route->signals", i); + "Add signal-info to signal_info_array - " + "skipping NULL signal at index %d of route->signals", + i); signal_info_array->data_ptr[i] = NULL; signal_info_array->len = i + 1; // Return true as this is not a critical error, i.e. we can still continue with route @@ -288,8 +288,8 @@ static bool add_signal_info_for_signal(t_route_signal_info_array *signal_info_ar signal_info_array->len = i + 1; if (signal_info_array->data_ptr[i] == NULL) { syslog_server(LOG_ERR, - "Get drive route signal info array: " - "Unable to allocate memory for array index %d", i); + "Add signal-info to signal_info_array - unable to allocate memory for array index %d", + i); return false; } @@ -302,7 +302,7 @@ static bool add_signal_info_for_signal(t_route_signal_info_array *signal_info_ar signal_info_array->data_ptr[i]->id = strdup(signal_id_item); if (signal_info_array->data_ptr[i]->id == NULL) { syslog_server(LOG_ERR, - "Get drive route signal info array: Unable to allocate memory for signal id %s", + "Add signal-info to signal_info_array - unable to allocate memory for signal id %s", signal_id_item); return false; } @@ -313,17 +313,21 @@ static t_route_signal_info_array get_route_signal_info_array(const t_interlockin t_route_signal_info_array info_arr = {.data_ptr = NULL, .len = 0}; if (!validate_interlocking_route_members_not_null(route)) { syslog_server(LOG_ERR, - "Get drive route signal info array: route is NULL or some route details are NULL"); + "Get route signal info array - route is NULL or some route details are NULL"); return info_arr; } - syslog_server(LOG_NOTICE, "Get drive route signal info array: Start building for route id %s", route->id); + syslog_server(LOG_DEBUG, + "Get route signal info array - route: %s - start building", + route->id); // 1. Allocate memory for array of pointers to t_route_signal_info type entities const size_t number_of_signal_infos = route->signals->len; info_arr.data_ptr = (t_route_signal_info**) malloc(sizeof(t_route_signal_info*) * number_of_signal_infos); if (info_arr.data_ptr == NULL) { - syslog_server(LOG_ERR, "Get drive route signal info array: Could not allocate memory for array"); + syslog_server(LOG_ERR, + "Get route signal info array - route: %s - could not allocate memory for array", + route->id); return info_arr; } // 2. For every signal in route->signals... @@ -341,8 +345,9 @@ static t_route_signal_info_array get_route_signal_info_array(const t_interlockin for (size_t i = 0; i < info_arr.len; ++i) { if (info_arr.data_ptr[i] == NULL) { syslog_server(LOG_WARNING, - "Get drive route signal info array: " - "Skipping NULL signal_info at index %d of info_arr", i); + "Get route signal info array - route: %s - " + "skipped NULL signal_info at pos %d of info_arr", + i); continue; } @@ -361,6 +366,9 @@ static t_route_signal_info_array get_route_signal_info_array(const t_interlockin } } } + syslog_server(LOG_DEBUG, + "Get route signal info array - route: %s - finished building", + route->id); return info_arr; } @@ -383,7 +391,7 @@ static t_route_repeated_segment_flags get_route_repeated_segment_flags(const t_i r_seg_flags.arr = malloc(sizeof(bool) * route_path_len); if (r_seg_flags.arr == NULL) { syslog_server(LOG_ERR, - "Get repeated segment flags for route %s: Unable to allocate memory for array", + "Get repeated segment flags - route: %s - unable to allocate memory for array", route->id); return r_seg_flags; } @@ -508,8 +516,8 @@ static size_t update_route_signals_for_train_pos(t_route_signal_info_array *sign t_route_signal_info *sig_info = signal_info_array->data_ptr[sig_info_index]; if (sig_info == NULL) { - syslog_server(LOG_ERR, - "Update route signals: For route %s, signal_info_array[%d] is NULL", + syslog_server(LOG_WARNING, + "Update route signals - route: %s - signal_info_array[%d] is NULL", route->id, sig_info_index); continue; } @@ -519,14 +527,13 @@ static size_t update_route_signals_for_train_pos(t_route_signal_info_array *sign if (sig_info->index_in_route_path <= train_pos_index) { // 4. Try to set the signal to signal_stop_aspect. if (bidib_set_signal(sig_info->id, signal_stop_aspect)) { - // Log_ERR... but what else? Safety violation once we have a safety layer? - syslog_server(LOG_ERR, - "Update route signals: Unable to set signal %s to %s on route %s", - sig_info->id, signal_stop_aspect, route->id); + syslog_server(LOG_WARNING, + "Update route signals - route: %s signal: %s - unable to set signal to %s", + route->id, sig_info->id, signal_stop_aspect); } else { bidib_flush(); syslog_server(LOG_NOTICE, - "Update route signals: Signal %s set to %s on route %s", + "Update route signals - route: %s signal: %s - signal set to %s", sig_info->id, signal_stop_aspect, route->id); sig_info->has_been_set_to_stop = true; signals_set_to_stop++; @@ -541,21 +548,21 @@ static bool drive_route_decoupled_signal_info_array_valid(const char *route_id, t_route_signal_info_array *signal_info_array) { if (signal_info_array == NULL || route_id == NULL) { syslog_server(LOG_ERR, - "Drive route decoupled signal info array validation: " - "Route id or signal info array is NULL"); + "Drive route decoupled signal info array validation - " + "route id or signal info array is NULL"); return false; } // Check that signal_info_array array is not empty and has at least 2 entries (source, destination) if (signal_info_array->data_ptr == NULL) { syslog_server(LOG_ERR, - "Drive route decoupled signal info array validation: " - "Signal info array retrieved for route %s is NULL", + "Drive route decoupled signal info array validation - route: %s - " + "signal info array is NULL", route_id); return false; } else if (signal_info_array->len < 2) { syslog_server(LOG_ERR, - "Drive route decoupled signal info array validation: Signal info array " - "retrieved for route %s has only %d elements (at least two elements needed)", + "Drive route decoupled signal info array validation - route: %s - " + "signal info array has only %d elements (at least two elements needed)", route_id, signal_info_array->len); return false; } @@ -570,13 +577,14 @@ static bool drive_route_decoupled_signal_info_array_valid(const char *route_id, * @return true signal updating successful (all signals were passed and set to stop) * @return false signal updating failed */ -static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, t_interlocking_route *route) { +static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, + t_interlocking_route *route) { if (route == NULL || route->id == NULL) { - syslog_server(LOG_ERR, "Drive route decoupled: Route or route id is NULL"); + syslog_server(LOG_ERR, "Drive route decoupled - route or route id is NULL"); return false; } if (train_id == NULL) { - syslog_server(LOG_ERR, "Drive route decoupled: Train id is NULL, route id is %s", route->id); + syslog_server(LOG_ERR, "Drive route decoupled - route: %s - train id is NULL", route->id); return false; } @@ -591,8 +599,8 @@ static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, } syslog_server(LOG_DEBUG, - "Drive route decoupled: Retrieved signal_info_array with %d elements for route id %s", - signal_info_array.len, route->id); + "Drive route decoupled - route: %s train: %s - signal_info_array has %d elements", + route->id, train_id, signal_info_array.len); // Signals in a route shall be set to stop once the train has driven passed them. // Destination signal is already in STOP aspect, thus signal_info_array.len - 1 signals. @@ -604,12 +612,13 @@ static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, while (running && drive_route_params_valid(train_id, route) && signals_set_to_stop < signals_to_set_to_stop_count) { // 1. Get position of train, and determine index (in route->path) of where the train is - t_train_index_on_route_query train_pos_query = get_train_pos_index_in_route_ignore_repeated_segments(train_id, route, &repeated_segment_flags); + t_train_index_on_route_query train_pos_query = + get_train_pos_index_in_route_ignore_repeated_segments(train_id, route, &repeated_segment_flags); if (train_pos_query.err_code != OKAY_TRAIN_ON_ROUTE) { syslog_server(LOG_DEBUG, - "Drive route decoupled: Unable to determine position of train %s on route id %s", - train_id, route->id); + "Drive route decoupled - route: %s train: %s - train position unknown", + route->id, train_id); // Train position unknown, perhaps temporarily lost -> skip this iteration. usleep(TRAIN_DRIVE_TIME_STEP); continue; @@ -620,16 +629,16 @@ static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, if (train_pos_index_previous != train_pos_query.pos_index || first_okay_position) { const char *path_item = g_array_index(route->path, char *, train_pos_query.pos_index); syslog_server(LOG_DEBUG, - "Drive route decoupled: Train %s now at route path index %d (%s) on route %s", - train_id, train_pos_query.pos_index, - path_item != NULL ? path_item : "NULL", - route->id); + "Drive route decoupled - route: %s train: %s - train is at index %d (%s)", + route->id, train_id, train_pos_query.pos_index, + path_item != NULL ? path_item : "NULL"); if (train_pos_index_previous > train_pos_query.pos_index) { syslog_server(LOG_DEBUG, - "Drive route decoupled: Train %s position index %d on route %s is " - "lower than the previous value of %d", - train_id, train_pos_query.pos_index, route->id, train_pos_index_previous); + "Drive route decoupled - route: %s train: %s - " + "new train path index %d is lower than previous path index %d", + route->id, train_id, + train_pos_query.pos_index, train_pos_index_previous); } signals_set_to_stop += update_route_signals_for_train_pos(&signal_info_array, route, train_pos_query.pos_index); @@ -640,7 +649,7 @@ static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, } syslog_server(LOG_NOTICE, - "Drive route decoupled: Finished setting %d signals to stop for route id %s", + "Drive route decoupled - Finished setting %d signals to stop for route id %s", signals_set_to_stop, route->id); free_route_signal_info_array(&signal_info_array); free_route_repeated_segment_flags(&repeated_segment_flags); @@ -649,6 +658,9 @@ static bool drive_route_progressive_stop_signals_decoupled(const char *train_id, __attribute__ ((unused)) static bool drive_route_progressive_stop_signals(const char *train_id, t_interlocking_route *route) { + if (train_id == NULL || route == NULL || route->id == NULL) { + return false; + } const char *signal_stop_aspect = "aspect_stop"; const char *next_signal = route->source; bool set_signal_stop = true; @@ -679,13 +691,14 @@ static bool drive_route_progressive_stop_signals(const char *train_id, t_interlo // Set signal to the Stop aspect set_signal_stop = false; if (bidib_set_signal(next_signal, signal_stop_aspect)) { - syslog_server(LOG_ERR, "Drive route progressive stop signals: " - "Unable to set route signal %s to aspect %s", + syslog_server(LOG_ERR, + "Drive route progressive stop signals - " + "unable to set route signal %s to aspect %s", next_signal, signal_stop_aspect); } else { bidib_flush(); - syslog_server(LOG_NOTICE, "Drive route progressive stop signals: " - "Set signal - signal: %s state: %s", + syslog_server(LOG_NOTICE, + "Drive route progressive stop signals - set signal: %s to aspect: %s", next_signal, signal_stop_aspect); } } @@ -700,21 +713,23 @@ static bool drive_route(const int grab_id, const char *route_id, const bool is_a pthread_mutex_unlock(&grabbed_trains_mutex); if (train_id == NULL) { - syslog_server(LOG_ERR, - "Drive route: Unable to allocate memory for train_id"); + syslog_server(LOG_ERR, "Drive route - unable to allocate memory for train_id"); return false; } t_interlocking_route *route = get_route(route_id); if (route == NULL || !drive_route_params_valid(train_id, route)) { - syslog_server(LOG_ERR, "Drive route: Unable to start driving because route is invalid"); + syslog_server(LOG_ERR, "Drive route - unable to start driving because route is invalid"); free(train_id); return false; } // Driving starts: Driving direction is computed from the route orientation - syslog_server(LOG_NOTICE, "Drive route: Driving starts"); - pthread_mutex_lock(&grabbed_trains_mutex); + syslog_server(LOG_NOTICE, + "Drive route - route: %s train: %s - %s driving starts", + route->id, train_id, is_automatic ? "automatic" : "manual"); + + pthread_mutex_lock(&grabbed_trains_mutex); const int engine_instance = grabbed_trains[grab_id].dyn_containers_engine_instance; const char requested_forwards = is_forward_driving(route, train_id); if (is_automatic) { @@ -725,32 +740,38 @@ static bool drive_route(const int grab_id, const char *route_id, const bool is_a pthread_mutex_unlock(&grabbed_trains_mutex); // Set the signals along the route to Stop as the train drives past them + // This will return as soon as the train has passed all but the destination signal const bool result = drive_route_progressive_stop_signals_decoupled(train_id, route); + // If driving is automatic, slow train down at the end of the route if (is_automatic && result) { const char *pre_dest_segment = g_array_index(route->path, char *, route->path->len - 2); while (running && !train_position_is_at(train_id, pre_dest_segment) && drive_route_params_valid(train_id, route)) { usleep(TRAIN_DRIVE_TIME_STEP); - route = get_route(route->id); } + + syslog_server(LOG_NOTICE, + "Drive route - route: %s train: %s - slowing down for end of route", + train_id, route_id); pthread_mutex_lock(&grabbed_trains_mutex); - syslog_server(LOG_NOTICE, "Drive route: Slowing %s for end of route %s", train_id, route_id); dyn_containers_set_train_engine_instance_inputs(engine_instance, DRIVING_SPEED_STOPPING, requested_forwards); pthread_mutex_unlock(&grabbed_trains_mutex); } + // Wait for train to reach the end of the route const char *dest_segment = g_array_index(route->path, char *, route->path->len - 1); while (running && result && !is_segment_occupied(dest_segment) && drive_route_params_valid(train_id, route)) { usleep(TRAIN_DRIVE_TIME_STEP); - route = get_route(route->id); } // Driving stops - syslog_server(LOG_NOTICE, "Drive route: Driving stops"); + syslog_server(LOG_NOTICE, + "Drive route - route: %s train: %s - driving stops", + route->id, train_id); pthread_mutex_lock(&grabbed_trains_mutex); dyn_containers_set_train_engine_instance_inputs(engine_instance, 0, requested_forwards); pthread_mutex_unlock(&grabbed_trains_mutex); @@ -765,11 +786,17 @@ static bool drive_route(const int grab_id, const char *route_id, const bool is_a } static int grab_train(const char *train, const char *engine) { + if (train == NULL || engine == NULL) { + syslog_server(LOG_ERR, "Grab train - invalid (NULL) parameter(s)"); + return -1; + } pthread_mutex_lock(&grabbed_trains_mutex); for (size_t i = 0; i < TRAIN_ENGINE_INSTANCE_COUNT_MAX; i++) { if (grabbed_trains[i].is_valid && strcmp(grabbed_trains[i].name->str, train) == 0) { pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Train %s already grabbed", train); + syslog_server(LOG_ERR, + "Grab train - train: %s engine: %s - train already grabbed", + train, engine); return -1; } } @@ -779,7 +806,9 @@ static int grab_train(const char *train, const char *engine) { while (grabbed_trains[next_grab_id].is_valid) { if (next_grab_id == start) { pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "All grab ids in use"); + syslog_server(LOG_ERR, + "Grab train - train: %s engine: %s - all grab ids in use", + train, engine); return -1; } increment_next_grab_id(); @@ -791,12 +820,16 @@ static int grab_train(const char *train, const char *engine) { strcpy(grabbed_trains[grab_id].track_output, "master"); if (dyn_containers_set_train_engine_instance(&grabbed_trains[grab_id], train, engine)) { pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Train engine %s could not be used", engine); + syslog_server(LOG_ERR, + "Grab train - train: %s engine: %s - train engine could not be set", + train, engine); return -1; } grabbed_trains[grab_id].is_valid = true; pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_NOTICE, "Train %s grabbed", train); + syslog_server(LOG_NOTICE, + "Grab train - train: %s engine: %s - train grabbed with id: %d", + train, engine, grab_id); return grab_id; } @@ -806,7 +839,9 @@ bool release_train(int grab_id) { if (grabbed_trains[grab_id].is_valid) { grabbed_trains[grab_id].is_valid = false; dyn_containers_free_train_engine_instance(grabbed_trains[grab_id].dyn_containers_engine_instance); - syslog_server(LOG_NOTICE, "Train %s released", grabbed_trains[grab_id].name->str); + syslog_server(LOG_NOTICE, + "Release train - grab id: %d train: %s - released", + grab_id, grabbed_trains[grab_id].name->str); g_string_free(grabbed_trains[grab_id].name, TRUE); grabbed_trains[grab_id].name = NULL; success = true; @@ -821,36 +856,59 @@ void release_all_grabbed_trains(void) { } } -onion_connection_status handler_grab_train(void *_, onion_request *req, - onion_response *res) { +char *train_id_from_grab_id(int grab_id) { + pthread_mutex_lock(&grabbed_trains_mutex); + if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { + pthread_mutex_unlock(&grabbed_trains_mutex); + return NULL; + } + char *train_id = strdup(grabbed_trains[grab_id].name->str); + pthread_mutex_unlock(&grabbed_trains_mutex); + if (train_id == NULL) { + syslog_server(LOG_ERR, "Train id from grab id - unable to allocate memory for train_id"); + return NULL; + } + return train_id; +} + + +onion_connection_status handler_grab_train(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { - syslog_server(LOG_DEBUG, "Request received: Grab train"); const char *data_train = onion_request_get_post(req, "train"); - const char *data_engine = onion_request_get_post(req, "engine"); + const char *data_engine = onion_request_get_post(req, "engine"); + if (data_train == NULL || data_engine == NULL) { syslog_server(LOG_ERR, "Request: Grab train - invalid parameters"); return OCS_NOT_IMPLEMENTED; + } + syslog_server(LOG_NOTICE, + "Request: Grab train - train: %s engine: %s - start", + data_train, data_engine); + + t_bidib_train_state_query train_state_query = bidib_get_train_state(data_train); + if (!train_state_query.known) { + bidib_free_train_state_query(train_state_query); + syslog_server(LOG_ERR, + "Request: Grab train - train: %s engine: %s - " + "unknown train or train state - abort", + data_train, data_engine); + return OCS_NOT_IMPLEMENTED; + } + bidib_free_train_state_query(train_state_query); + + int grab_id = grab_train(data_train, data_engine); + if (grab_id == -1) { + syslog_server(LOG_ERR, + "Request: Grab train - train: %s engine: %s - train could not be grabbed - abort", + data_train, data_engine); + return OCS_NOT_IMPLEMENTED; } else { - t_bidib_train_state_query train_state_query = - bidib_get_train_state(data_train); - if (!train_state_query.known) { - bidib_free_train_state_query(train_state_query); - syslog_server(LOG_ERR, "Request: Grab train - train not known"); - return OCS_NOT_IMPLEMENTED; - } else { - bidib_free_train_state_query(train_state_query); - int grab_id = grab_train(data_train, data_engine); - if (grab_id == -1) { - // TODO: more precise error message if all slots are taken - syslog_server(LOG_ERR, "Request: Grab train - train already grabbed or engine not found"); - return OCS_NOT_IMPLEMENTED; - } else { - syslog_server(LOG_NOTICE, "Request: Grab train - train: %s", data_train); - onion_response_printf(res, "%ld,%d", session_id, grab_id); - return OCS_PROCESSED; - } - } + syslog_server(LOG_NOTICE, + "Request: Grab train - train: %s engine: %s - finish", + data_train, data_engine); + onion_response_printf(res, "%ld,%d", session_id, grab_id); + return OCS_PROCESSED; } } else { syslog_server(LOG_ERR, "Request: Grab train - system not running or wrong request type"); @@ -858,45 +916,58 @@ onion_connection_status handler_grab_train(void *_, onion_request *req, } } -onion_connection_status handler_release_train(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_release_train(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { - syslog_server(LOG_DEBUG, "Request received: Release train"); const char *data_session_id = onion_request_get_post(req, "session-id"); const char *data_grab_id = onion_request_get_post(req, "grab-id"); - int client_session_id = params_check_session_id(data_session_id); - int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); + const int client_session_id = params_check_session_id(data_session_id); + const int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); + if (client_session_id != session_id) { - syslog_server(LOG_ERR, "Request: Release train - invalid session id (%s != %d)", - data_session_id, session_id); + syslog_server(LOG_ERR, + "Request: Release train - grab id: %d - invalid session id: %s", + grab_id, data_session_id); return OCS_NOT_IMPLEMENTED; } - pthread_mutex_lock(&grabbed_trains_mutex); - if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { - pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Release train - invalid grab id"); + // If grab_id is valid, train_id will be, too. + char *train_id = train_id_from_grab_id(grab_id); + if (train_id == NULL) { + syslog_server(LOG_ERR, "Request: Release train - grab id: %d - invalid grab id", grab_id); return OCS_NOT_IMPLEMENTED; } - // Ensure that the train has stopped moving + syslog_server(LOG_NOTICE, + "Request: Release train - grab id: %d train: %s - start", + grab_id, train_id); + + // Set train speed to 0 + pthread_mutex_lock(&grabbed_trains_mutex); const int engine_instance = grabbed_trains[grab_id].dyn_containers_engine_instance; dyn_containers_set_train_engine_instance_inputs(engine_instance, 0, true); - char *train_id = strdup(grabbed_trains[grab_id].name->str); pthread_mutex_unlock(&grabbed_trains_mutex); - if (train_id == NULL) { - syslog_server(LOG_ERR, - "Request: Release train - unable to allocate memory for train_id"); - return false; + + + // Wait until the train has stopped moving + t_bidib_train_state_query train_state_query = bidib_get_train_state(train_id); + while (train_state_query.data.set_speed_step != 0) { + bidib_free_train_state_query(train_state_query); + usleep(TRAIN_DRIVE_TIME_STEP); + train_state_query = bidib_get_train_state(train_id); } + bidib_free_train_state_query(train_state_query); if (!release_train(grab_id)) { - syslog_server(LOG_ERR, "Request: Release train %s - invalid grab id", train_id); + syslog_server(LOG_ERR, + "Request: Release train - grab id: %d train: %s - invalid grab id - abort", + grab_id, train_id); free(train_id); return OCS_NOT_IMPLEMENTED; } else { - syslog_server(LOG_NOTICE, "Request: Release train %s", train_id); + syslog_server(LOG_NOTICE, + "Request: Release train - grab id: %d train: %s - finish", + grab_id, train_id); free(train_id); return OCS_PROCESSED; } @@ -906,8 +977,7 @@ onion_connection_status handler_release_train(void *_, onion_request *req, } } -onion_connection_status handler_request_route(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_request_route(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_session_id = onion_request_get_post(req, "session-id"); @@ -916,74 +986,74 @@ onion_connection_status handler_request_route(void *_, onion_request *req, const char *data_destination_name = onion_request_get_post(req, "destination"); const int client_session_id = params_check_session_id(data_session_id); const int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); - if (client_session_id != session_id) { - syslog_server(LOG_ERR, "Request: Request train route - invalid session id"); - return OCS_NOT_IMPLEMENTED; - } else if (data_source_name == NULL || data_destination_name == NULL) { + + if (data_source_name == NULL || data_destination_name == NULL) { syslog_server(LOG_ERR, "Request: Request train route - invalid parameters"); return OCS_NOT_IMPLEMENTED; - } + } else if (client_session_id != session_id) { + syslog_server(LOG_ERR, + "Request: Request train route - from: %s to: %s - invalid session id", + data_source_name, data_destination_name); + return OCS_NOT_IMPLEMENTED; + } - pthread_mutex_lock(&grabbed_trains_mutex); - if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { - pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Request train route - bad grab id"); + // If grab_id is valid, train_id will be, too. + char *train_id = train_id_from_grab_id(grab_id); + if (train_id == NULL) { + syslog_server(LOG_ERR, + "Request: Request train route - from: %s to: %s - invalid grab id", + data_source_name, data_destination_name); return OCS_NOT_IMPLEMENTED; + } + + syslog_server(LOG_NOTICE, + "Request: Request train route - train: %s from: %s to: %s - start", + train_id, data_source_name, data_destination_name); + + // Use interlocker to find and grant a route + GString *route_id = grant_route(train_id, data_source_name, data_destination_name); + if (route_id->str != NULL && params_check_is_number(route_id->str)) { + syslog_server(LOG_NOTICE, + "Request: Request train route - train: %s from: %s to: %s - route %s granted", + train_id, data_source_name, data_destination_name, route_id->str); + onion_response_printf(res, "%s", route_id->str); } else { - char *train_id = strdup(grabbed_trains[grab_id].name->str); - pthread_mutex_unlock(&grabbed_trains_mutex); - if (train_id == NULL) { - syslog_server(LOG_ERR, - "Request: Request train route - unable to allocate memory for train_id"); - return OCS_NOT_IMPLEMENTED; - } - - // Use interlocker to find and grant a route + onion_response_set_code(res, HTTP_BAD_REQUEST); + syslog_server(LOG_WARNING, + "Request: Request train route - train: %s from: %s to: %s - route %s not granted", + train_id, data_source_name, data_destination_name, route_id->str); - GString *route_id = grant_route(train_id, - data_source_name, - data_destination_name); - if (route_id->str != NULL && params_check_is_number(route_id->str)) { - syslog_server(LOG_NOTICE, "Request: Request train route - " - "train: %s route: %s", - train_id, route_id->str); - onion_response_printf(res, "%s", route_id->str); - g_string_free(route_id, true); - free(train_id); - return OCS_PROCESSED; + if (strcmp(route_id->str, "no_interlocker") == 0) { + onion_response_printf(res, "No interlocker has been selected for use"); + } else if (strcmp(route_id->str, "no_routes") == 0) { + onion_response_printf(res, + "No routes possible from %s to %s", + data_source_name, data_destination_name); + } else if (strcmp(route_id->str, "not_grantable") == 0) { + onion_response_printf(res, "Route found conflicts with others"); + } else if (strcmp(route_id->str, "not_clear") == 0) { + onion_response_printf(res, + "Route found has occupied tracks or source signal is not stop"); } else { - syslog_server(LOG_ERR, "Request: Request train route - " - "train: %s route not granted", - train_id); - free(train_id); - if (strcmp(route_id->str, "no_interlocker") == 0) { - onion_response_printf(res, "No interlocker has been selected for use"); - } else if (strcmp(route_id->str, "no_routes") == 0) { - onion_response_printf(res, "No routes possible from %s to %s", - data_source_name, data_destination_name); - } else if (strcmp(route_id->str, "not_grantable") == 0) { - onion_response_printf(res, "Route found conflicts with others"); - } else if (strcmp(route_id->str, "not_clear") == 0) { - onion_response_printf(res, "Route found has occupied tracks " - "or source signal is not stop"); - } else { - onion_response_printf(res, "Route could not be granted (%s)", - route_id->str); - } - g_string_free(route_id, true); - - onion_response_set_code(res, HTTP_BAD_REQUEST); - return OCS_PROCESSED; + onion_response_printf(res, "Route could not be granted (%s)", route_id->str); } + syslog_server(LOG_NOTICE, + "Request: Request train route - train: %s from: %s to: %s - finish", + train_id, data_source_name, data_destination_name); } + g_string_free(route_id, true); + free(train_id); + return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Request train route - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Request train route - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_request_route_id(void *_, onion_request *req, - onion_response *res) { +///TODO: Discuss - maybe this should be called "request_route_by_id", to distinguish it from +// just getting a route id of/for something (similar to a monitor endpoint). +onion_connection_status handler_request_route_id(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_session_id = onion_request_get_post(req, "session-id"); @@ -992,59 +1062,65 @@ onion_connection_status handler_request_route_id(void *_, onion_request *req, const int client_session_id = params_check_session_id(data_session_id); const int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); const char *route_id = params_check_route_id(data_route_id); - if (client_session_id != session_id) { - syslog_server(LOG_ERR, "Request: Request train route - invalid session id"); + + if (strcmp(route_id, "") == 0) { + syslog_server(LOG_ERR, "Request: Request train route id - invalid route id"); return OCS_NOT_IMPLEMENTED; - } else if (strcmp(route_id, "") == 0) { - syslog_server(LOG_ERR, "Request: Request train route - invalid parameters"); + } else if (client_session_id != session_id) { + syslog_server(LOG_ERR, + "Request: Request train route id - route: %s - invalid session id", + route_id); return OCS_NOT_IMPLEMENTED; } - pthread_mutex_lock(&grabbed_trains_mutex); - if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { - pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Request train route - bad grab id"); + // If grab_id is valid, train_id will be, too. + char *train_id = train_id_from_grab_id(grab_id); + if (train_id == NULL) { + syslog_server(LOG_ERR, + "Request: Request train route id - route: %s - invalid grab id", + route_id); return OCS_NOT_IMPLEMENTED; + } + + syslog_server(LOG_NOTICE, + "Request: Request train route id - train: %s route: %s - start", + train_id, route_id); + + // Grant the route ID using an internal algorithm + const char *result = grant_route_id(train_id, route_id); + + if (strcmp(result, "granted") == 0) { + onion_response_printf(res, "%s", result); + syslog_server(LOG_NOTICE, + "Request: Request train route id - train: %s route: %s - route granted", + train_id, route_id, result); } else { - char *train_id = strdup(grabbed_trains[grab_id].name->str); - pthread_mutex_unlock(&grabbed_trains_mutex); - if (train_id == NULL) { - syslog_server(LOG_ERR, - "Request: Request train route - unable to allocate memory for train_id"); - return OCS_NOT_IMPLEMENTED; - } - - // Grant the route ID using an internal algorithm - - const char *result = grant_route_id(train_id, route_id); - if (strcmp(result, "granted") == 0) { - syslog_server(LOG_NOTICE, "Request: Request train route - " - "train: %s route: %s", - train_id, route_id); - onion_response_printf(res, "%s", result); - free(train_id); - return OCS_PROCESSED; + onion_response_set_code(res, HTTP_BAD_REQUEST); + syslog_server(LOG_WARNING, + "Request: Request train route id - train: %s route: %s - route not granted (%s)", + train_id, route_id, result); + if (strcmp(result, "not_grantable") == 0) { + onion_response_printf(res, + "Route %s is not available or has conflicts with others", + route_id); + } else if (strcmp(result, "not_clear") == 0) { + onion_response_printf(res, + "Route %s has occupied tracks or source signal is not stop", + route_id); } else { - syslog_server(LOG_ERR, "Request: Request train route - " - "train: %s route: %s not granted", - train_id, route_id); - free(train_id); - if (strcmp(result, "not_grantable") == 0) { - onion_response_printf(res, "Route %s is not available " - "or has conflicts with others", route_id); - } else if (strcmp(result, "not_clear") == 0) { - onion_response_printf(res, "Route %s has occupied tracks " - "or source signal is not stop", route_id); - } else { - onion_response_printf(res, "Route %s could not be granted", - route_id); - } - onion_response_set_code(res, HTTP_BAD_REQUEST); - return OCS_PROCESSED; + onion_response_printf(res, + "Route %s could not be granted", + route_id); } } + syslog_server(LOG_NOTICE, + "Request: Request train route id - train: %s route: %s - finish", + train_id, route_id); + free(train_id); + return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Request train route - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Request train route id - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -1057,26 +1133,32 @@ onion_connection_status handler_driving_direction(void *_, onion_request *req, const char *data_route_id = onion_request_get_post(req, "route-id"); const char *route_id = params_check_route_id(data_route_id); if (data_train == NULL) { - syslog_server(LOG_ERR, "Request: Driving direction - bad train id"); + syslog_server(LOG_ERR, "Request: Driving direction - train id is NULL"); return OCS_NOT_IMPLEMENTED; } else if (strcmp(route_id, "") == 0) { - syslog_server(LOG_ERR, "Request: Driving direction - bad route id"); + syslog_server(LOG_ERR, + "Request: Driving direction - train: %s - invalid route id", + data_train); return OCS_NOT_IMPLEMENTED; - } else { - const t_interlocking_route *route = get_route(route_id); - const char *direction = is_forward_driving(route, data_train) - ? "forwards" : "backwards"; - onion_response_printf(res, "%s", direction); - return OCS_PROCESSED; } + + syslog_server(LOG_INFO, "Request: Driving direction - train: %s - start", data_train); + pthread_mutex_lock(&interlocker_mutex); + const t_interlocking_route *route = get_route(route_id); + onion_response_printf(res, "%s", + is_forward_driving(route, data_train) ? "forwards" : "backwards"); + pthread_mutex_unlock(&interlocker_mutex); + syslog_server(LOG_INFO, "Request: Driving direction - train: %s - finish", data_train); + return OCS_PROCESSED; + } else { - syslog_server(LOG_ERR, "Request: Driving direction - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Driving direction - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; - } + } } -onion_connection_status handler_drive_route(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_drive_route(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_session_id = onion_request_get_post(req, "session-id"); @@ -1087,31 +1169,45 @@ onion_connection_status handler_drive_route(void *_, onion_request *req, const int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); const char *route_id = params_check_route_id(data_route_id); const char *mode = params_check_mode(data_mode); + if (client_session_id != session_id) { syslog_server(LOG_ERR, "Request: Drive route - invalid session id"); return OCS_NOT_IMPLEMENTED; } else if (strcmp(mode, "") == 0) { - syslog_server(LOG_ERR, "Request: Drive route - bad driving mode"); + syslog_server(LOG_ERR, "Request: Drive route - invalid driving mode"); return OCS_NOT_IMPLEMENTED; } else if (strcmp(route_id, "") == 0) { - syslog_server(LOG_ERR, "Request: Drive route - bad route id"); + syslog_server(LOG_ERR, "Request: Drive route - invalid route id"); return OCS_NOT_IMPLEMENTED; } - pthread_mutex_lock(&grabbed_trains_mutex); - if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { - pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Drive route - bad grab id"); + // If grab_id is valid, train_id will be, too. + char *train_id = train_id_from_grab_id(grab_id); + if (train_id == NULL) { + syslog_server(LOG_ERR, "Request: Drive route - route: %s - invalid grab id", route_id); return OCS_NOT_IMPLEMENTED; + } + + syslog_server(LOG_NOTICE, + "Request: Drive route - route: %s train: %s drive mode: %s - start", + route_id, train_id, mode); + + const bool is_automatic = (strcmp(mode, "automatic") == 0); + if (drive_route(grab_id, route_id, is_automatic)) { + onion_response_printf(res, "Route %s driving completed", route_id); + syslog_server(LOG_NOTICE, + "Request: Drive route - route: %s train: %s drive mode: %s - finish", + route_id, train_id, mode); + free(train_id); + return OCS_PROCESSED; } else { - pthread_mutex_unlock(&grabbed_trains_mutex); - const bool is_automatic = (strcmp(mode, "automatic") == 0); - if (drive_route(grab_id, route_id, is_automatic)) { - onion_response_printf(res, "Route %s driving completed", route_id); - return OCS_PROCESSED; - } else { - return OCS_NOT_IMPLEMENTED; - } + syslog_server(LOG_ERR, + "Request: Drive route - route: %s train: %s drive mode: %s - " + "driving failed - abort", + route_id, train_id, mode); + ///TODO: Automatic countermeasures? e.g. set train speed to 0 + free(train_id); + return OCS_NOT_IMPLEMENTED; } } else { syslog_server(LOG_ERR, "Request: Drive route - system not running or wrong request type"); @@ -1123,7 +1219,6 @@ onion_connection_status handler_set_dcc_train_speed(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { - syslog_server(LOG_DEBUG, "Request received: Set train speed"); const char *data_session_id = onion_request_get_post(req, "session-id"); const char *data_grab_id = onion_request_get_post(req, "grab-id"); const char *data_speed = onion_request_get_post(req, "speed"); @@ -1131,37 +1226,46 @@ onion_connection_status handler_set_dcc_train_speed(void *_, onion_request *req, int client_session_id = params_check_session_id(data_session_id); int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); int speed = params_check_speed(data_speed); + if (client_session_id != session_id) { - syslog_server(LOG_ERR, "Request: Set train speed - invalid session id"); - return OCS_NOT_IMPLEMENTED; - } else if (speed == 999) { - syslog_server(LOG_ERR, "Request: Set train speed - bad speed"); - return OCS_NOT_IMPLEMENTED; - } else if (data_track_output == NULL) { - syslog_server(LOG_ERR, "Request: Set train speed - bad track output"); + syslog_server(LOG_ERR, "Request: Set dcc train speed - invalid session id"); return OCS_NOT_IMPLEMENTED; } pthread_mutex_lock(&grabbed_trains_mutex); if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Set train speed - bad grab id"); + syslog_server(LOG_ERR, "Request: Set dcc train speed - invalid grab id"); return OCS_NOT_IMPLEMENTED; - } else { - strcpy(grabbed_trains[grab_id].track_output, data_track_output); - int dyn_containers_engine_instance = grabbed_trains[grab_id].dyn_containers_engine_instance; - if (speed < 0) { - dyn_containers_set_train_engine_instance_inputs(dyn_containers_engine_instance, - -speed, false); - } else { - dyn_containers_set_train_engine_instance_inputs(dyn_containers_engine_instance, - speed, true); - } + } else if (speed == 999) { + syslog_server(LOG_ERR, + "Request: Set dcc train speed - train: %s speed: %d - bad speed", + grabbed_trains[grab_id].name->str, speed); pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_PROCESSED; + return OCS_NOT_IMPLEMENTED; + } else if (data_track_output == NULL) { + syslog_server(LOG_ERR, + "Request: Set dcc train speed - train: %s speed: %d - invalid track output", + grabbed_trains[grab_id].name->str, speed); + pthread_mutex_unlock(&grabbed_trains_mutex); + return OCS_NOT_IMPLEMENTED; } + + syslog_server(LOG_NOTICE, + "Request: Set dcc train speed - train: %s speed: %d - start", + grabbed_trains[grab_id].name->str, speed); + strcpy(grabbed_trains[grab_id].track_output, data_track_output); + const int eng_instance = grabbed_trains[grab_id].dyn_containers_engine_instance; + dyn_containers_set_train_engine_instance_inputs(eng_instance, abs(speed), speed >= 0); + + syslog_server(LOG_NOTICE, + "Request: Set dcc train speed - train: %s speed: %d - finish", + grabbed_trains[grab_id].name->str, speed); + pthread_mutex_unlock(&grabbed_trains_mutex); + return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Set train speed - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Set dcc train speed - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -1178,41 +1282,55 @@ onion_connection_status handler_set_calibrated_train_speed(void *_, int client_session_id = params_check_session_id(data_session_id); int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); int speed = params_check_calibrated_speed(data_speed); + if (client_session_id != session_id) { syslog_server(LOG_ERR, "Request: Set calibrated train speed - invalid session id"); return OCS_NOT_IMPLEMENTED; + } + + pthread_mutex_lock(&grabbed_trains_mutex); + if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { + pthread_mutex_unlock(&grabbed_trains_mutex); + syslog_server(LOG_ERR, "Request: Set calibrated train speed - invalid grab id"); + return OCS_NOT_IMPLEMENTED; } else if (speed == 999) { - syslog_server(LOG_ERR, "Request: Set calibrated train speed - bad speed"); + syslog_server(LOG_ERR, + "Request: Set calibrated train speed - train: %s speed: %d - bad speed", + grabbed_trains[grab_id].name->str, speed); + pthread_mutex_unlock(&grabbed_trains_mutex); return OCS_NOT_IMPLEMENTED; } else if (data_track_output == NULL) { - syslog_server(LOG_ERR, "Request: Set calibrated train speed - bad track output"); + syslog_server(LOG_ERR, + "Request: Set calibrated train speed - train: %s speed: %d - " + "invalid track output", + grabbed_trains[grab_id].name->str, speed); + pthread_mutex_unlock(&grabbed_trains_mutex); return OCS_NOT_IMPLEMENTED; } - pthread_mutex_lock(&grabbed_trains_mutex); - if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { + syslog_server(LOG_NOTICE, + "Request: Set calibrated train speed - train: %s speed: %d - start", + grabbed_trains[grab_id].name->str, speed); + if (bidib_set_calibrated_train_speed(grabbed_trains[grab_id].name->str, + speed, data_track_output)) { + syslog_server(LOG_ERR, + "Request: Set calibrated train speed - train: %s speed: %d - " + "invalid parameters - abort", + grabbed_trains[grab_id].name->str, speed); pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Set calibrated train speed - bad grab id"); return OCS_NOT_IMPLEMENTED; } else { - if (bidib_set_calibrated_train_speed(grabbed_trains[grab_id].name->str, - speed, data_track_output)) { - syslog_server(LOG_ERR, "Request: Set calibrated train speed - bad " - "parameter values"); - pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_NOT_IMPLEMENTED; - } else { - bidib_flush(); - syslog_server(LOG_NOTICE, "Request: Set calibrated train speed - " - "train: %s speed: %d", - grabbed_trains[grab_id].name->str, speed); - pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_PROCESSED; - } + bidib_flush(); + syslog_server(LOG_NOTICE, + "Request: Set calibrated train speed - train: %s speed: %d - finish", + grabbed_trains[grab_id].name->str, speed); + pthread_mutex_unlock(&grabbed_trains_mutex); + return OCS_PROCESSED; } + } else { - syslog_server(LOG_ERR, "Request: Set calibrated train speed - system not running " - "or wrong request type"); + syslog_server(LOG_ERR, + "Request: Set calibrated train speed - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -1227,37 +1345,46 @@ onion_connection_status handler_set_train_emergency_stop(void *_, const char *data_track_output = onion_request_get_post(req, "track-output"); int client_session_id = params_check_session_id(data_session_id); int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); + if (client_session_id != session_id) { syslog_server(LOG_ERR, "Request: Set train emergency stop - invalid session id"); return OCS_NOT_IMPLEMENTED; - } else if (data_track_output == NULL) { - syslog_server(LOG_ERR, "Request: Set train emergency stop - bad track output"); - return OCS_NOT_IMPLEMENTED; } pthread_mutex_lock(&grabbed_trains_mutex); if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Set train emergency stop - bad grab id"); + syslog_server(LOG_ERR, "Request: Set train emergency stop - invalid grab id"); + return OCS_NOT_IMPLEMENTED; + } else if (data_track_output == NULL) { + syslog_server(LOG_ERR, + "Request: Set train emergency stop - train: %s - invalid track output", + grabbed_trains[grab_id].name->str); + pthread_mutex_unlock(&grabbed_trains_mutex); + return OCS_NOT_IMPLEMENTED; + } + syslog_server(LOG_NOTICE, + "Request: Set train emergency stop - train: %s - start", + grabbed_trains[grab_id].name->str); + + if (bidib_emergency_stop_train(grabbed_trains[grab_id].name->str, data_track_output)) { + syslog_server(LOG_ERR, + "Request: Set train emergency stop - train: %s - invalid parameters - abort", + grabbed_trains[grab_id].name->str); + pthread_mutex_unlock(&grabbed_trains_mutex); return OCS_NOT_IMPLEMENTED; } else { - if (bidib_emergency_stop_train(grabbed_trains[grab_id].name->str, - data_track_output)) { - syslog_server(LOG_ERR, "Request: Set train emergency stop - bad " - "parameter values"); - pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_NOT_IMPLEMENTED; - } else { - bidib_flush(); - syslog_server(LOG_NOTICE, "Request: Set train emergency stop - train: %s", - grabbed_trains[grab_id].name->str); - pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_PROCESSED; - } + bidib_flush(); + syslog_server(LOG_NOTICE, + "Request: Set train emergency stop - train: %s - finish", + grabbed_trains[grab_id].name->str); + pthread_mutex_unlock(&grabbed_trains_mutex); + return OCS_PROCESSED; } + } else { - syslog_server(LOG_ERR, "Request: Set train emergency stop - system not running " - "or wrong request type"); + syslog_server(LOG_ERR, + "Request: Set train emergency stop - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -1275,46 +1402,63 @@ onion_connection_status handler_set_train_peripheral(void *_, int client_session_id = params_check_session_id(data_session_id); int grab_id = params_check_grab_id(data_grab_id, TRAIN_ENGINE_INSTANCE_COUNT_MAX); int state = params_check_state(data_state); + if (client_session_id != session_id) { syslog_server(LOG_ERR, "Request: Set train peripheral - invalid session id"); return OCS_NOT_IMPLEMENTED; + } + + pthread_mutex_lock(&grabbed_trains_mutex); + if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { + pthread_mutex_unlock(&grabbed_trains_mutex); + syslog_server(LOG_ERR, "Request: Set train peripheral - invalid grab id"); + return OCS_NOT_IMPLEMENTED; } else if (state == -1) { - syslog_server(LOG_ERR, "Request: Set train peripheral - bad state"); + syslog_server(LOG_ERR, + "Request: Set train peripheral - train: %s - invalid state", + grabbed_trains[grab_id].name->str); + pthread_mutex_unlock(&grabbed_trains_mutex); return OCS_NOT_IMPLEMENTED; } else if (data_peripheral == NULL) { - syslog_server(LOG_ERR, "Request: Set train peripheral - bad peripheral"); + syslog_server(LOG_ERR, + "Request: Set train peripheral - train: %s - invalid peripheral", + grabbed_trains[grab_id].name->str); + pthread_mutex_unlock(&grabbed_trains_mutex); return OCS_NOT_IMPLEMENTED; } else if (data_track_output == NULL) { - syslog_server(LOG_ERR, "Request: Set train peripheral - bad track output"); + syslog_server(LOG_ERR, + "Request: Set train peripheral - train: %s peripheral: %s - " + "invalid track output", + grabbed_trains[grab_id].name->str, data_peripheral); + pthread_mutex_unlock(&grabbed_trains_mutex); return OCS_NOT_IMPLEMENTED; } - pthread_mutex_lock(&grabbed_trains_mutex); - if (grab_id == -1 || !grabbed_trains[grab_id].is_valid) { + syslog_server(LOG_NOTICE, + "Request: Set train peripheral - train: %s peripheral: %s state: 0x%02x - start", + grabbed_trains[grab_id].name->str, data_peripheral, state); + if (bidib_set_train_peripheral(grabbed_trains[grab_id].name->str, + data_peripheral, state, + data_track_output)) { + syslog_server(LOG_ERR, + "Request: Set train peripheral - train: %s " + "peripheral: %s state: 0x%02x - invalid parameters - abort", + grabbed_trains[grab_id].name->str, data_peripheral, state); pthread_mutex_unlock(&grabbed_trains_mutex); - syslog_server(LOG_ERR, "Request: Set train peripheral - bad grab id"); return OCS_NOT_IMPLEMENTED; } else { - if (bidib_set_train_peripheral(grabbed_trains[grab_id].name->str, - data_peripheral, state, - data_track_output)) { - syslog_server(LOG_ERR, "Request: Set train peripheral - bad " - "parameter values"); - pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_NOT_IMPLEMENTED; - } else { - bidib_flush(); - syslog_server(LOG_NOTICE, "Request: Set train peripheral - train: %s " - "peripheral: %s state: 0x%02x", - grabbed_trains[grab_id].name->str, - data_peripheral, state); - pthread_mutex_unlock(&grabbed_trains_mutex); - return OCS_PROCESSED; - } + bidib_flush(); + syslog_server(LOG_NOTICE, + "Request: Set train peripheral - train: %s peripheral: %s state: 0x%02x" + " - finish", + grabbed_trains[grab_id].name->str, data_peripheral, state); + pthread_mutex_unlock(&grabbed_trains_mutex); + return OCS_PROCESSED; } + } else { - syslog_server(LOG_ERR, "Request: Set train peripheral - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Set train peripheral - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } diff --git a/server/src/handler_driver.h b/server/src/handler_driver.h index 6465eaa9..0ca471b3 100644 --- a/server/src/handler_driver.h +++ b/server/src/handler_driver.h @@ -34,6 +34,9 @@ #define TRAIN_ENGINE_COUNT_MAX 4 #define TRAIN_ENGINE_INSTANCE_COUNT_MAX 5 +#define MICROSECOND 1 +#define TRAIN_DRIVE_TIME_STEP 10000 * MICROSECOND // 0.01 seconds + extern pthread_mutex_t grabbed_trains_mutex; typedef struct { @@ -54,6 +57,14 @@ bool release_train(int grab_id); void release_all_grabbed_trains(void); +/** + * @brief For a given grab-id, return the associated train name (a heap-allocated string) if applicable. + * Caller must free the returned string. + * @param grab_id Grab-id with which the desired train is grabbed + * @return char* the name of the train grabbed by grab-id; NULL if not grabbed or otherwise invalid. + */ +char *train_id_from_grab_id(int grab_id); + onion_connection_status handler_grab_train(void *_, onion_request *req, onion_response *res); diff --git a/server/src/handler_monitor.c b/server/src/handler_monitor.c index a55a587d..18bcf9ec 100644 --- a/server/src/handler_monitor.c +++ b/server/src/handler_monitor.c @@ -22,27 +22,26 @@ * present swtbahn-cli (in alphabetic order by surname): * * - Nicolas Gross + * - Bernhard Luedtke * */ -#include #include #include -#include #include #include +#include -#include "server.h" #include "handler_monitor.h" -#include "handler_driver.h" +#include "server.h" #include "handler_controller.h" -#include "bahn_data_util.h" -#include "interlocking.h" +#include "handler_driver.h" #include "param_verification.h" +#include "interlocking.h" +#include "bahn_data_util.h" #include "websocket_uploader/engine_uploader.h" -onion_connection_status handler_get_trains(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_trains(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *trains = g_string_new(""); @@ -53,84 +52,78 @@ onion_connection_status handler_get_trains(void *_, onion_request *req, train_grabbed(query.ids[i]) ? "yes" : "no"); } bidib_free_id_list_query(query); - char response[trains->len + 1]; - strcpy(response, trains->str); + onion_response_printf(res, "%s", trains->str); + syslog_server(LOG_INFO, "Request: Get available trains - done"); g_string_free(trains, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get available trains"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get available trains - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get available trains - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_get_train_state(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_train_state(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_train = onion_request_get_post(req, "train"); if (data_train == NULL) { syslog_server(LOG_ERR, "Request: Get train state - invalid parameters"); return OCS_NOT_IMPLEMENTED; - } else { - t_bidib_train_state_query train_state_query = - bidib_get_train_state(data_train); - t_bidib_train_position_query train_position_query = - bidib_get_train_position(data_train); - if (train_state_query.known) { - GString *seg_string = g_string_new("no"); - GString *block_string = g_string_new("no"); - if (train_position_query.length > 0) { - g_string_printf(seg_string, "%s", train_position_query.segments[0]); - for (size_t i = 1; i < train_position_query.length; i++) { - g_string_append_printf(seg_string, ", %s", train_position_query.segments[i]); - } - - for (size_t i = 0; i < train_position_query.length; i++) { - const char *block_id = - config_get_block_id_of_segment(train_position_query.segments[i]); - if (block_id != NULL) { - g_string_printf(block_string, "%s", block_id); - break; - } + } + + t_bidib_train_state_query train_state_query = bidib_get_train_state(data_train); + t_bidib_train_position_query train_position_query = bidib_get_train_position(data_train); + + if (train_state_query.known) { + GString *seg_string = g_string_new("no"); + GString *block_string = g_string_new("no"); + if (train_position_query.length > 0) { + g_string_printf(seg_string, "%s", train_position_query.segments[0]); + for (size_t i = 1; i < train_position_query.length; i++) { + g_string_append_printf(seg_string, ", %s", train_position_query.segments[i]); + } + for (size_t i = 0; i < train_position_query.length; i++) { + const char *block_id = + config_get_block_id_of_segment(train_position_query.segments[i]); + if (block_id != NULL) { + g_string_printf(block_string, "%s", block_id); + break; } } - bidib_free_train_position_query(train_position_query); - - GString *ret_string = g_string_new(""); - g_string_append_printf(ret_string, "grabbed: %s - on segment: %s - on block: %s" - " - orientation: %s" - " - speed step: %d - detected speed: %d km/h - direction: %s", - train_grabbed(data_train) ? "yes" : "no", - seg_string->str, - block_string->str, - (train_state_query.data.orientation == - BIDIB_TRAIN_ORIENTATION_LEFT) ? - "left" : "right", - train_state_query.data.set_speed_step, - train_state_query.data.detected_kmh_speed, - train_state_query.data.set_is_forwards - ? "forwards" : "backwards"); - bidib_free_train_state_query(train_state_query); - char response[ret_string->len + 1]; - strcpy(response, ret_string->str); - g_string_free(seg_string, true); - g_string_free(ret_string, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get train state"); - return OCS_PROCESSED; - } else { - bidib_free_train_position_query(train_position_query); - bidib_free_train_state_query(train_state_query); - syslog_server(LOG_ERR, "Request: Get train state - invalid train"); - return OCS_NOT_IMPLEMENTED; } + bidib_free_train_position_query(train_position_query); + + GString *ret_string = g_string_new(""); + g_string_append_printf(ret_string, "grabbed: %s - on segment: %s - on block: %s" + " - orientation: %s" + " - speed step: %d - detected speed: %d km/h - direction: %s", + train_grabbed(data_train) ? "yes" : "no", + seg_string->str, + block_string->str, + (train_state_query.data.orientation == + BIDIB_TRAIN_ORIENTATION_LEFT) ? + "left" : "right", + train_state_query.data.set_speed_step, + train_state_query.data.detected_kmh_speed, + train_state_query.data.set_is_forwards + ? "forwards" : "backwards"); + bidib_free_train_state_query(train_state_query); + onion_response_printf(res, "%s", ret_string->str); + syslog_server(LOG_INFO, "Request: Get train state - train: %s - done", data_train); + g_string_free(seg_string, true); + g_string_free(ret_string, true); + return OCS_PROCESSED; + } else { + bidib_free_train_position_query(train_position_query); + bidib_free_train_state_query(train_state_query); + syslog_server(LOG_ERR, + "Request: Get train state - train: %s - invalid train", + data_train); + return OCS_NOT_IMPLEMENTED; } } else { - syslog_server(LOG_ERR, "Request: Get train state - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, "Request: Get train state - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -143,35 +136,36 @@ onion_connection_status handler_get_train_peripherals(void *_, onion_request *re if (data_train == NULL) { syslog_server(LOG_ERR, "Request: Get train peripherals - invalid parameters"); return OCS_NOT_IMPLEMENTED; - } else { - t_bidib_id_list_query query = - bidib_get_train_peripherals(data_train); - if (query.length > 0) { - GString *train_peripherals = g_string_new(""); - for (size_t i = 0; i < query.length; i++) { - t_bidib_train_peripheral_state_query per_state = + } + + t_bidib_id_list_query query = bidib_get_train_peripherals(data_train); + if (query.length > 0) { + GString *train_peripherals = g_string_new(""); + for (size_t i = 0; i < query.length; i++) { + t_bidib_train_peripheral_state_query per_state = bidib_get_train_peripheral_state(data_train, query.ids[i]); - g_string_append_printf(train_peripherals, "%s%s - state: %s", - i != 0 ? "\n" : "", query.ids[i], - per_state.state == 1 ? "on" : "off"); - } - bidib_free_id_list_query(query); - char response[train_peripherals->len + 1]; - strcpy(response, train_peripherals->str); - g_string_free(train_peripherals, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get train peripherals"); - return OCS_PROCESSED; - } else { - bidib_free_id_list_query(query); - syslog_server(LOG_ERR, "Request: Get train train peripherals - invalid " - "train"); - return OCS_NOT_IMPLEMENTED; + g_string_append_printf(train_peripherals, "%s%s - state: %s", + i != 0 ? "\n" : "", query.ids[i], + per_state.state == 1 ? "on" : "off"); } + bidib_free_id_list_query(query); + + onion_response_printf(res, "%s", train_peripherals->str); + syslog_server(LOG_INFO, + "Request: Get train peripherals - train: %s - done", + data_train); + g_string_free(train_peripherals, true); + return OCS_PROCESSED; + } else { + bidib_free_id_list_query(query); + syslog_server(LOG_ERR, + "Request: Get train train peripherals - train: %s - invalid train", + data_train); + return OCS_NOT_IMPLEMENTED; } } else { - syslog_server(LOG_ERR, "Request: Get train peripherals - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get train peripherals - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -184,7 +178,7 @@ onion_connection_status handler_get_track_outputs(void *_, onion_request *req, t_bidib_id_list_query query = bidib_get_track_outputs(); for (size_t i = 0; i < query.length; i++) { t_bidib_track_output_state_query track_output_state = - bidib_get_track_output_state(query.ids[i]); + bidib_get_track_output_state(query.ids[i]); if (track_output_state.known) { char *state_string; switch (track_output_state.cs_state) { @@ -215,6 +209,9 @@ onion_connection_status handler_get_track_outputs(void *_, onion_request *req, case 0xFF: state_string = "query"; break; + default: + state_string = "off"; + break; } g_string_append_printf(track_outputs, "%s%s - state: %s", i != 0 ? "\n" : "", query.ids[i], @@ -222,70 +219,61 @@ onion_connection_status handler_get_track_outputs(void *_, onion_request *req, } } bidib_free_id_list_query(query); - char response[track_outputs->len + 1]; - strcpy(response, track_outputs->str); + + onion_response_printf(res, "%s", track_outputs->str); + syslog_server(LOG_INFO, "Request: Get track outputs - done"); g_string_free(track_outputs, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get track outputs"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get track outputs - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get track outputs - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_get_points(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_points(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *points = g_string_new(""); t_bidib_id_list_query query = bidib_get_connected_points(); for (size_t i = 0; i < query.length; i++) { - t_bidib_unified_accessory_state_query point_state = - bidib_get_point_state(query.ids[i]); + t_bidib_unified_accessory_state_query point_state = bidib_get_point_state(query.ids[i]); GString *execution_state = g_string_new(""); if (point_state.type == BIDIB_ACCESSORY_BOARD) { g_string_printf(execution_state, "(target state%s reached)", - point_state.board_accessory_state.execution_state ? - " not" : ""); + point_state.board_accessory_state.execution_state ? " not" : ""); } - char execution_state_str[execution_state->len + 1]; - strcpy(execution_state_str, execution_state->str); - g_string_free(execution_state, true); g_string_append_printf(points, "%s%s - state: %s %s", i != 0 ? "\n" : "", query.ids[i], point_state.type == BIDIB_ACCESSORY_BOARD ? point_state.board_accessory_state.state_id : point_state.dcc_accessory_state.state_id, - execution_state_str); + execution_state->str); + g_string_free(execution_state, true); bidib_free_unified_accessory_state_query(point_state); } bidib_free_id_list_query(query); - char response[points->len + 1]; - strcpy(response, points->str); + + onion_response_printf(res, "%s", points->str); + syslog_server(LOG_INFO, "Request: Get points - done"); g_string_free(points, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get points"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get points - system not running or wrong " - "request type"); + syslog_server(LOG_ERR, "Request: Get points - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_get_signals(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_signals(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *signals = g_string_new(""); t_bidib_id_list_query query = bidib_get_connected_signals(); for (size_t i = 0; i < query.length; i++) { t_bidib_unified_accessory_state_query signal_state = - bidib_get_signal_state(query.ids[i]); + bidib_get_signal_state(query.ids[i]); g_string_append_printf(signals, "%s%s - state: %s", i != 0 ? "\n" : "", query.ids[i], signal_state.type == BIDIB_ACCESSORY_BOARD ? @@ -294,15 +282,13 @@ onion_connection_status handler_get_signals(void *_, onion_request *req, bidib_free_unified_accessory_state_query(signal_state); } bidib_free_id_list_query(query); - char response[signals->len + 1]; - strcpy(response, signals->str); + + onion_response_printf(res, "%s", signals->str); + syslog_server(LOG_INFO, "Request: Get signals - done"); g_string_free(signals, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get signals"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get signals - system not running or wrong " - "request type"); + syslog_server(LOG_ERR, "Request: Get signals - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -316,30 +302,30 @@ onion_connection_status handler_get_point_aspects(void *_, onion_request *req, if (data_point == NULL) { syslog_server(LOG_ERR, "Request: Get point aspects - invalid parameters"); return OCS_NOT_IMPLEMENTED; - } else { - t_bidib_id_list_query query = bidib_get_point_aspects(data_point); - if (query.length > 0) { - GString *aspects = g_string_new(""); - for (size_t i = 0; i < query.length; i++) { - g_string_append_printf(aspects, "%s%s", i != 0 ? ", " : "", - query.ids[i]); - } - bidib_free_id_list_query(query); - char response[aspects->len + 1]; - strcpy(response, aspects->str); - g_string_free(aspects, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get point aspects"); - return OCS_PROCESSED; - } else { - bidib_free_id_list_query(query); - syslog_server(LOG_ERR, "Request: Get point aspects - invalid point"); - return OCS_NOT_IMPLEMENTED; + } + + t_bidib_id_list_query query = bidib_get_point_aspects(data_point); + if (query.length > 0) { + GString *aspects = g_string_new(""); + for (size_t i = 0; i < query.length; i++) { + g_string_append_printf(aspects, "%s%s", i != 0 ? ", " : "", query.ids[i]); } + bidib_free_id_list_query(query); + + onion_response_printf(res, "%s", aspects->str); + syslog_server(LOG_INFO, "Request: Get point aspects - point: %s - done", data_point); + g_string_free(aspects, true); + return OCS_PROCESSED; + } else { + bidib_free_id_list_query(query); + syslog_server(LOG_ERR, + "Request: Get point aspects - point: %s - invalid point", + data_point); + return OCS_NOT_IMPLEMENTED; } } else { - syslog_server(LOG_ERR, "Request: Get point aspects - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get point aspects - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -352,43 +338,43 @@ onion_connection_status handler_get_signal_aspects(void *_, onion_request *req, if (data_signal == NULL) { syslog_server(LOG_ERR, "Request: Get signal aspects - invalid parameters"); return OCS_NOT_IMPLEMENTED; - } else { - t_bidib_id_list_query query = bidib_get_signal_aspects(data_signal); - if (query.length > 0) { - GString *aspects = g_string_new(""); - for (size_t i = 0; i < query.length; i++) { - g_string_append_printf(aspects, "%s%s", i != 0 ? ", " : "", - query.ids[i]); - } - bidib_free_id_list_query(query); - char response[aspects->len + 1]; - strcpy(response, aspects->str); - g_string_free(aspects, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get signal aspects"); - return OCS_PROCESSED; - } else { - bidib_free_id_list_query(query); - syslog_server(LOG_ERR, "Request: Get signal aspects - invalid signal"); - return OCS_NOT_IMPLEMENTED; + } + + t_bidib_id_list_query query = bidib_get_signal_aspects(data_signal); + if (query.length > 0) { + GString *aspects = g_string_new(""); + for (size_t i = 0; i < query.length; i++) { + g_string_append_printf(aspects, "%s%s", i != 0 ? ", " : "", query.ids[i]); } + bidib_free_id_list_query(query); + + onion_response_printf(res, "%s", aspects->str); + syslog_server(LOG_INFO, + "Request: Get signal aspects - signal: %s - done", + data_signal); + g_string_free(aspects, true); + return OCS_PROCESSED; + } else { + bidib_free_id_list_query(query); + syslog_server(LOG_ERR, + "Request: Get signal aspects - signal: %s - invalid signal", + data_signal); + return OCS_NOT_IMPLEMENTED; } } else { - syslog_server(LOG_ERR, "Request: Get signal aspects - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get signal aspects - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_get_segments(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_segments(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *segments = g_string_new(""); t_bidib_id_list_query seg_query = bidib_get_connected_segments(); for (size_t i = 0; i < seg_query.length; i++) { - t_bidib_segment_state_query seg_state_query = - bidib_get_segment_state(seg_query.ids[i]); + t_bidib_segment_state_query seg_state_query = bidib_get_segment_state(seg_query.ids[i]); g_string_append_printf(segments, "%s%s - occupied: %s", i != 0 ? "\n" : "", seg_query.ids[i], seg_state_query.data.occupied ? "yes" : "no"); @@ -397,92 +383,81 @@ onion_connection_status handler_get_segments(void *_, onion_request *req, t_bidib_id_query id_query; for (size_t j = 0; j < seg_state_query.data.dcc_address_cnt; j++) { id_query = bidib_get_train_id(seg_state_query.data.dcc_addresses[j]); - if (id_query.known) { - g_string_append_printf(segments, "%s%s", - j != 0 ? ", " : "", id_query.id); - } else { - g_string_append_printf(segments, "%s%s", - j != 0 ? ", " : "", "unknown"); - } + g_string_append_printf(segments, "%s%s", + j != 0 ? ", " : "", + id_query.known ? id_query.id : "unknown"); bidib_free_id_query(id_query); } } bidib_free_segment_state_query(seg_state_query); } bidib_free_id_list_query(seg_query); - char response[segments->len + 1]; - strcpy(response, segments->str); + + onion_response_printf(res, "%s", segments->str); + syslog_server(LOG_INFO, "Request: Get segments - done"); g_string_free(segments, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get segments"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get segments - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, "Request: Get segments - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_get_reversers(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_reversers(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { if (!reversers_state_update()) { syslog_server(LOG_ERR, "Request: Get reversers - unable to request state update"); return OCS_NOT_IMPLEMENTED; - } else { - GString *reversers = g_string_new(""); - t_bidib_id_list_query rev_query = bidib_get_connected_reversers(); - for (size_t i = 0; i < rev_query.length; i++) { - const char *reverser_id = rev_query.ids[i]; - t_bidib_reverser_state_query rev_state_query = - bidib_get_reverser_state(reverser_id); - if (!rev_state_query.available) { - continue; - } - - char *state_value_str = "unknown"; - switch (rev_state_query.data.state_value) { - case BIDIB_REV_EXEC_STATE_OFF: - state_value_str = "off"; - break; - case BIDIB_REV_EXEC_STATE_ON: - state_value_str = "on"; - break; - default: - state_value_str = "unknown"; - break; - } - - g_string_append_printf(reversers, "%s%s - state: %s", - i != 0 ? "\n" : "", - reverser_id, state_value_str); - bidib_free_reverser_state_query(rev_state_query); + } + + GString *reversers = g_string_new(""); + t_bidib_id_list_query rev_query = bidib_get_connected_reversers(); + for (size_t i = 0; i < rev_query.length; i++) { + const char *reverser_id = rev_query.ids[i]; + t_bidib_reverser_state_query rev_state_query = bidib_get_reverser_state(reverser_id); + if (!rev_state_query.available) { + continue; } - bidib_free_id_list_query(rev_query); - char response[reversers->len + 1]; - strcpy(response, reversers->str); - g_string_free(reversers, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get reversers"); - return OCS_PROCESSED; + + char *state_value_str = "unknown"; + switch (rev_state_query.data.state_value) { + case BIDIB_REV_EXEC_STATE_OFF: + state_value_str = "off"; + break; + case BIDIB_REV_EXEC_STATE_ON: + state_value_str = "on"; + break; + default: + state_value_str = "unknown"; + break; + } + + g_string_append_printf(reversers, "%s%s - state: %s", + i != 0 ? "\n" : "", + reverser_id, state_value_str); + bidib_free_reverser_state_query(rev_state_query); } + bidib_free_id_list_query(rev_query); + + onion_response_printf(res, "%s", reversers->str); + syslog_server(LOG_INFO, "Request: Get reversers - done"); + g_string_free(reversers, true); + return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get reversers - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, "Request: Get reversers - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_get_peripherals(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_peripherals(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *peripherals = g_string_new(""); t_bidib_id_list_query per_query = bidib_get_connected_peripherals(); for (size_t i = 0; i < per_query.length; i++) { t_bidib_peripheral_state_query per_state_query = - bidib_get_peripheral_state(per_query.ids[i]); + bidib_get_peripheral_state(per_query.ids[i]); g_string_append_printf(peripherals, "%s%s - %s: %d", i != 0 ? "\n" : "", per_query.ids[i], per_state_query.data.state_id, @@ -490,15 +465,14 @@ onion_connection_status handler_get_peripherals(void *_, onion_request *req, bidib_free_peripheral_state_query(per_state_query); } bidib_free_id_list_query(per_query); - char response[peripherals->len + 1]; - strcpy(response, peripherals->str); + + onion_response_printf(res, "%s", peripherals->str); + syslog_server(LOG_INFO, "Request: Get peripherals - done"); g_string_free(peripherals, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get peripherals"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get peripherals - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get peripherals - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -509,7 +483,7 @@ onion_connection_status handler_get_verification_option(void *_, onion_request * if ((onion_request_get_flags(req) & OR_METHODS) == OR_GET) { onion_response_printf(res, "verification-enabled: %s", verification_enabled ? "true" : "false"); - syslog_server(LOG_NOTICE, "Request: Get verification option"); + syslog_server(LOG_INFO, "Request: Get verification option - done"); return OCS_PROCESSED; } else { syslog_server(LOG_ERR, "Request: Get verification option - wrong request type"); @@ -522,9 +496,8 @@ onion_connection_status handler_get_verification_url(void *_, onion_request *req build_response_header(res); if ((onion_request_get_flags(req) & OR_METHODS) == OR_GET) { const char *verif_url = get_verifier_url(); - onion_response_printf(res, "verification-url: %s", - verif_url == NULL ? "null" : verif_url); - syslog_server(LOG_NOTICE, "Request: Get verification url"); + onion_response_printf(res, "verification-url: %s", verif_url == NULL ? "null" : verif_url); + syslog_server(LOG_INFO, "Request: Get verification url - done"); return OCS_PROCESSED; } else { syslog_server(LOG_ERR, "Request: Get verification url - wrong request type"); @@ -542,11 +515,13 @@ onion_connection_status handler_get_granted_routes(void *_, onion_request *req, if (route_ids != NULL) { for (size_t i = 0; i < route_ids->len; i++) { const char *route_id = g_array_index(route_ids, char *, i); - t_interlocking_route *route = get_route(route_id); - if (route->train != NULL) { - g_string_append_printf(granted_routes, "%sroute id: %s train: %s", - needNewLine ? "\n" : "", route->id, route->train); - needNewLine = true; + if (route_id != NULL) { + t_interlocking_route *route = get_route(route_id); + if (route != NULL && route->train != NULL) { + g_string_append_printf(granted_routes, "%sroute id: %s train: %s", + needNewLine ? "\n" : "", route->id, route->train); + needNewLine = true; + } } } g_array_free(route_ids, true); @@ -556,15 +531,13 @@ onion_connection_status handler_get_granted_routes(void *_, onion_request *req, g_string_append_printf(granted_routes, "No granted routes"); } - char response[granted_routes->len + 1]; - strcpy(response, granted_routes->str); + onion_response_printf(res, "%s", granted_routes->str); + syslog_server(LOG_INFO, "Request: Get granted routes - done"); g_string_free(granted_routes, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get granted routes"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get granted routes - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get granted routes - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -593,8 +566,7 @@ void sprintf_garray_interlocking_point(GString *output, GArray *garray) { } } -onion_connection_status handler_get_route(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_route(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *data_route_id = onion_request_get_post(req, "route-id"); @@ -602,49 +574,48 @@ onion_connection_status handler_get_route(void *_, onion_request *req, if (route_id == NULL || strcmp(route_id, "") == 0 || get_route(route_id) == NULL) { syslog_server(LOG_ERR, "Request: Get route - invalid parameters"); return OCS_NOT_IMPLEMENTED; - } else { - GString *route_str = g_string_new(""); - t_interlocking_route *route = get_route(route_id); - g_string_append_printf(route_str, "route id: %s\n", route->id); - g_string_append_printf(route_str, " source signal: %s\n", route->source); - g_string_append_printf(route_str, " destination signal: %s\n", route->destination); - g_string_append_printf(route_str, " orientation: %s\n", route->orientation); - g_string_append_printf(route_str, " length: %f\n", route->length); - g_string_append_printf(route_str, " path: "); - sprintf_garray_char(route_str, route->path); - g_string_append_printf(route_str, "\n sections: "); - sprintf_garray_char(route_str, route->sections); - g_string_append_printf(route_str, "\n points: "); - sprintf_garray_interlocking_point(route_str, route->points); - g_string_append_printf(route_str, "\n signals: "); - sprintf_garray_char(route_str, route->signals); - g_string_append_printf(route_str, "\n conflicting route ids: "); - sprintf_garray_char(route_str, route->conflicts); - - g_string_append_printf(route_str, "\nstatus:"); - g_string_append_printf(route_str, "\n granted conflicting route ids: "); - GArray *granted_route_conflicts = get_granted_route_conflicts(route_id); - sprintf_garray_char(route_str, granted_route_conflicts); - g_array_free(granted_route_conflicts, true); - - pthread_mutex_lock(&interlocker_mutex); - g_string_append_printf(route_str, "\n route clear: %s", - get_route_is_clear(route_id) ? "yes": "no"); - pthread_mutex_unlock(&interlocker_mutex); - - g_string_append_printf(route_str, "\n granted train: %s", - route->train == NULL ? "none" : route->train); - - char response[route_str->len + 1]; - strcpy(response, route_str->str); - g_string_free(route_str, true); - onion_response_printf(res, "%s", response); - syslog_server(LOG_NOTICE, "Request: Get route"); - return OCS_PROCESSED; } + + syslog_server(LOG_INFO, "Request: Get route - route: %s - start", route_id); + GString *route_str = g_string_new(""); + + pthread_mutex_lock(&interlocker_mutex); + t_interlocking_route *route = get_route(route_id); + g_string_append_printf(route_str, "route id: %s\n", route->id); + g_string_append_printf(route_str, " source signal: %s\n", route->source); + g_string_append_printf(route_str, " destination signal: %s\n", route->destination); + g_string_append_printf(route_str, " orientation: %s\n", route->orientation); + g_string_append_printf(route_str, " length: %f\n", route->length); + g_string_append_printf(route_str, " path: "); + sprintf_garray_char(route_str, route->path); + g_string_append_printf(route_str, "\n sections: "); + sprintf_garray_char(route_str, route->sections); + g_string_append_printf(route_str, "\n points: "); + sprintf_garray_interlocking_point(route_str, route->points); + g_string_append_printf(route_str, "\n signals: "); + sprintf_garray_char(route_str, route->signals); + g_string_append_printf(route_str, "\n conflicting route ids: "); + sprintf_garray_char(route_str, route->conflicts); + + g_string_append_printf(route_str, "\nstatus:"); + g_string_append_printf(route_str, "\n granted conflicting route ids: "); + GArray *granted_route_conflicts = get_granted_route_conflicts(route_id); + sprintf_garray_char(route_str, granted_route_conflicts); + g_array_free(granted_route_conflicts, true); + + g_string_append_printf(route_str, "\n route clear: %s", + get_route_is_clear(route_id) ? "yes": "no"); + + g_string_append_printf(route_str, "\n granted train: %s", + route->train == NULL ? "none" : route->train); + pthread_mutex_unlock(&interlocker_mutex); + + onion_response_printf(res, "%s", route_str->str); + syslog_server(LOG_INFO, "Request: Get route - route: %s - finish", route_id); + g_string_free(route_str, true); + return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get route - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, "Request: Get route - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -792,8 +763,7 @@ GString *debug_info(void) { return info_str; } -onion_connection_status handler_get_debug_info(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_debug_info(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *debug_info_str = debug_info(); @@ -805,8 +775,7 @@ onion_connection_status handler_get_debug_info(void *_, onion_request *req, syslog_server(LOG_NOTICE, "Request: Get debug info"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get debug info - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, "Request: Get debug info - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -846,8 +815,8 @@ onion_connection_status handler_get_debug_info_extra(void *_, onion_request *req syslog_server(LOG_NOTICE, "Request: Get debug info extra"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Get debug info extra - system not running or " - "wrong request type"); + syslog_server(LOG_ERR, + "Request: Get debug info extra - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } diff --git a/server/src/handler_monitor.h b/server/src/handler_monitor.h index 89d3a073..bf562991 100644 --- a/server/src/handler_monitor.h +++ b/server/src/handler_monitor.h @@ -28,7 +28,7 @@ #ifndef HANDLER_MONITOR_H #define HANDLER_MONITOR_H -#include +#include #include "dyn_containers_interface.h" #include "dyn_containers.h" diff --git a/server/src/handler_upload.c b/server/src/handler_upload.c index 3a0dc2b7..a9041746 100644 --- a/server/src/handler_upload.c +++ b/server/src/handler_upload.c @@ -28,14 +28,12 @@ */ -#include #include +#include +#include #include -#include -#include #include -#include -#include +#include #include "handler_upload.h" #include "server.h" @@ -60,7 +58,7 @@ bool clear_dir(const char dir[]) { DIR *dir_handle = opendir(dir); if (dir_handle == NULL) { closedir(dir_handle); - syslog_server(LOG_ERR, "Upload clear dir: Directory %s could not be opened", dir); + syslog_server(LOG_ERR, "Clear Directory - Directory %s could not be opened", dir); return false; } @@ -99,13 +97,18 @@ bool engine_file_exists(const char filename[]) { DIR *dir_handle = opendir(engine_dir); if (dir_handle == NULL) { closedir(dir_handle); - syslog_server(LOG_ERR, "Upload engine file exists: Directory %s could not be opened", engine_dir); + syslog_server(LOG_ERR, + "Engine file exists check - directory %s could not be opened", + engine_dir); return true; } struct dirent *dir_entry = NULL; while ((dir_entry = readdir(dir_handle)) != NULL) { if (strcmp(dir_entry->d_name, filename) == 0) { closedir(dir_handle); + syslog_server(LOG_NOTICE, + "Engine file exists check - engine %s already exists", + filename); return true; } } @@ -137,20 +140,24 @@ bool plugin_is_unremovable(const char name[]) { onion_connection_status handler_upload_engine(void *_, onion_request *req, onion_response *res) { build_response_header(res); - if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *filename = onion_request_get_post(req, "file"); const char *temp_filepath = onion_request_get_file(req, "file"); if (filename == NULL || temp_filepath == NULL) { - syslog_server(LOG_ERR, "Request: Upload Engine - engine file is invalid"); + syslog_server(LOG_ERR, "Request: Upload engine - engine file is invalid"); onion_response_set_code(res, HTTP_BAD_REQUEST); onion_response_printf(res, "Engine file is invalid"); return OCS_PROCESSED; } + syslog_server(LOG_NOTICE, "Request: Upload engine - engine file: %s - start", filename); + if (engine_file_exists(filename)) { - syslog_server(LOG_WARNING, "Request: Upload Engine - engine file already exists"); + syslog_server(LOG_ERR, + "Request: Upload engine - engine file: %s - " + "engine file already exists - abort", + filename); onion_response_set_code(res, HTTP_BAD_REQUEST); onion_response_printf(res, "Engine file already exists"); return OCS_PROCESSED; @@ -164,14 +171,15 @@ onion_connection_status handler_upload_engine(void *_, onion_request *req, onion char final_filepath[PATH_MAX + NAME_MAX]; snprintf(final_filepath, sizeof(final_filepath), "%s/%s", engine_dir, filename); onion_shortcut_rename(temp_filepath, final_filepath); - syslog_server(LOG_DEBUG, "Request: Upload Engine - copied engine SCCharts file from %s to %s", - temp_filepath, final_filepath); + syslog_server(LOG_DEBUG, + "Request: Upload engine - engine file: %s - copied engine file from %s to %s", + filename, temp_filepath, final_filepath); if (verification_enabled) { verif_result engine_verif_result = verify_engine_model(final_filepath); if (!engine_verif_result.success) { // Stop upload if verification did not succeed - syslog_server(LOG_NOTICE, "Request: Upload Engine - Engine verification failed"); + syslog_server(LOG_NOTICE, "Request: Upload Engine - engine verification failed - abort"); remove_engine_files(libname); onion_response_set_code(res, HTTP_BAD_REQUEST); if (engine_verif_result.message != NULL) { @@ -190,23 +198,34 @@ onion_connection_status handler_upload_engine(void *_, onion_request *req, onion if (status == DYNLIB_COMPILE_SCCHARTS_C_ERR || status == DYNLIB_COMPILE_SHARED_SCCHARTS_ERR) { remove_engine_files(libname); - syslog_server(LOG_ERR, "Request: Upload Engine - engine file %s could not be compiled " - "into a C file and then to a shared library", filepath); - onion_response_set_code(res, HTTP_BAD_REQUEST); - onion_response_printf(res, "Engine file %s could not be compiled into a C file " - "and then a shared library", filepath); + syslog_server(LOG_ERR, + "Request: Upload engine - engine file: %s - could not be " + "compiled into a C file and then to a shared library - abort", + filepath); + ///TODO: Discuss which code to return + onion_response_set_code(res, HTTP_INTERNAL_ERROR); + onion_response_printf(res, + "Engine file %s could not be compiled into a C file " + "and then a shared library", + filepath); return OCS_PROCESSED; } + syslog_server(LOG_DEBUG, + "Request: Upload engine - engine file: %s - engine compiled", + filename); - syslog_server(LOG_NOTICE, "Request: Upload Engine - engine %s compiled", filename); pthread_mutex_lock(&dyn_containers_mutex); const int engine_slot = dyn_containers_get_free_engine_slot(); if (engine_slot < 0) { pthread_mutex_unlock(&dyn_containers_mutex); remove_engine_files(libname); - - syslog_server(LOG_ERR, "Request: Upload Engine - no available engine slot"); - onion_response_set_code(res, HTTP_BAD_REQUEST); + + syslog_server(LOG_WARNING, + "Request: Upload engine - engine file: %s - " + "no available engine slot - abort", + filename); + ///TODO: Discuss which code to return + onion_response_set_code(res, HTTP_INTERNAL_ERROR); onion_response_printf(res, "No available engine slot"); return OCS_PROCESSED; } @@ -214,32 +233,32 @@ onion_connection_status handler_upload_engine(void *_, onion_request *req, onion snprintf(filepath, sizeof(filepath), "%s/%s", engine_dir, libname); dyn_containers_set_engine(engine_slot, filepath); pthread_mutex_unlock(&dyn_containers_mutex); + syslog_server(LOG_NOTICE, "Request: Upload engine - engine file: %s - finish", filename); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Upload Engine - system not running or wrong request type"); - + syslog_server(LOG_ERR, "Request: Upload engine - system not running or wrong request type"); + ///TODO: Discuss which code to return onion_response_set_code(res, HTTP_BAD_REQUEST); onion_response_printf(res, "System not running or wrong request type"); return OCS_PROCESSED; } } -onion_connection_status handler_refresh_engines(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_get_engines(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *train_engines = dyn_containers_get_train_engines(); onion_response_printf(res, "%s", train_engines->str); g_string_free(train_engines, true); + syslog_server(LOG_INFO, "Request: Get engines - done"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Refresh engines - system not running or wrong request type"); + syslog_server(LOG_ERR, "Request: Get engines - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } -onion_connection_status handler_remove_engine(void *_, onion_request *req, - onion_response *res) { +onion_connection_status handler_remove_engine(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *name = onion_request_get_post(req, "engine-name"); @@ -248,48 +267,53 @@ onion_connection_status handler_remove_engine(void *_, onion_request *req, "Request: Remove engine - engine name \"%s\" is " "invalid or engine is unremovable", (name == NULL) ? "null" : name); - onion_response_printf(res, "Engine name is invalid or engine is unremovable"); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Engine name is invalid or engine is unremovable"); return OCS_PROCESSED; } + syslog_server(LOG_NOTICE, "Request: Remove engine - engine: %s - start", name); + pthread_mutex_lock(&dyn_containers_mutex); const int engine_slot = dyn_containers_get_engine_slot(name); if (engine_slot < 0) { pthread_mutex_unlock(&dyn_containers_mutex); - syslog_server(LOG_ERR, - "Request: Remove engine - engine %s could not be found", + syslog_server(LOG_WARNING, + "Request: Remove engine - engine: %s - engine could not be found - abort", name); - onion_response_printf(res, "Engine %s could not be found", name); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Engine %s could not be found", name); return OCS_PROCESSED; } const bool engine_freed_successfully = dyn_containers_free_engine(engine_slot); pthread_mutex_unlock(&dyn_containers_mutex); if (!engine_freed_successfully) { - syslog_server(LOG_ERR, "Request: Remove engine - engine %s is still in use", name); + syslog_server(LOG_WARNING, + "Request: Remove engine - engine: %s - engine is still in use - abort", + name); - onion_response_printf(res, "Engine %s is still in use", name); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Engine %s is still in use", name); return OCS_PROCESSED; } if (!remove_engine_files(name)) { - syslog_server(LOG_ERR, "Request: Remove engine - engine %s files could not be removed", + syslog_server(LOG_ERR, + "Request: Remove engine - engine: %s - files could not be removed - abort", name); - onion_response_printf(res, "Engine %s files could not be removed", name); + ///TODO: This is an internal error, should return different response code IMO onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Engine %s files could not be removed", name); return OCS_PROCESSED; } - - syslog_server(LOG_NOTICE, "Request: Remove engine - engine %s removed", name); + syslog_server(LOG_NOTICE, "Request: Remove engine - engine: %s - finish", name); return OCS_PROCESSED; } else { syslog_server(LOG_ERR, "Request: Remove engine - system not running or wrong request type"); - onion_response_printf(res, "System not running or wrong request type"); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "System not running or wrong request type"); return OCS_PROCESSED; } } @@ -298,14 +322,15 @@ bool interlocker_file_exists(const char filename[]) { DIR *dir_handle = opendir(interlocker_dir); if (dir_handle == NULL) { closedir(dir_handle); - syslog_server(LOG_ERR, "Upload: Directory %s could not be opened", interlocker_dir); + syslog_server(LOG_ERR, + "Interlocker file exists check - directory %s could not be opened", + interlocker_dir); return true; } struct dirent *dir_entry = NULL; while ((dir_entry = readdir(dir_handle)) != NULL) { if (strcmp(dir_entry->d_name, filename) == 0) { closedir(dir_handle); - syslog_server(LOG_ERR, "Upload: Interlocker %s already exists", filename); return true; } } @@ -339,16 +364,22 @@ onion_connection_status handler_upload_interlocker(void *_, onion_request *req, if (filename == NULL || temp_filepath == NULL) { syslog_server(LOG_ERR, "Request: Upload - interlocker file is invalid"); - onion_response_printf(res, "Interlocker file is invalid"); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Interlocker file is invalid"); return OCS_PROCESSED; } + syslog_server(LOG_NOTICE, + "Request: Upload interlocker - interlocker file: %s - start", + filename); if (interlocker_file_exists(filename)) { - syslog_server(LOG_ERR, "Request: Upload - interlocker file already exists"); + syslog_server(LOG_ERR, + "Request: Upload interlocker - interlocker file: %s - " + "file already exists - abort", + filename); - onion_response_printf(res, "Interlocker file already exists"); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Interlocker file already exists"); return OCS_PROCESSED; } @@ -360,22 +391,28 @@ onion_connection_status handler_upload_interlocker(void *_, onion_request *req, char final_filepath[PATH_MAX + NAME_MAX]; snprintf(final_filepath, sizeof(final_filepath), "%s/%s", interlocker_dir, filename); onion_shortcut_rename(temp_filepath, final_filepath); - syslog_server(LOG_NOTICE, "Request: Upload - copied interlocker BahnDSL file from %s to %s", - temp_filepath, final_filepath); + syslog_server(LOG_DEBUG, + "Request: Upload interlocker - interlocker file: %s - " + "copied interlocker BahnDSL file from %s to %s", + filename, temp_filepath, final_filepath); char filepath[sizeof(final_filepath)]; remove_file_extension(filepath, final_filepath, ".bahn"); const dynlib_status status = dynlib_compile_bahndsl(filepath, interlocker_dir); if (status == DYNLIB_COMPILE_SHARED_BAHNDSL_ERR) { + syslog_server(LOG_ERR, + "Request: Upload interlocker - interlocker file: %s - " + "interlocker could not be compiled - abort", + filename); remove_interlocker_files(libname); - - syslog_server(LOG_ERR, "Request: Upload - interlocker file %s could not be compiled", filepath); - onion_response_printf(res, "Interlocker file %s could not be compiled", filepath); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Interlocker file %s could not be compiled", filepath); return OCS_PROCESSED; } - syslog_server(LOG_NOTICE, "Request: Upload - interlocker %s compiled", filename); + syslog_server(LOG_DEBUG, + "Request: Upload interlocker - interlocker file: %s - interlocker compiled", + filename); pthread_mutex_lock(&dyn_containers_mutex); const int interlocker_slot = dyn_containers_get_free_interlocker_slot(); @@ -383,19 +420,26 @@ onion_connection_status handler_upload_interlocker(void *_, onion_request *req, pthread_mutex_unlock(&dyn_containers_mutex); remove_interlocker_files(libname); - syslog_server(LOG_ERR, "Request: Upload - no available interlocker slot"); + syslog_server(LOG_WARNING, + "Request: Upload interlocker - interlocker file: %s - " + "no available interlocker slot - abort", + filename); - onion_response_printf(res, "No available interlocker slot"); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "No available interlocker slot"); return OCS_PROCESSED; } snprintf(filepath, sizeof(filepath), "%s/%s", interlocker_dir, libname); dyn_containers_set_interlocker(interlocker_slot, filepath); pthread_mutex_unlock(&dyn_containers_mutex); + syslog_server(LOG_NOTICE, + "Request: Upload interlocker - interlocker file: %s - finish", + filename); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Upload - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Upload interlocker - system not running or wrong request type"); onion_response_printf(res, "System not running or wrong request type"); onion_response_set_code(res, HTTP_BAD_REQUEST); @@ -403,16 +447,18 @@ onion_connection_status handler_upload_interlocker(void *_, onion_request *req, } } -onion_connection_status handler_refresh_interlockers(void *_, onion_request *req, +onion_connection_status handler_get_interlockers(void *_, onion_request *req, onion_response *res) { build_response_header(res); if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { GString *interlockers = dyn_containers_get_interlockers(); onion_response_printf(res, "%s", interlockers->str); g_string_free(interlockers, true); + syslog_server(LOG_INFO, "Request: Get interlockers - done"); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Refresh interlockers - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Get interlockers - system not running or wrong request type"); return OCS_NOT_IMPLEMENTED; } } @@ -423,55 +469,63 @@ onion_connection_status handler_remove_interlocker(void *_, onion_request *req, if (running && ((onion_request_get_flags(req) & OR_METHODS) == OR_POST)) { const char *name = onion_request_get_post(req, "interlocker-name"); if (name == NULL || plugin_is_unremovable(name)) { - syslog_server(LOG_ERR, "Request: Remove interlocker - interlocker name is invalid or interlocker is unremovable", name); + syslog_server(LOG_ERR, + "Request: Remove interlocker - interlocker name is invalid " + "or interlocker is unremovable"); onion_response_printf(res, "Interlocker name is invalid or interlocker is unremovable"); onion_response_set_code(res, HTTP_BAD_REQUEST); return OCS_PROCESSED; } + syslog_server(LOG_NOTICE, "Request: Remove interlocker - interlocker: %s - start", name); pthread_mutex_lock(&dyn_containers_mutex); const int interlocker_slot = dyn_containers_get_interlocker_slot(name); if (interlocker_slot < 0) { pthread_mutex_unlock(&dyn_containers_mutex); syslog_server(LOG_ERR, - "Request: Remove interlocker - interlocker %s could not be found", + "Request: Remove interlocker - interlocker: %s - " + "interlocker could not be found - abort", name); - onion_response_printf(res, "Interlocker %s could not be found", name); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Interlocker %s could not be found", name); return OCS_PROCESSED; } const bool interlocker_freed_successfully = dyn_containers_free_interlocker(interlocker_slot); pthread_mutex_unlock(&dyn_containers_mutex); if (!interlocker_freed_successfully) { - syslog_server(LOG_ERR, - "Request: Remove interlocker - interlocker %s is still in use", + syslog_server(LOG_WARNING, + "Request: Remove interlocker - interlocker: %s - " + "interlocker is still in use - abort", name); - onion_response_printf(res, "Interlocker %s is still in use", name); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Interlocker %s is still in use", name); return OCS_PROCESSED; } if (!remove_interlocker_files(name)) { syslog_server(LOG_ERR, - "Request: Remove interlocker - interlocker %s files could not be removed", + "Request: Remove interlocker - interlocker: %s - " + "files could not be removed - abort", name); - onion_response_printf(res, "Interlocker %s files could not be removed", name); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "Interlocker %s files could not be removed", name); return OCS_PROCESSED; } - - syslog_server(LOG_NOTICE, "Request: Remove interlocker - interlocker %s removed", name); + syslog_server(LOG_NOTICE, + "Request: Remove interlocker - interlocker: %s - finish", + name); return OCS_PROCESSED; } else { - syslog_server(LOG_ERR, "Request: Remove interlocker - system not running or wrong request type"); + syslog_server(LOG_ERR, + "Request: Remove interlocker - system not running or wrong request type"); - onion_response_printf(res, "System not running or wrong request type"); onion_response_set_code(res, HTTP_BAD_REQUEST); + onion_response_printf(res, "System not running or wrong request type"); return OCS_PROCESSED; } } diff --git a/server/src/handler_upload.h b/server/src/handler_upload.h index 953267b9..a3bcc28e 100644 --- a/server/src/handler_upload.h +++ b/server/src/handler_upload.h @@ -40,7 +40,7 @@ bool clear_interlocker_dir(void); onion_connection_status handler_upload_engine(void *_, onion_request *req, onion_response *res); -onion_connection_status handler_refresh_engines(void *_, onion_request *req, +onion_connection_status handler_get_engines(void *_, onion_request *req, onion_response *res); onion_connection_status handler_remove_engine(void *_, onion_request *req, @@ -49,7 +49,7 @@ onion_connection_status handler_remove_engine(void *_, onion_request *req, onion_connection_status handler_upload_interlocker(void *_, onion_request *req, onion_response *res); -onion_connection_status handler_refresh_interlockers(void *_, onion_request *req, +onion_connection_status handler_get_interlockers(void *_, onion_request *req, onion_response *res); onion_connection_status handler_remove_interlocker(void *_, onion_request *req, diff --git a/server/src/interlocking.c b/server/src/interlocking.c index 44d9471c..66b0e0ab 100644 --- a/server/src/interlocking.c +++ b/server/src/interlocking.c @@ -27,7 +27,6 @@ */ #include -#include #include #include @@ -81,7 +80,7 @@ void create_interlocking_hashtable(void) { } } - syslog_server(LOG_NOTICE, "Interlocking create hash table: successful"); + syslog_server(LOG_NOTICE, "Interlocking create hash table - done"); } bool interlocking_table_initialise(const char *config_dir) { @@ -164,3 +163,11 @@ t_interlocking_route *get_route(const char *route_id) { return NULL; } + +unsigned int interlocking_table_get_size() { + if (route_hash_table != NULL) { + return g_hash_table_size(route_hash_table); + } + + return 0; +} diff --git a/server/src/interlocking.h b/server/src/interlocking.h index a7210464..355ad00c 100644 --- a/server/src/interlocking.h +++ b/server/src/interlocking.h @@ -115,5 +115,12 @@ int interlocking_table_get_route_id(const char *source_id, const char *destinati */ t_interlocking_route *get_route(const char *route_id); +/** + * Returns the number of routes in the interlocking table. + * + * @return unsigned int number of routes in the interlocking table. 0 if no interlocking table exists. + */ +unsigned int interlocking_table_get_size(); + #endif // INTERLOCKING_H diff --git a/server/src/param_verification.c b/server/src/param_verification.c index 5fc55577..c0968ece 100644 --- a/server/src/param_verification.c +++ b/server/src/param_verification.c @@ -122,16 +122,3 @@ bool params_check_is_bool_string(const char *string) { return false; } } - -bool params_check_verification_option(const char *string) { - if (string == NULL || *string == '\0' || isspace(*string)) { - return false; - } else if (strcmp("false", string) == 0 || strcmp("False", string) == 0 || strcmp("FALSE", string) == 0) { - return false; - } else if (strcmp("true", string) == 0 || strcmp("True", string) == 0 || strcmp("TRUE", string) == 0) { - return true; - } - - return false; -} - diff --git a/server/src/param_verification.h b/server/src/param_verification.h index 98340c2b..eb1abd60 100644 --- a/server/src/param_verification.h +++ b/server/src/param_verification.h @@ -49,6 +49,4 @@ bool params_check_is_number(const char *string); bool params_check_is_bool_string(const char *string); -bool params_check_verification_option(const char *string); - #endif // PARAM_VERIFICATION_H \ No newline at end of file diff --git a/server/src/server.c b/server/src/server.c index c293863a..af75327e 100644 --- a/server/src/server.c +++ b/server/src/server.c @@ -25,19 +25,18 @@ * */ -#include #include #include #include -#include #include +#include #include +#include #include #include -#include #include -#include #include +#include #include "handler_monitor.h" #include "handler_admin.h" @@ -63,37 +62,37 @@ void syslog_server(int priority, const char *format, ...) { vsnprintf(string, 1024, format, arg); syslog(priority, "server: %s", string); + va_end(arg); } void build_response_header(onion_response *res) { - onion_response_set_header(res, "Access-Control-Allow-Origin", - "*"); + onion_response_set_header(res, "Access-Control-Allow-Origin", "*"); onion_response_set_header(res, "Access-Control-Allow-Headers", "Authorization, Origin, X-Requested-With, Content-Type, Accept"); onion_response_set_header(res, "Access-Control-Allow-Methods", "POST, GET, PUT, DELETE, OPTIONS"); } -static onion_connection_status handler_assets(void *_, onion_request *req, - onion_response *res) { +static onion_connection_status handler_assets(void *_, onion_request *req, onion_response *res) { build_response_header(res); onion_response_set_header(res, "Cache-Control", "max-age=43200"); const char local_path[] = "../src/assets/"; char *global_path = realpath(local_path, NULL); if (!global_path) { - syslog_server(LOG_ERR, "Onion: Cannot calculate the global path of the given directory (%s)", + syslog_server(LOG_ERR, + "Onion - Cannot calculate the global path of the given directory (%s)", local_path); - ONION_ERROR("Cannot calculate the global path of the given directory (%s)", - local_path); + ONION_ERROR("Cannot calculate the global path of the given directory (%s)", local_path); return OCS_NOT_IMPLEMENTED; } struct stat st; if (stat(global_path, &st) != 0) { - syslog_server(LOG_ERR, "Onion: Cannot access to the exported directory/file (%s)", + syslog_server(LOG_ERR, + "Onion - Cannot access the exported directory/file (%s)", global_path); - ONION_ERROR("Cannot access to the exported directory/file (%s)", global_path); + ONION_ERROR("Cannot access the exported directory/file (%s)", global_path); onion_low_free(global_path); return OCS_NOT_IMPLEMENTED; } @@ -180,19 +179,16 @@ int main(int argc, char **argv) { onion_url_add(urls, "driver/direction", handler_driving_direction); onion_url_add(urls, "driver/drive-route", handler_drive_route); onion_url_add(urls, "driver/set-dcc-train-speed", handler_set_dcc_train_speed); - onion_url_add(urls, "driver/set-calibrated-train-speed", - handler_set_calibrated_train_speed); - onion_url_add(urls, "driver/set-train-emergency-stop", - handler_set_train_emergency_stop); - onion_url_add(urls, "driver/set-train-peripheral", - handler_set_train_peripheral); + onion_url_add(urls, "driver/set-calibrated-train-speed", handler_set_calibrated_train_speed); + onion_url_add(urls, "driver/set-train-emergency-stop", handler_set_train_emergency_stop); + onion_url_add(urls, "driver/set-train-peripheral", handler_set_train_peripheral); // --- upload functions --- onion_url_add(urls, "upload/engine", handler_upload_engine); - onion_url_add(urls, "upload/refresh-engines", handler_refresh_engines); + onion_url_add(urls, "upload/refresh-engines", handler_get_engines); onion_url_add(urls, "upload/remove-engine", handler_remove_engine); onion_url_add(urls, "upload/interlocker", handler_upload_interlocker); - onion_url_add(urls, "upload/refresh-interlockers", handler_refresh_interlockers); + onion_url_add(urls, "upload/refresh-interlockers", handler_get_interlockers); onion_url_add(urls, "upload/remove-interlocker", handler_remove_interlocker); // --- monitor functions --- @@ -219,7 +215,7 @@ int main(int argc, char **argv) { onion_listen(o); onion_free(o); if (running) { - stop_bidib(); + shutdown_server(); } cache_verifier_url(); free_verifier_url(); diff --git a/server/src/server.h b/server/src/server.h index 83ad6165..90ea88bb 100644 --- a/server/src/server.h +++ b/server/src/server.h @@ -29,7 +29,6 @@ #define SERVER_H #include - #include extern volatile time_t session_id; diff --git a/server/src/websocket_uploader/engine_uploader.c b/server/src/websocket_uploader/engine_uploader.c index d092e9f5..d9a4708b 100644 --- a/server/src/websocket_uploader/engine_uploader.c +++ b/server/src/websocket_uploader/engine_uploader.c @@ -111,8 +111,9 @@ bool parse_model_into_verif_msg_str(GString *destination, const char *model_file void send_verif_req_message(struct mg_connection *ws_connection, ws_verif_data* ws_data_ptr) { if (ws_connection == NULL || ws_data_ptr == NULL) { syslog_server(LOG_ERR, - "Websocket upload engine: Unable to open and parse model file, " - "connection or ws_verif_data* is/are NULL"); + "Websocket engine uploader: Send verification request message - " + "invalid parameters"); + return; } // Read sctx model from file, build msg with necessary formatting @@ -122,7 +123,8 @@ void send_verif_req_message(struct mg_connection *ws_connection, ws_verif_data* // Check if parsing succeeded if (!parse_success) { syslog_server(LOG_ERR, - "Websocket upload engine: Unable to open and parse model file to be uploaded"); + "Websocket engine uploader: Send verification request message - " + "unable to parse model file"); ws_data_ptr->finished = true; ws_data_ptr->success = false; g_string_free(g_verif_msg_str, true); @@ -132,18 +134,20 @@ void send_verif_req_message(struct mg_connection *ws_connection, ws_verif_data* // Try to send verification request if (g_verif_msg_str != NULL && g_verif_msg_str->len > 0) { syslog_server(LOG_INFO, - "Websocket upload engine: Sending verification request to verifier server"); + "Websocket engine uploader: Send verification request message - " + "sending request to verifier server"); ssize_t sent_bytes = mg_ws_send(ws_connection, g_verif_msg_str->str, g_verif_msg_str->len, WEBSOCKET_OP_TEXT); if (sent_bytes <= 0) { syslog_server(LOG_ERR, - "Websocket upload engine: Sending verification request failed"); + "Send verification request message - sending verification request failed"); ws_data_ptr->finished = true; ws_data_ptr->success = false; } } else { syslog_server(LOG_ERR, - "Websocket upload engine: Websocket msg payload setup has gone wrong"); + "Websocket engine uploader: Send verification request message - " + "failed to construct message to send"); ws_data_ptr->finished = true; ws_data_ptr->success = false; } @@ -162,7 +166,8 @@ void send_verif_req_message(struct mg_connection *ws_connection, ws_verif_data* void process_verification_result_msg(struct mg_ws_message *ws_msg, ws_verif_data *ws_data_ptr) { if (ws_msg == NULL || ws_data_ptr == NULL) { syslog_server(LOG_ERR, - "Websocket upload engine: received message or ws_verif_data is NULL"); + "Websocket engine uploader: Process verification result message - " + "invalid parameters"); return; } @@ -170,8 +175,9 @@ void process_verification_result_msg(struct mg_ws_message *ws_msg, ws_verif_data char *verif_success = strstr(ws_msg->data.ptr, msg_type_result_status_true_sig); if (verif_success) { - syslog_server(LOG_INFO, "Websocket upload engine: Verification Server finished," - " verification succeeded"); + syslog_server(LOG_INFO, + "Websocket engine uploader: Process verification result message - " + "engine satisfies all its properties"); ws_data_ptr->success = true; ws_data_ptr->finished = true; } else { @@ -180,13 +186,15 @@ void process_verification_result_msg(struct mg_ws_message *ws_msg, ws_verif_data char *status_false_in_reply = strstr(ws_msg->data.ptr, msg_type_result_status_false_sig); if (!status_false_in_reply) { // No 'status' field in answer with either true or false - syslog_server(LOG_INFO, "Websocket upload engine: Verification Server finished," - " verification status not specified"); - ws_data_ptr->message = g_string_new("Verification finished but no result status known."); + syslog_server(LOG_INFO, + "Websocket engine uploader: Process verification result message - " + "engine verification result inconclusive"); + ws_data_ptr->message = g_string_new("Engine verification done but result is unknown."); } else { // Ordinary failure. Save server's reply (to forward to client later on) - syslog_server(LOG_INFO, "Websocket upload engine: Verification Server finished, " - "verification did not succeed"); + syslog_server(LOG_INFO, + "Websocket engine uploader: Process verification result message - " + "engine does not satisfy all its properties"); ws_data_ptr->message = g_string_new(""); g_string_append_printf(ws_data_ptr->message,"%s", ws_msg->data.ptr); } @@ -207,16 +215,18 @@ void process_verif_server_reply(struct mg_ws_message *ws_msg, ws_verif_data *ws_ // Parses mg_ws_message, which is expected to contain a message from the verification server. // Then adjusts ws_data_ptr struct according to server's message. if (ws_msg == NULL || ws_data_ptr == NULL) { - syslog_server(LOG_INFO, - "Websocket upload engine: Can't process verification server reply, " + syslog_server(LOG_ERR, + "Websocket engine uploader: Process verification server reply - " "invalid parameters"); + return; } // Check that expected field "__MESSAGE_TYPE__" is contained in message char *msg_type_is_defined = strstr(ws_msg->data.ptr, msg_type_field_key); if (!msg_type_is_defined) { - syslog_server(LOG_INFO, - "Websocket upload engine: Verification Server replied in unknown format"); + syslog_server(LOG_ERR, + "Websocket engine uploader: Process verification server reply - " + "reply lacks __MESSAGE_TYPE__ field"); return; } @@ -227,16 +237,20 @@ void process_verif_server_reply(struct mg_ws_message *ws_msg, ws_verif_data *ws_ if (type_verif_req_received) { // verification has started syslog_server(LOG_INFO, - "Websocket upload engine: Verification Server started verification"); + "Websocket engine uploader: Process verification server reply - " + "verification server begun verification"); ws_data_ptr->started = true; } else if (type_verif_req_result) { + syslog_server(LOG_INFO, + "Websocket engine uploader: Process verification server reply - " + "verification server completed verification"); // verification has finished, parse result (updates ws_data_ptr) process_verification_result_msg(ws_msg, ws_data_ptr); } else { // Unknown message type specified by the server. syslog_server(LOG_WARNING, - "Websocket upload engine: Verification Server replied " - "in unknown format"); + "Websocket engine uploader: Process verification server reply - " + "invalid reply format"); // We are pessimistic and assume that the verification server will not reply again // after this "mistake" ws_data_ptr->success = false; @@ -261,13 +275,13 @@ void websocket_verification_callback(struct mg_connection *ws_connection, ws_verif_data *ws_data_ptr = fn_data; if (ws_connection == NULL) { syslog_server(LOG_ERR, - "Websocket upload engine: ws_connection is NULL in Websocket callback"); + "Websocket engine uploader: verification callback - connection is NULL"); // Error is encountered, the verification can't be completed ws_data_ptr->success = false; ws_data_ptr->finished = true; } else if (ev == MG_EV_ERROR) { syslog_server(LOG_ERR, - "Websocket upload engine: Websocket callback received error event: %s", + "Websocket engine uploader: verification callback - received error event: %s", (char *) ev_data); // Error is encountered, the verification can't be completed ws_data_ptr->success = false; @@ -280,7 +294,8 @@ void websocket_verification_callback(struct mg_connection *ws_connection, process_verif_server_reply((struct mg_ws_message *) ev_data, ws_data_ptr); } else if (ev == MG_EV_CLOSE) { syslog_server(LOG_INFO, - "Websocket upload engine: Closing websocket connection to verifier server"); + "Websocket engine uploader: verification callback - " + "closing websocket connection to verifier server"); ws_data_ptr->finished = true; } } @@ -292,10 +307,11 @@ verif_result verify_engine_model(const char* f_filepath) { if (verifier_url == NULL) { syslog_server(LOG_ERR, - "Websocket upload engine: No verifier URL has been set, abort"); + "Websocket engine uploader: Verify engine model - " + "no verifier URL has been set, abort"); verif_result result_data; result_data.success = false; - result_data.message = g_string_new("No verifier URL has been set, " + result_data.message = g_string_new("No verifier server URL has been set, " "thus no verification was possible"); return result_data; } @@ -320,7 +336,8 @@ verif_result verify_engine_model(const char* f_filepath) { ws_verif_data.finished = true; ws_verif_data.success = false; syslog_server(LOG_WARNING, - "Websocket upload engine: Verification did not start within %d ms, abort", + "Websocket engine uploader: Verify engine model - " + "verification did not start within %d ms, abort", (poll_counter * websocket_single_poll_length_ms)); } } @@ -346,8 +363,7 @@ verif_result verify_engine_model(const char* f_filepath) { void set_verifier_url(const char *upd_verifier_url) { if (upd_verifier_url == NULL) { - syslog_server(LOG_WARNING, - "Websocket set verifier url: proposed URL is NULL, URL not updated"); + syslog_server(LOG_WARNING, "Set verifier URL - proposed URL is NULL, URL not updated"); return; } if (verifier_url != NULL) { @@ -355,8 +371,7 @@ void set_verifier_url(const char *upd_verifier_url) { verifier_url = NULL; } verifier_url = strdup(upd_verifier_url); - syslog_server(LOG_NOTICE, - "Websocket set verifier url: verifier URL set to: %s", verifier_url); + syslog_server(LOG_NOTICE, "Set verifier URL - verifier URL set to: %s", verifier_url); } @@ -394,15 +409,14 @@ void load_cached_verifier_url() { free(buffer); syslog_server(LOG_INFO, - "Websocket load cached verifier url: loaded %s from cache", + "Load cached verifier URL - loaded URL %s from cache", verifier_url); } else { - syslog_server(LOG_NOTICE, - "Websocket load cached verifier url: no content in cache file"); + syslog_server(LOG_NOTICE, "Load cached verifier URL - no content in cache file"); } } else { syslog_server(LOG_NOTICE, - "Websocket load cached verifier url: url cache file could not be opened"); + "Load cached verifier URL - cache file could not be opened"); } } @@ -410,20 +424,20 @@ void load_cached_verifier_url() { void cache_verifier_url() { // write current verifier url to cache file unless url is null if (verifier_url == NULL) { - syslog_server(LOG_NOTICE, "Websocket cache verifier url: url not cached as it is NULL"); + syslog_server(LOG_NOTICE, "Cache verifier URL - not cached as URL is NULL"); return; } // Open file, write string into file, close file. FILE* file = fopen(cache_file_verifier_url, "w"); if (file == NULL) { - syslog_server(LOG_ERR, "Websocket cache verifier url: file opening failed"); + syslog_server(LOG_ERR, "Cache verifier URL - cache file opening failed"); return; } // Write the content to the file fputs(verifier_url, file); - syslog_server(LOG_INFO, "Websocket cache verifier url: cached url %s", verifier_url); + syslog_server(LOG_INFO, "Cache verifier URL - cached URL %s", verifier_url); // Close the file fclose(file);