Changes of Revision 32

pipewire-aptx.changes Changed
x
 
1
@@ -1,4 +1,9 @@
2
 -------------------------------------------------------------------
3
+Wed Aug  9 15:43:07 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
4
+
5
+- Update to version 0.3.77
6
+
7
+-------------------------------------------------------------------
8
 Mon Jul 31 19:02:32 UTC 2023 - Bjørn Lie <zaitor@opensuse.org>
9
 
10
 - Update to version 0.3.76
11
pipewire-aptx.spec Changed
10
 
1
@@ -7,7 +7,7 @@
2
 %define soversion 0_2
3
 
4
 Name:           pipewire-aptx
5
-Version:        0.3.76
6
+Version:        0.3.77
7
 Release:        0
8
 Summary:        PipeWire Bluetooth aptX codec plugin
9
 License:        MIT
10
pipewire-0.3.76.tar.gz/NEWS -> pipewire-0.3.77.tar.gz/NEWS Changed
69
 
1
@@ -1,3 +1,57 @@
2
+# PipeWire 0.3.77 (2023-08-04)
3
+
4
+This is a quick bugfix release that is API and ABI compatible with previous
5
+0.3.x releases.
6
+
7
+## Highlights
8
+  - Fix a bug in ALSA source where the available number of samples was miscaluclated
9
+    and resulted in xruns in some cases.
10
+  - A new L permission was added to make it possible to force a link between
11
+    nodes even when the nodes can't see eachother.
12
+  - The VBAN module now supports midi send and receive as well.
13
+  - Many cleanups and small fixes.
14
+
15
+
16
+## PipeWire
17
+  - Global objects now only show permissions that apply to them. The permissions
18
+    required to perform various API calls are documented.
19
+  - A new L permission was added to make it possible to force a link between
20
+    nodes even when the nodes can't see eachother.
21
+  - Config files need to end with .conf.
22
+  - The client.api is added the to global properties of a node.
23
+
24
+## modules
25
+  - The VBAN module now supports midi send and receive as well.
26
+  - Fix module-profiler alignment and make sure we don't overrun our buffers with
27
+    many nodes.
28
+  - Protect libcanberra calls with a mutex because it is not thread safe. (#2834)
29
+
30
+## SPA
31
+  - Support older compilers for spa_clear_ptr().
32
+  - Fix a bug in ALSA source where the available number of samples was miscaluclated
33
+    and resulted in xruns. (#3395)
34
+  - Don't set inotify on /dev but on the videoX devices directly. Setting inotify
35
+    on /dev would cause a lot of spurious wakeups and lock contention in the
36
+    fsnotify subsystem on some benchmarks.
37
+  - Audioconvert now rate limits the warnings when it runs out of buffers. (#3384)
38
+
39
+## pulse-server
40
+  - Some bugs and inconsistencies were fixed in device lookup.
41
+  - Improve subscribe event emission, detect changes to the sink or the monitor
42
+    and send the right sink/source event. (#3388)
43
+
44
+## JACK
45
+  - The libjack.so now has a minor version of 3 and a micro version of the pipewire
46
+    version.
47
+  - JACK clients will now see portregistration from other jack clients when they
48
+    activate/deactivate like real JACK. (#3260)
49
+
50
+## bluetooth
51
+  - Use some more autoptr cleanups, fix some leaks.
52
+
53
+Older versions:
54
+
55
+
56
 # PipeWire 0.3.76 (2023-07-28)
57
 
58
 This is a quick bugfix release that is API and ABI compatible with previous
59
@@ -36,9 +90,6 @@
60
   - LE Audio support is now enabled by default when liblc3 is available now that
61
     bluez has support for detecting the hardware features.
62
 
63
-Older versions:
64
-
65
-
66
 # PipeWire 0.3.75 (2023-07-21)
67
 
68
 This is a bugfix release that is API and ABI compatible with previous
69
pipewire-0.3.76.tar.gz/doc/dma-buf.dox -> pipewire-0.3.77.tar.gz/doc/dma-buf.dox Changed
20
 
1
@@ -147,6 +147,18 @@
2
 In cases where mapping a single plane is required the size should be obtained locally
3
 via the filedescriptor.
4
 
5
+# SPA param video format helpers
6
+
7
+SPA offers helper functions to parse and build a spa_pod object to/from the spa_video_info_*
8
+struct. The flags `SPA_VIDEO_FLAG_MODIFIER` and `SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED`
9
+are used to indicate modifier usage with the format. `SPA_VIDEO_FLAG_MODIFIER` declares the
10
+parsed/provided spa_video_info_* struct contains valid modifier information. For legacy
11
+reasons `spa_format_video_*_build` will announce any modifier != 0 even when this flag is
12
+unused. `SPA_VIDEO_FLAG_MODIFIER_FIXATION_REQUIRED` is exclusive to the parse helpers and
13
+declares that the parsed spa_pod contains modifier information which needs to be fixated as
14
+described aboath. The list of available modifiers has to be parsed manually from the spa_pod
15
+object.
16
+
17
 # v4l2
18
 
19
 Another use case for streaming via DMA-BUFs are exporting a camera feed from v4l2
20
pipewire-0.3.76.tar.gz/meson.build -> pipewire-0.3.77.tar.gz/meson.build Changed
24
 
1
@@ -1,5 +1,5 @@
2
 project('pipewire', 'c' ,
3
-  version : '0.3.76',
4
+  version : '0.3.77',
5
   license :  'MIT', 'LGPL-2.1-or-later', 'GPL-2.0-only' ,
6
   meson_version : '>= 0.61.1',
7
   default_options :  'warning_level=3',
8
@@ -25,6 +25,15 @@
9
 soversion = 0
10
 libversion = '@0@.@1@.0'.format(soversion, pipewire_version_minor.to_int() * 100 + pipewire_version_micro.to_int())
11
 
12
+# LADI/jack
13
+# 3, for PipeWire being the third JACK implementation, after JACK1 and jackdmp/JACK2)
14
+jack_version_major = 3
15
+jack_version_minor = pipewire_version_minor.to_int() * 100 + pipewire_version_micro.to_int()
16
+# libjackserver version has 0 for major (for compatibility with other implementations),
17
+# 3 for minor, and "100*pipewire_version_minor + pipewire_version_micro"
18
+# as micro version (the minor libpipewire soversion number)
19
+libjackversion = '@0@.@1@.@2@'.format(soversion, jack_version_major, jack_version_minor)
20
+
21
 pipewire_name = 'pipewire-@0@'.format(apiversion)
22
 spa_name = 'spa-@0@'.format(spaversion)
23
 
24
pipewire-0.3.76.tar.gz/pipewire-jack/src/meson.build -> pipewire-0.3.77.tar.gz/pipewire-jack/src/meson.build Changed
28
 
1
@@ -36,7 +36,7 @@
2
 pipewire_jack = shared_library('jack',
3
     pipewire_jack_sources,
4
     soversion : soversion,
5
-    version : libversion,
6
+    version : libjackversion,
7
     c_args : pipewire_jack_c_args,
8
     include_directories : configinc, jack_inc,
9
     dependencies : pipewire_dep, mathlib,
10
@@ -47,7 +47,7 @@
11
 pipewire_jackserver = shared_library('jackserver',
12
     pipewire_jackserver_sources,
13
     soversion : soversion,
14
-    version : libversion,
15
+    version : libjackversion,
16
     c_args : pipewire_jack_c_args,
17
     include_directories : configinc, jack_inc,
18
     dependencies : pipewire_dep, mathlib,
19
@@ -58,7 +58,7 @@
20
 pipewire_jacknet = shared_library('jacknet',
21
     pipewire_net_sources,
22
     soversion : soversion,
23
-    version : libversion,
24
+    version : libjackversion,
25
     c_args : pipewire_jack_c_args,
26
     include_directories : configinc, jack_inc,
27
     dependencies : pipewire_dep, mathlib,
28
pipewire-0.3.76.tar.gz/pipewire-jack/src/pipewire-jack.c -> pipewire-0.3.77.tar.gz/pipewire-jack/src/pipewire-jack.c Changed
169
 
1
@@ -137,6 +137,8 @@
2
            char node_name512;
3
            int32_t priority;
4
            uint32_t client_id;
5
+           unsigned is_jack:1;
6
+           unsigned is_running:1;
7
        } node;
8
        struct {
9
            uint32_t src;
10
@@ -926,6 +928,7 @@
11
    int32_t avail;
12
    uint32_t index;
13
    struct notify *notify;
14
+   bool do_graph = false;
15
 
16
    if (c->frozen_callbacks != 0 || !c->pending_callbacks)
17
        return;
18
@@ -976,11 +979,12 @@
19
                    o->port_link.dst_serial,
20
                    notify->arg1,
21
                    c->connect_arg);
22
+
23
+           do_graph = true;
24
            break;
25
        case NOTIFY_TYPE_GRAPH:
26
            pw_log_debug("%p: graph", c);
27
-           recompute_latencies(c);
28
-           do_callback(c, graph_callback, c->active, c->graph_arg);
29
+           do_graph = true;
30
            break;
31
        case NOTIFY_TYPE_BUFFER_FRAMES:
32
            pw_log_debug("%p: buffer frames %d", c, notify->arg1);
33
@@ -1031,6 +1035,10 @@
34
        index += sizeof(struct notify);
35
        spa_ringbuffer_read_update(&c->notify_ring, index);
36
    }
37
+   if (do_graph) {
38
+       recompute_latencies(c);
39
+       do_callback(c, graph_callback, c->active, c->graph_arg);
40
+   }
41
    thaw_callbacks(c);
42
    pw_log_debug("%p: leave", c);
43
 }
44
@@ -3061,6 +3069,35 @@
45
    .destroy = proxy_destroy,
46
 };
47
 
48
+static void node_info(void *data, const struct pw_node_info *info)
49
+{
50
+   struct object *n = data;
51
+   struct client *c = n->client;
52
+
53
+   pw_log_info("DSP node %d state change %s", info->id,
54
+           pw_node_state_as_string(info->state));
55
+
56
+   n->node.is_running = (info->state == PW_NODE_STATE_RUNNING);
57
+
58
+   if (info->change_mask & PW_NODE_CHANGE_MASK_STATE) {
59
+       struct object *p;
60
+       spa_list_for_each(p, &c->context.objects, link) {
61
+           if (p->type != INTERFACE_Port || p->removed ||
62
+               p->port.node_id != info->id)
63
+               continue;
64
+           if (n->node.is_running)
65
+               queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, p, 1, NULL);
66
+           else
67
+               queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, p, 0, NULL);
68
+       }
69
+   }
70
+}
71
+
72
+static const struct pw_node_events node_events = {
73
+   PW_VERSION_NODE,
74
+   .info = node_info,
75
+};
76
+
77
 static void port_param(void *data, int seq,
78
            uint32_t id, uint32_t index, uint32_t next,
79
            const struct spa_pod *param)
80
@@ -3105,7 +3142,7 @@
81
    struct client *c = (struct client *) data;
82
    struct object *o, *ot, *op;
83
    const char *str;
84
-   bool is_first = true;
85
+   bool do_emit = true;
86
    uint32_t serial;
87
 
88
    if (props == NULL)
89
@@ -3162,7 +3199,7 @@
90
            snprintf(o->node.name, sizeof(o->node.name), "%.*s-%d",
91
                    (int)(sizeof(tmp)-11), tmp, id);
92
        } else {
93
-           is_first = ot == NULL;
94
+           do_emit = ot == NULL;
95
            snprintf(o->node.name, sizeof(o->node.name), "%s", tmp);
96
        }
97
        if (id == c->node_id) {
98
@@ -3174,9 +3211,21 @@
99
 
100
        if ((str = spa_dict_lookup(props, PW_KEY_PRIORITY_SESSION)) != NULL)
101
            o->node.priority = pw_properties_parse_int(str);
102
+       if ((str = spa_dict_lookup(props, PW_KEY_CLIENT_API)) != NULL)
103
+           o->node.is_jack = spa_streq(str, "jack");
104
 
105
        pw_log_debug("%p: add node %d", c, id);
106
 
107
+       if (o->node.is_jack) {
108
+           o->proxy = pw_registry_bind(c->registry,
109
+               id, type, PW_VERSION_NODE, 0);
110
+           if (o->proxy) {
111
+               pw_proxy_add_listener(o->proxy,
112
+                       &o->proxy_listener, &proxy_events, o);
113
+               pw_proxy_add_object_listener(o->proxy,
114
+                       &o->object_listener, &node_events, o);
115
+           }
116
+       }
117
        pthread_mutex_lock(&c->context.lock);
118
        spa_list_append(&c->context.objects, &o->link);
119
        pthread_mutex_unlock(&c->context.lock);
120
@@ -3255,6 +3304,8 @@
121
            o->port.latencySPA_DIRECTION_INPUT = SPA_LATENCY_INFO(SPA_DIRECTION_INPUT);
122
            o->port.latencySPA_DIRECTION_OUTPUT = SPA_LATENCY_INFO(SPA_DIRECTION_OUTPUT);
123
 
124
+           do_emit = !ot->node.is_jack || ot->node.is_running;
125
+
126
            o->proxy = pw_registry_bind(c->registry,
127
                id, type, PW_VERSION_PORT, 0);
128
            if (o->proxy) {
129
@@ -3409,23 +3460,24 @@
130
 
131
    switch (o->type) {
132
    case INTERFACE_Node:
133
-       if (is_first) {
134
-           pw_log_info("%p: client added \"%s\"", c, o->node.name);
135
+       pw_log_info("%p: client added \"%s\" emit:%d", c, o->node.name, do_emit);
136
+       if (do_emit)
137
            queue_notify(c, NOTIFY_TYPE_REGISTRATION, o, 1, NULL);
138
-       }
139
        break;
140
 
141
    case INTERFACE_Port:
142
-       pw_log_info("%p: port added %u/%u \"%s\"", c, o->id, o->serial, o->port.name);
143
-       queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, o, 1, NULL);
144
+       pw_log_info("%p: port added %u/%u \"%s\" emit:%d", c, o->id,
145
+               o->serial, o->port.name, do_emit);
146
+       if (do_emit)
147
+           queue_notify(c, NOTIFY_TYPE_PORTREGISTRATION, o, 1, NULL);
148
        break;
149
 
150
    case INTERFACE_Link:
151
        pw_log_info("%p: link %u %u/%u -> %u/%u added", c,
152
                o->id, o->port_link.src, o->port_link.src_serial,
153
                o->port_link.dst, o->port_link.dst_serial);
154
-       queue_notify(c, NOTIFY_TYPE_CONNECT, o, 1, NULL);
155
-       queue_notify(c, NOTIFY_TYPE_GRAPH, NULL, 0, NULL);
156
+       if (do_emit)
157
+           queue_notify(c, NOTIFY_TYPE_CONNECT, o, 1, NULL);
158
        break;
159
    }
160
    emit_callbacks(c);
161
@@ -3479,7 +3531,6 @@
162
                    o->port_link.src, o->port_link.src_serial,
163
                    o->port_link.dst, o->port_link.dst_serial);
164
            queue_notify(c, NOTIFY_TYPE_CONNECT, o, 0, NULL);
165
-           queue_notify(c, NOTIFY_TYPE_GRAPH, NULL, 0, NULL);
166
        } else {
167
            pw_log_warn("unlink between unknown ports %d and %d",
168
                    o->port_link.src, o->port_link.dst);
169
pipewire-0.3.76.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c -> pipewire-0.3.77.tar.gz/pipewire-v4l2/src/pipewire-v4l2.c Changed
11
 
1
@@ -985,7 +985,9 @@
2
    MAKE_FORMAT(Y10, video, raw, 2, UNKNOWN),
3
    MAKE_FORMAT(Y12, video, raw, 2, UNKNOWN),
4
    MAKE_FORMAT(Y16, video, raw, 2, GRAY16_LE),
5
+#ifdef V4L2_PIX_FMT_Y16_BE
6
    MAKE_FORMAT(Y16_BE, video, raw, 2, GRAY16_BE),
7
+#endif
8
    MAKE_FORMAT(Y10BPACK, video, raw, 2, UNKNOWN),
9
 
10
    /* Palette formats */
11
pipewire-0.3.76.tar.gz/spa/include/spa/utils/cleanup.h -> pipewire-0.3.77.tar.gz/spa/include/spa/utils/cleanup.h Changed
38
 
1
@@ -40,13 +40,20 @@
2
    _old_value; \
3
 })
4
 
5
+#if __GNUC__ > 10 || defined(__clang__)
6
 #define spa_steal_ptr(ptr) ((__typeof__(*(ptr)) *) spa_exchange((ptr), NULL))
7
+#else
8
+#define spa_steal_ptr(ptr) ((__typeof__(ptr)) spa_exchange((ptr), NULL))
9
+#endif
10
+
11
 #define spa_steal_fd(fd) spa_exchange((fd), -1)
12
 
13
 /* ========================================================================== */
14
 
15
 #include <stdlib.h>
16
 
17
+
18
+#if __GNUC__ > 10 || defined(__clang__)
19
 #define spa_clear_ptr(ptr, destructor) \
20
 __extension__ ({ \
21
    __typeof__(*(ptr)) *_old_value = spa_steal_ptr(ptr); \
22
@@ -54,6 +61,15 @@
23
        destructor(_old_value); \
24
    (void) 0; \
25
 })
26
+#else
27
+#define spa_clear_ptr(ptr, destructor) \
28
+__extension__ ({ \
29
+   __typeof__(ptr) _old_value = spa_steal_ptr(ptr); \
30
+   if (_old_value) \
31
+       destructor(_old_value); \
32
+   (void) 0; \
33
+})
34
+#endif
35
 
36
 static inline void _spa_autofree_cleanup_func(void *p)
37
 {
38
pipewire-0.3.76.tar.gz/spa/plugins/alsa/alsa-pcm.c -> pipewire-0.3.77.tar.gz/spa/plugins/alsa/alsa-pcm.c Changed
14
 
1
@@ -2498,9 +2498,10 @@
2
 
3
            if (avail < target)
4
                max_read = target - avail;
5
-           else if (avail > target)
6
+           else if (avail > target) {
7
                snd_pcm_forward(state->hndl, avail - target);
8
-           avail = target;
9
+               avail = target;
10
+           }
11
            state->alsa_sync = false;
12
        } else
13
            state->alsa_sync_warning = true;
14
pipewire-0.3.76.tar.gz/spa/plugins/audioconvert/audioconvert.c -> pipewire-0.3.77.tar.gz/spa/plugins/audioconvert/audioconvert.c Changed
129
 
1
@@ -9,12 +9,14 @@
2
 
3
 #include <spa/support/plugin.h>
4
 #include <spa/support/cpu.h>
5
+#include <spa/support/loop.h>
6
 #include <spa/support/log.h>
7
 #include <spa/utils/result.h>
8
 #include <spa/utils/list.h>
9
 #include <spa/utils/json.h>
10
 #include <spa/utils/names.h>
11
 #include <spa/utils/string.h>
12
+#include <spa/utils/ratelimit.h>
13
 #include <spa/node/node.h>
14
 #include <spa/node/io.h>
15
 #include <spa/node/utils.h>
16
@@ -190,6 +192,8 @@
17
    uint32_t quantum_limit;
18
    enum spa_direction direction;
19
 
20
+   struct spa_ratelimit rate_limit;
21
+
22
    struct props props;
23
 
24
    struct spa_io_position *io_position;
