#include "Bluetooth/Device.h" #include "UniFi/Device.h" #include "Util/StaticDevice.h" #include "Util/INIh.h" #include #include #include #include #include #include #include #include #include #include int main(int argc, char** argv) { try { Logging::OpenLog(); Logging::SetLogMask(Logging::Severity::Debug); bool daemon = false; clipp::group cli { clipp::option("-d", "--daemon").set(daemon).doc("Run the process as Daemon") }; if (!clipp::parse(argc, argv, cli)) { std::cout << clipp::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) { Logging::Log(Logging::Severity::Info, "Starting PresenceDetection 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); } else { Logging::Log(Logging::Severity::Info, "Starting PresenceDetection"); } std::string target = iniReader.Get("PresenceDetection", "Target", ""); bool unifi = iniReader.GetBoolean("PresenceDetection", "UniFi", false); bool bluetooth = iniReader.GetBoolean("PresenceDetection", "Bluetooth", false); std::vector staticDevices; auto sections = iniReader.Sections(); for (auto section : sections) { if (section != "PresenceDetection" && section != "UniFi" && section != "Bluetooth") { std::string WifiMac = iniReader.Get(section, "WifiMac", ""); std::string BluetoothMac = iniReader.Get(section, "BluetoothMac", ""); if (WifiMac.empty() && BluetoothMac.empty()) { std::stringstream ss; ss << section << ": No Wifi or Bluetooth Mac address defined" << std::endl; throw std::runtime_error(ss.str()); } auto staticDevice = PresenceDetection::Util::StaticDevice(WifiMac, BluetoothMac); std::string OnlineURL = iniReader.Get(section, "OnlineURL", ""); if (!OnlineURL.empty()) staticDevice.SetOnlineURL(OnlineURL); std::string WifiOnlineURL = iniReader.Get(section, "WifiOnlineURL", ""); if (!WifiOnlineURL.empty()) staticDevice.SetWifiOnlineURL(WifiOnlineURL); std::string BluetoothOnlineURL = iniReader.Get(section, "BluetoothOnlineURL", ""); if (!BluetoothOnlineURL.empty()) staticDevice.SetBluetoothOnlineURL(BluetoothOnlineURL); std::string OfflineURL = iniReader.Get(section, "OfflineURL", ""); if (!OfflineURL.empty()) staticDevice.SetOfflineURL(OfflineURL); std::string WifiOfflineURL = iniReader.Get(section, "WifiOfflineURL", ""); if (!WifiOfflineURL.empty()) staticDevice.SetWifiOfflineURL(WifiOfflineURL); std::string BluetoothOfflineURL = iniReader.Get(section, "BluetoothOfflineURL", ""); if (!BluetoothOfflineURL.empty()) staticDevice.SetBluetoothOfflineURL(BluetoothOfflineURL); staticDevices.push_back(staticDevice); } } 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."); int port = iniReader.GetInteger("UniFi", "Port", 8443); 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."); int timeout = iniReader.GetInteger("UniFi", "Timeout", 150); std::string inventoryURL = iniReader.Get("UniFi", "Inventory", ""); pUniFiDevice = std::make_shared(hostname, port, username, password, cookiefile, timeout, inventoryURL, target, staticDevices); } std::shared_ptr pBluetoothDevice; if (bluetooth) { int timeout = iniReader.GetInteger("Bluetooth", "Timeout", 150); std::string inventoryURL = iniReader.Get("Bluetooth", "Inventory", ""); pBluetoothDevice = std::make_shared(timeout, inventoryURL, target, staticDevices); } sigset_t wset; sigemptyset(&wset); sigaddset(&wset,SIGHUP); sigaddset(&wset,SIGINT); sigaddset(&wset,SIGTERM); int sig; sigwait(&wset,&sig); Logging::Log(Logging::Severity::Info, "Stopping PresenceDetection..."); if (pUniFiDevice) pUniFiDevice->Stop(); if (pBluetoothDevice) pBluetoothDevice->Stop(); if (pUniFiDevice) pUniFiDevice->Wait(); if (pBluetoothDevice) pBluetoothDevice->Wait(); Logging::CloseLog(); } catch (const std::exception& e) { std::stringstream ss; ss << "ERROR: " << e.what() << std::endl; std::cerr << ss.str() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); Logging::CloseLog(); return -1; } return 0; }