Driver.cpp 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. #include "Driver.h"
  2. #include "Functions.h"
  3. #include <json.hpp>
  4. #include <Logging.h>
  5. #include <algorithm>
  6. #include <sstream>
  7. namespace PresenceDetection {
  8. namespace Bluetooth {
  9. Driver::Driver(int timeout, const std::string& inventoryURL, const std::string& target, const std::vector<Util::StaticDevice>& staticDevices) :
  10. m_timeout(timeout),
  11. m_checkInterval(3),
  12. m_inventoryURL(inventoryURL),
  13. m_target(target),
  14. m_staticDevices(staticDevices)
  15. {
  16. if (!m_inventoryURL.empty())
  17. UpdateDevicesFromInventory();
  18. ClearDevices();
  19. Start();
  20. }
  21. Driver::~Driver()
  22. {
  23. }
  24. void Driver::Start()
  25. {
  26. int checkInterval = m_checkInterval * 1000;
  27. m_deviceTimer.StartContinuous(checkInterval, static_cast<std::function<void()>>(std::bind(&Driver::UpdatePresentDevices, this)));
  28. if (!m_inventoryURL.empty())
  29. m_inventoryTimer.StartContinuous(600000, static_cast<std::function<void()>>(std::bind(&Driver::UpdateDevicesFromInventory, this)));
  30. }
  31. void Driver::Stop()
  32. {
  33. m_deviceTimer.Stop();
  34. if (!m_inventoryURL.empty())
  35. m_inventoryTimer.Stop();
  36. }
  37. void Driver::Wait()
  38. {
  39. m_deviceTimer.Wait();
  40. if (!m_inventoryURL.empty())
  41. m_inventoryTimer.Wait();
  42. }
  43. void Driver::ClearDevices()
  44. {
  45. for (std::vector<Util::DynamicDevice>::iterator it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); ++it)
  46. {
  47. try
  48. {
  49. SendStateChange(false, it->MacAddress());
  50. }
  51. catch (const std::exception& e)
  52. {
  53. std::stringstream ss;
  54. ss << "Bluetooth::Driver::ClearDevices() - Error: " << e.what() << std::endl;
  55. Logging::Log(Logging::Severity::Error, ss.str());
  56. }
  57. }
  58. for (std::vector<Util::StaticDevice>::iterator it = m_staticDevices.begin(); it != m_staticDevices.end(); ++it)
  59. {
  60. if (it->HasBluetoothMac())
  61. {
  62. try
  63. {
  64. SendStateChange(false, it->BluetoothMac());
  65. }
  66. catch (const std::exception& e)
  67. {
  68. std::stringstream ss;
  69. ss << "Bluetooth::Driver::ClearDevices() - Error: " << e.what() << std::endl;
  70. Logging::Log(Logging::Severity::Error, ss.str());
  71. }
  72. }
  73. }
  74. }
  75. void Driver::UpdateDevicesFromInventory()
  76. {
  77. try
  78. {
  79. Http::HttpRequest request(m_inventoryURL);
  80. std::string devices = m_httpClient.Open(request);
  81. nlohmann::json json = nlohmann::json::parse(devices);
  82. m_dynamicDevices.clear();
  83. for (auto& element : json)
  84. if (element["bluetooth"] != "")
  85. {
  86. std::string bluetooth = element["bluetooth"];
  87. std::transform(bluetooth.begin(), bluetooth.end(), bluetooth.begin(), ::tolower);
  88. m_dynamicDevices.push_back(Util::DynamicDevice(bluetooth));
  89. }
  90. }
  91. catch (const std::exception& e)
  92. {
  93. std::stringstream ss;
  94. ss << "Bluetooth::Driver::GetDevicesFromInventory() - Error: " << e.what() << std::endl;
  95. Logging::Log(Logging::Severity::Error, ss.str());
  96. }
  97. }
  98. void Driver::UpdatePresentDevices()
  99. {
  100. std::vector<std::string> presentDevices;
  101. std::vector<std::string> ignoredDevices;
  102. for (std::vector<Util::DynamicDevice>::iterator it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); ++it)
  103. {
  104. try
  105. {
  106. bool pollDevice = false;
  107. if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->MacAddress()) == m_presentDevices.end())
  108. {
  109. pollDevice = true;
  110. }
  111. else
  112. {
  113. it->IncrementProbeCounter();
  114. if (it->ProbeCounter() * m_checkInterval >= m_timeout)
  115. {
  116. pollDevice = true;
  117. it->ResetProbeCounter();
  118. }
  119. }
  120. if (pollDevice && Functions::Ping(it->MacAddress()))
  121. {
  122. if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->MacAddress()) == m_presentDevices.end())
  123. SendStateChange(true, it->MacAddress());
  124. presentDevices.push_back(it->MacAddress());
  125. }
  126. else if (pollDevice)
  127. {
  128. it->ResetProbeCounter();
  129. }
  130. else
  131. {
  132. ignoredDevices.push_back(it->MacAddress());
  133. }
  134. }
  135. catch (const std::exception& e)
  136. {
  137. std::stringstream ss;
  138. ss << "Bluetooth::Driver::UpdatePresentDevices() - Error: " << e.what() << std::endl;
  139. Logging::Log(Logging::Severity::Error, ss.str());
  140. }
  141. }
  142. for (std::vector<Util::StaticDevice>::iterator it = m_staticDevices.begin(); it != m_staticDevices.end(); ++it)
  143. {
  144. if (it->HasBluetoothMac())
  145. {
  146. try
  147. {
  148. bool pollDevice = false;
  149. if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->BluetoothMac()) == m_presentDevices.end())
  150. {
  151. pollDevice = true;
  152. }
  153. else
  154. {
  155. it->IncrementProbeCounter();
  156. if (it->ProbeCounter() * m_checkInterval >= m_timeout)
  157. {
  158. pollDevice = true;
  159. it->ResetProbeCounter();
  160. }
  161. }
  162. if (pollDevice && Functions::Ping(it->BluetoothMac()))
  163. {
  164. if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->BluetoothMac()) == m_presentDevices.end())
  165. SendStateChange(true, it->BluetoothMac());
  166. presentDevices.push_back(it->BluetoothMac());
  167. }
  168. else if (pollDevice)
  169. {
  170. it->ResetProbeCounter();
  171. }
  172. else
  173. {
  174. ignoredDevices.push_back(it->BluetoothMac());
  175. }
  176. }
  177. catch (const std::exception& e)
  178. {
  179. std::stringstream ss;
  180. ss << "Bluetooth::Driver::UpdatePresentDevices() - Error: " << e.what() << std::endl;
  181. Logging::Log(Logging::Severity::Error, ss.str());
  182. }
  183. }
  184. }
  185. for (std::vector<std::string>::iterator it = m_presentDevices.begin(); it != m_presentDevices.end(); ++it)
  186. if (std::find(presentDevices.begin(), presentDevices.end(), *it) == presentDevices.end() &&
  187. std::find(ignoredDevices.begin(), ignoredDevices.end(), *it) == ignoredDevices.end())
  188. SendStateChange(false, *it);
  189. for (std::vector<std::string>::iterator it = m_presentDevices.begin(); it != m_presentDevices.end(); ++it)
  190. if (std::find(ignoredDevices.begin(), ignoredDevices.end(), *it) != ignoredDevices.end())
  191. presentDevices.push_back(*it);
  192. m_presentDevices.assign(presentDevices.begin(), presentDevices.end());
  193. }
  194. void Driver::SendStateChange(bool present, const std::string& macAddress)
  195. {
  196. char sign;
  197. if (present)
  198. sign = '+';
  199. else
  200. sign = '-';
  201. std::stringstream ss;
  202. ss << "Bluetooth: " << sign << " " << macAddress;
  203. Logging::Log(Logging::Severity::Info, ss.str());
  204. if (!m_target.empty())
  205. {
  206. std::stringstream url;
  207. url << m_target << "/Bluetooth/" << sign << "/" << macAddress;
  208. try
  209. {
  210. Http::HttpRequest request(url.str());
  211. request.ReturnType(Http::HttpRequest::ReturnType::None);
  212. m_httpClient.Open(request);
  213. }
  214. catch (const std::exception& e)
  215. {
  216. std::stringstream ss;
  217. ss << "Bluetooth::Driver::SendStateChange() - Error: " << e.what() << std::endl;
  218. Logging::Log(Logging::Severity::Error, ss.str());
  219. }
  220. }
  221. for (std::vector<Util::StaticDevice>::iterator it = m_staticDevices.begin(); it != m_staticDevices.end(); ++it)
  222. {
  223. if (it->HasBluetoothMac() && it->BluetoothMac() == macAddress)
  224. {
  225. it->SetBluetoothState(present);
  226. std::vector<std::string> urls;
  227. if (present)
  228. {
  229. if (!it->GetWifiState() && it->HasOnlineURL())
  230. urls.push_back(it->OnlineURL());
  231. if (it->HasBluetoothOnlineURL())
  232. urls.push_back(it->BluetoothOnlineURL());
  233. }
  234. else if (!present)
  235. {
  236. if (!it->GetWifiState() && it->HasOfflineURL())
  237. urls.push_back(it->OfflineURL());
  238. if (it->HasBluetoothOfflineURL())
  239. urls.push_back(it->BluetoothOfflineURL());
  240. }
  241. for (auto& url : urls)
  242. {
  243. try
  244. {
  245. Http::HttpRequest request(url);
  246. request.ReturnType(Http::HttpRequest::ReturnType::None);
  247. m_httpClient.Open(request);
  248. }
  249. catch (const std::exception& e)
  250. {
  251. std::stringstream ss;
  252. ss << "Bluetooth::Driver::SendStateChange() - Error: " << e.what() << std::endl;
  253. Logging::Log(Logging::Severity::Error, ss.str());
  254. }
  255. }
  256. }
  257. }
  258. }
  259. } // namespace Bluetooth
  260. } // namespace PresenceDetection