25
@@ -2316,12 +2320,8 @@
26
 {
27
    struct buffer *b;
28
 
29
-   if (spa_list_is_empty(&port->queue)) {
30
-       if (port->n_buffers > 0)
31
-           spa_log_warn(this->log, "%p: out of buffers on port %d %d",
32
-               this, port->id, port->n_buffers);
33
+   if (spa_list_is_empty(&port->queue))
34
        return NULL;
35
-   }
36
 
37
    b = spa_list_first(&port->queue, struct buffer, link);
38
    spa_log_trace_fp(this->log, "%p: peek buffer %d/%d on port %d %u",
39
@@ -2331,10 +2331,12 @@
40
 
41
 static inline void dequeue_buffer(struct impl *this, struct port *port, struct buffer *b)
42
 {
43
-   spa_list_remove(&b->link);
44
-   SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED);
45
    spa_log_trace_fp(this->log, "%p: dequeue buffer %d on port %d %u",
46
            this, b->id, port->id, b->flags);
47
+   if (!SPA_FLAG_IS_SET(b->flags, BUFFER_FLAG_QUEUED))
48
+       return;
49
+   spa_list_remove(&b->link);
50
+   SPA_FLAG_CLEAR(b->flags, BUFFER_FLAG_QUEUED);
51
 }
52
 
53
 static int
54
@@ -2614,6 +2616,14 @@
55
    return true;
56
 }
57
 
58
+static uint64_t get_time_ns(struct impl *impl)
59
+{
60
+   struct timespec now;
61
+   if (clock_gettime(CLOCK_MONOTONIC, &now) < 0)
62
+       return 0;
63
+   return SPA_TIMESPEC_TO_NSEC(&now);
64
+}
65
+
66
 static int impl_node_process(void *object)
67
 {
68
    struct impl *this = object;
69
@@ -2626,12 +2636,13 @@
70
    struct buffer *buf, *out_bufsMAX_PORTS;
71
    struct spa_data *bd;
72
    struct dir *dir;
73
-   int tmp = 0, res = 0;
74
+   int tmp = 0, res = 0, missed;
75
    bool in_passthrough, mix_passthrough, resample_passthrough, out_passthrough;
76
    bool in_avail = false, flush_in = false, flush_out = false;
77
    bool draining = false, in_empty = this->out_offset == 0;
78
    struct spa_io_buffers *io, *ctrlio = NULL;
79
    const struct spa_pod_sequence *ctrl = NULL;
80
+   uint64_t current_time;
81
 
82
    /* calculate quantum scale, this is how many samples we need to produce or
83
     * consume. Also update the rate scale, this is sent to the resampler to adjust
84
@@ -2640,6 +2651,7 @@
85
    if (SPA_LIKELY(this->io_position)) {
86
        double r =  this->rate_scale;
87
 
88
+       current_time = this->io_position->clock.nsec;
89
        quant_samples = this->io_position->clock.duration;
90
        if (this->direction == SPA_DIRECTION_INPUT) {
91
            if (this->io_position->clock.rate.denom != this->resample.o_rate)
92
@@ -2660,8 +2672,10 @@
93
            this->rate_scale = r;
94
        }
95
    }
96
-   else
97
+   else {
98
+       current_time = get_time_ns(this);
99
        quant_samples = this->quantum_limit;
100
+   }
101
 
102
    dir = &this->dirSPA_DIRECTION_INPUT;
103
    in_passthrough = dir->conv.is_passthrough;
104
@@ -2789,6 +2803,11 @@
105
                queue_buffer(this, port, io->buffer_id);
106
 
107
            buf = peek_buffer(this, port);
108
+           if (buf == NULL && port->n_buffers > 0 &&
109
+               (missed = spa_ratelimit_test(&this->rate_limit, current_time)) >= 0) {
110
+               spa_log_warn(this->log, "%p: (%d missed) out of buffers on port %d %d",
111
+                   this, missed, port->id, port->n_buffers);
112
+           }
113
        }
114
        out_bufsi = buf;
115
 
116
@@ -3195,9 +3214,11 @@
117
        this->cpu_flags = spa_cpu_get_flags(this->cpu);
118
        this->max_align = SPA_MIN(MAX_ALIGN, spa_cpu_get_max_align(this->cpu));
119
    }
120
-
121
    props_reset(&this->props);
122
 
123
+   this->rate_limit.interval = 2 * SPA_NSEC_PER_SEC;
124
+   this->rate_limit.burst = 1;
125
+
126
    this->mix.options = CHANNELMIX_OPTION_UPMIX | CHANNELMIX_OPTION_MIX_LFE;
127
    this->mix.upmix = CHANNELMIX_UPMIX_NONE;
128
    this->mix.log = this->log;
129
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/backend-hsphfpd.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/backend-hsphfpd.c Changed
201
 
1
@@ -170,10 +170,9 @@
2
 {
3
    spa_list_remove(&endpoint->link);
4
    free(endpoint->path);
5
-   if (endpoint->local_address)
6
-       free(endpoint->local_address);
7
-   if (endpoint->remote_address)
8
-       free(endpoint->remote_address);
9
+   free(endpoint->local_address);
10
+   free(endpoint->remote_address);
11
+   free(endpoint);
12
 }
13
 
14
 static bool hsphfpd_cmp_transport_path(struct spa_bt_transport *t, const void *data)
15
@@ -198,9 +197,9 @@
16
                              int type,
17
                              void *value)
18
 {
19
-   DBusMessage *m, *r;
20
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
21
    DBusMessageIter iter;
22
-   DBusError err;
23
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
24
 
25
    m = dbus_message_new_method_call(HSPHFPD_SERVICE, path, DBUS_INTERFACE_PROPERTIES, "Set");
26
    if (m == NULL)
27
@@ -209,15 +208,9 @@
28
    dbus_message_iter_init_append(m, &iter);
29
    dbus_message_iter_append_basic(&iter, type, value);
30
 
31
-   dbus_error_init(&err);
32
-
33
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
34
-   dbus_message_unref(m);
35
-   m = NULL;
36
-
37
    if (r == NULL) {
38
        spa_log_error(backend->log, "Transport Set() failed for transport %s (%s)", path, err.message);
39
-       dbus_error_free(&err);
40
        return -EIO;
41
    }
42
 
43
@@ -226,7 +219,6 @@
44
        return -EIO;
45
    }
46
 
47
-   dbus_message_unref(r);
48
    return 0;
49
 }
50
 
51
@@ -447,7 +439,7 @@
52
    const char *interface;
53
    const char *property;
54
    const char *agent_codec;
55
-   DBusMessage *r = NULL;
56
+   spa_autoptr(DBusMessage) r = NULL;
57
 
58
    if (!check_signature(m, "ss")) {
59
        r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call");
60
@@ -488,7 +480,6 @@
61
    if (!dbus_connection_send(conn, r, NULL))
62
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
63
 
64
-   dbus_message_unref(r);
65
    return DBUS_HANDLER_RESULT_HANDLED;
66
 }
67
 
68
@@ -497,7 +488,7 @@
69
    const char *interface;
70
    DBusMessageIter iter, array, dict, data;
71
    const char *agent_codec;
72
-   DBusMessage *r = NULL;
73
+   spa_autoptr(DBusMessage) r = NULL;
74
 
75
    if (!check_signature(m, "s")) {
76
        r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call");
77
@@ -538,7 +529,6 @@
78
    if (!dbus_connection_send(conn, r, NULL))
79
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
80
 
81
-   dbus_message_unref(r);
82
    return DBUS_HANDLER_RESULT_HANDLED;
83
 }
84
 
85
@@ -547,7 +537,6 @@
86
    struct impl *backend = userdata;
87
    DBusMessageIter arg_i;
88
    const char *transport_path;
89
-   int fd;
90
    const char *sender;
91
    const char *endpoint_path = NULL;
92
    const char *air_codec = NULL;
93
@@ -560,7 +549,8 @@
94
    struct hsphfpd_endpoint *endpoint;
95
    struct spa_bt_transport *transport;
96
    struct hsphfpd_transport_data *transport_data;
97
-   DBusMessage *r = NULL;
98
+   spa_autoptr(DBusMessage) r = NULL;
99
+   spa_autoclose int fd = -1;
100
 
101
    if (!check_signature(m, "oha{sv}")) {
102
        r = dbus_message_new_error(m, DBUS_ERROR_INVALID_ARGS, "Invalid signature in method call");
103
@@ -578,7 +568,6 @@
104
 
105
    sender = dbus_message_get_sender(m);
106
    if (!spa_streq(sender, backend->hsphfpd_service_id)) {
107
-       close(fd);
108
        spa_log_error(backend->log, "Sender '%s' is not authorized", sender);
109
        r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Sender '%s' is not authorized", sender);
110
        goto fail;
111
@@ -601,28 +590,24 @@
112
                                                                        &mtu);
113
 
114
    if (!endpoint_path) {
115
-       close(fd);
116
        spa_log_error(backend->log, "Endpoint property was not specified");
117
        r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "Endpoint property was not specified");
118
        goto fail;
119
    }
120
 
121
    if (!air_codec) {
122
-       close(fd);
123
        spa_log_error(backend->log, "AirCodec property was not specified");
124
        r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "AirCodec property was not specified");
125
        goto fail;
126
    }
127
 
128
    if (!rx_volume_control) {
129
-       close(fd);
130
        spa_log_error(backend->log, "RxVolumeControl property was not specified");
131
        r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "RxVolumeControl property was not specified");
132
        goto fail;
133
    }
134
 
135
    if (!tx_volume_control) {
136
-       close(fd);
137
        spa_log_error(backend->log, "TxVolumeControl property was not specified");
138
        r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "TxVolumeControl property was not specified");
139
        goto fail;
140
@@ -630,7 +615,6 @@
141
 
142
    if (rx_volume_control != HSPHFPD_VOLUME_CONTROL_NONE) {
143
        if (rx_volume_gain == (uint16_t)-1) {
144
-           close(fd);
145
            spa_log_error(backend->log, "RxVolumeGain property was not specified, but VolumeControl is not none");
146
            r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "RxVolumeGain property was not specified, but VolumeControl is not none");
147
            goto fail;
148
@@ -641,7 +625,6 @@
149
 
150
    if (tx_volume_control != HSPHFPD_VOLUME_CONTROL_NONE) {
151
        if (tx_volume_gain == (uint16_t)-1) {
152
-           close(fd);
153
            spa_log_error(backend->log, "TxVolumeGain property was not specified, but VolumeControl is not none");
154
            r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "TxVolumeGain property was not specified, but VolumeControl is not none");
155
            goto fail;
156
@@ -651,7 +634,6 @@
157
    }
158
 
159
    if (!mtu) {
160
-       close(fd);
161
        spa_log_error(backend->log, "MTU property was not specified");
162
        r = dbus_message_new_error(m, HSPHFPD_ERROR_REJECTED, "MTU property was not specified");
163
        goto fail;
164
@@ -659,14 +641,12 @@
165
 
166
    endpoint = endpoint_find(backend, endpoint_path);
167
    if (!endpoint) {
168
-       close(fd);
169
        spa_log_error(backend->log, "Endpoint %s does not exist", endpoint_path);
170
        r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s does not exist", endpoint_path);
171
        goto fail;
172
    }
173
 
174
    if (!endpoint->valid) {
175
-       close(fd);
176
        spa_log_error(backend->log, "Endpoint %s is not valid", endpoint_path);
177
        r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s is not valid", endpoint_path);
178
        goto fail;
179
@@ -674,7 +654,6 @@
180
 
181
    transport = spa_bt_transport_find(backend->monitor, endpoint_path);
182
    if (!transport) {
183
-       close(fd);
184
        spa_log_error(backend->log, "Endpoint %s is not connected", endpoint_path);
185
        r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s is not connected", endpoint_path);
186
        goto fail;
187
@@ -684,7 +663,6 @@
188
        spa_log_warn(backend->log, "Expecting codec to be %d, got %d", transport->codec, codec);
189
 
190
    if (transport->fd >= 0) {
191
-       close(fd);
192
        spa_log_error(backend->log, "Endpoint %s has already active transport", endpoint_path);
193
        r = dbus_message_new_error_printf(m, HSPHFPD_ERROR_REJECTED, "Endpoint %s has already active transport", endpoint_path);
194
        goto fail;
195
@@ -707,18 +685,15 @@
196
    transport->read_mtu = mtu;
197
    transport->write_mtu = mtu;
198
 
199
-   transport->fd = fd;
200
+   transport->fd = spa_steal_fd(fd);
201
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/backend-native.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/backend-native.c Changed
201
 
1
@@ -177,16 +177,9 @@
2
 
3
 static DBusHandlerResult profile_release(DBusConnection *conn, DBusMessage *m, void *userdata)
4
 {
5
-   DBusMessage *r;
6
-
7
-   r = dbus_message_new_error(m, BLUEZ_PROFILE_INTERFACE ".Error.NotImplemented",
8
-                                            "Method not implemented");
9
-   if (r == NULL)
10
-       return DBUS_HANDLER_RESULT_NEED_MEMORY;
11
-   if (!dbus_connection_send(conn, r, NULL))
12
+   if (!reply_with_error(conn, m, BLUEZ_PROFILE_INTERFACE ".Error.NotImplemented", "Method not implemented"))
13
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
14
 
15
-   dbus_message_unref(r);
16
    return DBUS_HANDLER_RESULT_HANDLED;
17
 }
18
 
19
@@ -1390,12 +1383,11 @@
20
    struct sockaddr_sco addr;
21
    socklen_t len;
22
    bdaddr_t src;
23
-   int sock = -1;
24
 
25
-   sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_SCO);
26
+   spa_autoclose int sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK, BTPROTO_SCO);
27
    if (sock < 0) {
28
        spa_log_error(backend->log, "socket(SEQPACKET, SCO) %s", strerror(errno));
29
-       goto fail;
30
+       return -1;
31
    }
32
 
33
    str2ba(adapter->address, &src);
34
@@ -1407,7 +1399,7 @@
35
 
36
    if (bind(sock, (struct sockaddr *) &addr, len) < 0) {
37
        spa_log_error(backend->log, "bind(): %s", strerror(errno));
38
-       goto fail;
39
+       return -1;
40
    }
41
 
42
    spa_log_debug(backend->log, "msbc=%d", (int)msbc);
43
@@ -1418,16 +1410,11 @@
44
        voice_config.setting = BT_VOICE_TRANSPARENT;
45
        if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &voice_config, sizeof(voice_config)) < 0) {
46
            spa_log_error(backend->log, "setsockopt(): %s", strerror(errno));
47
-           goto fail;
48
+           return -1;
49
        }
50
    }
51
 
52
-   return sock;
53
-
54
-fail:
55
-   if (sock >= 0)
56
-       close(sock);
57
-   return -1;
58
+   return spa_steal_fd(sock);
59
 }
60
 
61
 static int sco_do_connect(struct spa_bt_transport *t)
62
@@ -1436,11 +1423,7 @@
63
    struct spa_bt_device *d = t->device;
64
    struct transport_data *td = t->user_data;
65
    struct sockaddr_sco addr;
66
-   socklen_t len;
67
    int err;
68
-   int sock;
69
-   bdaddr_t dst;
70
-   int retry = 2;
71
 
72
    spa_log_debug(backend->log, "transport %p: enter sco_do_connect, codec=%u",
73
            t, t->codec);
74
@@ -1450,52 +1433,45 @@
75
    if (d->adapter == NULL)
76
        return -EIO;
77
 
78
-   str2ba(d->address, &dst);
79
-
80
-again:
81
-   sock = sco_create_socket(backend, d->adapter, (t->codec == HFP_AUDIO_CODEC_MSBC));
82
-   if (sock < 0)
83
-       return -1;
84
-
85
-   len = sizeof(addr);
86
-   memset(&addr, 0, len);
87
+   spa_zero(addr);
88
    addr.sco_family = AF_BLUETOOTH;
89
-   bacpy(&addr.sco_bdaddr, &dst);
90
-
91
-   spa_log_debug(backend->log, "transport %p: doing connect", t);
92
-   err = connect(sock, (struct sockaddr *) &addr, len);
93
-   if (err < 0 && errno == ECONNABORTED && retry-- > 0) {
94
-       spa_log_warn(backend->log, "connect(): %s. Remaining retry:%d",
95
-               strerror(errno), retry);
96
-       close(sock);
97
-       goto again;
98
-   } else if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
99
-       spa_log_error(backend->log, "connect(): %s", strerror(errno));
100
+   str2ba(d->address, &addr.sco_bdaddr);
101
+
102
+   for (int retry = 2;;) {
103
+       spa_autoclose int sock = sco_create_socket(backend, d->adapter, (t->codec == HFP_AUDIO_CODEC_MSBC));
104
+       if (sock < 0)
105
+           return -1;
106
+
107
+       spa_log_debug(backend->log, "transport %p: doing connect", t);
108
+       err = connect(sock, (struct sockaddr *) &addr, sizeof(addr));
109
+       if (err < 0 && errno == ECONNABORTED && retry-- > 0) {
110
+           spa_log_warn(backend->log, "connect(): %s. Remaining retry:%d",
111
+                   strerror(errno), retry);
112
+           continue;
113
+       } else if (err < 0 && !(errno == EAGAIN || errno == EINPROGRESS)) {
114
+           spa_log_error(backend->log, "connect(): %s", strerror(errno));
115
 #ifdef HAVE_BLUEZ_5_BACKEND_HFP_NATIVE
116
-       if (errno == EOPNOTSUPP && t->codec == HFP_AUDIO_CODEC_MSBC &&
117
-               td->rfcomm->msbc_supported_by_hfp) {
118
-           /* Adapter doesn't support msbc. Renegotiate. */
119
-           d->adapter->msbc_probed = true;
120
-           d->adapter->has_msbc = false;
121
-           td->rfcomm->msbc_supported_by_hfp = false;
122
-           if (t->profile == SPA_BT_PROFILE_HFP_HF) {
123
-               td->rfcomm->hfp_ag_switching_codec = true;
124
-               rfcomm_send_reply(td->rfcomm, "+BCS: 1");
125
-           } else if (t->profile == SPA_BT_PROFILE_HFP_AG) {
126
-               rfcomm_send_cmd(td->rfcomm, "AT+BAC=1");
127
+           if (errno == EOPNOTSUPP && t->codec == HFP_AUDIO_CODEC_MSBC &&
128
+                   td->rfcomm->msbc_supported_by_hfp) {
129
+               /* Adapter doesn't support msbc. Renegotiate. */
130
+               d->adapter->msbc_probed = true;
131
+               d->adapter->has_msbc = false;
132
+               td->rfcomm->msbc_supported_by_hfp = false;
133
+               if (t->profile == SPA_BT_PROFILE_HFP_HF) {
134
+                   td->rfcomm->hfp_ag_switching_codec = true;
135
+                   rfcomm_send_reply(td->rfcomm, "+BCS: 1");
136
+               } else if (t->profile == SPA_BT_PROFILE_HFP_AG) {
137
+                   rfcomm_send_cmd(td->rfcomm, "AT+BAC=1");
138
+               }
139
            }
140
-       }
141
 #endif
142
-       goto fail_close;
143
-   }
144
-
145
-   td->err = -EINPROGRESS;
146
+           return -1;
147
+       }
148
 
149
-   return sock;
150
+       td->err = -EINPROGRESS;
151
 
152
-fail_close:
153
-   close(sock);
154
-   return -1;
155
+       return spa_steal_fd(sock);
156
+   }
157
 }
158
 
159
 static int rfcomm_ag_sync_volume(struct rfcomm *rfcomm, bool later);
160
@@ -1726,25 +1702,24 @@
161
    struct impl *backend = source->data;
162
    struct sockaddr_sco addr;
163
    socklen_t addrlen;
164
-   int sock = -1;
165
    char local_address18, remote_address18;
166
    struct rfcomm *rfcomm;
167
    struct spa_bt_transport *t = NULL;
168
 
169
    if (source->rmask & (SPA_IO_HUP | SPA_IO_ERR)) {
170
        spa_log_error(backend->log, "error listening SCO connection: %s", strerror(errno));
171
-       goto fail;
172
+       return;
173
    }
174
 
175
    memset(&addr, 0, sizeof(addr));
176
    addrlen = sizeof(addr);
177
 
178
    spa_log_debug(backend->log, "doing accept");
179
-   sock = accept(source->fd, (struct sockaddr *) &addr, &addrlen);
180
+   spa_autoclose int sock = accept(source->fd, (struct sockaddr *) &addr, &addrlen);
181
    if (sock < 0) {
182
        if (errno != EAGAIN)
183
            spa_log_error(backend->log, "SCO accept(): %s", strerror(errno));
184
-       goto fail;
185
+       return;
186
    }
