PresenceDetection.cc 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. #include <iostream>
  2. #include <string>
  3. #include <signal.h>
  4. #include <syslog.h>
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <boost/lexical_cast.hpp>
  8. #include <boost/program_options.hpp>
  9. #include <boost/property_tree/ptree.hpp>
  10. #include <boost/property_tree/ini_parser.hpp>
  11. #include "UniFi/Device.h"
  12. #include "Bluetooth/Device.h"
  13. int main(int argc, char** argv)
  14. {
  15. try
  16. {
  17. setlogmask(LOG_UPTO(LOG_INFO));
  18. openlog("PresenceDetection", LOG_CONS | LOG_NDELAY | LOG_PERROR | LOG_PID, LOG_USER);
  19. boost::program_options::options_description description("Options");
  20. description.add_options()
  21. ("help,h", "Provide Help Message")
  22. ("daemon,d", "Run the process as Daemon");
  23. boost::program_options::variables_map vm;
  24. boost::program_options::store(boost::program_options::parse_command_line(argc, argv, description), vm);
  25. boost::program_options::notify(vm);
  26. if (vm.count("help"))
  27. {
  28. std::cerr << description << std::endl;
  29. return 1;
  30. }
  31. bool daemon = false;
  32. if (vm.count("daemon"))
  33. daemon = true;
  34. boost::property_tree::ptree pt;
  35. boost::property_tree::ini_parser::read_ini("PresenceDetection.ini", pt);
  36. if (daemon)
  37. {
  38. syslog(LOG_INFO, "Starting Daemon");
  39. pid_t pid, sid;
  40. pid = fork();
  41. if (pid < 0)
  42. exit(EXIT_FAILURE);
  43. if (pid > 0)
  44. exit(EXIT_SUCCESS);
  45. umask(0);
  46. sid = setsid();
  47. if (sid < 0)
  48. exit(EXIT_FAILURE);
  49. if ((chdir("/")) < 0)
  50. exit(EXIT_FAILURE);
  51. close(STDIN_FILENO);
  52. close(STDOUT_FILENO);
  53. close(STDERR_FILENO);
  54. }
  55. std::string target;
  56. boost::optional<boost::property_tree::ptree&> presenceDetectionTarget = pt.get_child_optional("PresenceDetection.Target");
  57. if (presenceDetectionTarget)
  58. target = pt.get<std::string>("PresenceDetection.Target");
  59. else
  60. throw std::runtime_error("Target directive missing in ini file.");
  61. bool unifi = false;
  62. boost::optional<boost::property_tree::ptree&> presenceDetectionUniFi = pt.get_child_optional("PresenceDetection.UniFi");
  63. if (presenceDetectionUniFi)
  64. unifi = (pt.get<std::string>("PresenceDetection.UniFi") == "On");
  65. bool bluetooth = false;
  66. boost::optional<boost::property_tree::ptree&> presenceDetectionBluetooth = pt.get_child_optional("PresenceDetection.Bluetooth");
  67. if (presenceDetectionBluetooth)
  68. bluetooth = (pt.get<std::string>("PresenceDetection.Bluetooth") == "On");
  69. std::shared_ptr<PresenceDetection::UniFi::Device> pUniFiDevice;
  70. if (unifi)
  71. {
  72. std::string hostname;
  73. boost::optional<boost::property_tree::ptree&> unifiHostname = pt.get_child_optional("UniFi.Hostname");
  74. if (unifiHostname)
  75. hostname = pt.get<std::string>("UniFi.Hostname");
  76. else
  77. throw std::runtime_error("UniFi Hostname directive missing in ini file.");
  78. std::string username;
  79. boost::optional<boost::property_tree::ptree&> unifiUsername = pt.get_child_optional("UniFi.Username");
  80. if (unifiUsername)
  81. username = pt.get<std::string>("UniFi.Username");
  82. else
  83. throw std::runtime_error("UniFi Username directive missing in ini file.");
  84. std::string password;
  85. boost::optional<boost::property_tree::ptree&> unifiPassword = pt.get_child_optional("UniFi.Password");
  86. if (unifiPassword)
  87. password = pt.get<std::string>("UniFi.Password");
  88. else
  89. throw std::runtime_error("UniFi Password directive missing in ini file.");
  90. std::string cookiefile;
  91. boost::optional<boost::property_tree::ptree&> unifiCookieFile = pt.get_child_optional("UniFi.CookieFile");
  92. if (unifiCookieFile)
  93. cookiefile = pt.get<std::string>("UniFi.CookieFile");
  94. else
  95. throw std::runtime_error("UniFi CookieFile directive missing in ini file.");
  96. pUniFiDevice = std::make_shared<PresenceDetection::UniFi::Device>(hostname, username, password, cookiefile, target);
  97. }
  98. std::shared_ptr<PresenceDetection::Bluetooth::Device> pBluetoothDevice;
  99. if (bluetooth)
  100. {
  101. std::string inventoryURL;
  102. boost::optional<boost::property_tree::ptree&> bluetoothInventoryURL = pt.get_child_optional("Bluetooth.Inventory");
  103. if (bluetoothInventoryURL)
  104. inventoryURL = pt.get<std::string>("Bluetooth.Inventory");
  105. else
  106. throw std::runtime_error("Bluetooth Inventory directive missing in ini file.");
  107. pBluetoothDevice = std::make_shared<PresenceDetection::Bluetooth::Device>(inventoryURL, target);
  108. }
  109. sigset_t wset;
  110. sigemptyset(&wset);
  111. sigaddset(&wset,SIGHUP);
  112. sigaddset(&wset,SIGINT);
  113. sigaddset(&wset,SIGTERM);
  114. int sig;
  115. sigwait(&wset,&sig);
  116. syslog(LOG_INFO, "Stopping...");
  117. if (pUniFiDevice)
  118. pUniFiDevice->Stop();
  119. if (pBluetoothDevice)
  120. pBluetoothDevice->Stop();
  121. if (pUniFiDevice)
  122. pUniFiDevice->Wait();
  123. if (pBluetoothDevice)
  124. pBluetoothDevice->Wait();
  125. closelog();
  126. }
  127. catch (const std::exception& e)
  128. {
  129. std::stringstream ss;
  130. ss << "ERROR: " << e.what() << std::endl;
  131. std::cerr << ss.str() << std::endl;
  132. syslog(LOG_ERR, "%s", ss.str().c_str());
  133. closelog();
  134. return -1;
  135. }
  136. return 0;
  137. }