diff --git a/Application/PresenceDetection.cc b/Application/PresenceDetection.cc index 45e53a7..27b714b 100644 --- a/Application/PresenceDetection.cc +++ b/Application/PresenceDetection.cc @@ -1,6 +1,6 @@ -#include "Bluetooth/Device.h" -#include "UniFi/Device.h" +#include "Bluetooth/Driver.h" #include "Util/StaticDevice.h" +#include "WiFi/Driver.h" #include #include #include @@ -70,7 +70,7 @@ int main(int argc, char** argv) std::string target = iniReader.Get("PresenceDetection", "Target", ""); - bool unifi = iniReader.GetBoolean("PresenceDetection", "UniFi", false); + bool wifi = iniReader.GetBoolean("PresenceDetection", "WiFi", false); bool bluetooth = iniReader.GetBoolean("PresenceDetection", "Bluetooth", false); @@ -80,7 +80,7 @@ int main(int argc, char** argv) for (auto section : sections) { if (section != "PresenceDetection" && - section != "UniFi" && + section != "WiFi" && section != "Bluetooth") { std::string WifiMac = iniReader.Get(section, "WifiMac", ""); @@ -123,42 +123,42 @@ int main(int argc, char** argv) } } - std::shared_ptr pUniFiDevice; - if (unifi) + std::shared_ptr pWiFiDriver; + if (wifi) { - std::string hostname = iniReader.Get("UniFi", "Hostname", ""); + std::string hostname = iniReader.Get("WiFi", "Hostname", ""); if (hostname.empty()) - throw std::runtime_error("UniFi Hostname directive missing in ini file."); + throw std::runtime_error("WiFi Hostname directive missing in ini file."); - int port = iniReader.GetInteger("UniFi", "Port", 8443); + int port = iniReader.GetInteger("WiFi", "Port", 8443); - std::string username = iniReader.Get("UniFi", "Username", ""); + std::string username = iniReader.Get("WiFi", "Username", ""); if (username.empty()) - throw std::runtime_error("UniFi Username directive missing in ini file."); + throw std::runtime_error("WiFi Username directive missing in ini file."); - std::string password = iniReader.Get("UniFi", "Password", ""); + std::string password = iniReader.Get("WiFi", "Password", ""); if (password.empty()) - throw std::runtime_error("UniFi Password directive missing in ini file."); + throw std::runtime_error("WiFi Password directive missing in ini file."); - std::string cookiefile = iniReader.Get("UniFi", "CookieFile", ""); + std::string cookiefile = iniReader.Get("WiFi", "CookieFile", ""); if (cookiefile.empty()) - throw std::runtime_error("UniFi CookieFile directive missing in ini file."); + throw std::runtime_error("WiFi CookieFile directive missing in ini file."); - int timeout = iniReader.GetInteger("UniFi", "Timeout", 150); + int timeout = iniReader.GetInteger("WiFi", "Timeout", 150); - std::string inventoryURL = iniReader.Get("UniFi", "Inventory", ""); + std::string inventoryURL = iniReader.Get("WiFi", "Inventory", ""); - pUniFiDevice = std::make_shared(hostname, port, username, password, cookiefile, timeout, inventoryURL, target, staticDevices); + pWiFiDriver = std::make_shared(hostname, port, username, password, cookiefile, timeout, inventoryURL, target, staticDevices); } - std::shared_ptr pBluetoothDevice; + std::shared_ptr pBluetoothDriver; if (bluetooth) { int timeout = iniReader.GetInteger("Bluetooth", "Timeout", 150); std::string inventoryURL = iniReader.Get("Bluetooth", "Inventory", ""); - pBluetoothDevice = std::make_shared(timeout, inventoryURL, target, staticDevices); + pBluetoothDriver = std::make_shared(timeout, inventoryURL, target, staticDevices); } sigset_t wset; @@ -171,17 +171,17 @@ int main(int argc, char** argv) Logging::Log(Logging::Severity::Info, "Stopping PresenceDetection..."); - if (pUniFiDevice) - pUniFiDevice->Stop(); + if (pWiFiDriver) + pWiFiDriver->Stop(); - if (pBluetoothDevice) - pBluetoothDevice->Stop(); + if (pBluetoothDriver) + pBluetoothDriver->Stop(); - if (pUniFiDevice) - pUniFiDevice->Wait(); + if (pWiFiDriver) + pWiFiDriver->Wait(); - if (pBluetoothDevice) - pBluetoothDevice->Wait(); + if (pBluetoothDriver) + pBluetoothDriver->Wait(); Logging::CloseLog(); } diff --git a/Application/Test.cc b/Application/Test.cc index 3e89afc..a241732 100644 --- a/Application/Test.cc +++ b/Application/Test.cc @@ -1,11 +1,9 @@ +#include "Bluetooth/Functions.h" +#include "Logic/Logic.h" +#include "WiFi/Functions.h" #include -#include -#include #include -#include -#include #include -#include #include @@ -16,6 +14,9 @@ void print() void TestINIReader() { + std::cout << "--------------------------------" << std::endl; + std::cout << "TestINIReader" << std::endl << std::endl; + INIReader reader("PresenceDetection.ini"); std::string target = reader.Get("PresenceDetection", "Target", ""); @@ -23,22 +24,73 @@ void TestINIReader() std::cout << "Error" << std::endl; std::cout << target.size() << " " << target << std::endl; - bool unifi = reader.GetBoolean("PresenceDetection", "UniFi", false); - if (unifi) - std::cout << "UniFi On" << std::endl; + bool wifi = reader.GetBoolean("PresenceDetection", "WiFi", false); + if (wifi) + std::cout << "WiFi On" << std::endl; else - std::cout << "UniFi Off" << std::endl; + std::cout << "WiFi Off" << std::endl; bool test = reader.GetBoolean("PresenceDetection", "Test", false); if (test) std::cout << "Test On" << std::endl; else std::cout << "Test Off" << std::endl; + + std::cout << "--------------------------------" << std::endl << std::endl; +} + +void TestLogic() +{ + std::cout << "--------------------------------" << std::endl; + std::cout << "TestLogic" << std::endl << std::endl; + + PresenceDetection::Logic::Logic logic("http://DomoticaPi:8080/api/inventory/WirelessDevice"); + + logic.LoadDevicesFromConfiguration(); + logic.UpdateDevicesFromInventory(); + + logic.DumpDevices(); + + std::cout << "--------------------------------" << std::endl << std::endl; +} + +void TestPing() +{ + std::cout << "--------------------------------" << std::endl; + std::cout << "TestPing" << std::endl << std::endl; + + bool wifi = PresenceDetection::WiFi::Functions::Ping("192.168.1.174"); + if (wifi) + std::cout << "192.168.1.174 Online" << std::endl; + else + std::cout << "192.168.1.174 Offline" << std::endl; + + bool bluetooth = PresenceDetection::Bluetooth::Functions::Ping("64:C7:53:77:2A:32"); + if (bluetooth) + std::cout << "64:C7:53:77:2A:32 Online" << std::endl; + else + std::cout << "64:C7:53:77:2A:32 Offline" << std::endl; + + bluetooth = PresenceDetection::Bluetooth::Functions::Ping("C8:BC:C8:22:94:68"); + if (bluetooth) + std::cout << "C8:BC:C8:22:94:68 Online" << std::endl; + else + std::cout << "C8:BC:C8:22:94:68 Offline" << std::endl; + + bluetooth = PresenceDetection::Bluetooth::Functions::Ping("E8:9E:B4:25:E1:E8"); + if (bluetooth) + std::cout << "E8:9E:B4:25:E1:E8 Online" << std::endl; + else + std::cout << "E8:9E:B4:25:E1:E8 Offline" << std::endl; + + std::cout << "--------------------------------" << std::endl << std::endl; } int main(int /*argc*/, char** /*argv[]*/) { - TestINIReader(); + //TestINIReader(); + //TestLogic(); + TestPing(); return 0; } diff --git a/Bluetooth/Device.cpp b/Bluetooth/Driver.cpp similarity index 88% rename from Bluetooth/Device.cpp rename to Bluetooth/Driver.cpp index e292a57..5d98e69 100644 --- a/Bluetooth/Device.cpp +++ b/Bluetooth/Driver.cpp @@ -1,4 +1,4 @@ -#include "Device.h" +#include "Driver.h" #include "Functions.h" #include #include @@ -9,7 +9,7 @@ namespace PresenceDetection { namespace Bluetooth { -Device::Device(int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices) : +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), @@ -22,33 +22,33 @@ Device::Device(int timeout, const std::string& inventoryURL, const std::string& Start(); } -Device::~Device() +Driver::~Driver() { } -void Device::Start() +void Driver::Start() { int checkInterval = m_checkInterval * 1000; - m_deviceTimer.StartContinuous(checkInterval, static_cast>(std::bind(&Device::UpdatePresentDevices, this))); + m_deviceTimer.StartContinuous(checkInterval, static_cast>(std::bind(&Driver::UpdatePresentDevices, this))); if (!m_inventoryURL.empty()) - m_inventoryTimer.StartContinuous(600000, static_cast>(std::bind(&Device::UpdateDevicesFromInventory, this))); + m_inventoryTimer.StartContinuous(600000, static_cast>(std::bind(&Driver::UpdateDevicesFromInventory, this))); } -void Device::Stop() +void Driver::Stop() { m_deviceTimer.Stop(); if (!m_inventoryURL.empty()) m_inventoryTimer.Stop(); } -void Device::Wait() +void Driver::Wait() { m_deviceTimer.Wait(); if (!m_inventoryURL.empty()) m_inventoryTimer.Wait(); } -void Device::ClearDevices() +void Driver::ClearDevices() { for (std::vector::iterator it = m_dynamicDevices.begin(); it != m_dynamicDevices.end(); ++it) { @@ -59,7 +59,7 @@ void Device::ClearDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::ClearDevices() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::ClearDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -75,14 +75,14 @@ void Device::ClearDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::ClearDevices() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::ClearDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } } } -void Device::UpdateDevicesFromInventory() +void Driver::UpdateDevicesFromInventory() { try { @@ -102,12 +102,12 @@ void Device::UpdateDevicesFromInventory() catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::GetDevicesFromInventory() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::GetDevicesFromInventory() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } -void Device::UpdatePresentDevices() +void Driver::UpdatePresentDevices() { std::vector presentDevices; std::vector ignoredDevices; @@ -149,7 +149,7 @@ void Device::UpdatePresentDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::UpdatePresentDevices() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::UpdatePresentDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -193,7 +193,7 @@ void Device::UpdatePresentDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::UpdatePresentDevices() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::UpdatePresentDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -211,7 +211,7 @@ void Device::UpdatePresentDevices() m_presentDevices.assign(presentDevices.begin(), presentDevices.end()); } -void Device::SendStateChange(bool present, const std::string& macAddress) +void Driver::SendStateChange(bool present, const std::string& macAddress) { char sign; if (present) @@ -237,7 +237,7 @@ void Device::SendStateChange(bool present, const std::string& macAddress) catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::SendStateChange() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::SendStateChange() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -276,7 +276,7 @@ void Device::SendStateChange(bool present, const std::string& macAddress) catch (const std::exception& e) { std::stringstream ss; - ss << "Bluetooth::Device::SendStateChange() - Error: " << e.what() << std::endl; + ss << "Bluetooth::Driver::SendStateChange() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } diff --git a/Bluetooth/Device.h b/Bluetooth/Driver.h similarity index 83% rename from Bluetooth/Device.h rename to Bluetooth/Driver.h index b956589..af3b454 100644 --- a/Bluetooth/Device.h +++ b/Bluetooth/Driver.h @@ -1,5 +1,5 @@ -#ifndef BLUETOOTH_DEVICE_H -#define BLUETOOTH_DEVICE_H +#ifndef BLUETOOTH_DRIVER_H +#define BLUETOOTH_DRIVER_H #include "Util/DynamicDevice.h" #include "Util/StaticDevice.h" @@ -12,11 +12,11 @@ namespace PresenceDetection { namespace Bluetooth { -class Device +class Driver { public: - Device(int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices); - ~Device(); + Driver(int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices); + ~Driver(); void Start(); void Stop(); @@ -47,4 +47,4 @@ private: } // namespace Bluetooth } // namespace PresenceDetection -#endif // BLUETOOTH_DEVICE_H +#endif // BLUETOOTH_DRIVER_H diff --git a/Bluetooth/Functions.cpp b/Bluetooth/Functions.cpp index b2fa55a..dcd69d3 100644 --- a/Bluetooth/Functions.cpp +++ b/Bluetooth/Functions.cpp @@ -43,8 +43,8 @@ bool Functions::Ping(const std::string& macAddress) str2ba(macAddress.c_str(), &socketAddress.l2_bdaddr); struct timeval timeoutStruct; - timeoutStruct.tv_sec = 3; - timeoutStruct.tv_usec = 0; + timeoutStruct.tv_sec = 1; + timeoutStruct.tv_usec = 0; //500000; fd_set writeDescriptor, errorDescriptor; FD_ZERO(&writeDescriptor); @@ -68,7 +68,7 @@ bool Functions::Ping(const std::string& macAddress) if (ret != 0) { - if (select(socketDescriptor + 1, &errorDescriptor, &writeDescriptor, NULL, &timeoutStruct) < 0) + if (select(socketDescriptor + 1, &errorDescriptor, &writeDescriptor, NULL, &timeoutStruct) <= 0) return false; int error = 0; @@ -125,7 +125,7 @@ bool Functions::Ping(const std::string& macAddress) pf[0].events = POLLIN; int err; - int timeout = 500; + int timeout = 200; if ((err = poll(pf, 1, timeout)) < 0) throw std::runtime_error("Poll failed"); diff --git a/Device/Device.cpp b/Device/Device.cpp new file mode 100644 index 0000000..7fb5402 --- /dev/null +++ b/Device/Device.cpp @@ -0,0 +1,55 @@ +#include "Device.h" + + +namespace PresenceDetection { +namespace Device { + +Device::Device(int id, const std::string& wifiMacAddress, const std::string& bluetoothAddress) : + m_id(id), + m_wifiMacAddress(wifiMacAddress), + m_bluetoothMacAddress(bluetoothAddress), + m_online(false) +{ +} + +Device::~Device() +{ +} + +Device::Device(const Device& other) +{ + m_id = other.m_id; + m_wifiMacAddress = other.m_wifiMacAddress; + m_bluetoothMacAddress = other.m_bluetoothMacAddress; + m_online = other.m_online; +} + +int Device::ID() const +{ + return m_id; +} + +std::string Device::WifiMacAddress() const +{ + return m_wifiMacAddress; +} + +std::string Device::BluetoothMacAddress() const +{ + return m_bluetoothMacAddress; +} + +bool Device::Online() const +{ + std::lock_guard lock(m_mutex); + return m_online; +} + +void Device::Online(bool online) +{ + std::lock_guard lock(m_mutex); + m_online = online; +} + +} // namespace Device +} // namespace PresenceDetection diff --git a/Device/Device.h b/Device/Device.h new file mode 100644 index 0000000..ab00e5c --- /dev/null +++ b/Device/Device.h @@ -0,0 +1,38 @@ +#ifndef DEVICE_DEVICE_H +#define DEVICE_DEVICE_H + +#include +#include + + +namespace PresenceDetection { +namespace Device { + +class Device +{ +public: + Device(int id, const std::string& wifiMacAddress, const std::string& bluetoothAddress); + ~Device(); + + Device(const Device& other); + + int ID() const; + std::string WifiMacAddress() const; + std::string BluetoothMacAddress() const; + + bool Online() const; + void Online(bool online); + +private: + int m_id; + std::string m_wifiMacAddress; + std::string m_bluetoothMacAddress; + + mutable std::mutex m_mutex; + bool m_online; +}; + +} // namespace Device +} // namespace PresenceDetection + +#endif // DEVICE_DEVICE_H diff --git a/UniFi/Makefile b/Device/Makefile similarity index 100% rename from UniFi/Makefile rename to Device/Makefile diff --git a/Logic/Logic.cpp b/Logic/Logic.cpp new file mode 100644 index 0000000..4ac7bd1 --- /dev/null +++ b/Logic/Logic.cpp @@ -0,0 +1,125 @@ +/* + +Logic -> + Contain all Configured Devices + -> Retrieve Devices from Domotica API + -> Retrieve Devices from Configuration + + +WiFi -> Check for Devices + Change to Offline + -> Ping (Internal to WiFi) + Fail + -> Update Device to Offline + Success + -> NOOP + Change to Online + -> Ping (Internal to WiFi) + Fail + -> NOOP + Success + -> Update Device to Online + + +Bluetooth -> Check for Devices + Change to Offline + Change to Online + + +API -> Poll Devices + +- Who keeps track of the devices? + Logic? + Driver? + +//*/ + +#include "Logic.h" +#include +#include +#include +#include +#include + + +namespace PresenceDetection { +namespace Logic { + +Logic::Logic(const std::string& inventoryURL) : + m_inventoryURL(inventoryURL) +{ +} + +Logic::~Logic() +{ +} + +void Logic::LoadDevicesFromConfiguration() +{ +} + +void Logic::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) + { + int id = std::stoi(element["id"].get()); + std::string wifi; + std::string bluetooth; + + //if (element["wifi"] != "") + if (element["macaddress"] != "") + { + //wifi = element["wifi"]; + wifi = element["macaddress"]; + std::transform(wifi.begin(), wifi.end(), wifi.begin(), ::tolower); + } + + if (element["bluetooth"] != "") + { + bluetooth = element["bluetooth"]; + std::transform(bluetooth.begin(), bluetooth.end(), bluetooth.begin(), ::tolower); + } + + m_dynamicDevices.push_back(Device::Device(id, wifi, bluetooth)); + } + } + catch (const std::exception& e) + { + std::stringstream ss; + ss << "Logic::GetDevicesFromInventory() - Error: " << e.what() << std::endl; + Logging::Log(Logging::Severity::Error, ss.str()); + } +} + +void Logic::DumpDevices() +{ + std::cout << "Static Devices:" << std::endl; + for (auto& device : m_staticDevices) + { + std::cout << "ID: " << device.ID() << std::endl; + std::cout << "Wifi: " << device.WifiMacAddress() << std::endl; + std::cout << "Bluetooth: " << device.BluetoothMacAddress() << std::endl; + std::cout << "Online: " << device.Online() << std::endl; + std::cout << std::endl; + } + + std::cout << "Dynamic Devices:" << std::endl; + for (auto& device : m_dynamicDevices) + { + std::cout << "ID: " << device.ID() << std::endl; + std::cout << "Wifi: " << device.WifiMacAddress() << std::endl; + std::cout << "Bluetooth: " << device.BluetoothMacAddress() << std::endl; + std::cout << "Online: " << device.Online() << std::endl; + std::cout << std::endl; + } +} + +} // namespace Logic +} // namespace PresenceDetection diff --git a/Logic/Logic.h b/Logic/Logic.h new file mode 100644 index 0000000..8871673 --- /dev/null +++ b/Logic/Logic.h @@ -0,0 +1,41 @@ +#ifndef LOGIC_LOGIC_H +#define LOGIC_LOGIC_H + +#include "Device/Device.h" +#include +#include +#include + + +namespace PresenceDetection { +namespace Logic { + +class Logic +{ +public: + Logic(const std::string& inventoryURL); + ~Logic(); + + void LoadDevicesFromConfiguration(); + void UpdateDevicesFromInventory(); + + void DumpDevices(); + +private: + //void UpdatePresentDevices(); + void PollBluetoothDevices(); + void PollWiFiDevices(); + +private: + Http::HttpClient m_httpClient; + + std::string m_inventoryURL; + std::vector m_dynamicDevices; + std::vector m_staticDevices; + +}; + +} // namespace Logic +} // namespace PresenceDetection + +#endif // LOGIC_LOGIC_H diff --git a/Logic/Makefile b/Logic/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/Logic/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file diff --git a/PresenceDetection.ini b/PresenceDetection.ini index fa04d7f..a8ce4a5 100644 --- a/PresenceDetection.ini +++ b/PresenceDetection.ini @@ -3,7 +3,7 @@ Target = UniFi = Bluetooth = -[UniFi] +[WiFi] Hostname = UniFi Port = Username = diff --git a/UniFi/Device.cpp b/WiFi/Driver.cpp similarity index 84% rename from UniFi/Device.cpp rename to WiFi/Driver.cpp index 100f35a..f309200 100644 --- a/UniFi/Device.cpp +++ b/WiFi/Driver.cpp @@ -1,4 +1,4 @@ -#include "Device.h" +#include "Driver.h" #include #include #include @@ -6,9 +6,9 @@ namespace PresenceDetection { -namespace UniFi { +namespace WiFi { -Device::Device(const std::string& hostname, int port, const std::string& username, const std::string& password, const std::string& cookieFile, int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices) : +Driver::Driver(const std::string& hostname, int port, const std::string& username, const std::string& password, const std::string& cookieFile, int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices) : m_loggedIn(false), m_hostname(hostname), m_port(port), @@ -27,34 +27,34 @@ Device::Device(const std::string& hostname, int port, const std::string& usernam Start(); } -Device::~Device() +Driver::~Driver() { Logout(); } -void Device::Start() +void Driver::Start() { int checkInterval = m_checkInterval * 1000; - m_deviceTimer.StartContinuous(checkInterval, static_cast>(std::bind(&Device::UpdatePresentDevices, this))); + m_deviceTimer.StartContinuous(checkInterval, static_cast>(std::bind(&Driver::UpdatePresentDevices, this))); if (!m_inventoryURL.empty()) - m_inventoryTimer.StartContinuous(300000, static_cast>(std::bind(&Device::UpdateDevicesFromInventory, this))); + m_inventoryTimer.StartContinuous(300000, static_cast>(std::bind(&Driver::UpdateDevicesFromInventory, this))); } -void Device::Stop() +void Driver::Stop() { m_deviceTimer.Stop(); if (!m_inventoryURL.empty()) m_inventoryTimer.Stop(); } -void Device::Wait() +void Driver::Wait() { m_deviceTimer.Wait(); if (!m_inventoryURL.empty()) m_inventoryTimer.Stop(); } -bool Device::Login() +bool Driver::Login() { std::stringstream url; url << "https://" << m_hostname << ":" << m_port << "/api/login"; @@ -88,7 +88,7 @@ bool Device::Login() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::Login() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::Login() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); std::lock_guard lock(m_mutex); m_loggedIn = false; @@ -100,7 +100,7 @@ bool Device::Login() return m_loggedIn; } -void Device::Logout() +void Driver::Logout() { std::stringstream url; url << "https://" << m_hostname << ":" << m_port << "/logout"; @@ -118,12 +118,12 @@ void Device::Logout() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::Logout() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::Logout() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } -void Device::ClearDevices() +void Driver::ClearDevices() { for (std::vector::iterator it = m_devices.begin(); it != m_devices.end(); ++it) { @@ -134,7 +134,7 @@ void Device::ClearDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::ClearDevices() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::ClearDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -150,14 +150,14 @@ void Device::ClearDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::ClearDevices() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::ClearDevices() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } } } -void Device::UpdateDevicesFromInventory() +void Driver::UpdateDevicesFromInventory() { try { @@ -177,12 +177,12 @@ void Device::UpdateDevicesFromInventory() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::GetDevicesFromInventory() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::GetDevicesFromInventory() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } -void Device::UpdatePresentDevices() +void Driver::UpdatePresentDevices() { bool loggedIn; { @@ -229,7 +229,12 @@ void Device::UpdatePresentDevices() if ((timeStamp - lastSeen) < m_timeout) { if (std::find(m_presentDevices.begin(), m_presentDevices.end(), macAddress) == m_presentDevices.end()) + { addedDevices.push_back(macAddress); + std::stringstream ss; + ss << "Device Added: " << device.dump() << std::endl; + Logging::Log(Logging::Severity::Info, ss.str()); + } presentDevices.push_back(macAddress); } else @@ -238,7 +243,7 @@ void Device::UpdatePresentDevices() { std::stringstream ss; ss << "TimeOut (" << m_timeout << "): " << macAddress << std::endl; - Logging::Log(Logging::Severity::Debug, ss.str()); + Logging::Log(Logging::Severity::Info, ss.str()); } } } @@ -260,7 +265,7 @@ void Device::UpdatePresentDevices() { std::stringstream ss; ss << "TimeOut (" << m_timeout << "): " << macAddress << std::endl; - Logging::Log(Logging::Severity::Debug, ss.str()); + Logging::Log(Logging::Severity::Info, ss.str()); } } } @@ -269,7 +274,7 @@ void Device::UpdatePresentDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::IsDevicePresent() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::IsDevicePresent() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); Logout(); return; @@ -288,7 +293,7 @@ void Device::UpdatePresentDevices() m_presentDevices.assign(presentDevices.begin(), presentDevices.end()); } -void Device::SendStateChange(bool present, const std::string& macAddress) +void Driver::SendStateChange(bool present, const std::string& macAddress) { char sign; if (present) @@ -297,13 +302,13 @@ void Device::SendStateChange(bool present, const std::string& macAddress) sign = '-'; std::stringstream ss; - ss << "UniFi: " << sign << " " << macAddress; + ss << "WiFi: " << sign << " " << macAddress; Logging::Log(Logging::Severity::Info, ss.str()); if (!m_target.empty()) { std::stringstream url; - url << m_target << "/UniFi/" << sign << "/" << macAddress; + url << m_target << "/WiFi/" << sign << "/" << macAddress; try { @@ -314,7 +319,7 @@ void Device::SendStateChange(bool present, const std::string& macAddress) catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::SendStateChange() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::SendStateChange() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -353,7 +358,7 @@ void Device::SendStateChange(bool present, const std::string& macAddress) catch (const std::exception& e) { std::stringstream ss; - ss << "UniFi::Device::SendStateChange() - Error: " << e.what() << std::endl; + ss << "WiFi::Driver::SendStateChange() - Error: " << e.what() << std::endl; Logging::Log(Logging::Severity::Error, ss.str()); } } @@ -361,5 +366,5 @@ void Device::SendStateChange(bool present, const std::string& macAddress) } } -} // namespace UniFi +} // namespace WiFi } // namespace PresenceDetection diff --git a/UniFi/Device.h b/WiFi/Driver.h similarity index 85% rename from UniFi/Device.h rename to WiFi/Driver.h index d2878d2..31b6e57 100644 --- a/UniFi/Device.h +++ b/WiFi/Driver.h @@ -1,5 +1,5 @@ -#ifndef UNIFI_DEVICE_H -#define UNIFI_DEVICE_H +#ifndef WIFI_DRIVER_H +#define WIFI_DRIVER_H #include "Util/StaticDevice.h" #include @@ -10,13 +10,13 @@ namespace PresenceDetection { -namespace UniFi { +namespace WiFi { -class Device +class Driver { public: - Device(const std::string& hostname, int port, const std::string& username, const std::string& password, const std::string& cookieFile, int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices); - ~Device(); + Driver(const std::string& hostname, int port, const std::string& username, const std::string& password, const std::string& cookieFile, int timeout, const std::string& inventoryURL, const std::string& target, const std::vector& staticDevices); + ~Driver(); void Start(); void Stop(); @@ -55,7 +55,7 @@ private: std::vector m_presentDevices; }; -} // namespace UniFi +} // namespace WiFi } // namespace PresenceDetection -#endif // UNIFI_DEVICE_H +#endif // WIFI_DRIVER_H diff --git a/WiFi/Functions.cpp b/WiFi/Functions.cpp new file mode 100644 index 0000000..c74a731 --- /dev/null +++ b/WiFi/Functions.cpp @@ -0,0 +1,122 @@ +#include "Functions.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +namespace PresenceDetection { +namespace WiFi { + +#define DEFDATALEN (64-ICMP_MINLEN) +#define MAXIPLEN 60 +#define MAXICMPLEN 76 +#define MAXPACKET (65536 - 60 - ICMP_MINLEN) + +bool Functions::Ping(const std::string& ipAddress) +{ + int s, i, cc, packlen, datalen = DEFDATALEN; + struct hostent *hp; + struct sockaddr_in to, from; + struct ip *ip; + u_char *packet, outpack[MAXPACKET]; + char hnamebuf[MAXHOSTNAMELEN]; + std::string hostname = ipAddress; + struct icmp *icp; + int ret, fromlen, hlen; + fd_set rfds; + struct timeval tv; + int retval; + + to.sin_family = AF_INET; + to.sin_addr.s_addr = inet_addr(ipAddress.c_str()); + + packlen = datalen + MAXIPLEN + MAXICMPLEN; + if ( (packet = (u_char *)malloc((u_int)packlen)) == NULL) + throw std::runtime_error("Can't allocate Packet"); + + if ( (s = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0) + throw std::runtime_error("Can't send on ICMP Socket"); + + icp = (struct icmp*)outpack; + icp->icmp_type = ICMP_ECHO; + icp->icmp_code = 0; + icp->icmp_cksum = 0; + icp->icmp_seq = 12345; + icp->icmp_id = getpid(); + + cc = datalen + ICMP_MINLEN; + icp->icmp_cksum = ICMPChecksum((unsigned short*)icp,cc); + + i = sendto(s, (char*)outpack, cc, 0, (struct sockaddr*)&to, (socklen_t)sizeof(struct sockaddr_in)); + if (i < 0) + throw std::runtime_error("Can't send on ICMP Packet"); + + FD_ZERO(&rfds); + FD_SET(s, &rfds); + tv.tv_sec = 0; + tv.tv_usec = 500000; + + while(1) + { + retval = select(s+1, &rfds, NULL, NULL, &tv); + if (retval == -1) + throw std::runtime_error("Can't select file descriptor"); + + if (!retval) + return false; + + fromlen = sizeof(sockaddr_in); + if ((ret = recvfrom(s, (char*)packet, packlen, 0,(struct sockaddr*)&from, (socklen_t*)&fromlen)) < 0) + throw std::runtime_error("Can't receive message from socket"); + + ip = (struct ip*)((char*)packet); + hlen = sizeof(struct ip); + if (ret < (hlen + ICMP_MINLEN)) + throw std::runtime_error("Can't allocate memory for receiving packets"); + + icp = (struct icmp*)(packet + hlen); + if (icp->icmp_type != ICMP_ECHOREPLY) + continue; + + if (icp->icmp_seq != 12345 || icp->icmp_id != getpid()) + continue; + + return true; + } + + return false; +} + +uint16_t Functions::ICMPChecksum(uint16_t* addr, unsigned len) +{ + uint16_t answer = 0; + uint32_t sum = 0; + + while (len > 1) + { + sum += *addr++; + len -= 2; + } + + if (len == 1) + { + *(unsigned char*)&answer = *(unsigned char*)addr ; + sum += answer; + } + + sum = (sum >> 16) + (sum & 0xffff); + sum += (sum >> 16); + answer = ~sum; + return answer; +} + +} // namespace WiFi +} // namespace PresenceDetection diff --git a/WiFi/Functions.h b/WiFi/Functions.h new file mode 100644 index 0000000..899d5e5 --- /dev/null +++ b/WiFi/Functions.h @@ -0,0 +1,22 @@ +#ifndef WIFI_FUNCTIONS_H +#define WIFI_FUNCTIONS_H + +#include + + +namespace PresenceDetection { +namespace WiFi { + +class Functions +{ +public: + static bool Ping(const std::string& ipAddress); + +private: + static uint16_t ICMPChecksum(uint16_t* addr, unsigned len); +}; + +} // namespace WiFi +} // namespace PresenceDetection + +#endif // WIFI_FUNCTIONS_H diff --git a/WiFi/Makefile b/WiFi/Makefile new file mode 120000 index 0000000..d0b0e8e --- /dev/null +++ b/WiFi/Makefile @@ -0,0 +1 @@ +../Makefile \ No newline at end of file