#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include config_t global_config; static MDB_env *mdb_env; static controller_t *this_controller; static struct pollfd poll_fds[POLL_FDS_COUNT]; static void terminate(int signum) { LOG_INFO("terminating controller (%d)\n", signum); for(int i = 0; i < POLL_FDS_COUNT; ++i) { close(poll_fds[i].fd); } mdb_env_close(mdb_env); controller_free(this_controller); free(global_config.database); 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); /******************** LOAD CONFIG ********************/ global_config.file = "controller.ini"; global_config.log_level = LOG_LEVEL_INFO; helper_parse_cli(argc, argv, &global_config); FILE * const ini_file = fopen(global_config.file, "rb"); if(ini_file == NULL) { LOG_FATAL("config file '%s' was not found\n", global_config.file); exit(1); } if(load_ini_file( ini_file, INI_DEFAULT_FORMAT, NULL, helper_load_config, &global_config)) { LOG_FATAL("unable to parse ini file\n"); exit(1); } fclose(ini_file); if(sizeof(time_t) < 8) { LOG_WARN("this system is not using 8-bit time\n"); } /******************** SETUP DATABASE AND THIS CONTROLLER ********************/ database_setup(&mdb_env, &global_config); this_controller = controller_load(mdb_env); int fd_discovery = helper_open_discovery_socket(this_controller->discovery_port); int fd_command = helper_bind_tcp_server("0.0.0.0", this_controller->command_port, 128); this_controller->command_port = helper_get_port(fd_command); controller_save(this_controller, mdb_env); /******************** SETUP WIRINGPI ********************/ wiringPiSetup(); piFaceSetup(PIFACE_GPIO_BASE); for(uint_fast8_t i = 0; i < this_controller->relay_count; ++i) { if(global_config.relay_configs[i].driver == RELAY_DRIVER_GPIO) { pinMode(global_config.relay_configs[i].pin, OUTPUT); } } /******************** SETUP SOCKETS ********************/ int timeout_msecs = ACCEPT_TIMEOUT_MSECONDS; int ret; /* Open STREAMS device. */ poll_fds[POLL_FDS_DISCOVERY].fd = fd_discovery; poll_fds[POLL_FDS_DISCOVERY].events = POLLIN; LOG_DEBUG("setup fd_discovery as %i on index %i\n", fd_discovery, POLL_FDS_DISCOVERY); poll_fds[POLL_FDS_COMMAND].fd = fd_command; poll_fds[POLL_FDS_COMMAND].events = POLLIN; LOG_DEBUG("setup fd_command as %i on index %i\n", fd_command, POLL_FDS_COMMAND); /******************** CHECK FOR TESTING RUN ********************/ if(global_config.run_type == RUN_TYPE_TEST) { runner_test(this_controller); terminate(0); } /******************** START MAIN LOOP ********************/ for(;;) { ret = poll(poll_fds, POLL_FDS_COUNT, timeout_msecs); if(ret == 0) { handler_loop(this_controller); } if(ret > 0) { handler_poll(poll_fds, this_controller, mdb_env); } } close(fd_discovery); mdb_env_close(mdb_env); return 0; }