187
 
188
    ba2str(&addr.sco_bdaddr, remote_address);
189
@@ -1754,7 +1729,7 @@
190
 
191
    if (getsockname(sock, (struct sockaddr *) &addr, &addrlen) < 0) {
192
        spa_log_error(backend->log, "SCO getsockname(): %s", strerror(errno));
193
-       goto fail;
194
+       return;
195
    }
196
 
197
    ba2str(&addr.sco_bdaddr, local_address);
198
@@ -1770,19 +1745,19 @@
199
    if (!t) {
200
        spa_log_debug(backend->log, "No transport for adapter %s and remote %s",
201
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/backend-ofono.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/backend-ofono.c Changed
201
 
1
@@ -140,8 +140,8 @@
2
 
3
 static int _audio_acquire(struct impl *backend, const char *path, uint8_t *codec)
4
 {
5
-   DBusMessage *m, *r;
6
-   DBusError err;
7
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
8
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
9
    int ret = 0;
10
 
11
    m = dbus_message_new_method_call(OFONO_SERVICE, path,
12
@@ -150,7 +150,6 @@
13
    if (m == NULL)
14
        return -ENOMEM;
15
 
16
-   dbus_error_init(&err);
17
 
18
    /*
19
     * XXX: We assume here oFono replies. It however can happen that the headset does
20
@@ -160,20 +159,15 @@
21
     * XXX: do better here right now.
22
     */
23
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
24
-   dbus_message_unref(m);
25
-   m = NULL;
26
-
27
    if (r == NULL) {
28
        spa_log_error(backend->log, "Transport Acquire() failed for transport %s (%s)",
29
                      path, err.message);
30
-       dbus_error_free(&err);
31
        return -EIO;
32
    }
33
 
34
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
35
        spa_log_error(backend->log, "Acquire returned error: %s", dbus_message_get_error_name(r));
36
-       ret = -EIO;
37
-       goto finish;
38
+       return -EIO;
39
    }
40
 
41
    if (!dbus_message_get_args(r, &err,
42
@@ -181,13 +175,9 @@
43
                               DBUS_TYPE_BYTE, codec,
44
                               DBUS_TYPE_INVALID)) {
45
        spa_log_error(backend->log, "Failed to parse Acquire() reply: %s", err.message);
46
-       dbus_error_free(&err);
47
-       ret = -EIO;
48
-       goto finish;
49
+       return -EIO;
50
    }
51
 
52
-finish:
53
-   dbus_message_unref(r);
54
    return ret;
55
 }
56
 
57
@@ -462,18 +452,12 @@
58
 static DBusHandlerResult ofono_release(DBusConnection *conn, DBusMessage *m, void *userdata)
59
 {
60
    struct impl *backend = userdata;
61
-   DBusMessage *r;
62
 
63
    spa_log_warn(backend->log, "release");
64
 
65
-   r = dbus_message_new_error(m, OFONO_HF_AUDIO_AGENT_INTERFACE ".Error.NotImplemented",
66
-                                            "Method not implemented");
67
-   if (r == NULL)
68
-       return DBUS_HANDLER_RESULT_NEED_MEMORY;
69
-   if (!dbus_connection_send(conn, r, NULL))
70
+   if (!reply_with_error(conn, m, OFONO_HF_AUDIO_AGENT_INTERFACE ".Error.NotImplemented", "Method not implemented"))
71
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
72
 
73
-   dbus_message_unref(r);
74
    return DBUS_HANDLER_RESULT_HANDLED;
75
 }
76
 
77
@@ -532,7 +516,7 @@
78
    uint8_t codec;
79
    struct spa_bt_transport *t;
80
    struct transport_data *td;
81
-   DBusMessage *r = NULL;
82
+   spa_autoptr(DBusMessage) r = NULL;
83
 
84
    if (dbus_message_get_args(m, NULL,
85
                              DBUS_TYPE_OBJECT_PATH, &path,
86
@@ -582,11 +566,9 @@
87
 
88
 fail:
89
    if (r) {
90
-       DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
91
        if (!dbus_connection_send(backend->conn, r, NULL))
92
-           res = DBUS_HANDLER_RESULT_NEED_MEMORY;
93
-       dbus_message_unref(r);
94
-       return res;
95
+           return DBUS_HANDLER_RESULT_NEED_MEMORY;
96
+       return DBUS_HANDLER_RESULT_HANDLED;
97
    }
98
 
99
    return DBUS_HANDLER_RESULT_HANDLED;
100
@@ -596,7 +578,6 @@
101
 {
102
    struct impl *backend = userdata;
103
    const char *path, *interface, *member;
104
-   DBusMessage *r;
105
    DBusHandlerResult res;
106
 
107
    path = dbus_message_get_path(m);
108
@@ -607,6 +588,7 @@
109
 
110
    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
111
        const char *xml = OFONO_INTROSPECT_XML;
112
+       spa_autoptr(DBusMessage) r = NULL;
113
 
114
        if ((r = dbus_message_new_method_return(m)) == NULL)
115
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
116
@@ -615,7 +597,6 @@
117
        if (!dbus_connection_send(backend->conn, r, NULL))
118
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
119
 
120
-       dbus_message_unref(r);
121
        res = DBUS_HANDLER_RESULT_HANDLED;
122
    }
123
    else if (dbus_message_is_method_call(m, OFONO_HF_AUDIO_AGENT_INTERFACE, "Release"))
124
@@ -631,22 +612,21 @@
125
 static void ofono_getcards_reply(DBusPendingCall *pending, void *user_data)
126
 {
127
    struct impl *backend = user_data;
128
-   DBusMessage *r;
129
    DBusMessageIter i, array_i, struct_i, props_i;
130
 
131
-   r = steal_reply_and_unref(&pending);
132
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
133
    if (r == NULL)
134
        return;
135
 
136
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
137
        spa_log_error(backend->log, "Failed to get a list of handsfree audio cards: %s",
138
                dbus_message_get_error_name(r));
139
-       goto finish;
140
+       return;
141
    }
142
 
143
    if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "a(oa{sv})")) {
144
        spa_log_error(backend->log, "Invalid arguments in GetCards() reply");
145
-       goto finish;
146
+       return;
147
    }
148
 
149
    dbus_message_iter_recurse(&i, &array_i);
150
@@ -663,22 +643,16 @@
151
 
152
            dbus_message_iter_next(&array_i);
153
    }
154
-
155
-finish:
156
-   dbus_message_unref(r);
157
 }
158
 
159
-static int backend_ofono_register(void *data)
160
+static int ofono_register(struct impl *backend)
161
 {
162
-   struct impl *backend = data;
163
-
164
-   DBusMessage *m, *r;
165
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
166
    const char *path = OFONO_AUDIO_CLIENT;
167
    uint8_t codecs2;
168
    const uint8_t *pcodecs = codecs;
169
-   int ncodecs = 0, res;
170
-   DBusPendingCall *call;
171
-   DBusError err;
172
+   int ncodecs = 0;
173
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
174
 
175
    spa_log_debug(backend->log, "Registering");
176
 
177
@@ -695,72 +669,77 @@
178
                                           DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pcodecs, ncodecs,
179
                                           DBUS_TYPE_INVALID);
180
 
181
-   dbus_error_init(&err);
182
-
183
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
184
-   dbus_message_unref(m);
185
-
186
    if (r == NULL) {
187
        if (dbus_error_has_name(&err, "org.freedesktop.DBus.Error.ServiceUnknown")) {
188
            spa_log_info(backend->log, "oFono not available: %s",
189
                    err.message);
190
-           res = -ENOTSUP;
191
+           return -ENOTSUP;
192
        } else {
193
            spa_log_warn(backend->log, "Registering Profile %s failed: %s (%s)",
194
                    path, err.message, err.name);
195
-           res = -EIO;
196
+           return -EIO;
197
        }
198
-       dbus_error_free(&err);
199
-       return res;
200
    }
201
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/bluez5-dbus.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/bluez5-dbus.c Changed
201
 
1
@@ -221,9 +221,10 @@
2
 }
3
 
4
 // Unregister virtual battery of device
5
-static void battery_remove(struct spa_bt_device *device) {
6
+static void battery_remove(struct spa_bt_device *device)
7
+{
8
    DBusMessageIter i, entry;
9
-   DBusMessage *m;
10
+   spa_autoptr(DBusMessage) m = NULL;
11
    const char *interface;
12
 
13
    cancel_and_unref(&device->battery_pending_call);
14
@@ -252,8 +253,6 @@
15
        spa_log_error(device->monitor->log, "sending " DBUS_SIGNAL_INTERFACES_REMOVED " failed");
16
    }
17
 
18
-   dbus_message_unref(m);
19
-
20
    device->has_battery = false;
21
 }
22
 
23
@@ -292,7 +291,7 @@
24
 {
25
    spa_log_debug(device->monitor->log, "updating battery: %s", device->battery_path);
26
 
27
-   DBusMessage *msg;
28
+   spa_autoptr(DBusMessage) msg = NULL;
29
    DBusMessageIter iter;
30
 
31
    msg = dbus_message_new_signal(device->battery_path,
32
@@ -308,13 +307,12 @@
33
 
34
    if (!dbus_connection_send(device->monitor->conn, msg, NULL))
35
        spa_log_error(device->monitor->log, "Error updating battery");
36
-
37
-   dbus_message_unref(msg);
38
 }
39
 
40
 // Create new virtual battery with value stored in current device object
41
-static void battery_create(struct spa_bt_device *device) {
42
-   DBusMessage *msg;
43
+static void battery_create(struct spa_bt_device *device)
44
+{
45
+   spa_autoptr(DBusMessage) msg = NULL;
46
    DBusMessageIter iter, entry, dict;
47
    msg = dbus_message_new_signal(PIPEWIRE_BATTERY_PROVIDER,
48
                      DBUS_INTERFACE_OBJECT_MANAGER,
49
@@ -339,8 +337,6 @@
50
        return;
51
    }
52
 
53
-   dbus_message_unref(msg);
54
-
55
    spa_log_debug(device->monitor->log, "Created virtual battery for %s", device->address);
56
    device->has_battery = true;
57
 }
58
@@ -348,17 +344,15 @@
59
 static void on_battery_provider_registered(DBusPendingCall *pending_call,
60
                       void *data)
61
 {
62
-   DBusMessage *reply;
63
    struct spa_bt_device *device = data;
64
 
65
    spa_assert(device->battery_pending_call == pending_call);
66
-   reply = steal_reply_and_unref(&device->battery_pending_call);
67
+   spa_autoptr(DBusMessage) reply = steal_reply_and_unref(&device->battery_pending_call);
68
 
69
    if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) {
70
        spa_log_error(device->monitor->log, "Failed to register battery provider. Error: %s", dbus_message_get_error_name(reply));
71
        spa_log_error(device->monitor->log, "BlueZ Battery Provider is not available, won't retry to register it. Make sure you are running BlueZ 5.56+ with experimental features to use Battery Provider.");
72
        device->adapter->battery_provider_unavailable = true;
73
-       dbus_message_unref(reply);
74
        return;
75
    }
76
 
77
@@ -368,14 +362,12 @@
78
 
79
    if (!device->has_battery)
80
        battery_create(device);
81
-
82
-   dbus_message_unref(reply);
83
 }
84
 
85
 // Register Battery Provider for adapter and then create virtual battery for device
86
 static void register_battery_provider(struct spa_bt_device *device)
87
 {
88
-   DBusMessage *method_call;
89
+   spa_autoptr(DBusMessage) method_call = NULL;
90
    DBusMessageIter message_iter;
91
 
92
    if (device->battery_pending_call) {
93
@@ -398,26 +390,12 @@
94
    dbus_message_iter_append_basic(&message_iter, DBUS_TYPE_OBJECT_PATH,
95
                       &object_path);
96
 
97
-   if (!dbus_connection_send_with_reply(device->monitor->conn, method_call, &device->battery_pending_call,
98
-                        DBUS_TIMEOUT_USE_DEFAULT)) {
99
-       dbus_message_unref(method_call);
100
-       spa_log_error(device->monitor->log, "Failed to register battery provider");
101
-       return;
102
-   }
103
-
104
-   dbus_message_unref(method_call);
105
-
106
+   device->battery_pending_call = send_with_reply(device->monitor->conn, method_call,
107
+                              on_battery_provider_registered, device);
108
    if (!device->battery_pending_call) {
109
        spa_log_error(device->monitor->log, "Failed to register battery provider");
110
        return;
111
    }
112
-
113
-   if (!dbus_pending_call_set_notify(
114
-           device->battery_pending_call, on_battery_provider_registered,
115
-           device, NULL)) {
116
-       spa_log_error(device->monitor->log, "Failed to register battery provider");
117
-       cancel_and_unref(&device->battery_pending_call);
118
-   }
119
 }
120
 
121
 static int media_codec_to_endpoint(const struct media_codec *codec,
122
@@ -546,20 +524,17 @@
123
    const char *path;
124
    uint8_t *cap, configA2DP_MAX_CAPS_SIZE;
125
    uint8_t *pconf = (uint8_t *) config;
126
-   DBusMessage *r;
127
-   DBusError err;
128
+   spa_autoptr(DBusMessage) r = NULL;
129
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
130
    int size, res;
131
    const struct media_codec *codec;
132
    bool sink;
133
 
134
-   dbus_error_init(&err);
135
-
136
    path = dbus_message_get_path(m);
137
 
138
    if (!dbus_message_get_args(m, &err, DBUS_TYPE_ARRAY,
139
                DBUS_TYPE_BYTE, &cap, &size, DBUS_TYPE_INVALID)) {
140
        spa_log_error(monitor->log, "Endpoint SelectConfiguration(): %s", err.message);
141
-       dbus_error_free(&err);
142
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
143
    }
144
    spa_log_info(monitor->log, "%p: %s select conf %d", monitor, path, size);
145
@@ -604,8 +579,6 @@
146
    if (!dbus_connection_send(conn, r, NULL))
147
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
148
 
149
-   dbus_message_unref(r);
150
-
151
    return DBUS_HANDLER_RESULT_HANDLED;
152
 }
153
 
154
@@ -618,7 +591,7 @@
155
    struct spa_bt_monitor *monitor = userdata;
156
    const char *path;
157
    DBusMessageIter args, props, iter;
158
-   DBusMessage *r = NULL;
159
+   spa_autoptr(DBusMessage) r = NULL;
160
    int res;
161
    const struct media_codec *codec;
162
    bool sink;
163
@@ -831,12 +804,8 @@
164
 
165
    dbus_message_iter_close_container(&iter, &dict);
166
 
167
-   if (r) {
168
-       if (!dbus_connection_send(conn, r, NULL))
169
-           return DBUS_HANDLER_RESULT_NEED_MEMORY;
170
-
171
-       dbus_message_unref(r);
172
-   }
173
+   if (!dbus_connection_send(conn, r, NULL))
174
+       return DBUS_HANDLER_RESULT_NEED_MEMORY;
175
 
176
    return DBUS_HANDLER_RESULT_HANDLED;
177
 
178
@@ -845,15 +814,8 @@
179
    goto error;
180
 
181
 error:
182
-   if (r)
183
-       dbus_message_unref(r);
184
-   if ((r = dbus_message_new_error(m, "org.bluez.Error.InvalidArguments", err_msg)) == NULL)
185
+   if (!reply_with_error(conn, m, "org.bluez.Error.InvalidArguments", err_msg))
186
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
187
-   if (!dbus_connection_send(conn, r, NULL)) {
188
-       dbus_message_unref(r);
189
-       return DBUS_HANDLER_RESULT_NEED_MEMORY;
190
-   }
191
-   dbus_message_unref(r);
192
    return DBUS_HANDLER_RESULT_HANDLED;
193
 }
194
 
195
@@ -1111,35 +1073,30 @@
196
 static int adapter_init_modalias(struct spa_bt_monitor *monitor, struct spa_bt_adapter *d)
197
 {
198
    char path1024;
199
-   FILE *f = NULL;
200
    int vendor_id, product_id;
201
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/dbus-helpers.h -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/dbus-helpers.h Changed
53
 
1
@@ -5,6 +5,8 @@
2
 #ifndef SPA_BLUEZ5_DBUS_HELPERS_H
3
 #define SPA_BLUEZ5_DBUS_HELPERS_H
4
 
5
+#include <stdbool.h>
6
+
7
 #include <dbus/dbus.h>
8
 
9
 #include <spa/utils/cleanup.h>
10
@@ -29,4 +31,42 @@
11
    return reply;
12
 }
13
 
14
+SPA_DEFINE_AUTOPTR_CLEANUP(DBusMessage, DBusMessage, {
15
+   spa_clear_ptr(*thing, dbus_message_unref);
16
+})
17
+
18
+static inline bool reply_with_error(DBusConnection *conn,
19
+                   DBusMessage *reply_to,
20
+                   const char *error_name, const char *error_message)
21
+{
22
+   spa_autoptr(DBusMessage) reply = dbus_message_new_error(reply_to, error_name, error_message);
23
+
24
+   return reply && dbus_connection_send(conn, reply, NULL);
25
+}
26
+
27
+static inline DBusPendingCall *send_with_reply(DBusConnection *conn,
28
+                          DBusMessage *m,
29
+                          DBusPendingCallNotifyFunction callback, void *user_data)
30
+{
31
+   DBusPendingCall *pending_call;
32
+
33
+   if (!dbus_connection_send_with_reply(conn, m, &pending_call, DBUS_TIMEOUT_USE_DEFAULT))
34
+       return NULL;
35
+
36
+   if (!pending_call)
37
+       return NULL;
38
+
39
+   if (!dbus_pending_call_set_notify(pending_call, callback, user_data, NULL)) {
40
+       dbus_pending_call_cancel(pending_call);
41
+       dbus_pending_call_unref(pending_call);
42
+       return NULL;
43
+   }
44
+
45
+   return pending_call;
46
+}
47
+
48
+SPA_DEFINE_AUTO_CLEANUP(DBusError, DBusError, {
49
+   dbus_error_free(thing);
50
+})
51
+
52
 #endif /* SPA_BLUEZ5_DBUS_HELPERS_H */
53
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/hci.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/hci.c Changed
48
 
1
@@ -29,10 +29,12 @@
2
 #include <bluetooth/hci.h>
3
 #include <bluetooth/hci_lib.h>
4
 
5
+#include <spa/utils/cleanup.h>
6
+
7
 int spa_bt_adapter_has_msbc(struct spa_bt_adapter *adapter)
8
 {
9
-   int hci_id, res;
10
-   int sock = -1;
11
+   int hci_id;
12
+   spa_autoclose int sock = -1;
13
    uint8_t features8, max_page = 0;
14
    struct sockaddr_hci a;
15
    const char *str;
16
@@ -46,28 +48,20 @@
17
 
18
    sock = socket(AF_BLUETOOTH, SOCK_RAW | SOCK_CLOEXEC, BTPROTO_HCI);
19
    if (sock < 0)
20
-       goto error;
21
+       return -errno;
22
 
23
    memset(&a, 0, sizeof(a));
24
    a.hci_family = AF_BLUETOOTH;
25
    a.hci_dev = hci_id;
26
    if (bind(sock, (struct sockaddr *) &a, sizeof(a)) < 0)
27
-       goto error;
28
+       return -errno;
29
 
30
    if (hci_read_local_ext_features(sock, 0, &max_page, features, 1000) < 0)
31
-       goto error;
32
-
33
-   close(sock);
34
+       return -errno;
35
 
36
    adapter->msbc_probed = true;
37
    adapter->has_msbc = ((features2 & LMP_TRSP_SCO) && (features3 & LMP_ESCO)) ? 1 : 0;
38
    return adapter->has_msbc;
39
-
40
-error:
41
-   res = -errno;
42
-   if (sock >= 0)
43
-       close(sock);
44
-   return res;
45
 }
46
 
47
 #endif
48
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/media-codecs.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/media-codecs.c Changed
30
 
1
@@ -9,6 +9,7 @@
2
  */
3
 
4
 #include <spa/utils/string.h>
5
+#include <spa/utils/cleanup.h>
6
 
7
 #include "media-codecs.h"
8
 
9
@@ -16,7 +17,8 @@
10
                 uint32_t cap, int preferred_value)
