PresenceDetection.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. #include <iostream>
  2. #include <string>
  3. #include <signal.h>
  4. #include <syslog.h>
  5. #include <unistd.h>
  6. #include <vector>
  7. #include <sys/types.h>
  8. #include <sys/stat.h>
  9. #include "Util/clipp.h"
  10. #include "Util/Device.h"
  11. #include "Util/INIh.h"
  12. #include "Util/Logger.h"
  13. #include "UniFi/Device.h"
  14. #include "Bluetooth/Device.h"
  15. int main(int argc, char** argv)
  16. {
  17. try
  18. {
  19. setlogmask(LOG_UPTO(LOG_DEBUG));
  20. openlog("PresenceDetection", LOG_NDELAY | LOG_PID, LOG_USER);
  21. bool daemon = false;
  22. PresenceDetection::Util::clipp::group cli {
  23. PresenceDetection::Util::clipp::option("-d", "--daemon").set(daemon).doc("Run the process as Daemon")
  24. };
  25. if (!PresenceDetection::Util::clipp::parse(argc, argv, cli))
  26. {
  27. std::cout << PresenceDetection::Util::clipp::make_man_page(cli, argv[0]) << std::endl;
  28. return 1;
  29. }
  30. PresenceDetection::Util::INIReader iniReader("PresenceDetection.ini");
  31. if (iniReader.ParseError() != 0)
  32. {
  33. std::cerr << "Can't read PresenceDetection.ini" << std::endl;
  34. return 1;
  35. }
  36. if (daemon)
  37. {
  38. PresenceDetection::Util::Logger::Log(PresenceDetection::Util::Logger::Severity::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 = iniReader.Get("PresenceDetection", "Target", "");
  56. bool unifi = iniReader.GetBoolean("PresenceDetection", "UniFi", false);
  57. bool bluetooth = iniReader.GetBoolean("PresenceDetection", "Bluetooth", false);
  58. std::vector<PresenceDetection::Util::Device> devices;
  59. auto sections = iniReader.Sections();
  60. for (auto section : sections)
  61. {
  62. if (section != "PresenceDetection" &&
  63. section != "UniFi" &&
  64. section != "Bluetooth")
  65. {
  66. std::string WifiMac = iniReader.Get(section, "WifiMac", "");
  67. std::string BluetoothMac = iniReader.Get(section, "BluetoothMac", "");
  68. if (WifiMac.empty() && BluetoothMac.empty())
  69. {
  70. std::stringstream ss;
  71. ss << section << ": No Wifi or Bluetooth Mac address defined" << std::endl;
  72. throw std::runtime_error(ss.str());
  73. }
  74. auto device = PresenceDetection::Util::Device(WifiMac, BluetoothMac);
  75. std::string OnlineURL = iniReader.Get(section, "OnlineURL", "");
  76. if (!OnlineURL.empty())
  77. device.SetOnlineURL(OnlineURL);
  78. std::string WifiOnlineURL = iniReader.Get(section, "WifiOnlineURL", "");
  79. if (!WifiOnlineURL.empty())
  80. device.SetWifiOnlineURL(WifiOnlineURL);
  81. std::string BluetoothOnlineURL = iniReader.Get(section, "BluetoothOnlineURL", "");
  82. if (!BluetoothOnlineURL.empty())
  83. device.SetBluetoothOnlineURL(BluetoothOnlineURL);
  84. std::string OfflineURL = iniReader.Get(section, "OfflineURL", "");
  85. if (!OfflineURL.empty())
  86. device.SetOfflineURL(OfflineURL);
  87. std::string WifiOfflineURL = iniReader.Get(section, "WifiOfflineURL", "");
  88. if (!WifiOfflineURL.empty())
  89. device.SetWifiOfflineURL(WifiOfflineURL);
  90. std::string BluetoothOfflineURL = iniReader.Get(section, "BluetoothOfflineURL", "");
  91. if (!BluetoothOfflineURL.empty())
  92. device.SetBluetoothOfflineURL(BluetoothOfflineURL);
  93. devices.push_back(device);
  94. }
  95. }
  96. std::shared_ptr<PresenceDetection::UniFi::Device> pUniFiDevice;
  97. if (unifi)
  98. {
  99. std::string hostname = iniReader.Get("UniFi", "Hostname", "");
  100. if (hostname.empty())
  101. throw std::runtime_error("UniFi Hostname directive missing in ini file.");
  102. int port = iniReader.GetInteger("UniFi", "Port", 8443);
  103. std::string username = iniReader.Get("UniFi", "Username", "");
  104. if (username.empty())
  105. throw std::runtime_error("UniFi Username directive missing in ini file.");
  106. std::string password = iniReader.Get("UniFi", "Password", "");
  107. if (password.empty())
  108. throw std::runtime_error("UniFi Password directive missing in ini file.");
  109. std::string cookiefile = iniReader.Get("UniFi", "CookieFile", "");
  110. if (cookiefile.empty())
  111. throw std::runtime_error("UniFi CookieFile directive missing in ini file.");
  112. int timeout = iniReader.GetInteger("UniFi", "Timeout", 150);
  113. std::string inventoryURL = iniReader.Get("UniFi", "Inventory", "");
  114. pUniFiDevice = std::make_shared<PresenceDetection::UniFi::Device>(hostname, port, username, password, cookiefile, timeout, inventoryURL, target, devices);
  115. }
  116. std::shared_ptr<PresenceDetection::Bluetooth::Device> pBluetoothDevice;
  117. if (bluetooth)
  118. {
  119. int timeout = iniReader.GetInteger("Bluetooth", "Timeout", 150);
  120. std::string inventoryURL = iniReader.Get("Bluetooth", "Inventory", "");
  121. pBluetoothDevice = std::make_shared<PresenceDetection::Bluetooth::Device>(timeout, inventoryURL, target, devices);
  122. }
  123. sigset_t wset;
  124. sigemptyset(&wset);
  125. sigaddset(&wset,SIGHUP);
  126. sigaddset(&wset,SIGINT);
  127. sigaddset(&wset,SIGTERM);
  128. int sig;
  129. sigwait(&wset,&sig);
  130. PresenceDetection::Util::Logger::Log(PresenceDetection::Util::Logger::Severity::Info, "Stopping...");
  131. if (pUniFiDevice)
  132. pUniFiDevice->Stop();
  133. if (pBluetoothDevice)
  134. pBluetoothDevice->Stop();
  135. if (pUniFiDevice)
  136. pUniFiDevice->Wait();
  137. if (pBluetoothDevice)
  138. pBluetoothDevice->Wait();
  139. closelog();
  140. }
  141. catch (const std::exception& e)
  142. {
  143. std::stringstream ss;
  144. ss << "ERROR: " << e.what() << std::endl;
  145. std::cerr << ss.str() << std::endl;
  146. PresenceDetection::Util::Logger::Log(PresenceDetection::Util::Logger::Severity::Error, ss.str());
  147. closelog();
  148. return -1;
  149. }
  150. return 0;
  151. }