PresenceDetection.cc 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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. std::string inventoryURL;
  97. boost::optional<boost::property_tree::ptree&> bluetoothInventoryURL = pt.get_child_optional("UniFi.Inventory");
  98. if (bluetoothInventoryURL)
  99. inventoryURL = pt.get<std::string>("UniFi.Inventory");
  100. else
  101. throw std::runtime_error("UniFi Inventory directive missing in ini file.");
  102. pUniFiDevice = std::make_shared<PresenceDetection::UniFi::Device>(hostname, username, password, cookiefile, inventoryURL, target);
  103. }
  104. std::shared_ptr<PresenceDetection::Bluetooth::Device> pBluetoothDevice;
  105. if (bluetooth)
  106. {
  107. std::string inventoryURL;
  108. boost::optional<boost::property_tree::ptree&> bluetoothInventoryURL = pt.get_child_optional("Bluetooth.Inventory");
  109. if (bluetoothInventoryURL)
  110. inventoryURL = pt.get<std::string>("Bluetooth.Inventory");
  111. else
  112. throw std::runtime_error("Bluetooth Inventory directive missing in ini file.");
  113. pBluetoothDevice = std::make_shared<PresenceDetection::Bluetooth::Device>(inventoryURL, target);
  114. }
  115. sigset_t wset;
  116. sigemptyset(&wset);
  117. sigaddset(&wset,SIGHUP);
  118. sigaddset(&wset,SIGINT);
  119. sigaddset(&wset,SIGTERM);
  120. int sig;
  121. sigwait(&wset,&sig);
  122. syslog(LOG_INFO, "Stopping...");
  123. if (pUniFiDevice)
  124. pUniFiDevice->Stop();
  125. if (pBluetoothDevice)
  126. pBluetoothDevice->Stop();
  127. if (pUniFiDevice)
  128. pUniFiDevice->Wait();
  129. if (pBluetoothDevice)
  130. pBluetoothDevice->Wait();
  131. closelog();
  132. }
  133. catch (const std::exception& e)
  134. {
  135. std::stringstream ss;
  136. ss << "ERROR: " << e.what() << std::endl;
  137. std::cerr << ss.str() << std::endl;
  138. syslog(LOG_ERR, "%s", ss.str().c_str());
  139. closelog();
  140. return -1;
  141. }
  142. return 0;
  143. }