11
 {
12
    size_t i;
13
-   int *scores, res;
14
+   spa_autofree int *scores = NULL;
15
+   int res;
16
    unsigned int max_priority;
17
 
18
    if (n == 0)
19
@@ -54,9 +56,8 @@
20
    }
21
 
22
    if (scoresres < 0)
23
-       res = -EINVAL;
24
+       return -EINVAL;
25
 
26
-   free(scores);
27
    return res;
28
 }
29
 
30
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/modemmanager.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/modemmanager.c Changed
201
 
1
@@ -40,35 +40,6 @@
2
    void *user_data;
3
 };
4
 
5
-static bool mm_dbus_connection_send_with_reply(struct impl *this, DBusMessage *m, DBusPendingCall **pending_return,
6
-                                               DBusPendingCallNotifyFunction function, void *user_data)
7
-{
8
-   spa_assert(*pending_return == NULL);
9
-
10
-   DBusPendingCall *pending_call;
11
-   bool ret = dbus_connection_send_with_reply(this->conn, m, &pending_call, -1);
12
-   if (!ret) {
13
-       spa_log_debug(this->log, "dbus call failure");
14
-       goto out;
15
-   }
16
-
17
-   spa_assert(pending_call);
18
-
19
-   ret = dbus_pending_call_set_notify(pending_call, function, user_data, NULL);
20
-   if (!ret) {
21
-       spa_log_debug(this->log, "dbus set notify failure");
22
-       cancel_and_unref(&pending_call);
23
-       goto out;
24
-   }
25
-
26
-   *pending_return = pending_call;
27
-
28
-out:
29
-   dbus_message_unref(m);
30
-
31
-   return ret;
32
-}
33
-
34
 static int mm_state_to_clcc(struct impl *this, MMCallState state)
35
 {
36
    switch (state) {
37
@@ -119,28 +90,27 @@
38
 {
39
    struct call *call = user_data;
40
    struct impl *this = call->this;
41
-   DBusMessage *r;
42
    DBusMessageIter arg_i, element_i;
43
    MMCallDirection direction;
44
    MMCallState state;
45
 
46
    spa_assert(call->pending == pending);
47
-   r = steal_reply_and_unref(&call->pending);
48
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&call->pending);
49
    if (r == NULL)
50
        return;
51
 
52
    if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
53
        spa_log_warn(this->log, "ModemManager D-Bus Call not available");
54
-       goto finish;
55
+       return;
56
    }
57
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
58
        spa_log_error(this->log, "GetAll() failed: %s", dbus_message_get_error_name(r));
59
-       goto finish;
60
+       return;
61
    }
62
 
63
    if (!dbus_message_iter_init(r, &arg_i) || !spa_streq(dbus_message_get_signature(r), "a{sv}")) {
64
        spa_log_error(this->log, "Invalid arguments in GetAll() reply");
65
-       goto finish;
66
+       return;
67
    }
68
 
69
    spa_log_debug(this->log, "Call path: %s", call->path);
70
@@ -184,9 +154,6 @@
71
 
72
        dbus_message_iter_next(&element_i);
73
    }
74
-
75
-finish:
76
-   dbus_message_unref(r);
77
 }
78
 
79
 static DBusHandlerResult mm_parse_voice_properties(struct impl *this, DBusMessageIter *props_i)
80
@@ -417,23 +384,22 @@
81
 static void mm_get_managed_objects_reply(DBusPendingCall *pending, void *user_data)
82
 {
83
    struct impl *this = user_data;
84
-   DBusMessage *r;
85
    DBusMessageIter i, array_i;
86
 
87
    spa_assert(this->pending == pending);
88
-   r = steal_reply_and_unref(&this->pending);
89
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&this->pending);
90
    if (r == NULL)
91
        return;
92
 
93
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
94
        spa_log_error(this->log, "Failed to get a list of endpoints from ModemManager: %s",
95
                dbus_message_get_error_name(r));
96
-       goto finish;
97
+       return;
98
    }
99
 
100
    if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "a{oa{sa{sv}}}")) {
101
        spa_log_error(this->log, "Invalid arguments in GetManagedObjects() reply");
102
-       goto finish;
103
+       return;
104
    }
105
 
106
    dbus_message_iter_recurse(&i, &array_i);
107
@@ -444,9 +410,6 @@
108
            mm_parse_interfaces(this, &dict_i);
109
            dbus_message_iter_next(&array_i);
110
    }
111
-
112
-finish:
113
-   dbus_message_unref(r);
114
 }
115
 
116
 static void call_free(struct call *call)
117
@@ -501,12 +464,10 @@
118
 static DBusHandlerResult mm_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
119
 {
120
    struct impl *this = user_data;
121
-   DBusError err;
122
-
123
-   dbus_error_init(&err);
124
 
125
    if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
126
        const char *name, *old_owner, *new_owner;
127
+       spa_auto(DBusError) err = DBUS_ERROR_INIT;
128
 
129
        spa_log_debug(this->log, "Name owner changed %s", dbus_message_get_path(m));
130
 
131
@@ -609,6 +570,7 @@
132
        const char *path;
133
        struct call *call_object;
134
        const char *mm_call_interface = MM_DBUS_INTERFACE_CALL;
135
+       spa_autoptr(DBusMessage) m = NULL;
136
 
137
        if (!spa_streq(this->modem.path, dbus_message_get_path(m)))
138
            goto finish;
139
@@ -632,7 +594,9 @@
140
        if (m == NULL)
141
            goto finish;
142
        dbus_message_append_args(m, DBUS_TYPE_STRING, &mm_call_interface, DBUS_TYPE_INVALID);
143
-       if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_properties_reply, call_object)) {
144
+
145
+       call_object->pending = send_with_reply(this->conn, m, mm_get_call_properties_reply, call_object);
146
+       if (!call_object->pending) {
147
            spa_log_error(this->log, "dbus call failure");
148
            goto finish;
149
        }
150
@@ -707,18 +671,16 @@
151
 
152
 static int add_filters(struct impl *this)
153
 {
154
-   DBusError err;
155
-
156
    if (this->filters_added)
157
        return 0;
158
 
159
-   dbus_error_init(&err);
160
-
161
    if (!dbus_connection_add_filter(this->conn, mm_filter_cb, this, NULL)) {
162
        spa_log_error(this->log, "failed to add filter function");
163
-       goto fail;
164
+       return -EIO;
165
    }
166
 
167
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
168
+
169
    dbus_bus_add_match(this->conn,
170
            "type='signal',sender='org.freedesktop.DBus',"
171
            "interface='org.freedesktop.DBus',member='NameOwnerChanged'," "arg0='" MM_DBUS_SERVICE "'", &err);
172
@@ -744,10 +706,6 @@
173
    this->filters_added = true;
174
 
175
    return 0;
176
-
177
-fail:
178
-   dbus_error_free(&err);
179
-   return -EIO;
180
 }
181
 
182
 bool mm_is_available(void *modemmanager)
183
@@ -771,12 +729,11 @@
184
    struct impl *this = dbus_cmd_data->this;
185
    struct call *call = dbus_cmd_data->call;
186
    void *user_data = dbus_cmd_data->user_data;
187
-   DBusMessage *r;
188
 
189
    free(data);
190
 
191
    spa_assert(call->pending == pending);
192
-   r = steal_reply_and_unref(&call->pending);
193
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&call->pending);
194
    if (r == NULL)
195
        return;
196
 
197
@@ -801,12 +758,11 @@
198
    struct dbus_cmd_data *dbus_cmd_data = data;
199
    struct impl *this = dbus_cmd_data->this;
200
    void *user_data = dbus_cmd_data->user_data;
201
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/player.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/player.c Changed
145
 
1
@@ -9,6 +9,7 @@
2
 #include <spa/utils/string.h>
3
 
4
 #include "defs.h"
5
+#include "dbus-helpers.h"
6
 #include "player.h"
7
 
8
 #define PLAYER_OBJECT_PATH_BASE    "/media_player"
9
@@ -167,18 +168,18 @@
10
 static DBusMessage *introspect(struct impl *impl, DBusMessage *m)
11
 {
12
    const char *xml = PLAYER_INTROSPECT_XML;
13
-   DBusMessage *r;
14
+   spa_autoptr(DBusMessage) r = NULL;
15
    if ((r = dbus_message_new_method_return(m)) == NULL)
16
        return NULL;
17
    if (!dbus_message_append_args(r, DBUS_TYPE_STRING, &xml, DBUS_TYPE_INVALID))
18
        return NULL;
19
-   return r;
20
+   return spa_steal_ptr(r);
21
 }
22
 
23
 static DBusHandlerResult player_handler(DBusConnection *c, DBusMessage *m, void *userdata)
24
 {
25
    struct impl *impl = userdata;
26
-   DBusMessage *r;
27
+   spa_autoptr(DBusMessage) r = NULL;
28
 
29
    if (dbus_message_is_method_call(m, DBUS_INTERFACE_INTROSPECTABLE, "Introspect")) {
30
        r = introspect(impl, m);
31
@@ -194,20 +195,16 @@
32
 
33
    if (r == NULL)
34
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
35
-   if (!dbus_connection_send(impl->conn, r, NULL)) {
36
-       dbus_message_unref(r);
37
+   if (!dbus_connection_send(impl->conn, r, NULL))
38
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
39
-   }
40
-   dbus_message_unref(r);
41
    return DBUS_HANDLER_RESULT_HANDLED;
42
 }
43
 
44
 static int send_update_signal(struct impl *impl)
45
 {
46
-   DBusMessage *m;
47
+   spa_autoptr(DBusMessage) m = NULL;
48
    const char *iface = PLAYER_INTERFACE;
49
    DBusMessageIter i, a;
50
-   int res = 0;
51
 
52
    m = dbus_message_new_signal(impl->path, DBUS_INTERFACE_PROPERTIES, "PropertiesChanged");
53
    if (m == NULL)
54
@@ -223,11 +220,9 @@
55
         dbus_message_iter_close_container(&i, &a);
56
 
57
    if (!dbus_connection_send(impl->conn, m, NULL))
58
-       res = -EIO;
59
-
60
-   dbus_message_unref(m);
61
+       return -EIO;
62
 
63
-   return res;
64
+   return 0;
65
 }
66
 
67
 static void update_properties(struct impl *impl, bool send_signal)
68
@@ -330,10 +325,9 @@
69
 {
70
    struct impl *impl = SPA_CONTAINER_OF(player, struct impl, this);
71
 
72
-   DBusError err;
73
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
74
    DBusMessageIter i;
75
-   DBusMessage *m, *r;
76
-   int res = 0;
77
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
78
 
79
    spa_log_debug(impl->log, "RegisterPlayer() for dummy AVRCP player %s for %s",
80
            impl->path, adapter_path);
81
@@ -347,34 +341,27 @@
82
    dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &impl->path);
83
    append_properties(impl, &i);
84
 
85
-   dbus_error_init(&err);
86
    r = dbus_connection_send_with_reply_and_block(impl->conn, m, -1, &err);
87
-   dbus_message_unref(m);
88
-
89
    if (r == NULL) {
90
        spa_log_error(impl->log, "RegisterPlayer() failed (%s)", err.message);
91
-       dbus_error_free(&err);
92
        return -EIO;
93
    }
94
 
95
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
96
        spa_log_error(impl->log, "RegisterPlayer() failed");
97
-       res = -EIO;
98
+       return -EIO;
99
    }
100
 
101
-   dbus_message_unref(r);
102
-
103
-   return res;
104
+   return 0;
105
 }
106
 
107
 int spa_bt_player_unregister(struct spa_bt_player *player, const char *adapter_path)
108
 {
109
    struct impl *impl = SPA_CONTAINER_OF(player, struct impl, this);
110
 
111
-   DBusError err;
112
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
113
    DBusMessageIter i;
114
-   DBusMessage *m, *r;
115
-   int res = 0;
116
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
117
 
118
    spa_log_debug(impl->log, "UnregisterPlayer() for dummy AVRCP player %s for %s",
119
            impl->path, adapter_path);
120
@@ -387,22 +374,16 @@
121
    dbus_message_iter_init_append(m, &i);
122
    dbus_message_iter_append_basic(&i, DBUS_TYPE_OBJECT_PATH, &impl->path);
123
 
124
-   dbus_error_init(&err);
125
    r = dbus_connection_send_with_reply_and_block(impl->conn, m, -1, &err);
126
-   dbus_message_unref(m);
127
-
128
    if (r == NULL) {
129
        spa_log_error(impl->log, "UnregisterPlayer() failed (%s)", err.message);
130
-       dbus_error_free(&err);
131
        return -EIO;
132
    }
133
 
134
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
135
        spa_log_error(impl->log, "UnregisterPlayer() failed");
136
-       res = -EIO;
137
+       return -EIO;
138
    }
139
 
140
-   dbus_message_unref(r);
141
-
142
-   return res;
143
+   return 0;
144
 }
145
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/quirks.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/quirks.c Changed
41
 
1
@@ -28,6 +28,7 @@
2
 #include <spa/support/plugin.h>
3
 #include <spa/monitor/device.h>
4
 #include <spa/monitor/utils.h>
5
+#include <spa/utils/cleanup.h>
6
 #include <spa/utils/hook.h>
7
 #include <spa/utils/type.h>
8
 #include <spa/utils/keys.h>
9
@@ -187,27 +188,21 @@
10
 {
11
    char *data;
12
    struct stat sbuf;
13
-   int fd = -1;
14
+   spa_autoclose int fd = -1;
15
 
16
    spa_log_debug(this->log, "loading %s", path);
17
 
18
    if ((fd = open(path, O_CLOEXEC | O_RDONLY)) < 0)
19
-       goto fail;
20
+       return -errno;
21
    if (fstat(fd, &sbuf) < 0)
22
-       goto fail;
23
+       return -errno;
24
    if ((data = mmap(NULL, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0)) == MAP_FAILED)
25
-       goto fail;
26
-   close(fd);
27
+       return -errno;
28
 
29
    load_quirks(this, data, sbuf.st_size);
30
    munmap(data, sbuf.st_size);
31
 
32
    return 0;
33
-
34
-fail:
35
-   if (fd >= 0)
36
-       close(fd);
37
-   return -errno;
38
 }
39
 
40
 struct spa_bt_quirks *spa_bt_quirks_create(const struct spa_dict *info, struct spa_log *log)
41
pipewire-0.3.76.tar.gz/spa/plugins/bluez5/upower.c -> pipewire-0.3.77.tar.gz/spa/plugins/bluez5/upower.c Changed
110
 
1
@@ -43,40 +43,36 @@
2
 static void upower_get_percentage_properties_reply(DBusPendingCall *pending, void *user_data)
3
 {
4
    struct impl *backend = user_data;
5
-   DBusMessage *r;
6
    DBusMessageIter i, variant_i;
7
 
8
    spa_assert(backend->pending_get_call == pending);
9
-   r = steal_reply_and_unref(&backend->pending_get_call);
10
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&backend->pending_get_call);
11
    if (r == NULL)
12
        return;
13
 
14
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
15
        spa_log_error(backend->log, "Failed to get percentage from UPower: %s",
16
                dbus_message_get_error_name(r));
17
-       goto finish;
18
+       return;
19
    }
20
 
21
    if (!dbus_message_iter_init(r, &i) || !spa_streq(dbus_message_get_signature(r), "v")) {
22
        spa_log_error(backend->log, "Invalid arguments in Get() reply");
23
-       goto finish;
24
+       return;
25
    }
26
 
27
    dbus_message_iter_recurse(&i, &variant_i);
28
    upower_parse_percentage(backend, &variant_i);
29
-
30
-finish:
31
-   dbus_message_unref(r);
32
 }
33
 
34
 static int update_battery_percentage(struct impl *this)
35
 {
36
    cancel_and_unref(&this->pending_get_call);
37
 
38
-   DBusMessage *m = dbus_message_new_method_call(UPOWER_SERVICE,
39
-                             UPOWER_DISPLAY_DEVICE_OBJECT,
40
-                             DBUS_INTERFACE_PROPERTIES,
41
-                             "Get");
42
+   spa_autoptr(DBusMessage) m = dbus_message_new_method_call(UPOWER_SERVICE,
43
+                                 UPOWER_DISPLAY_DEVICE_OBJECT,
44
+                                 DBUS_INTERFACE_PROPERTIES,
45
+                                 "Get");
46
    if (!m)
47
        return -ENOMEM;
48
 
49
@@ -86,10 +82,9 @@
50
                 DBUS_TYPE_INVALID);
51
    dbus_message_set_auto_start(m, false);
52
 
53
-   dbus_connection_send_with_reply(this->conn, m, &this->pending_get_call, -1);
54
-   dbus_pending_call_set_notify(this->pending_get_call, upower_get_percentage_properties_reply, this, NULL);
55
-
56
-   dbus_message_unref(m);
57
+   this->pending_get_call = send_with_reply(this->conn, m, upower_get_percentage_properties_reply, this);
58
+   if (!this->pending_get_call)
59
+       return -EIO;
60
 
61
    return 0;
62
 }
63
@@ -102,12 +97,10 @@
64
 static DBusHandlerResult upower_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
