#include <stdlib.h> #include <string.h> #include <stdio.h> #include <time.h> #include <lmdb.h> #include <signal.h> #include <syslog.h> #include <cli.h> #include <logger.h> #include <mongoose.h> #include <models/controller.h> #include <database.h> #include <config.h> #include <connections.h> #include <constants.h> #include <handlers.h> #include <drivers.h> #include <enums.h> #include <runners.h> #include <helpers.h> #include <wiringPi.h> #include <piFace.h> #include <wiring_debug.h> static struct mg_mgr mgr; static void terminate(int signum) { LOGGER_INFO("terminating controller (%d)\n", signum); // TODO fix mg_mgr_free() causing loop (can't terminate) //LOGGER_DEBUG("freeing mongoose manager\n"); //mg_mgr_free(&mgr); LOGGER_DEBUG("closing database\n"); database_free(); LOGGER_DEBUG("freeing global controller\n"); controller_free(global_controller); LOGGER_DEBUG("freeing relay configs config\n"); free(global_config->relay_configs); exit(signum); } /** * @brief The main function * * @param argc UNUSED * @param argv UNUSED * * @return Statuscode to indicate success (0) or failure (!0) */ int main(int argc, const char** argv) { (void)argc; (void)argv; signal(SIGINT, terminate); signal(SIGABRT, terminate); signal(SIGTERM, terminate); openlog("emgauwa-controller", 0, LOG_USER); setlogmask(LOG_UPTO(LOG_INFO)); /******************** LOAD CONFIG ********************/ config_init(); cli_t cli; cli_parse(argc, argv, &cli); config_load(global_config, cli.config_file); if(global_config->logging.file == NULL) { global_config->logging.file = stdout; } if(global_config->include) { config_load_directory(global_config, global_config->include); } if(sizeof(time_t) < 8) { LOGGER_WARNING("this system is not using 8-bit time\n"); } /******************** INIT DATABASE, SOCKETS AND THIS CONTROLLER ********************/ mg_mgr_init(&mgr, NULL); database_init(); global_controller = controller_load(); if(!global_controller) { global_controller = controller_create(); controller_save(); } connection_discovery_bind(&mgr); connection_mqtt_connect(&mgr); struct mg_connection *c_command = connection_command_bind(&mgr); if(global_controller->command_port == 0) { global_controller->command_port = helper_get_port(c_command->sock); controller_save(); } controller_debug(global_controller); helper_drop_privileges(); /******************** SETUP WIRINGPI ********************/ wiringPiSetup(); int piface_setup = 0; for(uint_fast8_t i = 0; i < global_config->relay_count; ++i) { int relay_default = global_config->relay_configs[i].init; if(relay_default == -1) { relay_default = global_config->relays_init; } if(relay_default == -1) { relay_default = global_config->relay_configs[i].inverted; } if(global_config->relay_configs[i].driver == RELAY_DRIVER_GPIO) { pinMode(global_config->relay_configs[i].pin, OUTPUT); driver_gpio_set(global_config->relay_configs[i].pin, relay_default); } if(global_config->relay_configs[i].driver == RELAY_DRIVER_PIFACE) { if(!piface_setup) { piFaceSetup(PIFACE_GPIO_BASE); piface_setup = 1; } driver_piface_set(global_config->relay_configs[i].pin, relay_default); } } /******************** CHECK FOR TESTING RUN ********************/ if(cli.demo_mode) { runner_test(global_controller); terminate(0); } /******************** START MAIN LOOP ********************/ time_t timer = 0; for (;;) { mg_mgr_poll(&mgr, 200); if(time(NULL) - timer >= 1) { if(!global_connection_mqtt) { connection_mqtt_connect(&mgr); } handler_loop(global_connection_mqtt); timer = time(NULL); } } terminate(0); return 0; }