#include #include #include #include #include #include #include #include #include #include #include "UniFi/Device.h" #include "Bluetooth/Device.h" int main(int argc, char** argv) { try { setlogmask(LOG_UPTO(LOG_INFO)); openlog("PresenceDetection", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER); boost::program_options::options_description description("Options"); description.add_options() ("help,h", "Provide Help Message") ("daemon,d", "Run the process as Daemon"); boost::program_options::variables_map vm; boost::program_options::store(boost::program_options::parse_command_line(argc, argv, description), vm); boost::program_options::notify(vm); if (vm.count("help")) { std::cerr << description << std::endl; return 1; } bool daemon = false; if (vm.count("daemon")) daemon = true; boost::property_tree::ptree pt; boost::property_tree::ini_parser::read_ini("PresenceDetection.ini", pt); if (daemon) { syslog(LOG_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; boost::optional presenceDetectionTarget = pt.get_child_optional("PresenceDetection.Target"); if (presenceDetectionTarget) target = pt.get("PresenceDetection.Target"); else throw std::runtime_error("Target directive missing in ini file."); bool unifi = false; boost::optional presenceDetectionUniFi = pt.get_child_optional("PresenceDetection.UniFi"); if (presenceDetectionUniFi) unifi = (pt.get("PresenceDetection.UniFi") == "On"); bool bluetooth = false; boost::optional presenceDetectionBluetooth = pt.get_child_optional("PresenceDetection.Bluetooth"); if (presenceDetectionBluetooth) bluetooth = (pt.get("PresenceDetection.Bluetooth") == "On"); std::shared_ptr pUniFiDevice; if (unifi) { std::string hostname; boost::optional unifiHostname = pt.get_child_optional("UniFi.Hostname"); if (unifiHostname) hostname = pt.get("UniFi.Hostname"); else throw std::runtime_error("UniFi Hostname directive missing in ini file."); std::string username; boost::optional unifiUsername = pt.get_child_optional("UniFi.Username"); if (unifiUsername) username = pt.get("UniFi.Username"); else throw std::runtime_error("UniFi Username directive missing in ini file."); std::string password; boost::optional unifiPassword = pt.get_child_optional("UniFi.Password"); if (unifiPassword) password = pt.get("UniFi.Password"); else throw std::runtime_error("UniFi Password directive missing in ini file."); std::string cookiefile; boost::optional unifiCookieFile = pt.get_child_optional("UniFi.CookieFile"); if (unifiCookieFile) cookiefile = pt.get("UniFi.CookieFile"); else throw std::runtime_error("UniFi CookieFile directive missing in ini file."); std::string inventoryURL; boost::optional bluetoothInventoryURL = pt.get_child_optional("UniFi.Inventory"); if (bluetoothInventoryURL) inventoryURL = pt.get("UniFi.Inventory"); else 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; boost::optional bluetoothInventoryURL = pt.get_child_optional("Bluetooth.Inventory"); if (bluetoothInventoryURL) inventoryURL = pt.get("Bluetooth.Inventory"); else 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); syslog(LOG_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; syslog(LOG_ERR, "%s", ss.str().c_str()); closelog(); return -1; } return 0; }