65
 {
66
    struct impl *this = user_data;
67
-   DBusError err;
68
-
69
-   dbus_error_init(&err);
70
 
71
    if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
72
        const char *name, *old_owner, *new_owner;
73
+       spa_auto(DBusError) err = DBUS_ERROR_INIT;
74
 
75
        spa_log_debug(this->log, "Name owner changed %s", dbus_message_get_path(m));
76
 
77
@@ -176,18 +169,16 @@
78
 
79
 static int add_filters(struct impl *this)
80
 {
81
-   DBusError err;
82
-
83
    if (this->filters_added)
84
        return 0;
85
 
86
-   dbus_error_init(&err);
87
-
88
    if (!dbus_connection_add_filter(this->conn, upower_filter_cb, this, NULL)) {
89
        spa_log_error(this->log, "failed to add filter function");
90
-       goto fail;
91
+       return -EIO;
92
    }
93
 
94
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
95
+
96
    dbus_bus_add_match(this->conn,
97
            "type='signal',sender='org.freedesktop.DBus',"
98
            "interface='org.freedesktop.DBus',member='NameOwnerChanged'," "arg0='" UPOWER_SERVICE "'", &err);
99
@@ -199,10 +190,6 @@
100
    this->filters_added = true;
101
 
102
    return 0;
103
-
104
-fail:
105
-   dbus_error_free(&err);
106
-   return -EIO;
107
 }
108
 
109
 void *upower_register(struct spa_log *log,
110
pipewire-0.3.76.tar.gz/spa/plugins/v4l2/v4l2-udev.c -> pipewire-0.3.77.tar.gz/spa/plugins/v4l2/v4l2-udev.c Changed
201
 
1
@@ -33,8 +33,10 @@
2
 #define ACTION_DISABLE 2
3
 
4
 struct device {
5
+   struct impl *impl;
6
    uint32_t id;
7
    struct udev_device *dev;
8
+   struct spa_source notify;
9
    unsigned int accessible:1;
10
    unsigned int ignored:1;
11
    unsigned int emitted:1;
12
@@ -59,66 +61,79 @@
13
         uint32_t n_devices;
14
 
15
    struct spa_source source;
16
-   struct spa_source notify;
17
 };
18
 
19
-static int impl_udev_open(struct impl *this)
20
+static int stop_inotify(struct device *dev);
21
+static int start_inotify(struct device *dev);
22
+
23
+static int impl_udev_open(struct impl *impl)
24
 {
25
-   if (this->udev == NULL) {
26
-       this->udev = udev_new();
27
-       if (this->udev == NULL)
28
+   if (impl->udev == NULL) {
29
+       impl->udev = udev_new();
30
+       if (impl->udev == NULL)
31
            return -ENOMEM;
32
    }
33
    return 0;
34
 }
35
 
36
-static int impl_udev_close(struct impl *this)
37
+static int impl_udev_close(struct impl *impl)
38
 {
39
-   if (this->udev != NULL)
40
-       udev_unref(this->udev);
41
-   this->udev = NULL;
42
+   if (impl->udev != NULL)
43
+       udev_unref(impl->udev);
44
+   impl->udev = NULL;
45
    return 0;
46
 }
47
 
48
-static struct device *add_device(struct impl *this, uint32_t id, struct udev_device *dev)
49
+static struct device *add_device(struct impl *impl, uint32_t id, struct udev_device *dev)
50
 {
51
    struct device *device;
52
 
53
-   if (this->n_devices >= MAX_DEVICES)
54
+   if (impl->n_devices >= MAX_DEVICES)
55
        return NULL;
56
-   device = &this->devicesthis->n_devices++;
57
+   device = &impl->devicesimpl->n_devices++;
58
    spa_zero(*device);
59
+   device->impl = impl;
60
+   device->notify.fd = -1;
61
    device->id = id;
62
    udev_device_ref(dev);
63
    device->dev = dev;
64
+   start_inotify(device);
65
    return device;
66
 }
67
 
68
-static struct device *find_device(struct impl *this, uint32_t id)
69
+static struct device *find_device(struct impl *impl, uint32_t id)
70
 {
71
    uint32_t i;
72
-   for (i = 0; i < this->n_devices; i++) {
73
-       if (this->devicesi.id == id)
74
-           return &this->devicesi;
75
+   for (i = 0; i < impl->n_devices; i++) {
76
+       if (impl->devicesi.id == id)
77
+           return &impl->devicesi;
78
    }
79
    return NULL;
80
 }
81
 
82
-static void remove_device(struct impl *this, struct device *device)
83
+static void clear_device(struct device *device)
84
+{
85
+   stop_inotify(device);
86
+   if (device->dev)
87
+       udev_device_unref(device->dev);
88
+}
89
+
90
+static void remove_device(struct device *device)
91
 {
92
-   udev_device_unref(device->dev);
93
-   *device = this->devices--this->n_devices;
94
+   struct impl *impl = device->impl;
95
+   clear_device(device);
96
+   *device = impl->devices--impl->n_devices;
97
 }
98
 
99
-static void clear_devices(struct impl *this)
100
+static void clear_devices(struct impl *impl)
101
 {
102
         uint32_t i;
103
-   for (i = 0; i < this->n_devices; i++)
104
-           udev_device_unref(this->devicesi.dev);
105
-   this->n_devices = 0;
106
+   for (i = 0; i < impl->n_devices; i++)
107
+       clear_device(&impl->devicesi);
108
+   impl->n_devices = 0;
109
 }
110
 
111
-static uint32_t get_device_id(struct impl *this, struct udev_device *dev)
112
+static uint32_t get_device_id(struct impl *impl, struct udev_device *dev)
113
 {
114
    const char *str;
115
 
116
@@ -214,8 +229,9 @@
117
    *d = 0;
118
 }
119
 
120
-static int emit_object_info(struct impl *this, struct device *device)
121
+static int emit_object_info(struct device *device)
122
 {
123
+   struct impl *impl = device->impl;
124
    struct spa_device_object_info info;
125
    uint32_t id = device->id;
126
    struct udev_device *dev = device->dev;
127
@@ -315,54 +331,55 @@
128
        itemsn_items++ = SPA_DICT_ITEM_INIT(SPA_KEY_DEVICE_CAPABILITIES, str);
129
    }
130
         info.props = &SPA_DICT_INIT(items, n_items);
131
-        spa_device_emit_object_info(&this->hooks, id, &info);
132
+        spa_device_emit_object_info(&impl->hooks, id, &info);
133
    device->emitted = true;
134
 
135
    return 1;
136
 }
137
 
138
-static bool check_access(struct impl *this, struct device *device)
139
+static bool check_access(struct device *device)
140
 {
141
    char path128;
142
 
143
    snprintf(path, sizeof(path), "/dev/video%u", device->id);
144
    device->accessible = access(path, R_OK|W_OK) >= 0;
145
-   spa_log_debug(this->log, "%s accessible:%u", path, device->accessible);
146
+   spa_log_debug(device->impl->log, "%s accessible:%u", path, device->accessible);
147
 
148
    return device->accessible;
149
 }
150
 
151
-static void process_device(struct impl *this, uint32_t action, struct udev_device *dev)
152
+static void process_device(struct impl *impl, uint32_t action, struct udev_device *dev)
153
 {
154
    uint32_t id;
155
    struct device *device;
156
    bool emitted;
157
 
158
-   if ((id = get_device_id(this, dev)) == SPA_ID_INVALID)
159
+   if ((id = get_device_id(impl, dev)) == SPA_ID_INVALID)
160
        return;
161
 
162
-   device = find_device(this, id);
163
+   device = find_device(impl, id);
164
    if (device && device->ignored)
165
        return;
166
 
167
    switch (action) {
168
    case ACTION_ADD:
169
        if (device == NULL)
170
-           device = add_device(this, id, dev);
171
+           device = add_device(impl, id, dev);
172
        if (device == NULL)
173
            return;
174
-       if (!check_access(this, device))
175
+       if (!check_access(device))
176
            return;
177
-       emit_object_info(this, device);
178
+       else
179
+           emit_object_info(device);
180
        break;
181
 
182
    case ACTION_REMOVE:
183
        if (device == NULL)
184
            return;
185
        emitted = device->emitted;
186
-       remove_device(this, device);
187
+       remove_device(device);
188
        if (emitted)
189
-           spa_device_emit_object_info(&this->hooks, id, NULL);
190
+           spa_device_emit_object_info(&impl->hooks, id, NULL);
191
        break;
192
 
193
    case ACTION_DISABLE:
194
@@ -370,27 +387,16 @@
195
            return;
196
        if (device->emitted) {
197
            device->emitted = false;
198
-           spa_device_emit_object_info(&this->hooks, id, NULL);
199
+           spa_device_emit_object_info(&impl->hooks, id, NULL);
200
        }
201
pipewire-0.3.76.tar.gz/src/modules/module-metadata/metadata.c -> pipewire-0.3.77.tar.gz/src/modules/module-metadata/metadata.c Changed
9
 
1
@@ -265,6 +265,7 @@
2
    impl->global = pw_global_new(context,
3
            PW_TYPE_INTERFACE_Metadata,
4
            PW_VERSION_METADATA,
5
+           PW_METADATA_PERM_MASK,
6
            properties,
7
            global_bind, impl);
8
    if (impl->global == NULL) {
9
pipewire-0.3.76.tar.gz/src/modules/module-profiler.c -> pipewire-0.3.77.tar.gz/src/modules/module-profiler.c Changed
45
 
1
@@ -4,6 +4,7 @@
2
 
3
 #include <string.h>
4
 #include <stdio.h>
5
+#include <stdalign.h>
6
 #include <errno.h>
7
 #include <sys/types.h>
8
 #include <sys/stat.h>
9
@@ -103,6 +104,7 @@
10
    struct spa_source *flush_event;
11
    unsigned int listening:1;
12
 
13
+   alignas(max_align_t)
14
    uint8_t flushFLUSH_BUFFER + sizeof(struct spa_pod_struct);
15
 };
16
 
17
@@ -132,12 +134,14 @@
18
        pw_log_trace("%p avail %d", impl, avail);
19
 
20
        if (avail > 0) {
21
-           spa_ringbuffer_read_data(&n->buffer, n->data, DATA_BUFFER,
22
-                   idx % DATA_BUFFER,
23
-                   SPA_PTROFF(p, sizeof(struct spa_pod_struct) + total, void),
24
-                   avail);
25
+           if (total + avail < FLUSH_BUFFER) {
26
+               spa_ringbuffer_read_data(&n->buffer, n->data, DATA_BUFFER,
27
+                       idx % DATA_BUFFER,
28
+                       SPA_PTROFF(p, sizeof(struct spa_pod_struct) + total, void),
29
+                       avail);
30
+               total += avail;
31
+           }
32
            spa_ringbuffer_read_update(&n->buffer, idx + avail);
33
-           total += avail;
34
        }
35
    }
36
 
37
@@ -458,6 +462,7 @@
38
    impl->global = pw_global_new(context,
39
            PW_TYPE_INTERFACE_Profiler,
40
            PW_VERSION_PROFILER,
41
+           PW_PROFILER_PERM_MASK,
42
            pw_properties_copy(props),
43
            global_bind, impl);
44
    if (impl->global == NULL) {
45
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/collect.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/collect.c Changed
100
 
1
@@ -6,6 +6,9 @@
2
 #include <spa/pod/builder.h>
3
 #include <spa/pod/parser.h>
4
 #include <spa/utils/string.h>
5
+
6
+#include <spa/param/audio/format-utils.h>
7
+
8
 #include <pipewire/pipewire.h>
9
 
10
 #include "collect.h"
11
@@ -226,7 +229,7 @@
12
    return SPA_ID_INVALID;
13
 }
14
 
15
-void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card,
16
+static void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card,
17
             struct device_info *dev_info, bool monitor, struct defs *defs)
18
 {
19
    struct pw_manager_param *p;
20
@@ -287,6 +290,57 @@
21
        dev_info->volume_info.volume.channels = dev_info->map.channels;
22
 }
23
 
24
+static void update_device_info(struct pw_manager *manager, struct pw_manager_object *o,
25
+       enum pw_direction direction, bool monitor, struct defs *defs)
26
+{
27
+   const char *str;
28
+   const char *key = monitor ? "device.info.monitor" : "device.info";
29
+   struct pw_manager_object *card = NULL;
30
+   struct pw_node_info *info = o->info;
31
+   struct device_info *dev_info, di;
32
+
33
+   if (info == NULL)
34
+       return;
35
+
36
+   di = DEVICE_INFO_INIT(direction);
37
+   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
38
+       di.card_id = (uint32_t)atoi(str);
39
+   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
40
+       di.device = (uint32_t)atoi(str);
41
+   if (di.card_id != SPA_ID_INVALID) {
42
+       struct selector sel = { .id = di.card_id, .type = pw_manager_object_is_card, };
43
+       card = select_object(manager, &sel);
44
+   }
45
+   collect_device_info(o, card, &di, monitor, defs);
46
+
47
+   dev_info = pw_manager_object_get_data(o, key);
48
+   if (dev_info) {
49
+       if (memcmp(dev_info, &di, sizeof(di)) != 0) {
50
+           if (monitor || direction == PW_DIRECTION_INPUT)
51
+               o->change_mask |= PW_MANAGER_OBJECT_FLAG_SOURCE;
52
+           else
53
+               o->change_mask |= PW_MANAGER_OBJECT_FLAG_SINK;
54
+       }
55
+   } else {
56
+       o->change_mask = ~0;
57
+       dev_info = pw_manager_object_add_data(o, key, sizeof(*dev_info));
58
+   }
59
+   if (dev_info != NULL)
60
+       *dev_info = di;
61
+}
62
+
63
+void get_device_info(struct pw_manager_object *o, struct device_info *info,
64
+       enum pw_direction direction, bool monitor)
65
+{
66
+   const char *key = monitor ? "device.info.monitor" : "device.info";
67
+   struct device_info *di;
68
+   di = pw_manager_object_get_data(o, key);
69
+   if (di != NULL)
70
+       *info = *di;
71
+   else
72
+       *info = DEVICE_INFO_INIT(direction);
73
+}
74
+
75
 static bool array_contains(uint32_t *vals, uint32_t n_vals, uint32_t val)
76
 {
77
    uint32_t n;
78
@@ -527,3 +581,21 @@
79
 
80
    return n_codecs;
81
 }
82
+
83
+void update_object_info(struct pw_manager *manager, struct pw_manager_object *o,
84
+       struct defs *defs)
85
+{
86
+   if (pw_manager_object_is_sink(o)) {
87
+       update_device_info(manager, o, PW_DIRECTION_OUTPUT, false, defs);
88
+       update_device_info(manager, o, PW_DIRECTION_OUTPUT, true, defs);
89
+   }
90
+   if (pw_manager_object_is_source(o)) {
91
+       update_device_info(manager, o, PW_DIRECTION_INPUT, false, defs);
92
+   }
93
+   if (pw_manager_object_is_source_output(o)) {
94
+       update_device_info(manager, o, PW_DIRECTION_INPUT, false, defs);
95
+   }
96
+   if (pw_manager_object_is_sink_input(o)) {
97
+       update_device_info(manager, o, PW_DIRECTION_OUTPUT, false, defs);
98
+   }
99
+}
100
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/collect.h -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/collect.h Changed
38
 
1
@@ -35,6 +35,8 @@
2
 struct pw_manager_object *select_object(struct pw_manager *m, struct selector *s);
3
 uint32_t id_to_index(struct pw_manager *m, uint32_t id);
4
 void select_best(struct selector *s, struct pw_manager_object *o);
5
+void update_object_info(struct pw_manager *manager, struct pw_manager_object *o,
6
+       struct defs *defs);
7
 
8
 /* ========================================================================== */
9
 
10
@@ -47,9 +49,11 @@
11
    unsigned int have_volume:1;
12
    unsigned int have_iec958codecs:1;
13
 
14
+   uint32_t card_id;
15
    uint32_t device;
16
    uint32_t active_port;
17
    const char *active_port_name;
18
+
19
 };
20
 
21
 #define DEVICE_INFO_INIT(_dir) \
22
@@ -58,12 +62,13 @@
23
        .ss = SAMPLE_SPEC_INIT,         \
24
        .map = CHANNEL_MAP_INIT,        \
25
        .volume_info = VOLUME_INFO_INIT,    \
26
+       .card_id = SPA_ID_INVALID,      \
27
        .device = SPA_ID_INVALID,       \
28
        .active_port = SPA_ID_INVALID,      \
29
    }
30
 
31
-void collect_device_info(struct pw_manager_object *device, struct pw_manager_object *card,
32
-            struct device_info *dev_info, bool monitor, struct defs *defs);
33
+void get_device_info(struct pw_manager_object *device, struct device_info *info,
34
+       enum pw_direction direction, bool monitor);
35
 
36
 /* ========================================================================== */
37
 
38
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/extensions/ext-device-restore.c Changed
42
 
1
@@ -220,17 +220,15 @@
2
 static int do_extension_device_restore_save_formats(struct client *client,
3
        uint32_t command, uint32_t tag, struct message *m)
4
 {
5
-   struct impl *impl = client->impl;
6
    struct pw_manager *manager = client->manager;
7
    struct selector sel;
8
    struct pw_manager_object *o, *card = NULL;
9
    struct pw_node_info *info;
10
    int res;
11
-   uint32_t type, sink_index, card_id = SPA_ID_INVALID;
12
+   uint32_t type, sink_index;
13
    uint8_t i, n_formats;
14
    uint32_t n_codecs = 0, codec, iec958codecs32;
15
    struct device_info dev_info;
16
-   const char *str;
17
 
18
    if ((res = message_get(m,
19
            TAG_U32, &type,
20
@@ -269,18 +267,12 @@
21
    if (o == NULL || (info = o->info) == NULL || info->props == NULL)
22
        return -ENOENT;
23
 
24
-   dev_info = DEVICE_INFO_INIT(SPA_DIRECTION_INPUT);
25
+   get_device_info(o, &dev_info, SPA_DIRECTION_INPUT, false);
26
 
27
-   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
28
-       card_id = (uint32_t)atoi(str);
29
-   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
30
-       dev_info.device = (uint32_t)atoi(str);
31
-   if (card_id != SPA_ID_INVALID) {
32
-       struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, };
33
+   if (dev_info.card_id != SPA_ID_INVALID) {
34
+       struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, };
35
        card = select_object(manager, &sel);
36
    }
37
-   collect_device_info(o, card, &dev_info, false, &impl->defs);
38
-
39
    if (card != NULL && dev_info.active_port != SPA_ID_INVALID) {
40
        res = set_card_codecs(card, dev_info.active_port,
41
                dev_info.device, n_codecs, iec958codecs);
42
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/manager.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/manager.c Changed
104
 
1
@@ -58,6 +58,7 @@
2
 
3
    const struct object_info *info;
4
 
5
+   int changed;
6
    struct spa_list pending_list;
7
 
8
    struct spa_hook proxy_listener;
9
@@ -210,7 +211,7 @@
10
 
11
    pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
12
 
13
-   info = o->this.info = pw_client_info_merge(o->this.info, info, o->this.changed == 0);
14
+   info = o->this.info = pw_client_info_merge(o->this.info, info, o->changed == 0);
15
    if (info == NULL)
16
        return;
17
 
18
@@ -218,7 +219,7 @@
19
        changed++;
20
 
21
    if (changed) {
22
-       o->this.changed += changed;
23
+       o->changed += changed;
24
        core_sync(o->manager);
25
    }
26
 }
27
@@ -251,7 +252,7 @@
28
 
29
    pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
30
 
31
-   info = o->this.info = pw_module_info_merge(o->this.info, info, o->this.changed == 0);
32
+   info = o->this.info = pw_module_info_merge(o->this.info, info, o->changed == 0);
33
    if (info == NULL)
34
        return;
35
 
36
@@ -259,7 +260,7 @@
37
        changed++;
38
 
39
    if (changed) {
40
-       o->this.changed += changed;
41
+       o->changed += changed;
42
        core_sync(o->manager);
43
    }
44
 }
45
@@ -292,7 +293,7 @@
46
 
47
    pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
48
 
49
-   info = o->this.info = pw_device_info_merge(o->this.info, info, o->this.changed == 0);
50
+   info = o->this.info = pw_device_info_merge(o->this.info, info, o->changed == 0);
51
    if (info == NULL)
52
        return;
53
 
54
@@ -331,7 +332,7 @@
55
        }
56
    }
57
    if (changed) {
58
-       o->this.changed += changed;
59
+       o->changed += changed;
60
        core_sync(o->manager);
61
    }
62
 }
63
@@ -377,7 +378,7 @@
64
            return;
65
 
66
        if ((dev = find_device(m, o->this.id, device)) != NULL) {
67
-           dev->this.changed++;
68
+           dev->changed++;
69
            core_sync(o->manager);
70
        }
71
    }
72
@@ -412,7 +413,7 @@
73
 
74
    pw_log_debug("object %p: id:%d change-mask:%08"PRIx64, o, o->this.id, info->change_mask);
75
 
76
-   info = o->this.info = pw_node_info_merge(o->this.info, info, o->this.changed == 0);
77
+   info = o->this.info = pw_node_info_merge(o->this.info, info, o->changed == 0);
78
    if (info == NULL)
79
        return;
80
 
81
@@ -446,7 +447,7 @@
82
        }
83
    }
84
    if (changed) {
85
-       o->this.changed += changed;
86
+       o->changed += changed;
87
        core_sync(o->manager);
88
    }
89
 }
90
@@ -678,10 +679,10 @@
91
            if (o->this.creating) {
92
                o->this.creating = false;
93
                manager_emit_added(m, &o->this);
94
-               o->this.changed = 0;
95
-           } else if (o->this.changed > 0) {
96
+               o->changed = 0;
97
+           } else if (o->changed > 0) {
98
                manager_emit_updated(m, &o->this);
99
-               o->this.changed = 0;
100
+               o->changed = 0;
101
            }
102
        }
103
    }
104
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/manager.h -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/manager.h Changed
16
 
1
@@ -71,11 +71,13 @@
2
    int (*message_handler)(struct pw_manager *m, struct pw_manager_object *o,
3
                           const char *message, const char *params, char **response);
4
 
5
-   int changed;
6
    void *info;
7
    struct spa_param_info *params;
8
    uint32_t n_params;
9
 
10
+#define PW_MANAGER_OBJECT_FLAG_SOURCE  (1<<0)
11
+#define PW_MANAGER_OBJECT_FLAG_SINK    (1<<1)
12
+   uint64_t change_mask;   /* object specific params change mask */
13
    struct spa_list param_list;
14
    unsigned int creating:1;
15
    unsigned int removing:1;
16
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/modules/module-zeroconf-publish.c Changed
45
 
