mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-05 07:15:34 -04:00
modules: add options to discover local services as well
This makes it possible to discover a local RAOP, pulse or RTP services and connect to them. IPv6 addresses need the interface appended to local addresses to make the connection work.
This commit is contained in:
parent
d8a32e5272
commit
d2ca50399a
3 changed files with 39 additions and 7 deletions
|
|
@ -45,6 +45,8 @@
|
||||||
*
|
*
|
||||||
* Options specific to the behavior of this module
|
* Options specific to the behavior of this module
|
||||||
*
|
*
|
||||||
|
* - `roap.discover-local` = allow discovery of local services as well.
|
||||||
|
* false by default.
|
||||||
* - `raop.latency.ms` = latency for all streams in microseconds. This
|
* - `raop.latency.ms` = latency for all streams in microseconds. This
|
||||||
* can be overwritten in the stream rules.
|
* can be overwritten in the stream rules.
|
||||||
* - `stream.rules` = <rules>: match rules, use create-stream actions. See
|
* - `stream.rules` = <rules>: match rules, use create-stream actions. See
|
||||||
|
|
@ -56,6 +58,7 @@
|
||||||
* context.modules = [
|
* context.modules = [
|
||||||
* { name = libpipewire-raop-discover
|
* { name = libpipewire-raop-discover
|
||||||
* args = {
|
* args = {
|
||||||
|
* #roap.discover-local = false;
|
||||||
* #raop.latency.ms = 1000
|
* #raop.latency.ms = 1000
|
||||||
* stream.rules = [
|
* stream.rules = [
|
||||||
* { matches = [
|
* { matches = [
|
||||||
|
|
@ -117,6 +120,8 @@ static const struct spa_dict_item module_props[] = {
|
||||||
struct impl {
|
struct impl {
|
||||||
struct pw_context *context;
|
struct pw_context *context;
|
||||||
|
|
||||||
|
bool discover_local;
|
||||||
|
|
||||||
struct pw_impl_module *module;
|
struct pw_impl_module *module;
|
||||||
struct spa_hook module_listener;
|
struct spa_hook module_listener;
|
||||||
|
|
||||||
|
|
@ -366,7 +371,7 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr
|
||||||
const char *str, *link_local_range = "169.254.";
|
const char *str, *link_local_range = "169.254.";
|
||||||
AvahiStringList *l;
|
AvahiStringList *l;
|
||||||
struct pw_properties *props = NULL;
|
struct pw_properties *props = NULL;
|
||||||
char at[AVAHI_ADDRESS_STR_MAX];
|
char at[AVAHI_ADDRESS_STR_MAX], if_suffix[16] = "";
|
||||||
|
|
||||||
if (event != AVAHI_RESOLVER_FOUND) {
|
if (event != AVAHI_RESOLVER_FOUND) {
|
||||||
pw_log_error("Resolving of '%s' failed: %s", name,
|
pw_log_error("Resolving of '%s' failed: %s", name,
|
||||||
|
|
@ -400,7 +405,13 @@ static void resolver_cb(AvahiServiceResolver *r, AvahiIfIndex interface, AvahiPr
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_properties_setf(props, "raop.ip", "%s", at);
|
if (a->proto == AVAHI_PROTO_INET6 &&
|
||||||
|
a->data.ipv6.address[0] == 0xfe &&
|
||||||
|
(a->data.ipv6.address[1] & 0xc0) == 0x80)
|
||||||
|
snprintf(if_suffix, sizeof(if_suffix), "%%%d", interface);
|
||||||
|
|
||||||
|
pw_properties_setf(props, "raop.ip", "%s%s", at, if_suffix);
|
||||||
|
pw_properties_setf(props, "raop.ifindex", "%d", interface);
|
||||||
pw_properties_setf(props, "raop.port", "%u", port);
|
pw_properties_setf(props, "raop.port", "%u", port);
|
||||||
pw_properties_setf(props, "raop.name", "%s", name);
|
pw_properties_setf(props, "raop.name", "%s", name);
|
||||||
pw_properties_setf(props, "raop.hostname", "%s", host_name);
|
pw_properties_setf(props, "raop.hostname", "%s", host_name);
|
||||||
|
|
@ -449,7 +460,7 @@ static void browser_cb(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProt
|
||||||
struct tunnel_info info;
|
struct tunnel_info info;
|
||||||
struct tunnel *t;
|
struct tunnel *t;
|
||||||
|
|
||||||
if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
|
if ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && !impl->discover_local)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info = TUNNEL_INFO(.name = name);
|
info = TUNNEL_INFO(.name = name);
|
||||||
|
|
@ -583,6 +594,9 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
impl->context = context;
|
impl->context = context;
|
||||||
impl->properties = props;
|
impl->properties = props;
|
||||||
|
|
||||||
|
impl->discover_local = pw_properties_get_bool(impl->properties,
|
||||||
|
"raop.discover-local", false);
|
||||||
|
|
||||||
pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
|
pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
|
||||||
|
|
||||||
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
|
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@
|
||||||
* - `net.mtu = <int>`: MTU to use, default 1280
|
* - `net.mtu = <int>`: MTU to use, default 1280
|
||||||
* - `net.ttl = <int>`: TTL to use, default 1
|
* - `net.ttl = <int>`: TTL to use, default 1
|
||||||
* - `net.loop = <bool>`: loopback multicast, default false
|
* - `net.loop = <bool>`: loopback multicast, default false
|
||||||
|
* `sess.discover-local`: discover local services as well, default false
|
||||||
* - `sess.min-ptime = <int>`: minimum packet time in milliseconds, default 2
|
* - `sess.min-ptime = <int>`: minimum packet time in milliseconds, default 2
|
||||||
* - `sess.max-ptime = <int>`: maximum packet time in milliseconds, default 20
|
* - `sess.max-ptime = <int>`: maximum packet time in milliseconds, default 20
|
||||||
* - `sess.latency.msec = <int>`: receiver latency in milliseconds, default 100
|
* - `sess.latency.msec = <int>`: receiver latency in milliseconds, default 100
|
||||||
|
|
@ -105,6 +106,7 @@
|
||||||
* #net.mtu = 1280
|
* #net.mtu = 1280
|
||||||
* #net.ttl = 1
|
* #net.ttl = 1
|
||||||
* #net.loop = false
|
* #net.loop = false
|
||||||
|
* #sess.discover-local = false
|
||||||
* #sess.min-ptime = 2
|
* #sess.min-ptime = 2
|
||||||
* #sess.max-ptime = 20
|
* #sess.max-ptime = 20
|
||||||
* #sess.name = "PipeWire RTP stream"
|
* #sess.name = "PipeWire RTP stream"
|
||||||
|
|
@ -226,6 +228,7 @@ struct impl {
|
||||||
struct spa_hook module_listener;
|
struct spa_hook module_listener;
|
||||||
struct pw_properties *props;
|
struct pw_properties *props;
|
||||||
|
|
||||||
|
bool discover_local;
|
||||||
AvahiPoll *avahi_poll;
|
AvahiPoll *avahi_poll;
|
||||||
AvahiClient *client;
|
AvahiClient *client;
|
||||||
AvahiServiceBrowser *browser;
|
AvahiServiceBrowser *browser;
|
||||||
|
|
@ -1287,7 +1290,7 @@ static struct service *make_service(struct impl *impl, const struct service_info
|
||||||
AvahiStringList *txt)
|
AvahiStringList *txt)
|
||||||
{
|
{
|
||||||
struct service *s = NULL;
|
struct service *s = NULL;
|
||||||
char at[AVAHI_ADDRESS_STR_MAX];
|
char at[AVAHI_ADDRESS_STR_MAX], if_suffix[16] = "";
|
||||||
struct session *sess;
|
struct session *sess;
|
||||||
int res, ipv;
|
int res, ipv;
|
||||||
struct pw_properties *props = NULL;
|
struct pw_properties *props = NULL;
|
||||||
|
|
@ -1384,9 +1387,15 @@ static struct service *make_service(struct impl *impl, const struct service_info
|
||||||
avahi_address_snprint(at, sizeof(at), &s->info.address);
|
avahi_address_snprint(at, sizeof(at), &s->info.address);
|
||||||
pw_log_info("create session: %s %s:%u %s", s->info.name, at, s->info.port, s->info.type);
|
pw_log_info("create session: %s %s:%u %s", s->info.name, at, s->info.port, s->info.type);
|
||||||
|
|
||||||
|
if (s->info.protocol == AVAHI_PROTO_INET6 &&
|
||||||
|
s->info.address.data.ipv6.address[0] == 0xfe &&
|
||||||
|
(s->info.address.data.ipv6.address[1] & 0xc0) == 0x80)
|
||||||
|
snprintf(if_suffix, sizeof(if_suffix), "%%%d", s->info.interface);
|
||||||
|
|
||||||
ipv = s->info.protocol == AVAHI_PROTO_INET ? 4 : 6;
|
ipv = s->info.protocol == AVAHI_PROTO_INET ? 4 : 6;
|
||||||
pw_properties_set(props, "sess.name", s->info.name);
|
pw_properties_set(props, "sess.name", s->info.name);
|
||||||
pw_properties_setf(props, "destination.ip", "%s", at);
|
pw_properties_setf(props, "destination.ip", "%s%s", at, if_suffix);
|
||||||
|
pw_properties_setf(props, "destination.ifindex", "%u", s->info.interface);
|
||||||
pw_properties_setf(props, "destination.port", "%u", s->info.port);
|
pw_properties_setf(props, "destination.port", "%u", s->info.port);
|
||||||
|
|
||||||
if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL)
|
if (pw_properties_get(props, PW_KEY_NODE_NAME) == NULL)
|
||||||
|
|
@ -1473,7 +1482,7 @@ static void browser_cb(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProt
|
||||||
struct service_info info;
|
struct service_info info;
|
||||||
struct service *s;
|
struct service *s;
|
||||||
|
|
||||||
if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
|
if ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && !impl->discover_local)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info = SERVICE_INFO(.interface = interface,
|
info = SERVICE_INFO(.interface = interface,
|
||||||
|
|
@ -1683,6 +1692,9 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
}
|
}
|
||||||
impl->props = props;
|
impl->props = props;
|
||||||
|
|
||||||
|
impl->discover_local = pw_properties_get_bool(impl->props,
|
||||||
|
"sess.discover-local", false);
|
||||||
|
|
||||||
stream_props = pw_properties_new(NULL, NULL);
|
stream_props = pw_properties_new(NULL, NULL);
|
||||||
if (stream_props == NULL) {
|
if (stream_props == NULL) {
|
||||||
res = -errno;
|
res = -errno;
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,8 @@
|
||||||
*
|
*
|
||||||
* ## Module Options
|
* ## Module Options
|
||||||
*
|
*
|
||||||
|
* - `pulse.discover-local` = allow discovery of local services as well.
|
||||||
|
* false by default.
|
||||||
* - `pulse.latency`: the latency to end-to-end latency in milliseconds to
|
* - `pulse.latency`: the latency to end-to-end latency in milliseconds to
|
||||||
* maintain (Default 200ms).
|
* maintain (Default 200ms).
|
||||||
*
|
*
|
||||||
|
|
@ -80,6 +82,7 @@ struct impl {
|
||||||
|
|
||||||
struct pw_properties *properties;
|
struct pw_properties *properties;
|
||||||
|
|
||||||
|
bool discover_local;
|
||||||
AvahiPoll *avahi_poll;
|
AvahiPoll *avahi_poll;
|
||||||
AvahiClient *client;
|
AvahiClient *client;
|
||||||
AvahiServiceBrowser *sink_browser;
|
AvahiServiceBrowser *sink_browser;
|
||||||
|
|
@ -375,7 +378,7 @@ static void browser_cb(AvahiServiceBrowser *b, AvahiIfIndex interface, AvahiProt
|
||||||
struct tunnel_info info;
|
struct tunnel_info info;
|
||||||
struct tunnel *t;
|
struct tunnel *t;
|
||||||
|
|
||||||
if (flags & AVAHI_LOOKUP_RESULT_LOCAL)
|
if ((flags & AVAHI_LOOKUP_RESULT_LOCAL) && !impl->discover_local)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
info = TUNNEL_INFO(.name = name);
|
info = TUNNEL_INFO(.name = name);
|
||||||
|
|
@ -519,6 +522,9 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
impl->context = context;
|
impl->context = context;
|
||||||
impl->properties = props;
|
impl->properties = props;
|
||||||
|
|
||||||
|
impl->discover_local = pw_properties_get_bool(impl->properties,
|
||||||
|
"pulse.discover-local", false);
|
||||||
|
|
||||||
pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
|
pw_impl_module_add_listener(module, &impl->module_listener, &module_events, impl);
|
||||||
|
|
||||||
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
|
pw_impl_module_update_properties(module, &SPA_DICT_INIT_ARRAY(module_props));
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue