#include "Driver.h" #include "Functions.h" #include #include #include #include namespace PresenceDetection { namespace Bluetooth { Driver::Driver(int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices) : m_timeout(timeout), m_checkInterval(3), m_inventoryURL(inventoryURL), m_target(target), m_staticDevices(staticDevices) { if (!m_inventoryURL.empty()) UpdateDevicesFromInventory(); ClearDevices(); Start(); } Driver::~Driver() { } void Driver::Start() { int checkInterval = m_checkInterval * 1000; m_deviceTimer.StartContinuous(checkInterval, static_cast>(std::bind(&Driver::UpdatePresentDevices, this))); if (!m_inventoryURL.empty()) m_inventoryTimer.StartContinuous(600000, static_cast>(std::bind(&Driver::UpdateDevicesFromInventory, this))); } void Driver::Stop() { m_deviceTimer.Stop(); if (!m_inventoryURL.empty()) m_inventoryTimer.Stop(); } void Driver::Wait() { m_deviceTimer.Wait(); if (!m_inventoryURL.empty()) m_inventoryTimer.Wait(); } void Driver::ClearDevices() { for (std::vector::iterator it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); ++it) { try { SendStateChange(false, it->MacAddress()); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::ClearDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } for (std::vector::iterator it = m_staticDevices.begin(); it != m_staticDevices.end(); ++it) { if (it->HasBluetoothMac()) { try { SendStateChange(false, it->BluetoothMac()); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::ClearDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } } } void Driver::UpdateDevicesFromInventory() { try { Http::HttpRequest request(m_inventoryURL); std::string devices = m_httpClient.Open(request); nlohmann::json json = nlohmann::json::parse(devices); m_dynamicDevices.clear(); for (auto& element : json) if (element["bluetooth"] != "") { std::string bluetooth = element["bluetooth"]; std::transform(bluetooth.begin(), bluetooth.end(), bluetooth.begin(), ::tolower); m_dynamicDevices.push_back(Util::DynamicDevice(bluetooth)); } } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::GetDevicesFromInventory() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } void Driver::UpdatePresentDevices() { std::vector presentDevices; std::vector ignoredDevices; for (std::vector::iterator it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); ++it) { try { bool pollDevice = false; if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->MacAddress()) == m_presentDevices.end()) { pollDevice = true; } else { it->IncrementProbeCounter(); if (it->ProbeCounter() * m_checkInterval >= m_timeout) { pollDevice = true; it->ResetProbeCounter(); } } if (pollDevice && Functions::Ping(it->MacAddress())) { if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->MacAddress()) == m_presentDevices.end()) SendStateChange(true, it->MacAddress()); presentDevices.push_back(it->MacAddress()); } else if (pollDevice) { it->ResetProbeCounter(); } else { ignoredDevices.push_back(it->MacAddress()); } } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::UpdatePresentDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } for (std::vector::iterator it = m_staticDevices.begin(); it != m_staticDevices.end(); ++it) { if (it->HasBluetoothMac()) { try { bool pollDevice = false; if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->BluetoothMac()) == m_presentDevices.end()) { pollDevice = true; } else { it->IncrementProbeCounter(); if (it->ProbeCounter() * m_checkInterval >= m_timeout) { pollDevice = true; it->ResetProbeCounter(); } } if (pollDevice && Functions::Ping(it->BluetoothMac())) { if (std::find(m_presentDevices.begin(), m_presentDevices.end(), it->BluetoothMac()) == m_presentDevices.end()) SendStateChange(true, it->BluetoothMac()); presentDevices.push_back(it->BluetoothMac()); } else if (pollDevice) { it->ResetProbeCounter(); } else { ignoredDevices.push_back(it->BluetoothMac()); } } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::UpdatePresentDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } } for (std::vector::iterator it = m_presentDevices.begin(); it != m_presentDevices.end(); ++it) if (std::find(presentDevices.begin(), presentDevices.end(), *it) == presentDevices.end() && std::find(ignoredDevices.begin(), ignoredDevices.end(), *it) == ignoredDevices.end()) SendStateChange(false, *it); for (std::vector::iterator it = m_presentDevices.begin(); it != m_presentDevices.end(); ++it) if (std::find(ignoredDevices.begin(), ignoredDevices.end(), *it) != ignoredDevices.end()) presentDevices.push_back(*it); m_presentDevices.assign(presentDevices.begin(), presentDevices.end()); } void Driver::SendStateChange(bool present, const std::string& macAddress) { char sign; if (present) sign = '+'; else sign = '-'; std::stringstream ss; ss << "Bluetooth: " << sign << " " << macAddress; Logging::Log(Logging::Severity::Info, ss.str()); if (!m_target.empty()) { std::stringstream url; url << m_target << "/Bluetooth/" << sign << "/" << macAddress; try { Http::HttpRequest request(url.str()); request.ReturnType(Http::HttpRequest::ReturnType::None); m_httpClient.Open(request); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::SendStateChange() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } for (std::vector::iterator it = m_staticDevices.begin(); it != m_staticDevices.end(); ++it) { if (it->HasBluetoothMac() && it->BluetoothMac() == macAddress) { it->SetBluetoothState(present); std::vector urls; if (present) { if (!it->GetWifiState() && it->HasOnlineURL()) urls.push_back(it->OnlineURL()); if (it->HasBluetoothOnlineURL()) urls.push_back(it->BluetoothOnlineURL()); } else if (!present) { if (!it->GetWifiState() && it->HasOfflineURL()) urls.push_back(it->OfflineURL()); if (it->HasBluetoothOfflineURL()) urls.push_back(it->BluetoothOfflineURL()); } for (auto& url : urls) { try { Http::HttpRequest request(url); request.ReturnType(Http::HttpRequest::ReturnType::None); m_httpClient.Open(request); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Driver::SendStateChange() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } } } } } // namespace Bluetooth } // namespace PresenceDetection