1
@@ -180,17 +180,14 @@
2
 static void fill_service_data(struct module_zeroconf_publish_data *d, struct service *s,
3
                struct pw_manager_object *o)
4
 {
5
-   struct impl *impl = d->module->impl;
6
    bool is_sink = pw_manager_object_is_sink(o);
7
    bool is_source = pw_manager_object_is_source(o);
8
    struct pw_node_info *info = o->info;
9
-   const char *name, *desc, *str;
10
-   uint32_t card_id = SPA_ID_INVALID;
11
+   const char *name, *desc;
12
    struct pw_manager *manager = d->manager;
13
    struct pw_manager_object *card = NULL;
14
    struct card_info card_info = CARD_INFO_INIT;
15
-   struct device_info dev_info = is_sink ?
16
-       DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT) : DEVICE_INFO_INIT(PW_DIRECTION_INPUT);
17
+   struct device_info dev_info;
18
    uint32_t flags = 0;
19
 
20
    if (info == NULL || info->props == NULL)
21
@@ -202,19 +199,15 @@
22
    if (name == NULL)
23
        name = "unknown";
24
 
25
-   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
26
-       card_id = (uint32_t)atoi(str);
27
-   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
28
-       dev_info.device = (uint32_t)atoi(str);
29
-   if (card_id != SPA_ID_INVALID) {
30
-       struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, };
31
+   get_device_info(o, &dev_info, is_sink ? PW_DIRECTION_OUTPUT : PW_DIRECTION_INPUT, false);
32
+
33
+   if (dev_info.card_id != SPA_ID_INVALID) {
34
+       struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, };
35
        card = select_object(manager, &sel);
36
    }
37
    if (card)
38
        collect_card_info(card, &card_info);
39
 
40
-   collect_device_info(o, card, &dev_info, false, &impl->defs);
41
-
42
    if (!pw_manager_object_is_virtual(o)) {
43
        if (is_sink)
44
            flags |= SINK_HARDWARE;
45
pipewire-0.3.76.tar.gz/src/modules/module-protocol-pulse/pulse-server.c -> pipewire-0.3.77.tar.gz/src/modules/module-protocol-pulse/pulse-server.c Changed
201
 
1
@@ -208,13 +208,15 @@
2
 {
3
    uint32_t event = 0, mask = 0, res_index = o->index;
4
 
5
-   if (pw_manager_object_is_sink(o)) {
6
+   pw_log_debug("index:%d id:%d %08lx type:%u", o->index, o->id, o->change_mask, type);
7
+
8
+   if (pw_manager_object_is_sink(o) && o->change_mask & PW_MANAGER_OBJECT_FLAG_SINK) {
9
        client_queue_subscribe_event(client,
10
                SUBSCRIPTION_MASK_SINK,
11
                SUBSCRIPTION_EVENT_SINK | type,
12
                res_index);
13
    }
14
-   if (pw_manager_object_is_source_or_monitor(o)) {
15
+   if (pw_manager_object_is_source_or_monitor(o) && o->change_mask & PW_MANAGER_OBJECT_FLAG_SOURCE) {
16
        mask = SUBSCRIPTION_MASK_SOURCE;
17
        event = SUBSCRIPTION_EVENT_SOURCE;
18
    }
19
@@ -808,6 +810,7 @@
20
 {
21
    struct client *client = data;
22
    struct pw_manager *manager = client->manager;
23
+   struct impl *impl = client->impl;
24
    const char *str;
25
 
26
    register_object_message_handlers(o);
27
@@ -869,8 +872,12 @@
28
        }
29
    }
30
 
31
+   update_object_info(manager, o, &impl->defs);
32
+
33
    send_object_event(client, o, SUBSCRIPTION_EVENT_NEW);
34
 
35
+   o->change_mask = 0;
36
+
37
    /* Adding sinks etc. may also change defaults */
38
    send_default_change_subscribe_event(client, pw_manager_object_is_sink(o), pw_manager_object_is_source_or_monitor(o));
39
 }
40
@@ -878,9 +885,15 @@
41
 static void manager_updated(void *data, struct pw_manager_object *o)
42
 {
43
    struct client *client = data;
44
+   struct pw_manager *manager = client->manager;
45
+   struct impl *impl = client->impl;
46
+
47
+   update_object_info(manager, o, &impl->defs);
48
 
49
    send_object_event(client, o, SUBSCRIPTION_EVENT_CHANGE);
50
 
51
+   o->change_mask = 0;
52
+
53
    set_temporary_move_target(client, o, SPA_ID_INVALID);
54
 
55
    send_latency_offset_subscribe_event(client, o);
56
@@ -1646,8 +1659,8 @@
57
    spa_zero(fix_ss);
58
    spa_zero(fix_map);
59
    if ((fix_format || fix_rate || fix_channels) && o != NULL) {
60
-       struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT);
61
-       collect_device_info(o, NULL, &dev_info, is_monitor, &impl->defs);
62
+       struct device_info dev_info;
63
+       get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, is_monitor);
64
        fix_ss.format = fix_format ? dev_info.ss.format : 0;
65
        fix_ss.rate = fix_rate ? dev_info.ss.rate : 0;
66
        fix_ss.channels = fix_channels ? dev_info.ss.channels : 0;
67
@@ -1936,8 +1949,8 @@
68
    spa_zero(fix_ss);
69
    spa_zero(fix_map);
70
    if ((fix_format || fix_rate || fix_channels) && o != NULL) {
71
-       struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT);
72
-       collect_device_info(o, NULL, &dev_info, is_monitor, &impl->defs);
73
+       struct device_info dev_info;
74
+       get_device_info(o, &dev_info, PW_DIRECTION_INPUT, is_monitor);
75
        fix_ss.format = fix_format ? dev_info.ss.format : 0;
76
        fix_ss.rate = fix_rate ? dev_info.ss.rate : 0;
77
        fix_ss.channels = fix_channels ? dev_info.ss.channels : 0;
78
@@ -2453,7 +2466,7 @@
79
        uint32_t index, const char *name, bool sink, bool *is_monitor)
80
 {
81
    struct selector sel;
82
-   bool monitor = false, find_default = false;
83
+   bool monitor = false, find_default = false, allow_monitor = false;
84
    struct pw_manager_object *o;
85
 
86
    if (name != NULL) {
87
@@ -2463,10 +2476,12 @@
88
            sink = true;
89
            find_default = true;
90
            monitor = true;
91
+           allow_monitor = true;
92
        } else if (spa_streq(name, DEFAULT_SOURCE)) {
93
            if (sink)
94
                return NULL;
95
            find_default = true;
96
+           allow_monitor = true;
97
        } else if (spa_streq(name, DEFAULT_SINK)) {
98
            if (!sink)
99
                return NULL;
100
@@ -2485,8 +2500,10 @@
101
 
102
    if (name != NULL) {
103
        if (spa_strendswith(name, ".monitor")) {
104
-           name = strndupa(name, strlen(name)-8);
105
-           monitor = true;
106
+           if (!sink) {
107
+               name = strndupa(name, strlen(name)-8);
108
+               allow_monitor = true;
109
+           }
110
        }
111
    } else if (index == SPA_ID_INVALID)
112
        return NULL;
113
@@ -2502,8 +2519,18 @@
114
 
115
    o = select_object(client->manager, &sel);
116
    if (o != NULL) {
117
-       if (!sink && pw_manager_object_is_monitor(o))
118
-           monitor = true;
119
+       if (!sink) {
120
+           if (pw_manager_object_is_monitor(o)) {
121
+               if (!allow_monitor)
122
+                   return NULL;
123
+               monitor = true;
124
+           }
125
+           else if (!pw_manager_object_is_source(o))
126
+               return NULL;
127
+       } else {
128
+           if (!pw_manager_object_is_sink(o))
129
+               return NULL;
130
+       }
131
    }
132
    if (is_monitor)
133
        *is_monitor = monitor;
134
@@ -2876,11 +2903,10 @@
135
 
136
 static int do_set_volume(struct client *client, uint32_t command, uint32_t tag, struct message *m)
137
 {
138
-   struct impl *impl = client->impl;
139
    struct pw_manager *manager = client->manager;
140
    struct pw_node_info *info;
141
-   uint32_t index, card_id = SPA_ID_INVALID;
142
-   const char *name, *str;
143
+   uint32_t index;
144
+   const char *name;
145
    struct volume volume;
146
    struct pw_manager_object *o, *card = NULL;
147
    int res;
148
@@ -2916,22 +2942,16 @@
149
    if (o == NULL || (info = o->info) == NULL || info->props == NULL)
150
        return -ENOENT;
151
 
152
-   dev_info = DEVICE_INFO_INIT(direction);
153
-
154
-   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
155
-       card_id = (uint32_t)atoi(str);
156
-   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
157
-       dev_info.device = (uint32_t)atoi(str);
158
-   if (card_id != SPA_ID_INVALID) {
159
-       struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, };
160
-       card = select_object(manager, &sel);
161
-   }
162
-   collect_device_info(o, card, &dev_info, is_monitor, &impl->defs);
163
+   get_device_info(o, &dev_info, direction, is_monitor);
164
 
165
    if (dev_info.have_volume &&
166
        volume_compare(&dev_info.volume_info.volume, &volume) == 0)
167
        goto done;
168
 
169
+   if (dev_info.card_id != SPA_ID_INVALID) {
170
+       struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, };
171
+       card = select_object(manager, &sel);
172
+   }
173
    if (card != NULL && !is_monitor && dev_info.active_port != SPA_ID_INVALID)
174
        res = set_card_volume_mute_delay(card, dev_info.active_port,
175
                dev_info.device, &volume, NULL, NULL);
176
@@ -2947,11 +2967,10 @@
177
 
178
 static int do_set_mute(struct client *client, uint32_t command, uint32_t tag, struct message *m)
179
 {
180
-   struct impl *impl = client->impl;
181
    struct pw_manager *manager = client->manager;
182
    struct pw_node_info *info;
183
-   uint32_t index, card_id = SPA_ID_INVALID;
184
-   const char *name, *str;
185
+   uint32_t index;
186
+   const char *name;
187
    bool mute;
188
    struct pw_manager_object *o, *card = NULL;
189
    int res;
190
@@ -2982,22 +3001,17 @@
191
    if (o == NULL || (info = o->info) == NULL || info->props == NULL)
192
        return -ENOENT;
193
 
194
-   dev_info = DEVICE_INFO_INIT(direction);
195
-
196
-   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
197
-       card_id = (uint32_t)atoi(str);
198
-   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
199
-       dev_info.device = (uint32_t)atoi(str);
200
-   if (card_id != SPA_ID_INVALID) {
201
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint-stream.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint-stream.c Changed
9
 
1
@@ -292,6 +292,7 @@
2
    this->global = pw_global_new (context,
3
            PW_TYPE_INTERFACE_EndpointStream,
4
            PW_VERSION_ENDPOINT_STREAM,
5
+           PW_ENDPOINT_STREAM_PERM_MASK,
6
            properties, endpoint_stream_bind, this);
7
    if (!this->global)
8
        goto no_mem;
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-endpoint/endpoint.c Changed
9
 
1
@@ -322,6 +322,7 @@
2
    this->global = pw_global_new (context,
3
            PW_TYPE_INTERFACE_Endpoint,
4
            PW_VERSION_ENDPOINT,
5
+           PW_ENDPOINT_PERM_MASK,
6
            NULL, endpoint_bind, this);
7
    if (!this->global)
8
        goto no_mem;
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-session/endpoint-link.c Changed
9
 
1
@@ -310,6 +310,7 @@
2
    this->global = pw_global_new(context,
3
            PW_TYPE_INTERFACE_EndpointLink,
4
            PW_VERSION_ENDPOINT_LINK,
5
+           PW_ENDPOINT_LINK_PERM_MASK,
6
            properties, endpoint_link_bind, this);
7
    if (!this->global)
8
        goto no_mem;
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/client-session/session.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/client-session/session.c Changed
9
 
1
@@ -283,6 +283,7 @@
2
    this->global = pw_global_new (context,
3
            PW_TYPE_INTERFACE_Session,
4
            PW_VERSION_SESSION,
5
+           PW_SESSION_PERM_MASK,
6
            NULL, session_bind, this);
7
    if (!this->global)
8
        goto no_mem;
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/endpoint-link.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/endpoint-link.c Changed
9
 
1
@@ -390,6 +390,7 @@
2
    impl->global = pw_global_new(context,
3
            PW_TYPE_INTERFACE_EndpointLink,
4
            PW_VERSION_ENDPOINT_LINK,
5
+           PW_ENDPOINT_LINK_PERM_MASK,
6
            properties,
7
            global_bind, impl);
8
    if (impl->global == NULL) {
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/endpoint-stream.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/endpoint-stream.c Changed
9
 
1
@@ -381,6 +381,7 @@
2
    impl->global = pw_global_new(context,
3
            PW_TYPE_INTERFACE_EndpointStream,
4
            PW_VERSION_ENDPOINT_STREAM,
5
+           PW_ENDPOINT_STREAM_PERM_MASK,
6
            properties,
7
            global_bind, impl);
8
    if (impl->global == NULL) {
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/endpoint.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/endpoint.c Changed
9
 
1
@@ -390,6 +390,7 @@
2
    impl->global = pw_global_new(context,
3
            PW_TYPE_INTERFACE_Endpoint,
4
            PW_VERSION_ENDPOINT,
5
+           PW_ENDPOINT_PERM_MASK,
6
            properties,
7
            global_bind, impl);
8
    if (impl->global == NULL) {
9
pipewire-0.3.76.tar.gz/src/modules/module-session-manager/session.c -> pipewire-0.3.77.tar.gz/src/modules/module-session-manager/session.c Changed
9
 
1
@@ -379,6 +379,7 @@
2
    impl->global = pw_global_new(context,
3
            PW_TYPE_INTERFACE_Session,
4
            PW_VERSION_SESSION,
5
+           PW_SESSION_PERM_MASK,
6
            properties,
7
            global_bind, impl);
8
    if (impl->global == NULL) {
9
pipewire-0.3.76.tar.gz/src/modules/module-vban/audio.c -> pipewire-0.3.77.tar.gz/src/modules/module-vban/audio.c Changed
12
 
1
@@ -209,8 +209,9 @@
2
 
3
        timestamp += tosend;
4
        avail -= tosend;
5
-       impl->header.n_frames++;
6
+       header.n_frames++;
7
    }
8
+   impl->header.n_frames = header.n_frames;
9
    spa_ringbuffer_read_update(&impl->ring, timestamp);
10
 }
11
 
12
pipewire-0.3.77.tar.gz/src/modules/module-vban/midi.c Added
201
 
1
@@ -0,0 +1,327 @@
2
+/* PipeWire */
3
+/* SPDX-FileCopyrightText: Copyright © 2023 Wim Taymans <wim.taymans@gmail.com> */
4
+/* SPDX-License-Identifier: MIT */
5
+
6
+static void vban_midi_process_playback(void *data)
7
+{
8
+   struct impl *impl = data;
9
+   struct pw_buffer *buf;
10
+   struct spa_data *d;
11
+   uint32_t timestamp, duration, maxsize, read;
12
+   struct spa_pod_builder b;
13
+   struct spa_pod_frame f1;
14
+   void *ptr;
15
+   struct spa_pod *pod;
16
+   struct spa_pod_control *c;
17
+
18
+   if ((buf = pw_stream_dequeue_buffer(impl->stream)) == NULL) {
19
+       pw_log_debug("Out of stream buffers: %m");
20
+       return;
21
+   }
22
+   d = buf->buffer->datas;
23
+
24
+   maxsize = d0.maxsize;
25
+
26
+   /* we always use the graph position to select events */
27
+   if (impl->io_position) {
28
+       duration = impl->io_position->clock.duration;
29
+       timestamp = impl->io_position->clock.position;
30
+   } else {
31
+       duration = 8192;
32
+       timestamp = 0;
33
+   }
34
+
35
+   /* we copy events into the buffer as they are available. */
36
+   spa_pod_builder_init(&b, d0.data, maxsize);
37
+   spa_pod_builder_push_sequence(&b, &f0, 0);
38
+
39
+   while (true) {
40
+       int32_t avail = spa_ringbuffer_get_read_index(&impl->ring, &read);
41
+       if (avail <= 0)
42
+           break;
43
+
44
+       ptr = SPA_PTROFF(impl->buffer, read & BUFFER_MASK2, void);
45
+
46
+       if ((pod = spa_pod_from_data(ptr, avail, 0, avail)) == NULL)
47
+           goto done;
48
+       if (!spa_pod_is_sequence(pod))
49
+           goto done;
50
+
51
+       /* the ringbuffer contains series of sequences, one for each
52
+        * received packet */
53
+       SPA_POD_SEQUENCE_FOREACH((struct spa_pod_sequence*)pod, c) {
54
+#if 0
55
+           /* try to render with given delay */
56
+           uint32_t target = c->offset + impl->target_buffer;
57
+           target = (uint64_t)target * rate / impl->rate;
58
+#else
59
+           uint32_t target = timestamp;
60
+#endif
61
+           if (timestamp != 0) {
62
+               /* skip old packets */
63
+               if (target < timestamp)
64
+                   continue;
65
+               /* event for next cycle */
66
+               if (target >= timestamp + duration)
67
+                   goto complete;
68
+           } else {
69
+               timestamp = target;
70
+           }
71
+           spa_pod_builder_control(&b, target - timestamp, SPA_CONTROL_Midi);
72
+           spa_pod_builder_bytes(&b,
73
+                   SPA_POD_BODY(&c->value),
74
+                   SPA_POD_BODY_SIZE(&c->value));
75
+       }
76
+       /* we completed a sequence (one RTP packet), advance ringbuffer
77
+        * and go to the next packet */
78
+       read += SPA_PTRDIFF(c, ptr);
79
+       spa_ringbuffer_read_update(&impl->ring, read);
80
+   }
81
+complete:
82
+   spa_pod_builder_pop(&b, &f0);
83
+
84
+   if (b.state.offset > maxsize) {
85
+       pw_log_warn("overflow buffer %u %u", b.state.offset, maxsize);
86
+       b.state.offset = 0;
87
+   }
88
+   d0.chunk->size = b.state.offset;
89
+   d0.chunk->stride = 1;
90
+   d0.chunk->offset = 0;
91
+done:
92
+   pw_stream_queue_buffer(impl->stream, buf);
93
+}
94
+
95
+static int parse_varlen(uint8_t *p, uint32_t avail, uint32_t *result)
96
+{
97
+   uint32_t value = 0, offs = 0;
98
+   while (offs < avail) {
99
+       uint8_t b = poffs++;
100
+       value = (value << 7) | (b & 0x7f);
101
+       if ((b & 0x80) == 0)
102
+           break;
103
+   }
104
+   *result = value;
105
+   return offs;
106
+}
107
+
108
+static int get_midi_size(uint8_t *p, uint32_t avail)
109
+{
110
+   int size;
111
+   uint32_t offs = 0, value;
112
+
113
+   switch (poffs++) {
114
+   case 0xc0 ... 0xdf:
115
+       size = 2;
116
+       break;
117
+   case 0x80 ... 0xbf:
118
+   case 0xe0 ... 0xef:
119
+       size = 3;
120
+       break;
121
+   case 0xff:
122
+   case 0xf0:
123
+   case 0xf7:
124
+       size = parse_varlen(&poffs, avail - offs, &value);
125
+       size += value + 1;
126
+       break;
127
+   default:
128
+       return -EINVAL;
129
+   }
130
+   return size;
131
+}
132
+
133
+static int vban_midi_receive_midi(struct impl *impl, uint8_t *packet,
134
+       uint32_t payload_offset, uint32_t plen)
135
+{
136
+   uint32_t write;
137
+   int32_t filled;
138
+   struct spa_pod_builder b;
139
+   struct spa_pod_frame f1;
140
+   void *ptr;
141
+   uint32_t offs = payload_offset;
142
+   uint32_t timestamp = 0;
143
+
144
+   /* no sync, resync */
145
+   if (!impl->have_sync) {
146
+       pw_log_info("sync to timestamp:%u", timestamp);
147
+       impl->have_sync = true;
148
+       impl->ring.readindex = impl->ring.writeindex;
149
+   }
150
+
151
+   filled = spa_ringbuffer_get_write_index(&impl->ring, &write);
152
+   if (filled > (int32_t)BUFFER_SIZE2) {
153
+       pw_log_warn("overflow");
154
+       return -ENOSPC;
155
+   }
156
+
157
+   ptr = SPA_PTROFF(impl->buffer, write & BUFFER_MASK2, void);
158
+
159
+   /* each packet is written as a sequence of events. The offset is
160
+    * the receive timestamp */
161
+   spa_pod_builder_init(&b, ptr, BUFFER_SIZE2 - filled);
162
+   spa_pod_builder_push_sequence(&b, &f0, 0);
163
+
164
+   while (offs < plen) {
165
+       int size;
166
+
167
+       spa_pod_builder_control(&b, timestamp, SPA_CONTROL_Midi);
168
+
169
+       size = get_midi_size(&packetoffs, plen - offs);
170
+
171
+       if (size <= 0 || offs + size > plen) {
172
+           pw_log_warn("invalid size (%08x) %d (%u %u)",
173
+                   packetoffs, size, offs, plen);
174
+           break;
175
+       }
176
+
177
+       spa_pod_builder_bytes(&b, &packetoffs, size);
178
+
179
+       offs += size;
180
+   }
181
+   spa_pod_builder_pop(&b, &f0);
182
+
183
+   write += b.state.offset;
184
+   spa_ringbuffer_write_update(&impl->ring, write);
185
+
186
+   return 0;
187
+}
188
+
189
+static int vban_midi_receive(struct impl *impl, uint8_t *buffer, ssize_t len)
190
+{
191
+   struct vban_header *hdr;
192
+   ssize_t hlen;
193
+   uint32_t n_frames;
194
+
195
+   if (len < VBAN_HEADER_SIZE)
196
+       goto short_packet;
197
+
198
+   hdr = (struct vban_header*)buffer;
199
+   if (strncmp(hdr->vban, "VBAN", 3))
200
+       goto invalid_version;
201
pipewire-0.3.76.tar.gz/src/modules/module-vban/stream.c -> pipewire-0.3.77.tar.gz/src/modules/module-vban/stream.c Changed
71
 
1
@@ -81,7 +81,7 @@
2
 };
3
 
4
 #include "module-vban/audio.c"
5
-//#include "module-vban/midi.c"
6
+#include "module-vban/midi.c"
7
 
8
 struct format_info {
9
    uint32_t media_subtype;
10
@@ -97,7 +97,7 @@
11
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_S32_LE, 4, VBAN_DATATYPE_INT32, },
12
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_F32_LE, 4, VBAN_DATATYPE_FLOAT32, },
13
    { SPA_MEDIA_SUBTYPE_raw, SPA_AUDIO_FORMAT_F64_LE, 8, VBAN_DATATYPE_FLOAT64, },
14
-   { SPA_MEDIA_SUBTYPE_control, 0, 1, },
15
+   { SPA_MEDIA_SUBTYPE_control, 0, 1, VBAN_SERIAL_MIDI | VBAN_DATATYPE_U8, },
16
 };
17
 
18
 static void stream_io_changed(void *data, uint32_t id, void *area, uint32_t size)
19
@@ -289,9 +289,6 @@
20
        goto out;
21
    }
22
    memcpy(impl->header.vban, "VBAN", 4);
23
-   if ((str = pw_properties_get(props, "sess.name")) == NULL)
24
-       str = "Stream1";
25
-   strcpy(impl->header.stream_name, str);
26
 
27
    switch (impl->info.media_subtype) {
28
    case SPA_MEDIA_SUBTYPE_raw:
29
@@ -307,6 +304,7 @@
30
        }
31
        impl->stride = impl->format_info->size * impl->stream_info.info.raw.channels;
32
        impl->rate = impl->stream_info.info.raw.rate;
33
+
34
        impl->header.format_SR = vban_sr_index(impl->rate);
35
        if (impl->header.format_SR == VBAN_SR_MAXNUMBER) {
36
            pw_log_error("unsupported audio rate:%u", impl->rate);
37
@@ -314,6 +312,9 @@
38
            goto out;
39
        }
40
        impl->header.format_bit = impl->format_info->format_bit;
41
+       if ((str = pw_properties_get(props, "sess.name")) == NULL)
42
+           str = "Stream1";
43
+       strcpy(impl->header.stream_name, str);
44
        break;
45
    case SPA_MEDIA_SUBTYPE_control:
46
        impl->stream_info = impl->info;
47
@@ -327,6 +328,14 @@
48
        impl->rate = pw_properties_get_uint32(props, "midi.rate", 10000);
49
        if (impl->rate == 0)
50
            impl->rate = 10000;
51
+
52
+       impl->header.format_SR = (0x1 << 5) | 14; /* 115200 */
53
+       impl->header.format_nbs = 0;
54
+       impl->header.format_nbc = 0;
55
+       impl->header.format_bit = impl->format_info->format_bit;
56
+       if ((str = pw_properties_get(props, "sess.name")) == NULL)
57
+           str = "Midi1";
58
+       strcpy(impl->header.stream_name, str);
59
        break;
60
    default:
61
        spa_assert_not_reached();
62
@@ -413,7 +422,7 @@
63
                                 SPA_TYPE_OBJECT_Format, SPA_PARAM_EnumFormat,
64
                                 SPA_FORMAT_mediaType,           SPA_POD_Id(SPA_MEDIA_TYPE_application),
65
                                 SPA_FORMAT_mediaSubtype,        SPA_POD_Id(SPA_MEDIA_SUBTYPE_control));
66
-//     vban_midi_init(impl, direction);
67
+       vban_midi_init(impl, direction);
68
        break;
69
    default:
70
        res = -EINVAL;
71
pipewire-0.3.76.tar.gz/src/modules/module-vban/vban.h -> pipewire-0.3.77.tar.gz/src/modules/module-vban/vban.h Changed
12
 
1
@@ -53,6 +53,10 @@
2
 #define VBAN_DATATYPE_12BITS   0x06
3
 #define VBAN_DATATYPE_10BITS   0x07
4
 
5
+#define VBAN_SERIAL_GENERIC    0x00
6
+#define VBAN_SERIAL_MIDI   0x10
7
+#define VBAN_SERIAL_USER   0xf0
8
+
9
 #ifdef __cplusplus
10
 }
11
 #endif
12
pipewire-0.3.76.tar.gz/src/modules/module-x11-bell.c -> pipewire-0.3.77.tar.gz/src/modules/module-x11-bell.c Changed
28
 
1
@@ -62,6 +62,10 @@
2
 PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
3
 #define PW_LOG_TOPIC_DEFAULT mod_topic
4
 
5
+/* libcanberra is not thread safe when doing ca_context_create()
6
+ * and so we need a global lock */
7
+static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
8
+
9
 struct impl {
10
    struct pw_context *context;
11
    struct pw_thread_loop *thread_loop;
12
@@ -83,6 +87,7 @@
13
    ca_context *ca;
14
    int res;
15
 
16
+   pthread_mutex_lock(&lock);
17
    if (impl->properties)
18
        sample = pw_properties_get(impl->properties, "sample.name");
19
    if (sample == NULL)
20
@@ -113,6 +118,7 @@
21
 exit_destroy:
22
    ca_context_destroy(ca);
23
 exit:
24
+   pthread_mutex_unlock(&lock);
25
    return res;
26
 }
27
 
28
pipewire-0.3.76.tar.gz/src/pipewire/client.h -> pipewire-0.3.77.tar.gz/src/pipewire/client.h Changed
45
 
1
@@ -25,6 +25,8 @@
2
  */
3
 #define PW_TYPE_INTERFACE_Client   PW_TYPE_INFO_INTERFACE_BASE "Client"
4
 
5
+#define PW_CLIENT_PERM_MASK        PW_PERM_RWXM
6
+
7
 #define PW_VERSION_CLIENT      3
8
 struct pw_client;
9
 
10
@@ -105,12 +107,16 @@
11
     * \param id the global id to report the error on
12
     * \param res an errno style error code
13
     * \param message an error string
14
+    *
15
+    * This requires W and X permissions on the client.
16
     */
17
    int (*error) (void *object, uint32_t id, int res, const char *message);
18
    /**
19
     * Update client properties
20
     *
21
     * \param props new properties
22
+    *
23
+    * This requires W and X permissions on the client.
24
     */
25
    int (*update_properties) (void *object, const struct spa_dict *props);
26
 
27
@@ -121,6 +127,8 @@
28
     *
29
     * \param index the first index to query, 0 for first
30
     * \param num the maximum number of items to get
31
+    *
32
+    * This requires W and X permissions on the client.
33
     */
34
    int (*get_permissions) (void *object, uint32_t index, uint32_t num);
35
    /**
36
@@ -135,6 +143,8 @@
37
     *
38
     * \param n_permissions number of permissions
39
     * \param permissions array of permissions
40
+    *
41
+    * This requires W and X permissions on the client.
42
     */
43
    int (*update_permissions) (void *object, uint32_t n_permissions,
44
            const struct pw_permission *permissions);
45
pipewire-0.3.76.tar.gz/src/pipewire/conf.c -> pipewire-0.3.77.tar.gz/src/pipewire/conf.c Changed
38
 
1
@@ -984,6 +984,11 @@
2
    return res == 0 ? data.count : res;
3
 }
