#include #include #include #include #include #include #include #include "Util/clipp.h" #include "Util/INIh.h" #include "Util/Logger.h" #include "UniFi/Device.h" #include "Bluetooth/Device.h" int main(int argc, char** argv) { try { setlogmask(LOG_UPTO(LOG_DEBUG)); openlog("PresenceDetection", LOG_NDELAY | LOG_PID, LOG_USER); bool daemon = false; PresenceDetection::Util::group cli { PresenceDetection::Util::option("-d", "--daemon").set(daemon).doc("Run the process as Daemon") }; if (!PresenceDetection::Util::parse(argc, argv, cli)) { std::cout << PresenceDetection::Util::make_man_page(cli, argv[0]) << std::endl; return 1; } PresenceDetection::Util::INIReader iniReader("PresenceDetection.ini"); if (iniReader.ParseError() != 0) { std::cerr << "Can't read PresenceDetection.ini" << std::endl; return 1; } if (daemon) { PresenceDetection::Util::Logger::Log(PresenceDetection::Util::Logger::Severity::Info, "Starting Daemon"); pid_t pid, sid; pid = fork(); if (pid < 0) exit(EXIT_FAILURE); if (pid > 0) exit(EXIT_SUCCESS); umask(0); sid = setsid(); if (sid < 0) exit(EXIT_FAILURE); if ((chdir("/")) < 0) exit(EXIT_FAILURE); close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); } std::string target = iniReader.Get("PresenceDetection", "Target", ""); if (target.empty()) throw std::runtime_error("Target directive missing in ini file."); bool unifi = iniReader.GetBoolean("PresenceDetection", "UniFi", false); bool bluetooth = iniReader.GetBoolean("PresenceDetection", "Bluetooth", false); std::shared_ptr pUniFiDevice; if (unifi) { std::string hostname = iniReader.Get("UniFi", "Hostname", ""); if (hostname.empty()) throw std::runtime_error("UniFi Hostname directive missing in ini file."); std::string username = iniReader.Get("UniFi", "Username", ""); if (username.empty()) throw std::runtime_error("UniFi Username directive missing in ini file."); std::string password = iniReader.Get("UniFi", "Password", ""); if (password.empty()) throw std::runtime_error("UniFi Password directive missing in ini file."); std::string cookiefile = iniReader.Get("UniFi", "CookieFile", ""); if (cookiefile.empty()) throw std::runtime_error("UniFi CookieFile directive missing in ini file."); std::string inventoryURL = iniReader.Get("UniFi", "Inventory", ""); if (inventoryURL.empty()) throw std::runtime_error("UniFi Inventory directive missing in ini file."); pUniFiDevice = std::make_shared(hostname, username, password, cookiefile, inventoryURL, target); } std::shared_ptr pBluetoothDevice; if (bluetooth) { std::string inventoryURL = iniReader.Get("Bluetooth", "Inventory", ""); if (inventoryURL.empty()) throw std::runtime_error("Bluetooth Inventory directive missing in ini file."); pBluetoothDevice = std::make_shared(inventoryURL, target); } sigset_t wset; sigemptyset(&wset); sigaddset(&wset,SIGHUP); sigaddset(&wset,SIGINT); sigaddset(&wset,SIGTERM); int sig; sigwait(&wset,&sig); PresenceDetection::Util::Logger::Log(PresenceDetection::Util::Logger::Severity::Info, "Stopping..."); if (pUniFiDevice) pUniFiDevice->Stop(); if (pBluetoothDevice) pBluetoothDevice->Stop(); if (pUniFiDevice) pUniFiDevice->Wait(); if (pBluetoothDevice) pBluetoothDevice->Wait(); closelog(); } catch (const std::exception& e) { std::stringstream ss; ss << "ERROR: " << e.what() << std::endl; std::cerr << ss.str() << std::endl; PresenceDetection::Util::Logger::Log(PresenceDetection::Util::Logger::Severity::Error, ss.str()); closelog(); return -1; } return 0; }