Revised Avahi client integration in mDNS client:
- aligned state handling with avahi-browse tool: browser is started in client callback - browsing is limited to IPv4 services discovered on the specific daemon network interface only Additional minor changes.
This commit is contained in:
parent
449db1c73c
commit
0f8b9e714e
@ -35,11 +35,11 @@ std::shared_ptr<Browser> Browser::create(
|
||||
return ptr;
|
||||
}
|
||||
|
||||
std::list<RemoteSource> Browser::get_remote_sources() {
|
||||
std::list<RemoteSource> Browser::get_remote_sources() const {
|
||||
std::list<RemoteSource> sources_list;
|
||||
std::shared_lock sources_lock(sources_mutex_);
|
||||
// return list of remote sources ordered by name
|
||||
for (auto& source: sources_.get<name_tag>()) {
|
||||
for (const auto& source: sources_.get<name_tag>()) {
|
||||
sources_list.push_back(source);
|
||||
}
|
||||
return sources_list;
|
||||
|
@ -61,12 +61,12 @@ class Browser : public MDNSClient {
|
||||
bool init() override;
|
||||
bool terminate() override;
|
||||
|
||||
std::list<RemoteSource> get_remote_sources();
|
||||
std::list<RemoteSource> get_remote_sources() const;
|
||||
|
||||
protected:
|
||||
// singleton, use create() to build
|
||||
Browser(std::shared_ptr<Config> config):
|
||||
config_(config),
|
||||
MDNSClient(config),
|
||||
startup_(std::chrono::steady_clock::now()){};
|
||||
|
||||
bool worker();
|
||||
@ -79,7 +79,6 @@ class Browser : public MDNSClient {
|
||||
const std::string& name,
|
||||
const std::string& domain) override;
|
||||
|
||||
std::shared_ptr<Config> config_;
|
||||
std::future<bool> res_;
|
||||
std::atomic_bool running_{false};
|
||||
|
||||
|
@ -95,6 +95,13 @@ std::shared_ptr<Config> Config::parse(const std::string& filename) {
|
||||
}
|
||||
config.ip_addr_ = ip_addr;
|
||||
config.ip_str_ = ip_str;
|
||||
auto interface_idx = get_interface_index(config.interface_name_);
|
||||
if (interface_idx < 0) {
|
||||
std::cerr << "Cannot retrieve index for interface "
|
||||
<< config.interface_name_ << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
config.interface_idx_ = interface_idx;
|
||||
config.config_filename_ = filename;
|
||||
config.need_restart_ = false;
|
||||
|
||||
|
@ -57,7 +57,8 @@ class Config {
|
||||
uint32_t get_ip_addr() const { return ip_addr_; };
|
||||
const std::string& get_ip_addr_str() const { return ip_str_; };
|
||||
bool get_need_restart() const { return need_restart_; };
|
||||
bool get_mdns_enabled() const { return mdns_enabled; };
|
||||
bool get_mdns_enabled() const { return mdns_enabled_; };
|
||||
int get_interface_idx() { return interface_idx_; };
|
||||
|
||||
void set_http_port(uint16_t http_port) { http_port_ = http_port; };
|
||||
void set_http_base_dir(const std::string& http_base_dir) { http_base_dir_ = http_base_dir; };
|
||||
@ -103,8 +104,9 @@ class Config {
|
||||
mac_addr_ = mac_addr;
|
||||
};
|
||||
void set_mdns_enabled(bool enabled) {
|
||||
mdns_enabled = enabled;
|
||||
mdns_enabled_ = enabled;
|
||||
};
|
||||
void set_interface_idx(int index) { interface_idx_ = index; };
|
||||
|
||||
private:
|
||||
/* from json */
|
||||
@ -125,13 +127,14 @@ class Config {
|
||||
std::string syslog_server_{""};
|
||||
std::string status_file_{"./status.json"};
|
||||
std::string interface_name_{"eth0"};
|
||||
bool mdns_enabled{true};
|
||||
bool mdns_enabled_{true};
|
||||
|
||||
/* set during init */
|
||||
std::array<uint8_t, 6> mac_addr_{0, 0, 0, 0, 0, 0};
|
||||
std::string mac_str_;
|
||||
uint32_t ip_addr_{0};
|
||||
std::string ip_str_;
|
||||
int interface_idx_;
|
||||
std::string config_filename_;
|
||||
|
||||
/* reconfig needs daemon restart */
|
||||
|
@ -48,8 +48,8 @@ std::pair<uint32_t, std::string> get_interface_ip(
|
||||
reinterpret_cast<struct sockaddr_in*>(&ifr.ifr_addr);
|
||||
uint32_t addr = ntohl(sockaddr->sin_addr.s_addr);
|
||||
std::string str_addr(ip::address_v4(addr).to_string());
|
||||
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name << " IP address "
|
||||
<< str_addr;*/
|
||||
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
|
||||
<< " IP address " << str_addr;*/
|
||||
|
||||
return std::make_pair(addr, str_addr);
|
||||
}
|
||||
@ -81,8 +81,31 @@ std::pair<std::array<uint8_t, 6>, std::string> get_interface_mac(
|
||||
char str_mac[18];
|
||||
sprintf(str_mac, "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name << " MAC address "
|
||||
<< str_mac;*/
|
||||
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
|
||||
<< " MAC address " << str_mac;*/
|
||||
|
||||
return std::make_pair(mac, str_mac);
|
||||
}
|
||||
|
||||
int get_interface_index(const std::string& interface_name) {
|
||||
int fd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
BOOST_LOG_TRIVIAL(error)
|
||||
<< "Cannot retrieve index for interface " << interface_name;
|
||||
return -1;
|
||||
}
|
||||
struct ifreq ifr;
|
||||
ifr.ifr_addr.sa_family = AF_INET;
|
||||
strncpy(ifr.ifr_name, interface_name.c_str(), IFNAMSIZ - 1);
|
||||
if (ioctl(fd, SIOCGIFADDR, &ifr) < 0) {
|
||||
close(fd);
|
||||
BOOST_LOG_TRIVIAL(error)
|
||||
<< "Cannot retrieve index for interface " << interface_name;
|
||||
return -1;
|
||||
}
|
||||
close(fd);
|
||||
/*BOOST_LOG_TRIVIAL(debug) << "interface " << interface_name
|
||||
<< " index " << ifr.ifr_ifindex;*/
|
||||
|
||||
return ifr.ifr_ifindex;
|
||||
}
|
||||
|
@ -24,5 +24,6 @@ std::pair<uint32_t, std::string> get_interface_ip(
|
||||
const std::string& interface_name);
|
||||
std::pair<std::array<uint8_t, 6>, std::string> get_interface_mac(
|
||||
const std::string& interface_name);
|
||||
int get_interface_index(const std::string& interface_name);
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <boost/asio.hpp>
|
||||
|
||||
#include "config.hpp"
|
||||
#include "interface.hpp"
|
||||
#include "log.hpp"
|
||||
#include "rtsp_client.hpp"
|
||||
|
||||
@ -156,16 +157,40 @@ void MDNSClient::browse_callback(AvahiServiceBrowser* b,
|
||||
}
|
||||
}
|
||||
|
||||
void MDNSClient::client_callback(AvahiClient* c,
|
||||
void MDNSClient::client_callback(AvahiClient* client,
|
||||
AvahiClientState state,
|
||||
void* userdata) {
|
||||
MDNSClient& mdns = *(reinterpret_cast<MDNSClient*>(userdata));
|
||||
/* Called whenever the client or server state changes */
|
||||
if (state == AVAHI_CLIENT_FAILURE) {
|
||||
|
||||
switch (state) {
|
||||
case AVAHI_CLIENT_FAILURE:
|
||||
BOOST_LOG_TRIVIAL(fatal) << "avahi_client:: server connection failure: "
|
||||
<< avahi_strerror(avahi_client_errno(c));
|
||||
<< avahi_strerror(avahi_client_errno(client));
|
||||
/* TODO reconnect if disconnected */
|
||||
avahi_threaded_poll_quit(mdns.poll_.get());
|
||||
break;
|
||||
|
||||
case AVAHI_CLIENT_S_REGISTERING:
|
||||
case AVAHI_CLIENT_S_RUNNING:
|
||||
case AVAHI_CLIENT_S_COLLISION:
|
||||
/* Create the service browser */
|
||||
mdns.sb_.reset(avahi_service_browser_new(client,
|
||||
mdns.config_->get_interface_idx(),
|
||||
AVAHI_PROTO_INET, "_rtsp._tcp", nullptr,
|
||||
{}, browse_callback, &mdns));
|
||||
if (mdns.sb_ == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(fatal)
|
||||
<< "avahi_client:: failed to create service browser: "
|
||||
<< avahi_strerror(avahi_client_errno(mdns.client_.get()));
|
||||
avahi_threaded_poll_quit(mdns.poll_.get());
|
||||
}
|
||||
break;
|
||||
|
||||
case AVAHI_CLIENT_CONNECTING:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -194,17 +219,6 @@ bool MDNSClient::init() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Create the service browser */
|
||||
sb_.reset(avahi_service_browser_new(client_.get(), AVAHI_IF_UNSPEC,
|
||||
AVAHI_PROTO_UNSPEC, "_rtsp._tcp", nullptr,
|
||||
{}, browse_callback, this));
|
||||
if (sb_ == nullptr) {
|
||||
BOOST_LOG_TRIVIAL(fatal)
|
||||
<< "avahi_client:: failed to create service browser: "
|
||||
<< avahi_strerror(avahi_client_errno(client_.get()));
|
||||
return false;
|
||||
}
|
||||
|
||||
(void)avahi_threaded_poll_start(poll_.get());
|
||||
#endif
|
||||
running_ = true;
|
||||
|
@ -38,7 +38,8 @@
|
||||
|
||||
class MDNSClient {
|
||||
public:
|
||||
MDNSClient(){};
|
||||
MDNSClient(std::shared_ptr<Config> config): config_(config){};
|
||||
MDNSClient() = delete;
|
||||
MDNSClient(const MDNSClient&) = delete;
|
||||
MDNSClient& operator=(const MDNSClient&) = delete;
|
||||
virtual ~MDNSClient() { terminate(); };
|
||||
@ -93,6 +94,8 @@ class MDNSClient {
|
||||
static void client_callback(AvahiClient* c,
|
||||
AvahiClientState state,
|
||||
void* userdata);
|
||||
|
||||
std::shared_ptr<Config> config_;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user