4
 
5
+static bool valid_conf_name(const char *str)
6
+{
7
+   return spa_streq(str, "null") || spa_strendswith(str, ".conf");
8
+}
9
+
10
 static int try_load_conf(const char *conf_prefix, const char *conf_name,
11
             struct pw_properties *conf)
12
 {
13
@@ -1018,6 +1023,11 @@
14
        conf_name = pw_properties_get(props, PW_KEY_CONFIG_NAME);
15
        if (conf_name == NULL)
16
            conf_name = "client.conf";
17
+       else if (!valid_conf_name(conf_name)) {
18
+           pw_log_error("%s '%s' does not end with .conf",
19
+               PW_KEY_CONFIG_NAME, conf_name);
20
+           return -EINVAL;
21
+       }
22
        if ((res = try_load_conf(conf_prefix, conf_name, conf)) < 0) {
23
            pw_log_error("can't load config %s: %s",
24
                conf_name, spa_strerror(res));
25
@@ -1030,6 +1040,12 @@
26
        struct pw_properties *override;
27
        const char *path, *name;
28
 
29
+       if (!valid_conf_name(conf_name)) {
30
+           pw_log_error("%s '%s' does not end with .conf",
31
+               PW_KEY_CONFIG_OVERRIDE_NAME, conf_name);
32
+           return -EINVAL;
33
+       }
34
+
35
        override = pw_properties_new(NULL, NULL);
36
        if (override == NULL) {
37
            res = -errno;
38
pipewire-0.3.76.tar.gz/src/pipewire/core.h -> pipewire-0.3.77.tar.gz/src/pipewire/core.h Changed
87
 
1
@@ -34,6 +34,8 @@
2
 #define PW_TYPE_INTERFACE_Core     PW_TYPE_INFO_INTERFACE_BASE "Core"
3
 #define PW_TYPE_INTERFACE_Registry PW_TYPE_INFO_INTERFACE_BASE "Registry"
4
 
5
+#define PW_CORE_PERM_MASK      PW_PERM_R|PW_PERM_X|PW_PERM_M
6
+
7
 #define PW_VERSION_CORE        4
8
 struct pw_core;
9
 #define PW_VERSION_REGISTRY    3
10
@@ -223,6 +225,8 @@
11
     * Start a conversation with the server. This will send
12
     * the core info and will destroy all resources for the client
13
     * (except the core and client resource).
14
+    *
15
+    * This requires X permissions on the core.
16
     */
17
    int (*hello) (void *object, uint32_t version);
18
    /**
19
@@ -235,6 +239,8 @@
20
     * methods and the resulting events have been handled.
21
     *
22
     * \param seq the seq number passed to the done event
23
+    *
24
+    * This requires X permissions on the core.
25
     */
26
    int (*sync) (void *object, uint32_t id, int seq);
27
    /**
28
@@ -243,6 +249,8 @@
29
     * Reply to the server ping event with the same seq.
30
     *
31
     * \param seq the seq number received in the ping event
32
+    *
33
+    * This requires X permissions on the core.
34
     */
35
    int (*pong) (void *object, uint32_t id, int seq);
36
    /**
37
@@ -257,9 +265,11 @@
38
     * This method is usually also emitted on the resource object with
39
     * \a id.
40
     *
41
-         * \param id object where the error occurred
42
+         * \param id resource id where the error occurred
43
          * \param res error code
44
          * \param message error description
45
+    *
46
+    * This requires X permissions on the core.
47
     */
48
    int (*error) (void *object, uint32_t id, int seq, int res, const char *message);
49
    /**
50
@@ -269,6 +279,8 @@
51
     * the global objects available from the PipeWire server
52
     * \param version the client version
53
     * \param user_data_size extra size
54
+    *
55
+    * This requires X permissions on the core.
56
     */
57
    struct pw_registry * (*get_registry) (void *object, uint32_t version,
58
            size_t user_data_size);
59
@@ -281,6 +293,8 @@
60
     * \param version the version of the interface
61
     * \param props extra properties
62
     * \param user_data_size extra size
63
+    *
64
+    * This requires X permissions on the core.
65
     */
66
    void * (*create_object) (void *object,
67
                   const char *factory_name,
68
@@ -294,6 +308,8 @@
69
     * Destroy the server resource for the given proxy.
70
     *
71
     * \param obj the proxy to destroy
72
+    *
73
+    * This requires X permissions on the core.
74
     */
75
    int (*destroy) (void *object, void *proxy);
76
 };
77
@@ -474,7 +490,8 @@
78
     *
79
     * Try to destroy the global object.
80
     *
81
-    * \param id the global id to destroy
82
+    * \param id the global id to destroy. The client needs X permissions
83
+    * on the global.
84
     */
85
    int (*destroy) (void *object, uint32_t id);
86
 };
87
pipewire-0.3.76.tar.gz/src/pipewire/device.h -> pipewire-0.3.77.tar.gz/src/pipewire/device.h Changed
37
 
1
@@ -25,6 +25,8 @@
2
 
3
 #define PW_TYPE_INTERFACE_Device   PW_TYPE_INFO_INTERFACE_BASE "Device"
4
 
5
+#define PW_DEVICE_PERM_MASK        PW_PERM_RWXM
6
+
7
 #define PW_VERSION_DEVICE      3
8
 struct pw_device;
9
 
10
@@ -105,6 +107,8 @@
11
     *
12
     * \param ids an array of param ids
13
     * \param n_ids the number of ids in \a ids
14
+    *
15
+    * This requires X permissions on the device.
16
     */
17
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
18
 
19
@@ -119,6 +123,8 @@
20
     * \param start the start index or 0 for the first param
21
     * \param num the maximum number of params to retrieve
22
     * \param filter a param filter or NULL
23
+    *
24
+    * This requires X permissions on the device.
25
     */
26
    int (*enum_params) (void *object, int seq, uint32_t id, uint32_t start, uint32_t num,
27
                const struct spa_pod *filter);
28
@@ -128,6 +134,8 @@
29
     * \param id the parameter id to set
30
     * \param flags extra parameter flags
31
     * \param param the parameter to set
32
+    *
33
+    * This requires W and X permissions on the device.
34
     */
35
    int (*set_param) (void *object, uint32_t id, uint32_t flags,
36
              const struct spa_pod *param);
37
pipewire-0.3.76.tar.gz/src/pipewire/extensions/metadata.h -> pipewire-0.3.77.tar.gz/src/pipewire/extensions/metadata.h Changed
52
 
1
@@ -21,6 +21,8 @@
2
  */
3
 #define PW_TYPE_INTERFACE_Metadata     PW_TYPE_INFO_INTERFACE_BASE "Metadata"
4
 
5
+#define PW_METADATA_PERM_MASK          PW_PERM_RWX
6
+
7
 #define PW_VERSION_METADATA            3
8
 struct pw_metadata;
9
 
10
@@ -29,6 +31,7 @@
11
 #define PW_METADATA_EVENT_PROPERTY     0
12
 #define PW_METADATA_EVENT_NUM          1
13
 
14
+
15
 /** \ref pw_metadata events */
16
 struct pw_metadata_events {
17
 #define PW_VERSION_METADATA_EVENTS     0
18
@@ -56,12 +59,33 @@
19
            const struct pw_metadata_events *events,
20
            void *data);
21
 
22
+   /**
23
+    * Set a metadata property
24
+    *
25
+    * Automatically emit property events for the subject and key
26
+    * when they are changed.
27
+    *
28
+    * \param subject the id of the global to associate the metadata
29
+    *                with.
30
+    * \param key the key of the metadata, NULL clears all metadata for
31
+    *                the subject.
32
+    * \param type the type of the metadata, this can be blank
33
+    * \param value the metadata value. NULL clears the metadata.
34
+    *
35
+    * This requires X and W permissions on the metadata. It also
36
+    * requires M permissions on the subject global.
37
+    */
38
    int (*set_property) (void *object,
39
            uint32_t subject,
40
            const char *key,
41
            const char *type,
42
            const char *value);
43
 
44
+   /**
45
+    * Clear all metadata
46
+    *
47
+    * This requires X and W permissions on the metadata.
48
+    */
49
    int (*clear) (void *object);
50
 };
51
 
52
pipewire-0.3.76.tar.gz/src/pipewire/extensions/profiler.h -> pipewire-0.3.77.tar.gz/src/pipewire/extensions/profiler.h Changed
10
 
1
@@ -26,6 +26,8 @@
2
 
3
 #define PW_EXTENSION_MODULE_PROFILER       PIPEWIRE_MODULE_PREFIX "module-profiler"
4
 
5
+#define PW_PROFILER_PERM_MASK          PW_PERM_R
6
+
7
 #define PW_PROFILER_EVENT_PROFILE      0
8
 #define PW_PROFILER_EVENT_NUM          1
9
 
10
pipewire-0.3.76.tar.gz/src/pipewire/extensions/session-manager/interfaces.h -> pipewire-0.3.77.tar.gz/src/pipewire/extensions/session-manager/interfaces.h Changed
150
 
1
@@ -21,18 +21,22 @@
2
  */
3
 
4
 #define PW_TYPE_INTERFACE_Session      PW_TYPE_INFO_INTERFACE_BASE "Session"
5
+#define PW_SESSION_PERM_MASK           PW_PERM_RWX
6
 #define PW_VERSION_SESSION         0
7
 struct pw_session;
8
 
9
 #define PW_TYPE_INTERFACE_Endpoint     PW_TYPE_INFO_INTERFACE_BASE "Endpoint"
10
+#define PW_ENDPOINT_PERM_MASK          PW_PERM_RWX
11
 #define PW_VERSION_ENDPOINT            0
12
 struct pw_endpoint;
13
 
14
 #define PW_TYPE_INTERFACE_EndpointStream   PW_TYPE_INFO_INTERFACE_BASE "EndpointStream"
15
+#define PW_ENDPOINT_STREAM_PERM_MASK       PW_PERM_RWX
16
 #define PW_VERSION_ENDPOINT_STREAM     0
17
 struct pw_endpoint_stream;
18
 
19
 #define PW_TYPE_INTERFACE_EndpointLink     PW_TYPE_INFO_INTERFACE_BASE "EndpointLink"
20
+#define PW_ENDPOINT_LINK_PERM_MASK     PW_PERM_RWX
21
 #define PW_VERSION_ENDPOINT_LINK       0
22
 struct pw_endpoint_link;
23
 
24
@@ -93,6 +97,8 @@
25
     *
26
     * \param ids an array of param ids
27
     * \param n_ids the number of ids in \a ids
28
+    *
29
+    * This requires X permissions.
30
     */
31
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
32
 
33
@@ -107,6 +113,8 @@
34
     * \param start the start index or 0 for the first param
35
     * \param num the maximum number of params to retrieve
36
     * \param filter a param filter or NULL
37
+    *
38
+    * This requires X permissions.
39
     */
40
    int (*enum_params) (void *object, int seq,
41
            uint32_t id, uint32_t start, uint32_t num,
42
@@ -118,6 +126,8 @@
43
     * \param id the parameter id to set
44
     * \param flags extra parameter flags
45
     * \param param the parameter to set
46
+    *
47
+    * This requires X and W permissions.
48
     */
49
    int (*set_param) (void *object, uint32_t id, uint32_t flags,
50
              const struct spa_pod *param);
51
@@ -195,6 +205,8 @@
52
     *
53
     * \param ids an array of param ids
54
     * \param n_ids the number of ids in \a ids
55
+    *
56
+    * This requires X permissions.
57
     */
58
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
59
 
60
@@ -209,6 +221,8 @@
61
     * \param start the start index or 0 for the first param
62
     * \param num the maximum number of params to retrieve
63
     * \param filter a param filter or NULL
64
+    *
65
+    * This requires X permissions.
66
     */
67
    int (*enum_params) (void *object, int seq,
68
            uint32_t id, uint32_t start, uint32_t num,
69
@@ -220,10 +234,17 @@
70
     * \param id the parameter id to set
71
     * \param flags extra parameter flags
72
     * \param param the parameter to set
73
+    *
74
+    * This requires X and W permissions.
75
     */
76
    int (*set_param) (void *object, uint32_t id, uint32_t flags,
77
              const struct spa_pod *param);
78
 
79
+   /**
80
+    * Create a link
81
+    *
82
+    * This requires X permissions.
83
+    */
84
    int (*create_link) (void *object, const struct spa_dict *props);
85
 };
86
 
87
@@ -298,6 +319,8 @@
88
     *
89
     * \param ids an array of param ids
90
     * \param n_ids the number of ids in \a ids
91
+    *
92
+    * This requires X permissions.
93
     */
94
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
95
 
96
@@ -312,6 +335,8 @@
97
     * \param start the start index or 0 for the first param
98
     * \param num the maximum number of params to retrieve
99
     * \param filter a param filter or NULL
100
+    *
101
+    * This requires X permissions.
102
     */
103
    int (*enum_params) (void *object, int seq,
104
            uint32_t id, uint32_t start, uint32_t num,
105
@@ -323,6 +348,8 @@
106
     * \param id the parameter id to set
107
     * \param flags extra parameter flags
108
     * \param param the parameter to set
109
+    *
110
+    * This requires X and W permissions.
111
     */
112
    int (*set_param) (void *object, uint32_t id, uint32_t flags,
113
              const struct spa_pod *param);
114
@@ -400,6 +427,8 @@
115
     *
116
     * \param ids an array of param ids
117
     * \param n_ids the number of ids in \a ids
118
+    *
119
+    * This requires X permissions.
120
     */
121
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
122
 
123
@@ -414,6 +443,8 @@
124
     * \param start the start index or 0 for the first param
125
     * \param num the maximum number of params to retrieve
126
     * \param filter a param filter or NULL
127
+    *
128
+    * This requires X permissions.
129
     */
130
    int (*enum_params) (void *object, int seq,
131
            uint32_t id, uint32_t start, uint32_t num,
132
@@ -425,10 +456,17 @@
133
     * \param id the parameter id to set
134
     * \param flags extra parameter flags
135
     * \param param the parameter to set
136
+    *
137
+    * This requires X and W permissions.
138
     */
139
    int (*set_param) (void *object, uint32_t id, uint32_t flags,
140
              const struct spa_pod *param);
141
 
142
+   /**
143
+    * Request a state on the link.
144
+    *
145
+    * This requires X and W permissions.
146
+    */
147
    int (*request_state) (void *object, enum pw_endpoint_link_state state);
148
 };
149
 
150
pipewire-0.3.76.tar.gz/src/pipewire/factory.h -> pipewire-0.3.77.tar.gz/src/pipewire/factory.h Changed
10
 
1
@@ -27,6 +27,8 @@
2
  */
3
 #define PW_TYPE_INTERFACE_Factory  PW_TYPE_INFO_INTERFACE_BASE "Factory"
4
 
5
+#define PW_FACTORY_PERM_MASK       PW_PERM_R|PW_PERM_M
6
+
7
 #define PW_VERSION_FACTORY     3
8
 struct pw_factory;
9
 
10
pipewire-0.3.76.tar.gz/src/pipewire/global.c -> pipewire-0.3.77.tar.gz/src/pipewire/global.c Changed
32
 
1
@@ -25,10 +25,10 @@
2
 SPA_EXPORT
3
 uint32_t pw_global_get_permissions(struct pw_global *global, struct pw_impl_client *client)
4
 {
5
-   if (client->permission_func == NULL)
6
-       return PW_PERM_ALL;
7
-
8
-   return client->permission_func(global, client, client->permission_data);
9
+   uint32_t permissions = global->permission_mask;
10
+   if (client->permission_func != NULL)
11
+       permissions &= client->permission_func(global, client, client->permission_data);
12
+   return permissions;
13
 }
14
 
15
 /** Create a new global
16
@@ -47,6 +47,7 @@
17
 pw_global_new(struct pw_context *context,
18
          const char *type,
19
          uint32_t version,
20
+         uint32_t permission_mask,
21
          struct pw_properties *properties,
22
          pw_global_bind_func_t func,
23
          void *object)
24
@@ -71,6 +72,7 @@
25
    this->context = context;
26
    this->type = type;
27
    this->version = version;
28
+   this->permission_mask = permission_mask;
29
    this->func = func;
30
    this->object = object;
31
    this->properties = properties;
32
pipewire-0.3.76.tar.gz/src/pipewire/global.h -> pipewire-0.3.77.tar.gz/src/pipewire/global.h Changed
9
 
1
@@ -65,6 +65,7 @@
2
 pw_global_new(struct pw_context *context,  /**< the context */
3
          const char *type,         /**< the interface type of the global */
4
          uint32_t version,         /**< the interface version of the global */
5
+         uint32_t permission_mask,     /**< mask of valid permissions */
6
          struct pw_properties *properties, /**< extra properties */
7
          pw_global_bind_func_t func,   /**< function to bind */
8
          void *object          /**< global object */);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-client.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-client.c Changed
9
 
1
@@ -514,6 +514,7 @@
2
    client->global = pw_global_new(context,
3
                       PW_TYPE_INTERFACE_Client,
4
                       PW_VERSION_CLIENT,
5
+                      PW_CLIENT_PERM_MASK,
6
                       properties,
7
                       global_bind,
8
                       client);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-core.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-core.c Changed
9
 
1
@@ -588,6 +588,7 @@
2
         core->global = pw_global_new(context,
3
                    PW_TYPE_INTERFACE_Core,
4
                    PW_VERSION_CORE,
5
+                   PW_CORE_PERM_MASK,
6
                    properties,
7
                    global_bind,
8
                    core);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-device.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-device.c Changed
9
 
1
@@ -560,6 +560,7 @@
2
         device->global = pw_global_new(context,
3
                       PW_TYPE_INTERFACE_Device,
4
                       PW_VERSION_DEVICE,
5
+                      PW_DEVICE_PERM_MASK,
6
                       properties,
7
                       global_bind,
8
                       device);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-factory.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-factory.c Changed
9
 
1
@@ -174,6 +174,7 @@
2
         factory->global = pw_global_new(context,
3
                    PW_TYPE_INTERFACE_Factory,
4
                    PW_VERSION_FACTORY,
5
+                   PW_FACTORY_PERM_MASK,
6
                    properties,
7
                    global_bind,
8
                    factory);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-link.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-link.c Changed
73
 
1
@@ -1131,7 +1131,7 @@
2
 }
3
 
4
 static int check_owner_permissions(struct pw_context *context,
5
-       struct pw_impl_node *node, uint32_t id, uint32_t permissions)
6
+       struct pw_impl_node *node, struct pw_global *other, uint32_t permissions)
7
 {
8
    const char *str;
9
    struct pw_impl_client *client;
10
@@ -1155,11 +1155,7 @@
11
        /* not the right object, something wrong */
12
        return -EIO;
13
 
14
-   if ((global = pw_context_find_global(context, id)) == NULL)
15
-       /* current client can't see node id */
16
-       return -errno;
17
-
18
-   perms = pw_global_get_permissions(global, client);
19
+   perms = pw_global_get_permissions(other, client);
20
    if ((perms & permissions) != permissions)
21
        /* owner client can't see other node */
22
        return -EPERM;
23
@@ -1174,12 +1170,37 @@
24
         struct pw_properties *properties)
