diff --git a/Bluetooth/Device.cpp b/Bluetooth/Device.cpp index 9bcba91..5a6f00b 100644 --- a/Bluetooth/Device.cpp +++ b/Bluetooth/Device.cpp @@ -45,59 +45,44 @@ void Device::UpdatePresentDevices() if (Functions::Ping(*it)) { if (std::find(m_presentDevices.begin(), m_presentDevices.end(), *it) == m_presentDevices.end()) - addedDevices.push_back(*it); + SendStateChange(true, *it); presentDevices.push_back(*it); } } for (std::vector::iterator it = m_presentDevices.begin(); it != m_presentDevices.end(); ++it) if (std::find(presentDevices.begin(), presentDevices.end(), *it) == presentDevices.end()) - removedDevices.push_back(*it); - - for (std::vector::iterator it = addedDevices.begin(); it != addedDevices.end(); ++it) - { - std::stringstream ss; - ss << "Bluetooth: + " << *it; - syslog(LOG_INFO, "%s", ss.str().c_str()); - - std::stringstream url; - url << m_target << "/Bluetooth/+/" << *it; - - try - { - m_httpClient.GetUrlSilent(url.str()); - } - catch (const std::exception& e) - { - std::stringstream ss; - ss << "BluetoothDevice::UpdatePresentDevices() - Error: " << e.what() << std::endl; - syslog(LOG_ERR, "%s", ss.str().c_str()); - } - } - - for (std::vector::iterator it = removedDevices.begin(); it != removedDevices.end(); ++it) - { - std::stringstream ss; - ss << "Bluetooth: - " << *it; - syslog(LOG_INFO, "%s", ss.str().c_str()); - - std::stringstream url; - url << m_target << "/Bluetooth/-/" << *it; - - try - { - m_httpClient.GetUrlSilent(url.str()); - } - catch (const std::exception& e) - { - std::stringstream ss; - ss << "BluetoothDevice::UpdatePresentDevices() - Error: " << e.what() << std::endl; - syslog(LOG_ERR, "%s", ss.str().c_str()); - } - } + SendStateChange(false, *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; + syslog(LOG_INFO, "%s", ss.str().c_str()); + + 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; + syslog(LOG_ERR, "%s", ss.str().c_str()); + } +} + } // namespace Bluetooth } // namespace PresenceDetection diff --git a/Bluetooth/Device.h b/Bluetooth/Device.h index 2ca75ea..c1b1480 100644 --- a/Bluetooth/Device.h +++ b/Bluetooth/Device.h @@ -22,6 +22,7 @@ public: private: void UpdatePresentDevices(); + void SendStateChange(bool present, const std::string& macAddress); private: Util::Timer m_timer; diff --git a/Bluetooth/Functions.cpp b/Bluetooth/Functions.cpp index 2f87185..4d941a9 100644 --- a/Bluetooth/Functions.cpp +++ b/Bluetooth/Functions.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include "Socket.h" @@ -42,8 +43,55 @@ bool Functions::Ping(const std::string& macAddress) socketAddress.l2_family = AF_BLUETOOTH; str2ba(macAddress.c_str(), &socketAddress.l2_bdaddr); - if (connect(socketDescriptor, reinterpret_cast(&socketAddress), sizeof(socketAddress)) < 0) - return false; + struct timeval timeoutStruct; + timeoutStruct.tv_sec = 3; + timeoutStruct.tv_usec = 0; + + fd_set writeDescriptor, errorDescriptor; + FD_ZERO(&writeDescriptor); + FD_ZERO(&errorDescriptor); + FD_SET(socketDescriptor, &writeDescriptor); + FD_SET(socketDescriptor, &errorDescriptor); + + int flags; + if((flags = fcntl(socketDescriptor, F_GETFL, 0) < 0)) + throw std::runtime_error("Can't get socket options"); + + if(fcntl(socketDescriptor, F_SETFL, flags | O_NONBLOCK) < 0) + throw std::runtime_error("Can't set socket options"); + + int ret = 0; + if ((ret = connect(socketDescriptor, reinterpret_cast(&socketAddress), sizeof(socketAddress)) < 0)) + { + if (errno != EINPROGRESS) + return false; + } + + if (ret != 0) + { + if (select(socketDescriptor + 1, &errorDescriptor, &writeDescriptor, NULL, &timeoutStruct) < 0) + return false; + + int error = 0; + socklen_t len = sizeof(error); + if (FD_ISSET(socketDescriptor, &errorDescriptor) || FD_ISSET(socketDescriptor, &writeDescriptor)) + { + if (getsockopt(socketDescriptor, SOL_SOCKET, SO_ERROR, &error, &len) < 0) + return false; + } + else + { + return false; + } + + if (error) + return false; + } + + if(fcntl(socketDescriptor, F_SETFL, flags) < 0) + throw std::runtime_error("Can't set socket options"); + + connect(socketDescriptor, reinterpret_cast(&socketAddress), sizeof(socketAddress)); memset(&socketAddress, 0, sizeof(socketAddress)); socklen_t optlen = sizeof(socketAddress); diff --git a/UniFi/Device.cpp b/UniFi/Device.cpp index e7532d5..a14eb27 100644 --- a/UniFi/Device.cpp +++ b/UniFi/Device.cpp @@ -71,7 +71,7 @@ bool Device::Login() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFiDevice::Login() - Error: " << e.what() << std::endl; + ss << "UniFi::Device::Login() - Error: " << e.what() << std::endl; syslog(LOG_ERR, "%s", ss.str().c_str()); std::lock_guard lock(m_mutex); m_loggedIn = false; @@ -98,7 +98,7 @@ void Device::Logout() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFiDevice::Logout() - Error: " << e.what() << std::endl; + ss << "UniFi::Device::Logout() - Error: " << e.what() << std::endl; syslog(LOG_ERR, "%s", ss.str().c_str()); } } @@ -156,7 +156,7 @@ void Device::UpdatePresentDevices() catch (const std::exception& e) { std::stringstream ss; - ss << "UniFiDevice::IsDevicePresent() - Error: " << e.what() << std::endl; + ss << "UniFi::Device::IsDevicePresent() - Error: " << e.what() << std::endl; syslog(LOG_ERR, "%s", ss.str().c_str()); Logout(); return; @@ -167,49 +167,40 @@ void Device::UpdatePresentDevices() removedDevices.push_back(*it); for (std::vector::iterator it = addedDevices.begin(); it != addedDevices.end(); ++it) - { - std::stringstream ss; - ss << "UniFi: + " << *it; - syslog(LOG_INFO, "%s", ss.str().c_str()); - - std::stringstream url; - url << m_target << "/UniFi/+/" << *it; - - try - { - m_httpClient.GetUrlSilent(url.str()); - } - catch (const std::exception& e) - { - std::stringstream ss; - ss << "UniFiDevice::UpdatePresentDevices() - Error: " << e.what() << std::endl; - syslog(LOG_ERR, "%s", ss.str().c_str()); - } - } + SendStateChange(true, *it); for (std::vector::iterator it = removedDevices.begin(); it != removedDevices.end(); ++it) - { - std::stringstream ss; - ss << "UniFi: - " << *it; - syslog(LOG_INFO, "%s", ss.str().c_str()); - - std::stringstream url; - url << m_target << "/UniFi/-/" << *it; - - try - { - m_httpClient.GetUrlSilent(url.str()); - } - catch (const std::exception& e) - { - std::stringstream ss; - ss << "UniFiDevice::UpdatePresentDevices() - Error: " << e.what() << std::endl; - syslog(LOG_ERR, "%s", ss.str().c_str()); - } - } + SendStateChange(false, *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 << "UniFi: " << sign << " " << macAddress; + syslog(LOG_INFO, "%s", ss.str().c_str()); + + std::stringstream url; + url << m_target << "/UniFi/" << sign << "/" << macAddress; + + try + { + m_httpClient.GetUrlSilent(url.str()); + } + catch (const std::exception& e) + { + std::stringstream ss; + ss << "UniFi::Device::SendStateChange() - Error: " << e.what() << std::endl; + syslog(LOG_ERR, "%s", ss.str().c_str()); + } +} + } // namespace UniFi } // namespace PresenceDetection diff --git a/UniFi/Device.h b/UniFi/Device.h index cadddfc..62ea203 100644 --- a/UniFi/Device.h +++ b/UniFi/Device.h @@ -26,6 +26,7 @@ private: void Logout(); void UpdatePresentDevices(); + void SendStateChange(bool present, const std::string& macAddress); private: Util::Timer m_timer;