#include #include #include "Util/JSON.h" #include "Util/Logger.h" #include "Functions.h" #include "Device.h" namespace PresenceDetection { namespace Bluetooth { Device::Device(int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& devices) : m_timeout(timeout), m_inventoryURL(inventoryURL), m_target(target), m_staticDevices(devices) { if (!m_inventoryURL.empty()) UpdateDevicesFromInventory(); ClearDevices(); Start(); } Device::~Device() { } void Device::Start() { int timeout = m_timeout * 1000; m_onlineDeviceTimer.StartContinuous(timeout, static_cast>(std::bind(&Device::UpdateOnlineDevices, this))); m_offlineDeviceTimer.StartContinuous(3000, static_cast>(std::bind(&Device::UpdateOfflineDevices, this))); if (!m_inventoryURL.empty()) m_inventoryTimer.StartContinuous(600000, static_cast>(std::bind(&Device::UpdateDevicesFromInventory, this))); } void Device::Stop() { m_onlineDeviceTimer.Stop(); m_offlineDeviceTimer.Stop(); if (!m_inventoryURL.empty()) m_inventoryTimer.Stop(); } void Device::Wait() { m_onlineDeviceTimer.Wait(); m_offlineDeviceTimer.Wait(); if (!m_inventoryURL.empty()) m_inventoryTimer.Wait(); } void Device::ClearDevices() { for (std::vector::iterator it = m_devices.begin(); it != m_devices.end(); ++it) { try { SendStateChange(false, *it); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Device::ClearDevices() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::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::Device::ClearDevices() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::Severity::Error, ss.str()); } } } } void Device::UpdateDevicesFromInventory() { try { std::string devices = m_httpClient.GetUrlContents(m_inventoryURL); Util::JSON json = Util::JSON::parse(devices); m_devices.clear(); for (auto& element : json) if (element["bluetooth"] != "") { std::string bluetooth = element["bluetooth"]; std::transform(bluetooth.begin(), bluetooth.end(), bluetooth.begin(), ::tolower); m_devices.push_back(bluetooth); } } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Device::GetDevicesFromInventory() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::Severity::Error, ss.str()); } } void Device::UpdateOnlineDevices() { UpdatePresentDevices(true); } void Device::UpdateOfflineDevices() { UpdatePresentDevices(false); } void Device::UpdatePresentDevices(bool updateOnlineDevices) { std::vector presentDevices; std::vector ignoredDevices; for (std::vector::iterator it = m_devices.begin(); it != m_devices.end(); ++it) { try { bool pollDevice = false; if (std::find(m_presentDevices.begin(), m_presentDevices.end(), *it) == m_presentDevices.end()) pollDevice = true; else pollDevice = updateOnlineDevices; if (pollDevice && Functions::Ping(*it)) { if (std::find(m_presentDevices.begin(), m_presentDevices.end(), *it) == m_presentDevices.end()) SendStateChange(true, *it); presentDevices.push_back(*it); } if (!pollDevice) ignoredDevices.push_back(*it); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Device::UpdatePresentDevices() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::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 pollDevice = updateOnlineDevices; 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()); } if (!pollDevice) ignoredDevices.push_back(it->BluetoothMac()); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Device::UpdatePresentDevices() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::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 Device::SendStateChange(bool present, const std::string& macAddress) { char sign; if (present) sign = '+'; else sign = '-'; std::stringstream ss; ss << "Bluetooth: " << sign << " " << macAddress; Util::Logger::Log(Util::Logger::Severity::Info, ss.str()); if (!m_target.empty()) { std::stringstream url; url << m_target << "/Bluetooth/" << sign << "/" << macAddress; try { m_httpClient.GetUrlSilent(url.str()); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Device::SendStateChange() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::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 { m_httpClient.GetUrlSilent(url); } catch (const std::exception& e) { std::stringstream ss; ss << "Bluetooth::Device::SendStateChange() - Error: " << e.what() << std::endl; Util::Logger::Log(Util::Logger::Severity::Error, ss.str()); } } } } } } // namespace Bluetooth } // namespace PresenceDetection