Code dump.

This commit is contained in:
Vibhav Pant
2023-08-21 23:19:01 +05:30
parent fc0eed544a
commit 8daff56437
32 changed files with 2479 additions and 78 deletions
@@ -0,0 +1,27 @@
#ifndef PLATFORM_IMPL_LINUX_ATOMIC_BOOLEAN_H_
#define PLATFORM_IMPL_LINUX_ATOMIC_BOOLEAN_H_
#include "internal/platform/implementation/atomic_boolean.h"
#include <atomic>
namespace nearby {
namespace linux {
// A boolean value that may be updated atomically.
class AtomicBoolean : public api::AtomicBoolean {
public:
AtomicBoolean(bool initial_value) : atomic_boolean_(initial_value) {}
~AtomicBoolean() override = default;
// Atomically read and return current value.
bool Get() const override { return atomic_boolean_; };
// Atomically exchange original value with a new one. Return previous value.
bool Set(bool value) override { return atomic_boolean_.exchange(value); };
private:
std::atomic_bool atomic_boolean_ = false;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,28 @@
#ifndef PLATFORM_IMPL_LINUX_ATOMIC_UINT32_H_
#define PLATFORM_IMPL_LINUX_ATOMIC_UINT32_H_
#include "internal/platform/implementation/atomic_reference.h"
#include <atomic>
#include <cstdint>
namespace nearby {
namespace linux {
// A boolean value that may be updated atomically.
class AtomicUint32 : public api::AtomicUint32 {
public:
AtomicUint32(std::uint32_t initial_value) : atomic_uint_(initial_value) {}
~AtomicUint32() override = default;
// Atomically read and return current value.
std::uint32_t Get() const override { return atomic_uint_; };
// Atomically exchange original value with a new one. Return previous value.
void Set(std::uint32_t value) override { atomic_uint_ = value; };
private:
std::atomic_bool atomic_uint_ = false;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,103 @@
#include "internal/platform/implementation/linux/avahi.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/logging.h"
#include "internal/platform/nsd_service_info.h"
namespace nearby {
namespace linux {
namespace avahi {
void ServiceBrowser::onItemNew(const int32_t &interface,
const int32_t &protocol, const std::string &name,
const std::string &type,
const std::string &domain,
const uint32_t &flags) {
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
<< ": Found new item through the ServiceBrowser: "
<< "interface: " << interface << ", protocol: "
<< protocol << ", name: '" << name << "', type: '"
<< type << "', domain: '" << domain
<< "', flags: " << flags;
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) {
NEARBY_LOGS(WARNING) << " found invalid text attribute: " << attr_str;
}
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_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?
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
<< ": Item removed through the ServiceBrowser: "
<< "interface: " << interface << ", protocol: "
<< protocol << ", name: '" << name << "', type: '"
<< type << "', domain: '" << domain
<< "', flags: " << flags;
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) {
NEARBY_LOGS(WARNING) << " found invalid text attribute: " << attr_str;
}
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) {
NEARBY_LOGS(ERROR) << __func__ << ": " << getObjectPath()
<< ": ServiceBrowser reported a failure: " << error;
}
void ServiceBrowser::onAllForNow() {
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
<< ": notified via ServiceBrowser that all records have "
"been added for now";
}
void ServiceBrowser::onCacheExhausted() {
NEARBY_LOGS(VERBOSE) << __func__ << ": " << getObjectPath()
<< ": notified via ServiceBrowser of cache exhaustion";
}
} // namespace avahi
} // namespace linux
} // namespace nearby
@@ -0,0 +1,78 @@
#ifndef PLATFORM_IMPL_LINUX_AVAHI_H_
#define PLATFORM_IMPL_LINUX_AVAHI_H_
#include <memory>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/ProxyInterfaces.h>
#include "internal/platform/implementation/linux/avahi_entrygroup_client_glue.h"
#include "internal/platform/implementation/linux/avahi_server_client_glue.h"
#include "internal/platform/implementation/linux/avahi_servicebrowser_client_glue.h"
#include "internal/platform/implementation/wifi_lan.h"
namespace nearby {
namespace linux {
namespace avahi {
class Server
: public sdbus::ProxyInterfaces<org::freedesktop::Avahi::Server2_proxy> {
public:
Server(sdbus::IConnection &system_bus)
: ProxyInterfaces(system_bus, "org.freedesktop.Avahi", "/") {
registerProxy();
}
~Server() { unregisterProxy(); }
protected:
void onStateChanged(const int32_t &state, const std::string &error) override {
}
};
class EntryGroup
: public sdbus::ProxyInterfaces<org::freedesktop::Avahi::EntryGroup_proxy> {
public:
EntryGroup(sdbus::IConnection &system_bus,
const sdbus::ObjectPath &entry_group_object_path)
: ProxyInterfaces(system_bus, "org.freedesktop.Avahi",
entry_group_object_path) {
registerProxy();
}
~EntryGroup() { unregisterProxy(); }
protected:
void onStateChanged(const int32_t &state, const std::string &error) override {
}
};
class ServiceBrowser : public sdbus::ProxyInterfaces<
org::freedesktop::Avahi::ServiceBrowser_proxy> {
public:
ServiceBrowser(sdbus::IConnection &system_bus,
const sdbus::ObjectPath &service_browser_object_path,
api::WifiLanMedium::DiscoveredServiceCallback callback)
: ProxyInterfaces(system_bus, "org.freedesktop.Avahi",
service_browser_object_path),
discovery_cb_(std::move(callback)) {
registerProxy();
}
~ServiceBrowser() { unregisterProxy(); }
protected:
void onItemNew(const int32_t &interface, const int32_t &protocol,
const std::string &name, const std::string &type,
const std::string &domain, const uint32_t &flags) override;
void 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) override;
void onFailure(const std::string &error) override;
void onAllForNow() override;
void onCacheExhausted() override;
private:
api::WifiLanMedium::DiscoveredServiceCallback discovery_cb_;
std::shared_ptr<Server> server_;
};
} // namespace avahi
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,94 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__avahi_entrygroup_client_glue_h__proxy__H__
#define __sdbuscpp__avahi_entrygroup_client_glue_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
namespace Avahi {
class EntryGroup_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.Avahi.EntryGroup";
protected:
EntryGroup_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); });
}
~EntryGroup_proxy() = default;
virtual void onStateChanged(const int32_t& state, const std::string& error) = 0;
public:
void Free()
{
proxy_.callMethod("Free").onInterface(INTERFACE_NAME);
}
void Commit()
{
proxy_.callMethod("Commit").onInterface(INTERFACE_NAME);
}
void Reset()
{
proxy_.callMethod("Reset").onInterface(INTERFACE_NAME);
}
int32_t GetState()
{
int32_t result;
proxy_.callMethod("GetState").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
bool IsEmpty()
{
bool result;
proxy_.callMethod("IsEmpty").onInterface(INTERFACE_NAME).storeResultsTo(result);
return result;
}
void AddService(const int32_t& interface, const int32_t& protocol, const uint32_t& flags, const std::string& name, const std::string& type, const std::string& domain, const std::string& host, const uint16_t& port, const std::vector<std::vector<uint8_t>>& txt)
{
proxy_.callMethod("AddService").onInterface(INTERFACE_NAME).withArguments(interface, protocol, flags, name, type, domain, host, port, txt);
}
void AddServiceSubtype(const int32_t& interface, const int32_t& protocol, const uint32_t& flags, const std::string& name, const std::string& type, const std::string& domain, const std::string& subtype)
{
proxy_.callMethod("AddServiceSubtype").onInterface(INTERFACE_NAME).withArguments(interface, protocol, flags, name, type, domain, subtype);
}
void UpdateServiceTxt(const int32_t& interface, const int32_t& protocol, const uint32_t& flags, const std::string& name, const std::string& type, const std::string& domain, const std::vector<std::vector<uint8_t>>& txt)
{
proxy_.callMethod("UpdateServiceTxt").onInterface(INTERFACE_NAME).withArguments(interface, protocol, flags, name, type, domain, txt);
}
void AddAddress(const int32_t& interface, const int32_t& protocol, const uint32_t& flags, const std::string& name, const std::string& address)
{
proxy_.callMethod("AddAddress").onInterface(INTERFACE_NAME).withArguments(interface, protocol, flags, name, address);
}
void AddRecord(const int32_t& interface, const int32_t& protocol, const uint32_t& flags, const std::string& name, const uint16_t& clazz, const uint16_t& type, const uint32_t& ttl, const std::vector<uint8_t>& rdata)
{
proxy_.callMethod("AddRecord").onInterface(INTERFACE_NAME).withArguments(interface, protocol, flags, name, clazz, type, ttl, rdata);
}
private:
sdbus::IProxy& proxy_;
};
}}} // namespaces
#endif
@@ -0,0 +1,399 @@
/*
* 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
@@ -0,0 +1,58 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__avahi_servicebrowser_client_glue_h__proxy__H__
#define __sdbuscpp__avahi_servicebrowser_client_glue_h__proxy__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
namespace Avahi {
class ServiceBrowser_proxy
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.Avahi.ServiceBrowser";
protected:
ServiceBrowser_proxy(sdbus::IProxy& proxy)
: proxy_(proxy)
{
proxy_.uponSignal("ItemNew").onInterface(INTERFACE_NAME).call([this](const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const uint32_t& flags){ this->onItemNew(interface, protocol, name, type, domain, flags); });
proxy_.uponSignal("ItemRemove").onInterface(INTERFACE_NAME).call([this](const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const uint32_t& flags){ this->onItemRemove(interface, protocol, name, type, domain, flags); });
proxy_.uponSignal("Failure").onInterface(INTERFACE_NAME).call([this](const std::string& error){ this->onFailure(error); });
proxy_.uponSignal("AllForNow").onInterface(INTERFACE_NAME).call([this](){ this->onAllForNow(); });
proxy_.uponSignal("CacheExhausted").onInterface(INTERFACE_NAME).call([this](){ this->onCacheExhausted(); });
}
~ServiceBrowser_proxy() = default;
virtual void onItemNew(const int32_t& interface, const int32_t& protocol, const std::string& name, const std::string& type, const std::string& domain, const uint32_t& flags) = 0;
virtual void 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) = 0;
virtual void onFailure(const std::string& error) = 0;
virtual void onAllForNow() = 0;
virtual void onCacheExhausted() = 0;
public:
void Free()
{
proxy_.callMethod("Free").onInterface(INTERFACE_NAME);
}
void Start()
{
proxy_.callMethod("Start").onInterface(INTERFACE_NAME);
}
private:
sdbus::IProxy& proxy_;
};
}}} // namespaces
#endif
@@ -13,7 +13,7 @@
namespace nearby {
namespace linux {
ExceptionOr<ByteArray> BluetoothInputStream::Read(std::int64_t size) {
ExceptionOr<ByteArray> InputStream::Read(std::int64_t size) {
if (!fd_.has_value())
return Exception::kIo;
@@ -30,33 +30,17 @@ ExceptionOr<ByteArray> BluetoothInputStream::Read(std::int64_t size) {
return ExceptionOr(ByteArray(data, size));
}
ExceptionOr<std::size_t> BluetoothInputStream::Skip(std::size_t offset) {
Exception InputStream::Close() {
if (!fd_.has_value())
return Exception::kIo;
return Exception{Exception::kIo};
auto off = lseek(fd_->get(), offset, SEEK_CUR);
if (off != offset) {
auto end = lseek(fd_->get(), 0, SEEK_END);
return off == end ? ExceptionOr((std::size_t)off) : Exception::kIo;
}
return ExceptionOr((std::size_t)(off));
auto ret = close(fd_->get()) < 0 ? Exception{Exception::kIo}
: Exception{Exception::kSuccess};
fd_.reset();
return ret;
}
ExceptionOr<ByteArray> BluetoothInputStream::ReadExactly(std::size_t size) {
if (!fd_.has_value())
return Exception::kIo;
char *data = new char[size];
ssize_t ret = read(fd_->get(), data, size);
if (ret < 0) {
delete[] data;
return Exception::kIo;
}
return ExceptionOr(ByteArray(data, size));
}
Exception BluetoothOutputStream::Write(const ByteArray &data) {
Exception OutputStream::Write(const ByteArray &data) {
if (!fd_.has_value())
return Exception{Exception::kIo};
@@ -71,18 +55,21 @@ Exception BluetoothOutputStream::Write(const ByteArray &data) {
return Exception{Exception::kSuccess};
}
Exception BluetoothOutputStream::Flush() {
return Exception{Exception::kSuccess};
}
Exception OutputStream::Flush() { return Exception{Exception::kSuccess}; }
Exception BluetoothOutputStream::Close() {
return close(fd_->get()) < 0 ? Exception{Exception::kIo}
: Exception{Exception::kSuccess};
Exception OutputStream::Close() {
if (!fd_.has_value())
return Exception{Exception::kIo};
auto ret = close(fd_->get()) < 0 ? Exception{Exception::kIo}
: Exception{Exception::kSuccess};
fd_.reset();
return ret;
}
Exception BluetoothSocket::Close() {
input_stream_.fd_.reset();
output_stream_.fd_.reset();
input_stream_.Close();
output_stream_.Close();
return Exception{Exception::kSuccess};
}
@@ -7,57 +7,26 @@
#include <sdbus-c++/Types.h>
#include <systemd/sd-bus.h>
#include "internal/platform/byte_array.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/bluetooth_classic.h"
#include "internal/platform/implementation/linux/stream.h"
namespace nearby {
namespace linux {
class BluetoothInputStream : public InputStream {
public:
BluetoothInputStream(sdbus::UnixFd &fd) : fd_(fd){};
ExceptionOr<ByteArray> Read(std::int64_t size) override;
ExceptionOr<size_t> Skip(size_t offset) override;
ExceptionOr<ByteArray> ReadExactly(std::size_t size);
Exception Close() override;
private:
friend class BluetoothSocket;
std::optional<sdbus::UnixFd> fd_;
};
class BluetoothOutputStream : public OutputStream {
public:
BluetoothOutputStream(sdbus::UnixFd &fd) : fd_(fd){};
Exception Write(const ByteArray &data) override;
Exception Flush() override;
Exception Close() override;
private:
friend class BluetoothSocket;
std::optional<sdbus::UnixFd> fd_;
};
class BluetoothSocket : public api::BluetoothSocket {
public:
BluetoothSocket(api::BluetoothDevice &device, sdbus::UnixFd fd)
: device_(device), output_stream_(fd), input_stream_(fd) {}
InputStream &GetInputStream() override { return input_stream_; }
OutputStream &GetOutputStream() override { return output_stream_; }
nearby::InputStream &GetInputStream() override { return input_stream_; }
nearby::OutputStream &GetOutputStream() override { return output_stream_; }
Exception Close() override;
api::BluetoothDevice *GetRemoteDevice() override { return &device_; };
private:
api::BluetoothDevice &device_;
BluetoothOutputStream output_stream_;
BluetoothInputStream input_stream_;
OutputStream output_stream_;
InputStream input_stream_;
};
} // namespace linux
} // namespace nearby
@@ -0,0 +1,36 @@
#ifndef PLATFORM_IMPL_LINUX_CONDITION_VARIABLE_H_
#define PLATFORM_IMPL_LINUX_CONDITION_VARIABLE_H_
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/condition_variable.h"
#include "internal/platform/implementation/linux/mutex.h"
#include "internal/platform/implementation/mutex.h"
namespace nearby {
namespace linux {
class ConditionVariable : public api::ConditionVariable {
public:
explicit ConditionVariable(api::Mutex *mutex)
: mutex_(static_cast<Mutex *>(mutex)->GetRegularMutex()) {}
~ConditionVariable() = default;
Exception Wait() override {
cond_var_.Wait(mutex_);
return {Exception::kSuccess};
}
Exception Wait(absl::Duration timeout) override {
cond_var_.WaitWithTimeout(mutex_, timeout);
return {Exception::kSuccess};
}
void Notify() override { cond_var_.SignalAll(); }
private:
absl::Mutex *mutex_;
absl::CondVar cond_var_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,50 @@
#ifndef PLATFORM_IMPL_LINUX_CREDENTIAL_STORAGE_H_
#define PLATFORM_IMPL_LINUX_CREDENTIAL_STORAGE_H_
#include <memory>
#include <sdbus-c++/IConnection.h>
#include <sdbus-c++/IProxy.h>
#include <sdbus-c++/sdbus-c++.h>
#include "absl/strings/string_view.h"
#include "internal/platform/implementation/credential_storage.h"
namespace nearby {
namespace linux {
class CredentialStorage : public api::CredentialStorage {
using LocalCredential = ::nearby::internal::LocalCredential;
using SharedCredential = ::nearby::internal::SharedCredential;
using PublicCredentialType = ::nearby::presence::PublicCredentialType;
using SaveCredentialsResultCallback =
::nearby::presence::SaveCredentialsResultCallback;
using CredentialSelector = ::nearby::presence::CredentialSelector;
using GetLocalCredentialsResultCallback =
::nearby::presence::GetLocalCredentialsResultCallback;
using GetPublicCredentialsResultCallback =
::nearby::presence::GetPublicCredentialsResultCallback;
CredentialStorage(sdbus::IConnection &connection);
~CredentialStorage() override = default;
void SaveCredentials(absl::string_view manager_app_id,
absl::string_view account_name,
const std::vector<LocalCredential> &Local_credentials,
const std::vector<SharedCredential> &Shared_credentials,
PublicCredentialType public_credential_type,
SaveCredentialsResultCallback callback) override;
void UpdateLocalCredential(absl::string_view manager_app_id,
absl::string_view account_name,
nearby::internal::LocalCredential credential,
SaveCredentialsResultCallback callback) override;
void
GetPublicCredentials(const CredentialSelector &credential_selector,
PublicCredentialType public_credential_type,
GetPublicCredentialsResultCallback callback) override;
private:
std::unique_ptr<sdbus::IProxy> proxy;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,35 @@
#include <memory>
#include <cassert>
#include <sdbus-c++/IConnection.h>
#include "internal/platform/implementation/linux/dbus.h"
#include "absl/base/call_once.h"
namespace nearby {
namespace linux {
static std::unique_ptr<sdbus::IConnection> global_system_bus_connection =
nullptr;
static std::unique_ptr<sdbus::IConnection> global_default_bus_connection =
nullptr;
static absl::once_flag bus_connection_init_;
static void initBusConnections() {
global_system_bus_connection =
sdbus::createSystemBusConnection("/com/github/google/nearby");
global_default_bus_connection =
sdbus::createDefaultBusConnection("/com/github/google/nearby");
}
sdbus::IConnection &getSystemBusConnection() {
absl::call_once(bus_connection_init_, initBusConnections);
assert(global_system_bus_connection != nullptr);
return *global_system_bus_connection;
}
sdbus::IConnection &getDefaultBusConnection() {
absl::call_once(bus_connection_init_, initBusConnections);
assert(global_default_bus_connection != nullptr);
return *global_default_bus_connection;
}
} // namespace linux
} // namespace nearby
@@ -1,6 +1,8 @@
#ifndef PLATFORM_IMPL_LINUX_DBUS_H_
#define PLATFORM_IMPL_LINUX_DBUS_H_
#include "internal/platform/logging.h"
#include <sdbus-c++/IConnection.h>
#define DBUS_LOG_METHOD_CALL_ERROR(p, m, e) \
do { \
@@ -26,4 +28,10 @@
<< " on object " << (p)->getObjectPath(); \
} while (false)
namespace nearby {
namespace linux {
extern sdbus::IConnection &getSystemBusConnection();
extern sdbus::IConnection &getDefaultBusConnection();
} // namespace linux
} // namespace nearby
#endif
@@ -91,10 +91,6 @@ std::optional<std::string> DeviceInfo::GetProfileUserName() const {
std::optional<std::filesystem::path> DeviceInfo::GetDownloadPath() const {
char *dir = getenv("XDG_DOWNLOAD_DIR");
if (dir == NULL) {
std::filesystem::path home_path(std::string(getenv("HOME")));
return home_path / "Desktop";
}
return std::filesystem::path(std::string(dir));
}
@@ -103,7 +99,7 @@ std::optional<std::filesystem::path> DeviceInfo::GetLocalAppDataPath() const {
if (dir == NULL) {
return std::filesystem::path("/tmp");
}
return std::filesystem::path(std::string(dir)) / "com.github.google.nearby";
return std::filesystem::path(std::string(dir)) / "Google Nearby";
}
std::optional<std::filesystem::path> DeviceInfo::GetTemporaryPath() const {
@@ -0,0 +1,111 @@
#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <memory>
#include <sys/syslog.h>
#define SD_JOURNAL_SUPPRESS_LOCATION true
#include <systemd/sd-journal.h>
#include "absl/base/call_once.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/implementation/linux/log_message.h"
namespace nearby {
static std::unique_ptr<linux::LogControl> global_log_control_;
static absl::once_flag log_control_init_;
static void init_log_control() {
global_log_control_ =
std::make_unique<linux::LogControl>(linux::getDefaultBusConnection());
}
namespace api {
void LogMessage::SetMinLogSeverity(Severity severity) {
absl::call_once(log_control_init_, init_log_control, nullptr);
assert(global_log_control_ != nullptr);
global_log_control_->LogLevel(severity);
}
bool LogMessage::ShouldCreateLogMessage(Severity severity) {
absl::call_once(log_control_init_, init_log_control, nullptr);
assert(global_log_control_ != nullptr);
return severity >= global_log_control_->GetLogLevel();
}
} // namespace api
namespace linux {
static inline int ConvertSeverityToSyslog(google::LogSeverity severity) {
switch (severity) {
case google::GLOG_WARNING:
return LOG_WARNING;
case google::GLOG_ERROR:
return LOG_ERR;
case google::GLOG_FATAL:
return LOG_EMERG;
case google::GLOG_INFO:
default:
return LOG_INFO;
}
}
void LogControl::send(google::LogSeverity severity, const char *full_filename,
const char *base_filename, int line,
const struct ::tm *tm_time, const char *message,
size_t message_len) {
switch (log_target_) {
case kJournal:
sd_journal_send("MESSAGE=%s", message, "PRIORITY=%d",
ConvertSeverityToSyslog(severity), "CODE_FILE=%s",
base_filename, "CODE_LINE=%d", line, NULL);
break;
case kSyslog: {
auto str = LogSink::ToString(severity, base_filename, line, tm_time,
message, message_len);
syslog(ConvertSeverityToSyslog(severity), "%s", str.c_str());
}
case kConsole:
default:
std::cout << LogSink::ToString(severity, base_filename, line, tm_time,
message, message_len)
<< "\n";
break;
}
}
static inline google::LogSeverity
ConvertSeverity(api::LogMessage::Severity severity) {
switch (severity) {
case api::LogMessage::Severity::kVerbose:
case api::LogMessage::Severity::kInfo:
return google::GLOG_INFO;
case api::LogMessage::Severity::kWarning:
return google::GLOG_WARNING;
case api::LogMessage::Severity::kError:
return google::GLOG_ERROR;
case api::LogMessage::Severity::kFatal:
return google::GLOG_FATAL;
}
}
// TODO: Set a LogSink depending on the target set by LogControl
LogMessage::LogMessage(const char *file, int line, Severity severity)
: log_streamer_(file, line, ConvertSeverity(severity),
global_log_control_.get(), false) {}
void LogMessage::Print(const char *format, ...) {
va_list ap;
va_start(ap, format);
char *buf = nullptr;
vasprintf(&buf, format, ap);
va_end(ap);
log_streamer_.stream() << std::string(buf);
}
std::ostream &LogMessage::Stream() { return log_streamer_.stream(); }
} // namespace linux
} // namespace nearby
@@ -0,0 +1,118 @@
#ifndef PLATFORM_IMPL_LINUX_LOG_MESSAGE_H_
#define PLATFORM_IMPL_LINUX_LOG_MESSAGE_H_
#include "absl/synchronization/mutex.h"
#include "glog/logging.h"
#include "internal/platform/implementation/linux/org_freedesktop_logcontrol_server_glue.h"
#include "internal/platform/implementation/log_message.h"
#include <sdbus-c++/AdaptorInterfaces.h>
#include <sdbus-c++/IConnection.h>
namespace nearby {
namespace linux {
// See documentation in
// cpp/platform/api/log_message.h
class LogMessage : public api::LogMessage {
public:
LogMessage(const char *file, int line, Severity severity);
~LogMessage() override;
void Print(const char *format, ...) override;
std::ostream &Stream() override;
private:
google::LogMessage log_streamer_;
static api::LogMessage::Severity min_log_severity_;
};
class LogControl
: public sdbus::AdaptorInterfaces<org::freedesktop::LogControl1_adaptor>,
public google::LogSink {
public:
LogControl(sdbus::IConnection &system_bus)
: AdaptorInterfaces(system_bus, "/com/github/google/nearby"),
severity_(api::LogMessage::LogMessage::Severity::kVerbose) {
registerAdaptor();
}
~LogControl() { unregisterAdaptor(); }
void LogLevel(const LogMessage::Severity &severity) { severity_ = severity; }
LogMessage::Severity GetLogLevel() { return severity_; }
protected:
std::string LogLevel() override {
switch (severity_) {
case api::LogMessage::Severity::kVerbose:
return "debug";
break;
case api::LogMessage::Severity::kInfo:
return "info";
break;
case api::LogMessage::Severity::kWarning:
return "warning";
break;
case api::LogMessage::Severity::kError:
return "err";
case api::LogMessage::Severity::kFatal:
return "emerg";
}
}
void LogLevel(const std::string &value) override {
if (value == "debug")
severity_ = api::LogMessage::Severity::kVerbose;
else if (value == "info")
severity_ = api::LogMessage::Severity::kInfo;
else if (value == "warning")
severity_ = api::LogMessage::Severity::kWarning;
else if (value == "err")
severity_ = api::LogMessage::Severity::kError;
else if (value == "crit" || value == "alert" || value == "emerg")
severity_ = api::LogMessage::Severity::kFatal;
}
enum LogTarget { kConsole, kKernel, kJournal, kSyslog };
std::string LogTarget() override {
switch (log_target_) {
case kConsole:
return "console";
case kKernel:
return "kmsg";
case kJournal:
return "journal";
case kSyslog:
return "syslog";
}
}
void LogTarget(const std::string &value) override {
if (value == "console")
log_target_ = kConsole;
else if (value == "kmsg")
log_target_ = kKernel;
else if (value == "journal")
log_target_ = kJournal;
else if (value == "syslog")
log_target_ = kSyslog;
}
std::string SyslogIdentifier() override {
return "com.github.com.google.nearby";
}
void send(google::LogSeverity severity, const char *full_filename,
const char *base_filename, int line, const struct ::tm *tm_time,
const char *message, size_t message_len) override;
private:
std::atomic<api::LogMessage::Severity> severity_;
std::atomic<enum LogTarget> log_target_;
};
} // namespace linux
} // namespace nearby
#endif // PLATFORM_IMPL_LINUX_LOG_MESSAGE_H_
@@ -0,0 +1,56 @@
#ifndef PLATFORM_IMPL_LINUX_MUTEX_H_
#define PLATFORM_IMPL_LINUX_MUTEX_H_
#include <mutex>
#include <variant>
#include "absl/synchronization/mutex.h"
#include "internal/platform/implementation/mutex.h"
namespace nearby {
namespace linux {
class ABSL_LOCKABLE Mutex : public api::Mutex {
public:
explicit Mutex(Mode mode) : mode_(mode) {
if (mode == Mode::kRecursive)
mutex_.emplace<std::recursive_mutex>();
else
mutex_.emplace<absl::Mutex>();
}
~Mutex() override = default;
Mutex(Mutex &&) = delete;
Mutex &operator=(Mutex &&) = delete;
Mutex(const Mutex &) = delete;
Mutex &operator=(const Mutex &) = delete;
void Lock() ABSL_EXCLUSIVE_LOCK_FUNCTION() override {
if (auto mutex = std::get_if<absl::Mutex>(&mutex_); mutex != nullptr) {
if (mode_ == Mode::kRegularNoCheck) {
mutex->ForgetDeadlockInfo();
}
mutex->Lock();
} else {
std::get_if<std::recursive_mutex>(&mutex_)->lock();
}
}
void Unlock() ABSL_UNLOCK_FUNCTION() override {
if (auto mutex = std::get_if<absl::Mutex>(&mutex_); mutex != nullptr) {
mutex->Unlock();
} else {
std::get_if<std::recursive_mutex>(&mutex_)->unlock();
}
}
absl::Mutex *GetRegularMutex() {
return std::get_if<absl::Mutex>(&mutex_);
}
private:
std::variant<absl::Mutex, std::recursive_mutex> mutex_;
Mode mode_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,94 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
-->
<node>
<interface name="org.freedesktop.Avahi.EntryGroup">
<method name="Free"/>
<method name="Commit"/>
<method name="Reset"/>
<method name="GetState">
<arg name="state" type="i" direction="out"/>
</method>
<signal name="StateChanged">
<arg name="state" type="i"/>
<arg name="error" type="s"/>
</signal>
<method name="IsEmpty">
<arg name="empty" type="b" direction="out"/>
</method>
<method name="AddService">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="host" type="s" direction="in"/>
<arg name="port" type="q" direction="in"/>
<arg name="txt" type="aay" direction="in"/>
</method>
<method name="AddServiceSubtype">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="subtype" type="s" direction="in"/>
</method>
<method name="UpdateServiceTxt">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="txt" type="aay" direction="in"/>
</method>
<method name="AddAddress">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="address" type="s" direction="in"/>
</method>
<method name="AddRecord">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="clazz" type="q" direction="in"/>
<arg name="type" type="q" direction="in"/>
<arg name="ttl" type="u" direction="in"/>
<arg name="rdata" type="ay" direction="in"/>
</method>
</interface>
</node>
@@ -0,0 +1,398 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
-->
<node>
<interface name="org.freedesktop.Avahi.Server">
<method name="GetVersionString">
<arg name="version" type="s" direction="out"/>
</method>
<method name="GetAPIVersion">
<arg name="version" type="u" direction="out"/>
</method>
<method name="GetHostName">
<arg name="name" type="s" direction="out"/>
</method>
<method name="SetHostName">
<arg name="name" type="s" direction="in"/>
</method>
<method name="GetHostNameFqdn">
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetDomainName">
<arg name="name" type="s" direction="out"/>
</method>
<method name="IsNSSSupportAvailable">
<arg name="yes" type="b" direction="out"/>
</method>
<method name="GetState">
<arg name="state" type="i" direction="out"/>
</method>
<signal name="StateChanged">
<arg name="state" type="i"/>
<arg name="error" type="s"/>
</signal>
<method name="GetLocalServiceCookie">
<arg name="cookie" type="u" direction="out"/>
</method>
<method name="GetAlternativeHostName">
<arg name="name" type="s" direction="in"/>
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetAlternativeServiceName">
<arg name="name" type="s" direction="in"/>
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetNetworkInterfaceNameByIndex">
<arg name="index" type="i" direction="in"/>
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetNetworkInterfaceIndexByName">
<arg name="name" type="s" direction="in"/>
<arg name="index" type="i" direction="out"/>
</method>
<method name="ResolveHostName">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="ResolveAddress">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="address" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="ResolveService">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="type" type="s" direction="out"/>
<arg name="domain" type="s" direction="out"/>
<arg name="host" type="s" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="port" type="q" direction="out"/>
<arg name="txt" type="aay" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="EntryGroupNew">
<arg name="path" type="o" direction="out"/>
</method>
<method name="DomainBrowserNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="btype" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="ServiceTypeBrowserNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="ServiceBrowserNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="ServiceResolverNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="HostNameResolverNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="AddressResolverNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="address" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="RecordBrowserNew">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="clazz" type="q" direction="in"/>
<arg name="type" type="q" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
</interface>
<interface name="org.freedesktop.Avahi.Server2">
<method name="GetVersionString">
<arg name="version" type="s" direction="out"/>
</method>
<method name="GetAPIVersion">
<arg name="version" type="u" direction="out"/>
</method>
<method name="GetHostName">
<arg name="name" type="s" direction="out"/>
</method>
<method name="SetHostName">
<arg name="name" type="s" direction="in"/>
</method>
<method name="GetHostNameFqdn">
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetDomainName">
<arg name="name" type="s" direction="out"/>
</method>
<method name="IsNSSSupportAvailable">
<arg name="yes" type="b" direction="out"/>
</method>
<method name="GetState">
<arg name="state" type="i" direction="out"/>
</method>
<signal name="StateChanged">
<arg name="state" type="i"/>
<arg name="error" type="s"/>
</signal>
<method name="GetLocalServiceCookie">
<arg name="cookie" type="u" direction="out"/>
</method>
<method name="GetAlternativeHostName">
<arg name="name" type="s" direction="in"/>
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetAlternativeServiceName">
<arg name="name" type="s" direction="in"/>
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetNetworkInterfaceNameByIndex">
<arg name="index" type="i" direction="in"/>
<arg name="name" type="s" direction="out"/>
</method>
<method name="GetNetworkInterfaceIndexByName">
<arg name="name" type="s" direction="in"/>
<arg name="index" type="i" direction="out"/>
</method>
<method name="ResolveHostName">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="ResolveAddress">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="address" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="ResolveService">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="type" type="s" direction="out"/>
<arg name="domain" type="s" direction="out"/>
<arg name="host" type="s" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="port" type="q" direction="out"/>
<arg name="txt" type="aay" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</method>
<method name="EntryGroupNew">
<arg name="path" type="o" direction="out"/>
</method>
<method name="DomainBrowserPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="btype" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="ServiceTypeBrowserPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="ServiceBrowserPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="ServiceResolverPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="type" type="s" direction="in"/>
<arg name="domain" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="HostNameResolverPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="aprotocol" type="i" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="AddressResolverPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="address" type="s" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
<method name="RecordBrowserPrepare">
<arg name="interface" type="i" direction="in"/>
<arg name="protocol" type="i" direction="in"/>
<arg name="name" type="s" direction="in"/>
<arg name="clazz" type="q" direction="in"/>
<arg name="type" type="q" direction="in"/>
<arg name="flags" type="u" direction="in"/>
<arg name="path" type="o" direction="out"/>
</method>
</interface>
</node>
@@ -0,0 +1,58 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
-->
<node>
<interface name="org.freedesktop.Avahi.ServiceBrowser">
<method name="Free"/>
<method name="Start"/>
<signal name="ItemNew">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="name" type="s"/>
<arg name="type" type="s"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="ItemRemove">
<arg name="interface" type="i"/>
<arg name="protocol" type="i"/>
<arg name="name" type="s"/>
<arg name="type" type="s"/>
<arg name="domain" type="s"/>
<arg name="flags" type="u"/>
</signal>
<signal name="Failure">
<arg name="error" type="s"/>
</signal>
<signal name="AllForNow"/>
<signal name="CacheExhausted"/>
</interface>
</node>
@@ -0,0 +1,57 @@
<?xml version="1.0" standalone='no'?><!--*-nxml-*-->
<?xml-stylesheet type="text/xsl" href="introspect.xsl"?>
<!DOCTYPE node SYSTEM "introspect.dtd">
<!--
This file is part of avahi.
avahi is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
avahi 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 Lesser General Public
License along with avahi; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
-->
<node>
<interface name="org.freedesktop.DBus.Introspectable">
<method name="Introspect">
<arg name="data" type="s" direction="out" />
</method>
</interface>
<interface name="org.freedesktop.Avahi.ServiceResolver">
<method name="Free"/>
<method name="Start"/>
<signal name="Found">
<arg name="interface" type="i" direction="out"/>
<arg name="protocol" type="i" direction="out"/>
<arg name="name" type="s" direction="out"/>
<arg name="type" type="s" direction="out"/>
<arg name="domain" type="s" direction="out"/>
<arg name="host" type="s" direction="out"/>
<arg name="aprotocol" type="i" direction="out"/>
<arg name="address" type="s" direction="out"/>
<arg name="port" type="q" direction="out"/>
<arg name="txt" type="aay" direction="out"/>
<arg name="flags" type="u" direction="out"/>
</signal>
<signal name="Failure">
<arg name="error" type="s"/>
</signal>
</interface>
</node>
@@ -0,0 +1,17 @@
<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
"https://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
<node>
<interface name="org.freedesktop.LogControl1">
<property name="LogLevel" type="s" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</property>
<property name="LogTarget" type="s" access="readwrite">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
<annotation name="org.freedesktop.systemd1.Privileged" value="true"/>
</property>
<property name="SyslogIdentifier" type="s" access="read">
<annotation name="org.freedesktop.DBus.Property.EmitsChangedSignal" value="false"/>
</property>
</interface>
</node>
@@ -0,0 +1,45 @@
/*
* This file was automatically generated by sdbus-c++-xml2cpp; DO NOT EDIT!
*/
#ifndef __sdbuscpp__org_freedesktop_logcontrol_server_glue_h__adaptor__H__
#define __sdbuscpp__org_freedesktop_logcontrol_server_glue_h__adaptor__H__
#include <sdbus-c++/sdbus-c++.h>
#include <string>
#include <tuple>
namespace org {
namespace freedesktop {
class LogControl1_adaptor
{
public:
static constexpr const char* INTERFACE_NAME = "org.freedesktop.LogControl1";
protected:
LogControl1_adaptor(sdbus::IObject& object)
: object_(object)
{
object_.registerProperty("LogLevel").onInterface(INTERFACE_NAME).withGetter([this](){ return this->LogLevel(); }).withSetter([this](const std::string& value){ this->LogLevel(value); }).withUpdateBehavior(sdbus::Flags::EMITS_NO_SIGNAL).markAsPrivileged();
object_.registerProperty("LogTarget").onInterface(INTERFACE_NAME).withGetter([this](){ return this->LogTarget(); }).withSetter([this](const std::string& value){ this->LogTarget(value); }).withUpdateBehavior(sdbus::Flags::EMITS_NO_SIGNAL).markAsPrivileged();
object_.registerProperty("SyslogIdentifier").onInterface(INTERFACE_NAME).withGetter([this](){ return this->SyslogIdentifier(); }).withUpdateBehavior(sdbus::Flags::EMITS_NO_SIGNAL);
}
~LogControl1_adaptor() = default;
private:
virtual std::string LogLevel() = 0;
virtual void LogLevel(const std::string& value) = 0;
virtual std::string LogTarget() = 0;
virtual void LogTarget(const std::string& value) = 0;
virtual std::string SyslogIdentifier() = 0;
private:
sdbus::IObject& object_;
};
}} // namespaces
#endif
@@ -1,12 +1,74 @@
#include "internal/platform/implementation/platform.h"
#include <filesystem>
#include <memory>
#include <string>
#include "internal/platform/implementation/linux/condition_variable.h"
#include "internal/platform/implementation/linux/mutex.h"
#include "internal/platform/implementation/platform.h"
#include "internal/platform/implementation/atomic_boolean.h"
#include "internal/platform/implementation/atomic_reference.h"
#include "internal/platform/implementation/count_down_latch.h"
#include "internal/platform/implementation/linux/atomic_boolean.h"
#include "internal/platform/implementation/linux/atomic_uint32.h"
#include "internal/platform/implementation/shared/count_down_latch.h"
#include "log_message.h"
namespace nearby {
namespace api {
namespace {
std::string ImplementationPlatform::GetCustomSavePath()
std::string ImplementationPlatform::GetCustomSavePath(const std::string &parent_folder, const std::string & file_name) {
auto fs = std::filesystem::path(parent_folder);
return fs / file_name;
}
std::string ImplementationPlatform::GetDownloadPath(const std::string& parent_folder, const std::string &file_name) {
auto downloads = std::filesystem::path(getenv("XDG_DOWNLOAD_DIR"));
return downloads / std::filesystem::path(parent_folder).filename() / std::filesystem::path(file_name).filename();
}
std::string ImplementationPlatform::GetDownloadPath(const std::string& file_name) {
auto downloads = std::filesystem::path(getenv("XDG_DOWNLOAD_DIR"));
return downloads / std::filesystem::path(file_name).filename();
}
std::string ImplementationPlatform::GetAppDataPath(const std::string &file_name) {
auto state = std::filesystem::path(getenv("XDG_STATE_HOME"));
return state / std::filesystem::path(file_name).filename();
}
OSName GetCurrentOS() { return OSName::kWindows; }
std::unique_ptr<api::AtomicBoolean> CreateAtomicBoolean(bool initial_value) {
return std::make_unique<linux::AtomicBoolean>(initial_value);
}
std::unique_ptr<api::AtomicUint32> CreateAtomicUint32(std::uint32_t value) {
return std::make_unique<linux::AtomicUint32>(value);
}
std::unique_ptr<api::CountDownLatch> ImplementationPlatform::CreateCountDownLatch(std::int32_t count) {
return std::make_unique<shared::CountDownLatch>(count);
}
#pragma push_macro("CreateMutex")
#undef CreateMutex
std::unique_ptr<api::Mutex> ImplementationPlatform::CreateMutex(Mutex::Mode mode) {
return std::make_unique<linux::Mutex>(mode);
}
#pragma pop_macro("CreateMutex")
std::unique_ptr<api::ConditionVariable>
ImplementationPlatform::CreateConditionVariable(api::Mutex *mutex) {
return std::make_unique<linux::ConditionVariable>(mutex);
}
std::unique_ptr<api::LogMessage> ImplementationPlatform::CreateLogMessage(
const char *file, int line, LogMessage::Severity severity
) {
return std::make_unique<linux::LogMessage>(file, line, severity);
}
} // namespace api
} // namespace nearby
@@ -0,0 +1,40 @@
#ifndef PLATFORM_IMPL_LINUX_STREAM_H_
#define PLATFORM_IMPL_LINUX_STREAM_H_
#include <optional>
#include <sdbus-c++/Types.h>
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace linux {
class InputStream : public nearby::InputStream {
public:
InputStream(sdbus::UnixFd &fd) : fd_(fd){};
ExceptionOr<ByteArray> Read(std::int64_t size) override;
Exception Close() override;
private:
std::optional<sdbus::UnixFd> fd_;
};
class OutputStream : public nearby::OutputStream {
public:
OutputStream(sdbus::UnixFd &fd) : fd_(fd){};
Exception Write(const ByteArray &data) override;
Exception Flush() override;
Exception Close() override;
private:
std::optional<sdbus::UnixFd> fd_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,240 @@
#include <arpa/inet.h>
#include <cerrno>
#include <cstdint>
#include <cstring>
#include <memory>
#include <netinet/in.h>
#include <sdbus-c++/Types.h>
#include <sys/socket.h>
#include <sdbus-c++/Error.h>
#include <sdbus-c++/IConnection.h>
#include "absl/strings/substitute.h"
#include "internal/platform/implementation/linux/avahi.h"
#include "internal/platform/implementation/linux/dbus.h"
#include "internal/platform/implementation/linux/wifi_lan.h"
#include "internal/platform/implementation/linux/wifi_lan_server_socket.h"
#include "internal/platform/implementation/linux/wifi_lan_socket.h"
#include "internal/platform/implementation/wifi_lan.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
WifiLanMedium::WifiLanMedium(sdbus::IConnection &system_bus,
NetworkManager &network_manager)
: system_bus_(system_bus), network_manager_(network_manager),
avahi_(std::make_shared<avahi::Server>(system_bus)),
entry_group_(nullptr) {}
WifiLanMedium::~WifiLanMedium() {
if (entry_group_ != nullptr) {
entry_group_->Free();
}
}
bool WifiLanMedium::IsNetworkConnected() const {
auto state = network_manager_.getState();
return state >= 50; // NM_STATE_CONNECTED_LOCAL
}
bool WifiLanMedium::StartAdvertising(const NsdServiceInfo &nsd_service_info) {
if (entry_group_ == nullptr) {
try {
auto object_path = avahi_->EntryGroupNew();
entry_group_ =
std::make_unique<avahi::EntryGroup>(system_bus_, object_path);
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(avahi_, "EntryGroupNew", e);
NEARBY_LOGS(ERROR) << __func__ << ": Could not create a new entry group.";
return false;
}
}
if (advertising_) {
NEARBY_LOGS(ERROR) << __func__
<< ": Cannot advertise while we are already advertising";
return false;
}
auto txt_records_map = nsd_service_info.GetTxtRecords();
std::vector<std::vector<std::uint8_t>> txt_records(txt_records_map.size());
std::size_t i = 0;
for (auto [key, value] : nsd_service_info.GetTxtRecords()) {
std::string entry = absl::Substitute("$0=$1", key, value);
txt_records[i++] = std::vector<std::uint8_t>(entry.begin(), entry.end());
}
try {
entry_group_->AddService(-1, // AVAHI_IF_UNSPEC
-1, // AVAHI_PROTO_UNSPED
0, nsd_service_info.GetServiceName(),
nsd_service_info.GetServiceType(), std::string(),
nsd_service_info.GetIPAddress(),
nsd_service_info.GetPort(), txt_records);
entry_group_->Commit();
} catch (const sdbus::Error &e) {
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
<< "' with message '" << e.getMessage()
<< "' while adding service";
}
advertising_ = true;
return true;
}
bool WifiLanMedium::StopAdvertising(const NsdServiceInfo &nsd_service_info) {
if (!advertising_) {
NEARBY_LOGS(ERROR) << __func__ << ": Advertising is already stopped.";
return false;
}
if (entry_group_ == nullptr) {
NEARBY_LOGS(ERROR) << __func__ << ": No entry group registered.";
return false;
}
try {
if (entry_group_->IsEmpty()) {
NEARBY_LOGS(ERROR)
<< __func__ << ": Cannot stop advertising on an empty entry group.";
return false;
}
entry_group_->Reset();
entry_group_->Commit();
} catch (const sdbus::Error &e) {
NEARBY_LOGS(ERROR) << __func__ << ": Got error '" << e.getName()
<< "' with message '" << e.getMessage()
<< "' while removing service";
}
advertising_ = false;
return true;
}
bool WifiLanMedium::StartDiscovery(
const std::string &service_type,
api::WifiLanMedium::DiscoveredServiceCallback callback) {
if (service_browsers_.count(service_type) != 0) {
auto &object = service_browsers_[service_type];
NEARBY_LOGS(ERROR) << __func__ << ": A service browser for service type "
<< service_type << " already exists at "
<< object->getObjectPath();
return false;
}
try {
sdbus::ObjectPath browser_object_path =
avahi_->ServiceBrowserPrepare(-1, // AVAHI_IF_UNSPEC
-1, // AVAHI_PROTO_UNSPED
service_type, std::string(), 0);
NEARBY_LOGS(VERBOSE)
<< __func__
<< ": Created a new org.freedesktop.Avahi.ServiceBrowser object at "
<< browser_object_path;
service_browsers_.emplace(service_type, system_bus_, browser_object_path,
std::move(callback));
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(avahi_, "ServiceBrowserPrepare", e);
}
auto &browser = service_browsers_[service_type];
try {
NEARBY_LOGS(VERBOSE) << __func__ << ": Starting service discovery for "
<< browser->getObjectPath();
browser->Start();
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(browser, "Start", e);
}
return true;
}
bool WifiLanMedium::StopDiscovery(const std::string &service_type) {
if (service_browsers_.count(service_type) == 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Service type " << service_type
<< " has not been registered for discovery";
return false;
}
auto &browser = service_browsers_[service_type];
try {
browser->Free();
} catch (const sdbus::Error &e) {
DBUS_LOG_METHOD_CALL_ERROR(browser, "Free", e);
}
service_browsers_.erase(service_type);
return true;
}
std::unique_ptr<api::WifiLanSocket>
WifiLanMedium::ConnectToService(const std::string &ip_address, int port,
CancellationFlag *cancellation_flag) {
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error opening socket: " << std::strerror(errno);
return nullptr;
}
NEARBY_LOGS(VERBOSE) << __func__ << ": Connecting to " << ip_address << ":"
<< port;
struct sockaddr_in addr;
addr.sin_addr.s_addr = inet_addr(ip_address.c_str());
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
auto ret =
connect(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr));
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error connecting to socket: "
<< std::strerror(errno);
return nullptr;
}
sdbus::UnixFd fd(sock);
return std::make_unique<WifiLanSocket>(std::move(fd));
}
std::unique_ptr<api::WifiLanServerSocket> ListenForService(int port = 0) {
auto sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error opening socket: " << std::strerror(errno);
return nullptr;
}
NEARBY_LOGS(VERBOSE) << __func__ << "Listening for services ";
struct sockaddr_in addr;
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl(INADDR_ANY);
addr.sin_port = htons(port);
auto ret =
bind(sock, reinterpret_cast<struct sockaddr *>(&addr), sizeof(addr));
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error binding to socket: " << std::strerror(errno);
return nullptr;
}
ret = listen(sock, 0);
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error listening on socket: "
<< std::strerror(errno);
return nullptr;
}
return std::make_unique<WifiLanServerSocket>(sdbus::UnixFd(sock));
}
absl::optional<std::pair<std::int32_t, std::int32_t>>
GetDynamicPortRange() {
return absl::nullopt;
}
} // namespace linux
} // namespace nearby
@@ -0,0 +1,58 @@
#ifndef PLATFORM_IMPL_LINUX_WIFI_LAN_H_
#define PLATFORM_IMPL_LINUX_WIFI_LAN_H_
#include <memory>
#include <unordered_map>
#include "absl/container/flat_hash_map.h"
#include "internal/platform/implementation/linux/avahi.h"
#include "internal/platform/implementation/linux/wifi_medium.h"
#include "internal/platform/implementation/wifi_lan.h"
#include "internal/platform/nsd_service_info.h"
namespace nearby {
namespace linux {
class WifiLanMedium : public api::WifiLanMedium {
public:
WifiLanMedium(sdbus::IConnection &system_bus,
NetworkManager &network_manager);
~WifiLanMedium() override;
bool IsNetworkConnected() const override;
bool StartAdvertising(const NsdServiceInfo &nsd_service_info) override;
bool StopAdvertising(const NsdServiceInfo &nsd_service_info) override;
bool StartDiscovery(const std::string &service_type,
DiscoveredServiceCallback callback) override;
bool StopDiscovery(const std::string &service_type) override;
std::unique_ptr<api::WifiLanSocket>
ConnectToService(const NsdServiceInfo &remote_service_info,
CancellationFlag *cancellation_flag) override {
return ConnectToService(remote_service_info.GetIPAddress(),
remote_service_info.GetPort(), cancellation_flag);
};
std::unique_ptr<api::WifiLanSocket>
ConnectToService(const std::string &ip_address, int port,
CancellationFlag *cancellation_flag) override;
std::unique_ptr<api::WifiLanServerSocket>
ListenForService(int port = 0) override;
absl::optional<std::pair<std::int32_t, std::int32_t>>
GetDynamicPortRange() override;
private:
DiscoveredServiceCallback discovery_cb_;
sdbus::IConnection &system_bus_;
NetworkManager &network_manager_;
std::shared_ptr<avahi::Server> avahi_;
std::unique_ptr<avahi::EntryGroup> entry_group_;
absl::flat_hash_map<std::string, std::unique_ptr<avahi::ServiceBrowser>>
service_browsers_;
bool advertising_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,82 @@
#include <cerrno>
#include <cstring>
#include <ifaddrs.h>
#include <memory>
#include <netinet/in.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sdbus-c++/Types.h>
#include "internal/platform/implementation/linux/wifi_lan_server_socket.h"
#include "internal/platform/exception.h"
#include "internal/platform/implementation/linux/wifi_lan_socket.h"
#include "internal/platform/logging.h"
namespace nearby {
namespace linux {
std::string WifiLanServerSocket::GetIPAddress() const {
struct ifaddrs *addrs = nullptr;
getifaddrs(&addrs);
for (auto ifaddr = addrs; ifaddr != NULL; ifaddr = ifaddr->ifa_next) {
if (ifaddr->ifa_addr == nullptr) {
continue;
}
if (ifaddr->ifa_addr->sa_family == AF_INET) {
auto addr =
&(reinterpret_cast<struct sockaddr_in *>(ifaddr->ifa_addr))->sin_addr;
char buf[INET_ADDRSTRLEN];
inet_ntop(AF_INET, addr, buf, INET_ADDRSTRLEN);
return std::string(buf);
}
}
return std::string();
}
int WifiLanServerSocket::GetPort() const {
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
auto ret =
getsockname(fd_.get(), reinterpret_cast<struct sockaddr *>(&sin), &len);
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error getting information for socket "
<< fd_.get() << ": " << std::strerror(errno);
return 0;
}
return ntohs(sin.sin_port);
}
std::unique_ptr<api::WifiLanSocket> WifiLanServerSocket::Accept() {
struct sockaddr_in addr;
socklen_t len = sizeof(addr);
auto conn =
accept(fd_.get(), reinterpret_cast<struct sockaddr *>(&addr), &len);
if (conn < 0) {
NEARBY_LOGS(ERROR) << __func__
<< ": Error accepting incoming connections on socket "
<< fd_.get() << ": " << std::strerror(errno);
return nullptr;
}
return std::make_unique<WifiLanSocket>(sdbus::UnixFd(conn));
}
Exception WifiLanServerSocket::Close() {
int fd = fd_.release();
auto ret = close(fd);
if (ret < 0) {
NEARBY_LOGS(ERROR) << __func__ << ": Error closing socket " << fd << ": "
<< std::strerror(errno);
return {Exception::kFailed};
}
return {Exception::kSuccess};
}
} // namespace linux
} // namespace nearby
@@ -0,0 +1,33 @@
#ifndef PLATFORM_IMPL_LINUX_WIFI_LAN_SERVER_SOCKET_H_
#define PLATFORM_IMPL_LINUX_WIFI_LAN_SERVER_SOCKET_H_
#include <netinet/in.h>
#include <sdbus-c++/Types.h>
#include "internal/platform/exception.h"
#include "internal/platform/implementation/wifi_lan.h"
namespace nearby {
namespace linux {
class WifiLanServerSocket : public api::WifiLanServerSocket {
public:
WifiLanServerSocket(int socket) {
fd_ = sdbus::UnixFd(socket);
}
~WifiLanServerSocket() override = default;
std::string GetIPAddress() const override;
int GetPort() const override;
std::unique_ptr<api::WifiLanSocket> Accept() override;
Exception Close() override;
sdbus::UnixFd fd_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -0,0 +1,42 @@
#ifndef PLATFORM_IMPL_LINUX_WIFI_LAN_SOCKET_H_
#define PLATFORM_IMPL_LINUX_WIFI_LAN_SOCKET_H_
#include <optional>
#include <sdbus-c++/Types.h>
#include "internal/platform/implementation/linux/stream.h"
#include "internal/platform/implementation/wifi_lan.h"
#include "internal/platform/input_stream.h"
#include "internal/platform/output_stream.h"
namespace nearby {
namespace linux {
class WifiLanSocket : public api::WifiLanSocket {
public:
WifiLanSocket(sdbus::UnixFd fd)
: fd_(fd), output_stream_(fd), input_stream_(fd) {}
~WifiLanSocket() = default;
nearby::InputStream &GetInputStream() override {
return input_stream_;
};
nearby::OutputStream &GetOutputStream() override {
return output_stream_;
};
Exception Close() override {
input_stream_.Close();
output_stream_.Close();
return Exception{Exception::kSuccess};
};
private:
sdbus::UnixFd fd_;
OutputStream output_stream_;
InputStream input_stream_;
};
} // namespace linux
} // namespace nearby
#endif
@@ -1,6 +1,7 @@
#ifndef PLATFORM_IMPL_LINUX_WIFI_MEDIUM_H_
#define PLATFORM_IMPL_LINUX_WIFI_MEDIUM_H_
#include <atomic>
#include <functional>
#include <memory>
#include <optional>
@@ -29,11 +30,16 @@ public:
}
~NetworkManager() { unregisterProxy(); }
std::uint32_t getState() const { return state_; }
protected:
void onCheckPermissions() override {}
void onStateChanged(const uint32_t &state) override {}
void onStateChanged(const uint32_t &state) override { state_ = state; }
void onDeviceAdded(const sdbus::ObjectPath &device_path) override {}
void onDeviceRemoved(const sdbus::ObjectPath &device_path) override {}
private:
std::atomic_uint32_t state_;
};
class NetworkManagerIP4Config
@@ -0,0 +1,16 @@
#ifndef PLATFORM_IMPL_LINUX_WIFI_LAN_SOCKET_H_
#define PLATFORM_IMPL_LINUX_WIFI_LAN_SOCKET_H_
namespace nearby {
namespace api {
class WifiLanSocket {
public:
~WifiLanSocket() = default;
private:
int fd;
};
}
}
#endif