| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 |
- #include "Finder.h"
- #include <BroadcastClient.h>
- #include <BroadcastServer.h>
- #include <Logging.h>
- #include <chrono>
- namespace VStarCam {
- Finder::Finder(const std::string& sourceAddress) :
- m_startTime(asio::system_timer::time_point(std::chrono::system_clock::duration::max())),
- m_timeout(std::chrono::seconds(5)),
- m_sourceAddress(sourceAddress),
- m_sourcePort(8600),
- m_targetPort(9600),
- m_port(0)
- {
- }
- Finder::~Finder()
- {
- }
- int Finder::GetPort(const std::string& ipAddress)
- {
- std::stringstream ss;
- ss << "Retrieving port for " << ipAddress << std::endl;
- Logging::Log(Logging::Severity::Info, ss.str());
- {
- std::unique_lock<std::mutex> lock(m_mutex);
- m_port = 0;
- m_targetAddress = ipAddress;
- }
- Network::BroadcastClient client(m_sourceAddress, m_targetPort, std::bind(&Finder::ProcessMessage, this, std::placeholders::_1));
- Network::BroadcastServer server(m_sourceAddress, m_sourcePort, std::function<void(const std::string&)>());
- m_startTime = std::chrono::system_clock::now();
- std::string message("\x44\x48\x01\x01\x0a");
- server.Broadcast(message, m_targetPort);
- while (!PortFound() && !Timeout())
- server.Broadcast(message, m_targetPort);
- std::unique_lock<std::mutex> lock(m_mutex);
- int port = m_port;
- m_port = 0;
- ss.str("");
- ss << "New port for " << ipAddress << ": " << port << std::endl;
- Logging::Log(Logging::Severity::Info, ss.str());
- return port;
- }
- bool Finder::Timeout() const
- {
- return m_startTime + m_timeout <= std::chrono::system_clock::now();
- }
- bool Finder::PortFound()
- {
- std::unique_lock<std::mutex> lock(m_mutex);
- return m_condition.wait_for(lock, std::chrono::milliseconds(1000)) == std::cv_status::no_timeout;
- }
- void Finder::ProcessMessage(const std::string& message)
- {
- std::string::const_iterator it = message.begin();
- // Skip Header
- it += 4;
- std::string ipAddress = GetString(it);
- std::string subnetMask = GetString(it);
- std::string gateway = GetString(it);
- std::string dns1 = GetString(it);
- std::string dns2 = GetString(it);
- // Skip Header
- it += 6;
- // Get Port
- unsigned int port;
- unsigned char low = *it++;
- unsigned char high = *it++;
- std::string hexPort;
- hexPort += high;
- hexPort += low;
- hexPort = StringToHex(hexPort);
- std::stringstream ss;
- ss << std::hex << hexPort;
- ss >> port;
- std::unique_lock<std::mutex> lock(m_mutex);
- if (ipAddress == m_targetAddress)
- {
- m_port = port;
- lock.unlock();
- m_condition.notify_one();
- }
- }
- std::string Finder::GetString(std::string::const_iterator& it) const
- {
- std::string output;
- while (static_cast<unsigned char>(*it) != 0)
- output += *it++;
- Advance(it);
- return output;
- }
- void Finder::Advance(std::string::const_iterator& it) const
- {
- while (static_cast<unsigned char>(*it) == 0)
- it++;
- }
- std::string Finder::StringToHex(const std::string& input) const
- {
- static const char* const lut = "0123456789ABCDEF";
- size_t len = input.length();
- std::string output;
- output.reserve(2 * len);
- for (size_t i = 0; i < len; ++i)
- {
- const unsigned char c = input[i];
- output.push_back(lut[c >> 4]);
- output.push_back(lut[c & 15]);
- }
- return output;
- }
- } // namespace VStarCam
|