Converted avahi resolve service to async

This commit is contained in:
Lasan Mahaliyana
2026-02-10 07:52:37 +05:30
parent ee582df8ee
commit 9acedeffe4
4 changed files with 84 additions and 463 deletions
+67 -59
View File
@@ -20,6 +20,32 @@
namespace nearby {
namespace linux {
namespace avahi {
void Server::onResolveServiceReply(const int32_t& interface,
const int32_t& protocol, const std::string& name,
const std::string& type, const std::string& domain,
const std::string& host, const int32_t& aprotocol,
const std::string& address, const uint16_t& port,
const std::vector<std::vector<uint8_t>>& txt, const uint32_t& flags,
const sdbus::Error* error) {
NsdServiceInfo info;
info.SetServiceName(name);
info.SetIPAddress(address);
info.SetPort(port);
info.SetServiceType(type + "."); // discovery callback expects an extra period at t
for (auto &attr : txt) {
auto attr_str = std::string(attr.begin(), attr.end());
size_t pos = attr_str.find('=');
if (pos == 0 || pos == std::string::npos || pos == attr_str.size() - 1) {
LOG(WARNING) << " found invalid text attribute: " << attr_str;
continue;
}
info.SetTxtRecord(attr_str.substr(0, pos), attr_str.substr(pos + 1));
}
discovery_cb_.service_discovered_cb(std::move(info));
};
void ServiceBrowser::onItemNew(const int32_t &interface,
const int32_t &protocol, const std::string &name,
const std::string &type,
@@ -36,75 +62,57 @@ void ServiceBrowser::onItemNew(const int32_t &interface,
return;
}
NsdServiceInfo info;
try {
auto [r_iface, r_protocol, r_name, r_type, r_domain, r_host, r_aprotocol,
r_address, r_port, r_txt, r_flags] =
server_->ResolveService(interface, protocol, name, type, domain,
0, // AVAHI_PROTO_INET
0);
info.SetServiceName(r_name);
info.SetIPAddress(r_address);
info.SetPort(r_port);
info.SetServiceType(r_type + "."); // discovery callback expects an extra period at t
for (auto &attr : r_txt) {
auto attr_str = std::string(attr.begin(), attr.end());
size_t pos = attr_str.find('=');
if (pos == 0 || pos == std::string::npos || pos == attr_str.size() - 1) {
LOG(WARNING) << " found invalid text attribute: " << attr_str;
continue;
}
info.SetTxtRecord(attr_str.substr(0, pos), attr_str.substr(pos + 1));
}
server_->ResolveService(interface, protocol, name, type, domain,
0, // AVAHI_PROTO_INET
0);
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(server_, "ResolveService", e);
}
discovery_cb_.service_discovered_cb(std::move(info));
}
void ServiceBrowser::onItemRemove(
const int32_t &interface, const int32_t &protocol, const std::string &name,
const std::string &type, const std::string &domain, const uint32_t &flags) {
// TODO: Can we even resolve removed items?
LOG(INFO) << __func__ << ": " << getObjectPath()
<< ": Item removed through the ServiceBrowser: "
<< "interface: " << interface << ", protocol: "
<< protocol << ", name: '" << name << "', type: '"
<< type << "', domain: '" << domain
<< "', flags: " << flags;
if (flags & kAvahiLookupResultLocal) {
LOG(INFO) << __func__ << ": Ignoring local service.";
return;
}
NsdServiceInfo info;
try {
auto [r_iface, r_protocol, r_name, r_type, r_domain, r_host, r_aprotocol,
r_address, r_port, r_txt, r_flags] =
server_->ResolveService(interface, protocol, name, type, domain,
0, // AVAHI_PROTO_INET
flags);
info.SetServiceName(r_name);
info.SetIPAddress(r_address);
info.SetPort(r_port);
info.SetServiceType(r_type);
for (auto &attr : r_txt) {
auto attr_str = std::string(attr.begin(), attr.end());
size_t pos = attr_str.find('=');
if (pos == 0 || pos == std::string::npos || pos == attr_str.size() - 1) {
LOG(WARNING) << " found invalid text attribute: " << attr_str;
continue;
}
info.SetTxtRecord(attr_str.substr(0, pos), attr_str.substr(pos + 1));
}
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(server_, "ResolveService", e);
}
discovery_cb_.service_lost_cb(std::move(info));
// // TODO: Can we even resolve removed items?
// LOG(INFO) << __func__ << ": " << getObjectPath()
// << ": Item removed through the ServiceBrowser: "
// << "interface: " << interface << ", protocol: "
// << protocol << ", name: '" << name << "', type: '"
// << type << "', domain: '" << domain
// << "', flags: " << flags;
// if (flags & kAvahiLookupResultLocal) {
// LOG(INFO) << __func__ << ": Ignoring local service.";
// return;
// }
//
// NsdServiceInfo info;
// try {
// auto [r_iface, r_protocol, r_name, r_type, r_domain, r_host, r_aprotocol,
// r_address, r_port, r_txt, r_flags] =
// server_->ResolveService(interface, protocol, name, type, domain,
// 0, // AVAHI_PROTO_INET
// flags);
// info.SetServiceName(r_name);
// info.SetIPAddress(r_address);
// info.SetPort(r_port);
// info.SetServiceType(r_type);
// for (auto &attr : r_txt) {
// auto attr_str = std::string(attr.begin(), attr.end());
// size_t pos = attr_str.find('=');
// if (pos == 0 || pos == std::string::npos || pos == attr_str.size() - 1) {
// LOG(WARNING) << " found invalid text attribute: " << attr_str;
// continue;
// }
//
// info.SetTxtRecord(attr_str.substr(0, pos), attr_str.substr(pos + 1));
// }
// } catch (const sdbus::Error &e) {
// DBUS_LOG_METHOD_CALL_ERROR(server_, "ResolveService", e);
// }
//
// // discovery_cb_.service_lost_cb(std::move(info));
}
void ServiceBrowser::onFailure(const std::string &error) {
+15 -5
View File
@@ -32,15 +32,27 @@ namespace avahi {
class Server final
: public sdbus::ProxyInterfaces<org::freedesktop::Avahi::Server2_proxy> {
public:
Server(sdbus::IConnection &system_bus)
: ProxyInterfaces(system_bus, "org.freedesktop.Avahi", "/") {
Server(sdbus::IConnection &system_bus,
api::WifiLanMedium::DiscoveredServiceCallback callback)
: ProxyInterfaces(system_bus, "org.freedesktop.Avahi", "/"),
discovery_cb_(std::move(callback))
{
registerProxy();
}
Server(sdbus::IConnection& system_bus)
: Server(system_bus, {}) {}
~Server() { unregisterProxy(); }
api::WifiLanMedium::DiscoveredServiceCallback discovery_cb_;
protected:
void onStateChanged(const int32_t &state, const std::string &error) override {
}
void onResolveServiceReply(const int32_t& interface,
const int32_t& protocol, const std::string& name,
const std::string& type, const std::string& domain,
const std::string& host, const int32_t& aprotocol,
const std::string& address, const uint16_t& port,
const std::vector<std::vector<uint8_t>>& txt, const uint32_t& flags,
const sdbus::Error* error) override;
};
class EntryGroup final
@@ -80,7 +92,6 @@ class ServiceBrowser final
std::shared_ptr<Server> avahi_server)
: ProxyInterfaces(system_bus, "org.freedesktop.Avahi",
service_browser_object_path),
discovery_cb_(std::move(callback)),
server_(avahi_server) {
registerProxy();
}
@@ -117,7 +128,6 @@ class ServiceBrowser final
kAvahiLookupResultStatic = 32,
};
api::WifiLanMedium::DiscoveredServiceCallback discovery_cb_;
std::shared_ptr<Server> server_;
};
} // namespace avahi
@@ -111,6 +111,7 @@
</method>
<method name="ResolveService">
<annotation name="org.freedesktop.DBus.Method.Async" value="client" />
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
@@ -298,6 +299,7 @@
</method>
<method name="ResolveService">
<annotation name="org.freedesktop.DBus.Method.Async" value="client" />
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
@@ -1,399 +0,0 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__avahi_server_client_glue_h__proxy__H__
#define __sdbuscpp__avahi_server_client_glue_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
namespace Avahi {
class Server_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.Avahi.Server";
protected:
Server_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("StateChanged").onInterface(INTERFACE_NAME).call([this](const int32_t& state, const std::string& error){ this->onStateChanged(state, error); });
}
~Server_proxy() = default;
virtual void onStateChanged(const int32_t& state, const std::string& error) = 0;
public:
std::string GetVersionString()
{
std::string result;
proxy_.callMethod("GetVersionString").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
uint32_t GetAPIVersion()
{
uint32_t result;
proxy_.callMethod("GetAPIVersion").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string GetHostName()
{
std::string result;
proxy_.callMethod("GetHostName").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void SetHostName(const std::string& name)
{
proxy_.callMethod("SetHostName").onInterface(INTERFACE_NAME).withArguments(name);
}
std::string GetHostNameFqdn()
{
std::string result;
proxy_.callMethod("GetHostNameFqdn").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string GetDomainName()
{
std::string result;
proxy_.callMethod("GetDomainName").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
bool IsNSSSupportAvailable()
{
bool result;
proxy_.callMethod("IsNSSSupportAvailable").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
int32_t GetState()
{
int32_t result;
proxy_.callMethod("GetState").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
uint32_t GetLocalServiceCookie()
{
uint32_t result;
proxy_.callMethod("GetLocalServiceCookie").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string GetAlternativeHostName(const std::string& name)
{
std::string result;
proxy_.callMethod("GetAlternativeHostName").onInterface(INTERFACE_NAME).withArguments(name).storeResultsTo(result);
return result;
}
std::string GetAlternativeServiceName(const std::string& name)
{
std::string result;
proxy_.callMethod("GetAlternativeServiceName").onInterface(INTERFACE_NAME).withArguments(name).storeResultsTo(result);
return result;
}
std::string GetNetworkInterfaceNameByIndex(const int32_t& index)
{
std::string result;
proxy_.callMethod("GetNetworkInterfaceNameByIndex").onInterface(INTERFACE_NAME).withArguments(index).storeResultsTo(result);
return result;
}
int32_t GetNetworkInterfaceIndexByName(const std::string& name)
{
int32_t result;
proxy_.callMethod("GetNetworkInterfaceIndexByName").onInterface(INTERFACE_NAME).withArguments(name).storeResultsTo(result);
return result;
}
std::tuple<int32_t, int32_t, std::string, int32_t, std::string, uint32_t> ResolveHostName(const int32_t& interface, const int32_t& protocol, const std::string& name, const int32_t& aprotocol, const uint32_t& flags)
{
std::tuple<int32_t, int32_t, std::string, int32_t, std::string, uint32_t> result;
proxy_.callMethod("ResolveHostName").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, aprotocol, flags).storeResultsTo(result);
return result;
}
std::tuple<int32_t, int32_t, int32_t, std::string, std::string, uint32_t> ResolveAddress(const int32_t& interface, const int32_t& protocol, const std::string& address, const uint32_t& flags)
{
std::tuple<int32_t, int32_t, int32_t, std::string, std::string, uint32_t> result;
proxy_.callMethod("ResolveAddress").onInterface(INTERFACE_NAME).withArguments(interface, protocol, address, flags).storeResultsTo(result);
return result;
}
std::tuple<int32_t, int32_t, std::string, std::string, std::string, std::string, int32_t, std::string, uint16_t, std::vector<std::vector<uint8_t>>, uint32_t> ResolveService(const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const int32_t& aprotocol, const uint32_t& flags)
{
std::tuple<int32_t, int32_t, std::string, std::string, std::string, std::string, int32_t, std::string, uint16_t, std::vector<std::vector<uint8_t>>, uint32_t> result;
proxy_.callMethod("ResolveService").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, type, domain, aprotocol, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath EntryGroupNew()
{
sdbus::ObjectPath result;
proxy_.callMethod("EntryGroupNew").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
sdbus::ObjectPath DomainBrowserNew(const int32_t& interface, const int32_t& protocol, const std::string& domain, const int32_t& btype, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("DomainBrowserNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, domain, btype, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath ServiceTypeBrowserNew(const int32_t& interface, const int32_t& protocol, const std::string& domain, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("ServiceTypeBrowserNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, domain, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath ServiceBrowserNew(const int32_t& interface, const int32_t& protocol, const std::string& type, const std::string& domain, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("ServiceBrowserNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, type, domain, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath ServiceResolverNew(const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const int32_t& aprotocol, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("ServiceResolverNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, type, domain, aprotocol, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath HostNameResolverNew(const int32_t& interface, const int32_t& protocol, const std::string& name, const int32_t& aprotocol, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("HostNameResolverNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, aprotocol, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath AddressResolverNew(const int32_t& interface, const int32_t& protocol, const std::string& address, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("AddressResolverNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, address, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath RecordBrowserNew(const int32_t& interface, const int32_t& protocol, const std::string& name, const uint16_t& clazz, const uint16_t& type, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("RecordBrowserNew").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, clazz, type, flags).storeResultsTo(result);
return result;
}
private:
sdbus::IProxy& proxy_;
};
}}} // namespaces
namespace org {
namespace freedesktop {
namespace Avahi {
class Server2_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.Avahi.Server2";
protected:
Server2_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("StateChanged").onInterface(INTERFACE_NAME).call([this](const int32_t& state, const std::string& error){ this->onStateChanged(state, error); });
}
~Server2_proxy() = default;
virtual void onStateChanged(const int32_t& state, const std::string& error) = 0;
public:
std::string GetVersionString()
{
std::string result;
proxy_.callMethod("GetVersionString").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
uint32_t GetAPIVersion()
{
uint32_t result;
proxy_.callMethod("GetAPIVersion").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string GetHostName()
{
std::string result;
proxy_.callMethod("GetHostName").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void SetHostName(const std::string& name)
{
proxy_.callMethod("SetHostName").onInterface(INTERFACE_NAME).withArguments(name);
}
std::string GetHostNameFqdn()
{
std::string result;
proxy_.callMethod("GetHostNameFqdn").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string GetDomainName()
{
std::string result;
proxy_.callMethod("GetDomainName").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
bool IsNSSSupportAvailable()
{
bool result;
proxy_.callMethod("IsNSSSupportAvailable").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
int32_t GetState()
{
int32_t result;
proxy_.callMethod("GetState").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
uint32_t GetLocalServiceCookie()
{
uint32_t result;
proxy_.callMethod("GetLocalServiceCookie").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
std::string GetAlternativeHostName(const std::string& name)
{
std::string result;
proxy_.callMethod("GetAlternativeHostName").onInterface(INTERFACE_NAME).withArguments(name).storeResultsTo(result);
return result;
}
std::string GetAlternativeServiceName(const std::string& name)
{
std::string result;
proxy_.callMethod("GetAlternativeServiceName").onInterface(INTERFACE_NAME).withArguments(name).storeResultsTo(result);
return result;
}
std::string GetNetworkInterfaceNameByIndex(const int32_t& index)
{
std::string result;
proxy_.callMethod("GetNetworkInterfaceNameByIndex").onInterface(INTERFACE_NAME).withArguments(index).storeResultsTo(result);
return result;
}
int32_t GetNetworkInterfaceIndexByName(const std::string& name)
{
int32_t result;
proxy_.callMethod("GetNetworkInterfaceIndexByName").onInterface(INTERFACE_NAME).withArguments(name).storeResultsTo(result);
return result;
}
std::tuple<int32_t, int32_t, std::string, int32_t, std::string, uint32_t> ResolveHostName(const int32_t& interface, const int32_t& protocol, const std::string& name, const int32_t& aprotocol, const uint32_t& flags)
{
std::tuple<int32_t, int32_t, std::string, int32_t, std::string, uint32_t> result;
proxy_.callMethod("ResolveHostName").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, aprotocol, flags).storeResultsTo(result);
return result;
}
std::tuple<int32_t, int32_t, int32_t, std::string, std::string, uint32_t> ResolveAddress(const int32_t& interface, const int32_t& protocol, const std::string& address, const uint32_t& flags)
{
std::tuple<int32_t, int32_t, int32_t, std::string, std::string, uint32_t> result;
proxy_.callMethod("ResolveAddress").onInterface(INTERFACE_NAME).withArguments(interface, protocol, address, flags).storeResultsTo(result);
return result;
}
std::tuple<int32_t, int32_t, std::string, std::string, std::string, std::string, int32_t, std::string, uint16_t, std::vector<std::vector<uint8_t>>, uint32_t> ResolveService(const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const int32_t& aprotocol, const uint32_t& flags)
{
std::tuple<int32_t, int32_t, std::string, std::string, std::string, std::string, int32_t, std::string, uint16_t, std::vector<std::vector<uint8_t>>, uint32_t> result;
proxy_.callMethod("ResolveService").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, type, domain, aprotocol, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath EntryGroupNew()
{
sdbus::ObjectPath result;
proxy_.callMethod("EntryGroupNew").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
sdbus::ObjectPath DomainBrowserPrepare(const int32_t& interface, const int32_t& protocol, const std::string& domain, const int32_t& btype, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("DomainBrowserPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, domain, btype, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath ServiceTypeBrowserPrepare(const int32_t& interface, const int32_t& protocol, const std::string& domain, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("ServiceTypeBrowserPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, domain, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath ServiceBrowserPrepare(const int32_t& interface, const int32_t& protocol, const std::string& type, const std::string& domain, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("ServiceBrowserPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, type, domain, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath ServiceResolverPrepare(const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const int32_t& aprotocol, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("ServiceResolverPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, type, domain, aprotocol, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath HostNameResolverPrepare(const int32_t& interface, const int32_t& protocol, const std::string& name, const int32_t& aprotocol, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("HostNameResolverPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, aprotocol, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath AddressResolverPrepare(const int32_t& interface, const int32_t& protocol, const std::string& address, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("AddressResolverPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, address, flags).storeResultsTo(result);
return result;
}
sdbus::ObjectPath RecordBrowserPrepare(const int32_t& interface, const int32_t& protocol, const std::string& name, const uint16_t& clazz, const uint16_t& type, const uint32_t& flags)
{
sdbus::ObjectPath result;
proxy_.callMethod("RecordBrowserPrepare").onInterface(INTERFACE_NAME).withArguments(interface, protocol, name, clazz, type, flags).storeResultsTo(result);
return result;
}
private:
sdbus::IProxy& proxy_;
};
}}} // namespaces
#endif