25
 {
26
    int res;
27
+   uint32_t in_perms, out_perms;
28
+   struct pw_global *in_global, *out_global;
29
+
30
+   if ((in_global = input->node->global) == NULL)
31
+       return -ENOENT;
32
+   if ((out_global = output->node->global) == NULL)
33
+       return -ENOENT;
34
+
35
+   in_perms = out_perms = PW_PERM_R | PW_PERM_L;
36
+   if (context->current_client != NULL) {
37
+       in_perms = pw_global_get_permissions(in_global, context->current_client);
38
+       out_perms = pw_global_get_permissions(out_global, context->current_client);
39
+   }
40
+   /* current client can't see input node or output node */
41
+   if (!PW_PERM_IS_R(in_perms) || !PW_PERM_IS_R(out_perms))
42
+       return -ENOENT;
43
+
44
    if ((res = check_owner_permissions(context, output->node,
45
-                   input->node->info.id, PW_PERM_R)) < 0)
46
-       return res;
47
+                   in_global, PW_PERM_R)) < 0) {
48
+       /* output node owner can't see input node, check if the current
49
+        * client has universal link permissions for the output node */
50
+       if (!PW_PERM_IS_L(out_perms))
51
+           return res;
52
+   }
53
    if ((res = check_owner_permissions(context, input->node,
54
-                   output->node->info.id, PW_PERM_R)) < 0)
55
-       return res;
56
+                   out_global, PW_PERM_R)) < 0) {
57
+       /* input node owner can't see output node, check if the current
58
+        * client has universal link permissions for the input node */
59
+       if (!PW_PERM_IS_L(in_perms))
60
+           return res;
61
+   }
62
    return 0;
63
 }
64
 
65
@@ -1462,6 +1483,7 @@
66
    link->global = pw_global_new(context,
67
                     PW_TYPE_INTERFACE_Link,
68
                     PW_VERSION_LINK,
69
+                    PW_LINK_PERM_MASK,
70
                     properties,
71
                     global_bind,
72
                     link);
73
pipewire-0.3.76.tar.gz/src/pipewire/impl-metadata.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-metadata.c Changed
9
 
1
@@ -519,6 +519,7 @@
2
         metadata->global = pw_global_new(context,
3
                    PW_TYPE_INTERFACE_Metadata,
4
                    PW_VERSION_METADATA,
5
+                   PW_METADATA_PERM_MASK,
6
                    properties,
7
                    global_bind,
8
                    metadata);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-module.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-module.c Changed
9
 
1
@@ -222,6 +222,7 @@
2
    this->global = pw_global_new(context,
3
                     PW_TYPE_INTERFACE_Module,
4
                     PW_VERSION_MODULE,
5
+                    PW_MODULE_PERM_MASK,
6
                     NULL,
7
                     global_bind,
8
                     this);
9
pipewire-0.3.76.tar.gz/src/pipewire/impl-node.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-node.c Changed
17
 
1
@@ -747,6 +747,7 @@
2
        PW_KEY_MODULE_ID,
3
        PW_KEY_FACTORY_ID,
4
        PW_KEY_CLIENT_ID,
5
+       PW_KEY_CLIENT_API,
6
        PW_KEY_DEVICE_ID,
7
        PW_KEY_PRIORITY_SESSION,
8
        PW_KEY_PRIORITY_DRIVER,
9
@@ -773,6 +774,7 @@
10
    this->global = pw_global_new(context,
11
                     PW_TYPE_INTERFACE_Node,
12
                     PW_VERSION_NODE,
13
+                    PW_NODE_PERM_MASK,
14
                     properties,
15
                     global_bind,
16
                     this);
17
pipewire-0.3.76.tar.gz/src/pipewire/impl-port.c -> pipewire-0.3.77.tar.gz/src/pipewire/impl-port.c Changed
9
 
1
@@ -1000,6 +1000,7 @@
2
    port->global = pw_global_new(node->context,
3
                PW_TYPE_INTERFACE_Port,
4
                PW_VERSION_PORT,
5
+               PW_PORT_PERM_MASK,
6
                properties,
7
                global_bind,
8
                port);
9
pipewire-0.3.76.tar.gz/src/pipewire/link.h -> pipewire-0.3.77.tar.gz/src/pipewire/link.h Changed
10
 
1
@@ -31,6 +31,8 @@
2
 
3
 #define PW_TYPE_INTERFACE_Link PW_TYPE_INFO_INTERFACE_BASE "Link"
4
 
5
+#define PW_LINK_PERM_MASK  PW_PERM_R | PW_PERM_X
6
+
7
 #define PW_VERSION_LINK        3
8
 struct pw_link;
9
 
10
pipewire-0.3.76.tar.gz/src/pipewire/module.h -> pipewire-0.3.77.tar.gz/src/pipewire/module.h Changed
10
 
1
@@ -24,6 +24,8 @@
2
  */
3
 #define PW_TYPE_INTERFACE_Module   PW_TYPE_INFO_INTERFACE_BASE "Module"
4
 
5
+#define PW_MODULE_PERM_MASK        PW_PERM_R|PW_PERM_M
6
+
7
 #define PW_VERSION_MODULE      3
8
 struct pw_module;
9
 
10
pipewire-0.3.76.tar.gz/src/pipewire/node.h -> pipewire-0.3.77.tar.gz/src/pipewire/node.h Changed
46
 
1
@@ -29,6 +29,8 @@
2
  */
3
 #define PW_TYPE_INTERFACE_Node PW_TYPE_INFO_INTERFACE_BASE "Node"
4
 
5
+#define PW_NODE_PERM_MASK  PW_PERM_RWXML
6
+
7
 #define PW_VERSION_NODE        3
8
 struct pw_node;
9
 
10
@@ -132,6 +134,8 @@
11
     *
12
     * \param ids an array of param ids
13
     * \param n_ids the number of ids in \a ids
14
+    *
15
+    * This requires X permissions on the node.
16
     */
17
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
18
 
19
@@ -146,6 +150,8 @@
20
     * \param start the start index or 0 for the first param
21
     * \param num the maximum number of params to retrieve
22
     * \param filter a param filter or NULL
23
+    *
24
+    * This requires X permissions on the node.
25
     */
26
    int (*enum_params) (void *object, int seq, uint32_t id,
27
            uint32_t start, uint32_t num,
28
@@ -157,6 +163,8 @@
29
     * \param id the parameter id to set
30
     * \param flags extra parameter flags
31
     * \param param the parameter to set
32
+    *
33
+    * This requires X and W permissions on the node.
34
     */
35
    int (*set_param) (void *object, uint32_t id, uint32_t flags,
36
            const struct spa_pod *param);
37
@@ -165,6 +173,8 @@
38
     * Send a command to the node
39
     *
40
     * \param command the command to send
41
+    *
42
+    * This requires X and W permissions on the node.
43
     */
44
    int (*send_command) (void *object, const struct spa_command *command);
45
 };
46
pipewire-0.3.76.tar.gz/src/pipewire/permission.h -> pipewire-0.3.77.tar.gz/src/pipewire/permission.h Changed
38
 
1
@@ -29,14 +29,19 @@
2
 #define PW_PERM_X  0100    /**< methods can be called on the object. The W flag must be
3
                  *  present in order to call methods that modify the object. */
4
 #define PW_PERM_M  0010    /**< metadata can be set on object, Since 0.3.9 */
5
+#define PW_PERM_L  0020    /**< a link can be made between a node that doesn't have
6
+                 *  permission to see the other node, Since 0.3.77 */
7
 
8
-#define PW_PERM_RWX    (PW_PERM_R|PW_PERM_W|PW_PERM_X)
9
+#define PW_PERM_RW (PW_PERM_R|PW_PERM_W)
10
+#define PW_PERM_RWX    (PW_PERM_RW|PW_PERM_X)
11
 #define PW_PERM_RWXM   (PW_PERM_RWX|PW_PERM_M)
12
+#define PW_PERM_RWXML  (PW_PERM_RWXM|PW_PERM_L)
13
 
14
 #define PW_PERM_IS_R(p) (((p)&PW_PERM_R) == PW_PERM_R)
15
 #define PW_PERM_IS_W(p) (((p)&PW_PERM_W) == PW_PERM_W)
16
 #define PW_PERM_IS_X(p) (((p)&PW_PERM_X) == PW_PERM_X)
17
 #define PW_PERM_IS_M(p) (((p)&PW_PERM_M) == PW_PERM_M)
18
+#define PW_PERM_IS_L(p) (((p)&PW_PERM_L) == PW_PERM_L)
19
 
20
 #define PW_PERM_ALL    PW_PERM_RWXM
21
 #define PW_PERM_INVALID    (uint32_t)(0xffffffff)
22
@@ -48,12 +53,13 @@
23
 
24
 #define PW_PERMISSION_INIT(id,p) ((struct pw_permission){ (id), (p) })
25
 
26
-#define PW_PERMISSION_FORMAT "%c%c%c%c"
27
+#define PW_PERMISSION_FORMAT "%c%c%c%c%c"
28
 #define PW_PERMISSION_ARGS(permission)     \
29
    (permission) & PW_PERM_R ? 'r' : '-',   \
30
    (permission) & PW_PERM_W ? 'w' : '-',   \
31
    (permission) & PW_PERM_X ? 'x' : '-',   \
32
-   (permission) & PW_PERM_M ? 'm' : '-'
33
+   (permission) & PW_PERM_M ? 'm' : '-',   \
34
+   (permission) & PW_PERM_L ? 'l' : '-'
35
 
36
 /**
37
  * \}
38
pipewire-0.3.76.tar.gz/src/pipewire/port.h -> pipewire-0.3.77.tar.gz/src/pipewire/port.h Changed
28
 
1
@@ -29,6 +29,8 @@
2
 
3
 #define PW_TYPE_INTERFACE_Port PW_TYPE_INFO_INTERFACE_BASE "Port"
4
 
5
+#define PW_PORT_PERM_MASK  PW_PERM_R|PW_PERM_X|PW_PERM_M
6
+
7
 #define PW_VERSION_PORT        3
8
 struct pw_port;
9
 
10
@@ -115,6 +117,8 @@
11
     *
12
     * \param ids an array of param ids
13
     * \param n_ids the number of ids in \a ids
14
+    *
15
+    * This requires X permissions on the port.
16
     */
17
    int (*subscribe_params) (void *object, uint32_t *ids, uint32_t n_ids);
18
 
19
@@ -129,6 +133,8 @@
20
     * \param start the start index or 0 for the first param
21
     * \param num the maximum number of params to retrieve
22
     * \param filter a param filter or NULL
23
+    *
24
+    * This requires X permissions on the port.
25
     */
26
    int (*enum_params) (void *object, int seq,
27
            uint32_t id, uint32_t start, uint32_t num,
28
pipewire-0.3.76.tar.gz/src/pipewire/private.h -> pipewire-0.3.77.tar.gz/src/pipewire/private.h Changed
9
 
1
@@ -288,6 +288,7 @@
2
 
3
    const char *type;       /**< type of interface */
4
    uint32_t version;       /**< version of interface */
5
+   uint32_t permission_mask;   /**< possible permissions */
6
 
7
    pw_global_bind_func_t func; /**< bind function */
8
    void *object;           /**< object associated with the interface */
9
pipewire-0.3.76.tar.gz/src/tools/pw-dump.c -> pipewire-0.3.77.tar.gz/src/tools/pw-dump.c Changed
9
 
1
@@ -1427,6 +1427,7 @@
2
        { "w", PW_PERM_W },
3
        { "x", PW_PERM_X },
4
        { "m", PW_PERM_M },
5
+       { "l", PW_PERM_L },
6
        { NULL, },
7
    };
8
 
9