/* Copyright 2016, Ableton AG, Berlin. All rights reserved.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* If you would like to incorporate Link into a proprietary software application,
* please contact .
*/
#pragma once
#include
#include
#include
#include
namespace ableton
{
namespace discovery
{
// Callback takes a range of asio::ip:address which is
// guaranteed to be sorted and unique
template
class InterfaceScanner
{
public:
using Timer = typename util::Injected::type::Timer;
InterfaceScanner(const std::chrono::seconds period,
util::Injected callback,
util::Injected io)
: mPeriod(period)
, mCallback(std::move(callback))
, mIo(std::move(io))
, mTimer(mIo->makeTimer())
{
}
void enable(const bool bEnable)
{
if (bEnable)
{
scan();
}
else
{
mTimer.cancel();
}
}
void scan()
{
using namespace std;
debug(mIo->log()) << "Scanning network interfaces";
// Rescan the hardware for available network interface addresses
vector addrs = mIo->scanNetworkInterfaces();
// Sort and unique them to guarantee consistent comparison
sort(begin(addrs), end(addrs));
addrs.erase(unique(begin(addrs), end(addrs)), end(addrs));
// Pass them to the callback
(*mCallback)(std::move(addrs));
// setup the next scanning
mTimer.expires_from_now(mPeriod);
using ErrorCode = typename Timer::ErrorCode;
mTimer.async_wait([this](const ErrorCode e) {
if (!e)
{
scan();
}
});
}
private:
const std::chrono::seconds mPeriod;
util::Injected mCallback;
util::Injected mIo;
Timer mTimer;
};
// Factory function
template
InterfaceScanner makeInterfaceScanner(
const std::chrono::seconds period,
util::Injected callback,
util::Injected io)
{
using namespace std;
return {period, move(callback), move(io)};
}
} // namespace discovery
} // namespace ableton