Overview

Request 5815 (accepted)

New upstream release

Submit package home:zaitor:...s:Essentials / pipewire-aptx to package Essentials / pipewire-aptx

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
510
 
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
 
202
    if ((r = dbus_message_new_method_return(m)) == NULL)
203
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
204
 
205
 fail:
206
    if (r) {
207
-       DBusHandlerResult res = DBUS_HANDLER_RESULT_HANDLED;
208
        if (!dbus_connection_send(backend->conn, r, NULL))
209
-           res = DBUS_HANDLER_RESULT_NEED_MEMORY;
210
-       dbus_message_unref(r);
211
-       return res;
212
+           return DBUS_HANDLER_RESULT_NEED_MEMORY;
213
    }
214
 
215
    return DBUS_HANDLER_RESULT_HANDLED;
216
@@ -728,7 +703,6 @@
217
 {
218
    struct impl *backend = userdata;
219
    const char *path, *interface, *member;
220
-   DBusMessage *r;
221
    DBusHandlerResult res;
222
 
223
    path = dbus_message_get_path(m);
224
@@ -739,6 +713,7 @@
225
 
226
    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
227
        const char *xml = AUDIO_AGENT_ENDPOINT_INTROSPECT_XML;
228
+       spa_autoptr(DBusMessage) r = NULL;
229
 
230
        if ((r = dbus_message_new_method_return(m)) == NULL)
231
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
232
@@ -747,7 +722,6 @@
233
        if (!dbus_connection_send(backend->conn, r, NULL))
234
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
235
 
236
-       dbus_message_unref(r);
237
        res = DBUS_HANDLER_RESULT_HANDLED;
238
    } else if (dbus_message_is_method_call(m, DBUS_INTERFACE_PROPERTIES, "Get"))
239
        res = audio_agent_get_property(c, m, path, userdata);
240
@@ -793,7 +767,7 @@
241
 {
242
    struct impl *backend = userdata;
243
    const char *path, *interface, *member;
244
-   DBusMessage *r;
245
+   spa_autoptr(DBusMessage) r = NULL;
246
 
247
    path = dbus_message_get_path(m);
248
    interface = dbus_message_get_interface(m);
249
@@ -827,27 +801,23 @@
250
 
251
    if (!dbus_connection_send(backend->conn, r, NULL))
252
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
253
-   dbus_message_unref(r);
254
 
255
-  return DBUS_HANDLER_RESULT_HANDLED;
256
+   return DBUS_HANDLER_RESULT_HANDLED;
257
 }
258
 
259
 static void hsphfpd_audio_acquire_reply(DBusPendingCall *pending, void *user_data)
260
 {
261
    struct spa_bt_transport *transport = user_data;
262
    struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
263
-   DBusMessage *r;
264
    const char *transport_path;
265
    const char *service_id;
266
    const char *agent_path;
267
-   DBusError error;
268
+   spa_auto(DBusError) error = DBUS_ERROR_INIT;
269
    int ret = 0;
270
 
271
-   dbus_error_init(&error);
272
-
273
    backend->acquire_in_progress = false;
274
 
275
-   r = steal_reply_and_unref(&pending);
276
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
277
    if (r == NULL)
278
        return;
279
 
280
@@ -889,8 +859,6 @@
281
    spa_log_debug(backend->log, "hsphfpd audio acquired");
282
 
283
 finish:
284
-   dbus_message_unref(r);
285
-
286
    if (ret < 0)
287
        spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_ERROR);
288
    else
289
@@ -901,10 +869,9 @@
290
 {
291
    struct spa_bt_transport *transport = data;
292
    struct impl *backend = SPA_CONTAINER_OF(transport->backend, struct impl, this);
293
-   DBusMessage *m;
294
+   spa_autoptr(DBusMessage) m = NULL;
295
    const char *air_codec = HSPHFP_AIR_CODEC_CVSD;
296
    const char *agent_codec = HSPHFP_AGENT_CODEC_PCM;
297
-   DBusPendingCall *call;
298
 
299
    spa_log_debug(backend->log, "transport %p: Acquire %s",
300
            transport, transport->path);
301
@@ -925,9 +892,8 @@
302
        return -ENOMEM;
303
    dbus_message_append_args(m, DBUS_TYPE_STRING, &air_codec, DBUS_TYPE_STRING, &agent_codec, DBUS_TYPE_INVALID);
304
 
305
-   dbus_connection_send_with_reply(backend->conn, m, &call, -1);
306
-   dbus_pending_call_set_notify(call, hsphfpd_audio_acquire_reply, transport, NULL);
307
-   dbus_message_unref(m);
308
+   if (!send_with_reply(backend->conn, m, hsphfpd_audio_acquire_reply, transport))
309
+       return -EIO;
310
 
311
    backend->acquire_in_progress = true;
312
 
313
@@ -1176,27 +1142,26 @@
314
 static void hsphfpd_get_endpoints_reply(DBusPendingCall *pending, void *user_data)
315
 {
316
    struct impl *backend = user_data;
317
-   DBusMessage *r;
318
    DBusMessageIter i, array_i;
319
 
320
-   r = steal_reply_and_unref(&pending);
321
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
322
    if (r == NULL)
323
        return;
324
 
325
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
326
        spa_log_error(backend->log, "Failed to get a list of endpoints from hsphfpd: %s",
327
                dbus_message_get_error_name(r));
328
-       goto finish;
329
+       return;
330
    }
331
 
332
    if (!spa_streq(dbus_message_get_sender(r), backend->hsphfpd_service_id)) {
333
        spa_log_error(backend->log, "Reply for GetManagedObjects() from invalid sender");
334
-       goto finish;
335
+       return;
336
    }
337
 
338
    if (!dbus_message_iter_init(r, &i) || !check_signature(r, "a{oa{sa{sv}}}")) {
339
        spa_log_error(backend->log, "Invalid arguments in GetManagedObjects() reply");
340
-       goto finish;
341
+       return;
342
    }
343
 
344
    dbus_message_iter_recurse(&i, &array_i);
345
@@ -1209,19 +1174,13 @@
346
    }
347
 
348
    backend->endpoints_listed = true;
349
-
350
-finish:
351
-   dbus_message_unref(r);
352
 }
353
 
354
-static int backend_hsphfpd_register(void *data)
355
+static int hsphfpd_register(struct impl *backend)
356
 {
357
-   struct impl *backend = data;
358
-   DBusMessage *m, *r;
359
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
360
    const char *path = APPLICATION_OBJECT_MANAGER_PATH;
361
-   DBusPendingCall *call;
362
-   DBusError err;
363
-   int res;
364
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
365
 
366
    spa_log_debug(backend->log, "Registering to hsphfpd");
367
 
368
@@ -1232,50 +1191,58 @@
369
 
370
    dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &path, DBUS_TYPE_INVALID);
371
 
372
-   dbus_error_init(&err);
373
-
374
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
375
-   dbus_message_unref(m);
376
-
377
    if (r == NULL) {
378
        if (dbus_error_has_name(&err, "org.freedesktop.DBus.Error.ServiceUnknown")) {
379
            spa_log_info(backend->log, "hsphfpd not available: %s",
380
                    err.message);
381
-           res = -ENOTSUP;
382
+           return -ENOTSUP;
383
        } else {
384
            spa_log_warn(backend->log, "Registering application %s failed: %s (%s)",
385
                    path, err.message, err.name);
386
-           res = -EIO;
387
+           return -EIO;
388
        }
389
-       dbus_error_free(&err);
390
-       return res;
391
    }
392
 
393
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
394
        spa_log_error(backend->log, "RegisterApplication() failed: %s",
395
                dbus_message_get_error_name(r));
396
-       goto finish;
397
+       return -EIO;
398
    }
399
-   dbus_message_unref(r);
400
 
401
    backend->hsphfpd_service_id = strdup(dbus_message_get_sender(r));
402
 
403
    spa_log_debug(backend->log, "Registered to hsphfpd");
404
 
405
+   return 0;
406
+}
407
+
408
+static int hsphfpd_get_endpoints(struct impl *backend)
409
+{
410
+   spa_autoptr(DBusMessage) m = NULL;
411
+
412
    m = dbus_message_new_method_call(HSPHFPD_SERVICE, "/",
413
            DBUS_INTERFACE_OBJECTMANAGER, "GetManagedObjects");
414
    if (m == NULL)
415
-       goto finish;
416
+       return -ENOMEM;
417
 
418
-   dbus_connection_send_with_reply(backend->conn, m, &call, -1);
419
-   dbus_pending_call_set_notify(call, hsphfpd_get_endpoints_reply, backend, NULL);
420
-   dbus_message_unref(m);
421
+   if (!send_with_reply(backend->conn, m, hsphfpd_get_endpoints_reply, backend))
422
+       return -EIO;
423
 
424
    return 0;
425
+}
426
 
427
-finish:
428
-   dbus_message_unref(r);
429
-   return -EIO;
430
+static int backend_hsphfpd_register(void *data)
431
+{
432
+   int ret = hsphfpd_register(data);
433
+   if (ret < 0)
434
+       return ret;
435
+
436
+   ret = hsphfpd_get_endpoints(data);
437
+   if (ret < 0)
438
+       return ret;
439
+
440
+   return 0;
441
 }
442
 
443
 static int backend_hsphfpd_unregistered(void *data)
444
@@ -1399,18 +1366,17 @@
445
 static int add_filters(void *data)
446
 {
447
    struct impl *backend = data;
448
-   DBusError err;
449
 
450
    if (backend->filters_added)
451
        return 0;
452
 
453
-   dbus_error_init(&err);
454
-
455
    if (!dbus_connection_add_filter(backend->conn, hsphfpd_filter_cb, backend, NULL)) {
456
        spa_log_error(backend->log, "failed to add filter function");
457
-       goto fail;
458
+       return -EIO;
459
    }
460
 
461
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
462
+
463
    dbus_bus_add_match(backend->conn,
464
            "type='signal',sender='" HSPHFPD_SERVICE "',"
465
            "interface='" DBUS_INTERFACE_OBJECTMANAGER "',member='InterfacesAdded'", &err);
466
@@ -1429,10 +1395,6 @@
467
    backend->filters_added = true;
468
 
469
    return 0;
470
-
471
-fail:
472
-   dbus_error_free(&err);
473
-   return -EIO;
474
 }
475
 
476
 static int backend_hsphfpd_free(void *data)
477
@@ -1467,28 +1429,19 @@
478
 
479
 static bool is_available(struct impl *backend)
480
 {
481
-   DBusMessage *m, *r;
482
-   DBusError err;
483
-   bool success = false;
484
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
485
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
486
 
487
    m = dbus_message_new_method_call(HSPHFPD_SERVICE, "/",
488
            DBUS_INTERFACE_INTROSPECTABLE, "Introspect");
489
    if (m == NULL)
490
        return false;
491
 
492
-   dbus_error_init(&err);
493
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
494
-   dbus_message_unref(m);
495
-
496
    if (r && dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
497
-       success = true;
498
-
499
-   if (r)
500
-       dbus_message_unref(r);
501
-   else
502
-       dbus_error_free(&err);
503
+       return true;
504
 
505
-   return success;
506
+   return false;
507
 }
508
 
509
 struct spa_bt_backend *backend_hsphfpd_new(struct spa_bt_monitor *monitor,
510
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
471
 
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
                      local_address, remote_address);
202
-       goto fail;
203
+       return;
204
    }
205
 
206
    /* The Synchronous Connection shall always be established by the AG, i.e. the remote profile
207
       should be a HSP AG or HFP AG profile */
208
    if ((t->profile & SPA_BT_PROFILE_HEADSET_AUDIO_GATEWAY) == 0) {
209
        spa_log_debug(backend->log, "transport %p: Rejecting incoming audio connection to an AG profile", t);
210
-       goto fail;
211
+       return;
212
    }
213
 
214
    if (t->fd >= 0) {
215
        spa_log_debug(backend->log, "transport %p: Rejecting, audio already connected", t);
216
-       goto fail;
217
+       return;
218
    }
219
 
220
    spa_log_debug(backend->log, "transport %p: codec=%u", t, t->codec);
221
@@ -1799,18 +1774,18 @@
222
            voice_config.setting = BT_VOICE_TRANSPARENT;
223
            if (setsockopt(sock, SOL_BLUETOOTH, BT_VOICE, &voice_config, sizeof(voice_config)) < 0) {
224
                spa_log_error(backend->log, "transport %p: setsockopt(): %s", t, strerror(errno));
225
-               goto fail;
226
+               return;
227
            }
228
        }
229
 
230
        /* First read from the accepted socket is non-blocking and returns a zero length buffer. */
231
        if (read(sock, &buff, 1) == -1) {
232
            spa_log_error(backend->log, "transport %p: Couldn't authorize SCO connection: %s", t, strerror(errno));
233
-           goto fail;
234
+           return;
235
        }
236
    }
237
 
238
-   t->fd = sock;
239
+   t->fd = spa_steal_fd(sock);
240
 
241
    sco_start_source(t);
242
 
243
@@ -1830,24 +1805,17 @@
244
    }
245
 
246
    spa_bt_transport_set_state(t, SPA_BT_TRANSPORT_STATE_PENDING);
247
-   return;
248
-
249
-fail:
250
-   if (sock >= 0)
251
-       close(sock);
252
-   return;
253
 }
254
 
255
-static int sco_listen(struct impl *backend)
256
+static void sco_listen(struct impl *backend)
257
 {
258
    struct sockaddr_sco addr;
259
-   int sock;
260
    uint32_t defer = 1;
261
 
262
-   sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
263
+   spa_autoclose int sock = socket(PF_BLUETOOTH, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC, BTPROTO_SCO);
264
    if (sock < 0) {
265
        spa_log_error(backend->log, "socket(SEQPACKET, SCO) %m");
266
-       return -errno;
267
+       return;
268
    }
269
 
270
    /* Bind to local address */
271
@@ -1857,7 +1825,7 @@
272
 
273
    if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
274
        spa_log_error(backend->log, "bind(): %m");
275
-       goto fail_close;
276
+       return;
277
    }
278
 
279
    if (setsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP, &defer, sizeof(defer)) < 0) {
280
@@ -1870,21 +1838,17 @@
281
    spa_log_debug(backend->log, "doing listen");
282
    if (listen(sock, 1) < 0) {
283
        spa_log_error(backend->log, "listen(): %m");
284
-       goto fail_close;
285
+       return;
286
    }
287
 
288
    backend->sco.func = sco_listen_event;
289
    backend->sco.data = backend;
290
-   backend->sco.fd = sock;
291
+   backend->sco.fd = spa_steal_fd(sock);
292
    backend->sco.mask = SPA_IO_IN;
293
    backend->sco.rmask = 0;
294
    spa_loop_add_source(backend->main_loop, &backend->sco);
295
 
296
-   return sock;
297
-
298
-fail_close:
299
-   close(sock);
300
-   return -1;
301
+   return;
302
 }
303
 
304
 static int rfcomm_ag_set_volume(struct spa_bt_transport *t, int id)
305
@@ -2195,14 +2159,14 @@
306
 static DBusHandlerResult profile_new_connection(DBusConnection *conn, DBusMessage *m, void *userdata)
307
 {
308
    struct impl *backend = userdata;
309
-   DBusMessage *r;
310
+   spa_autoptr(DBusMessage) r = NULL;
311
    DBusMessageIter it;
312
    const char *handler, *path;
313
    enum spa_bt_profile profile;
314
    struct rfcomm *rfcomm;
315
    struct spa_bt_device *d;
316
    struct spa_bt_transport *t = NULL;
317
-   int fd;
318
+   spa_autoclose int fd = -1;
319
 
320
    if (!dbus_message_has_signature(m, "oha{sv}")) {
321
        spa_log_warn(backend->log, "invalid NewConnection() signature");
322
@@ -2241,7 +2205,7 @@
323
    rfcomm->path = strdup(path);
324
    rfcomm->source.func = rfcomm_event;
325
    rfcomm->source.data = rfcomm;
326
-   rfcomm->source.fd = fd;
327
+   rfcomm->source.fd = spa_steal_fd(fd);
328
    rfcomm->source.mask = SPA_IO_IN;
329
    rfcomm->source.rmask = 0;
330
    /* By default all indicators are enabled */
331
@@ -2314,7 +2278,6 @@
332
        goto fail_need_memory;
333
    if (!dbus_connection_send(conn, r, NULL))
334
        goto fail_need_memory;
335
-   dbus_message_unref(r);
336
 
337
    return DBUS_HANDLER_RESULT_HANDLED;
338
 
339
@@ -2327,7 +2290,7 @@
340
 static DBusHandlerResult profile_request_disconnection(DBusConnection *conn, DBusMessage *m, void *userdata)
341
 {
342
    struct impl *backend = userdata;
343
-   DBusMessage *r;
344
+   spa_autoptr(DBusMessage) r = NULL;
345
    const char *handler, *path;
346
    struct spa_bt_device *d;
347
    enum spa_bt_profile profile = SPA_BT_PROFILE_NULL;
348
@@ -2367,7 +2330,6 @@
349
    if (!dbus_connection_send(conn, r, NULL))
350
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
351
 
352
-   dbus_message_unref(r);
353
    return DBUS_HANDLER_RESULT_HANDLED;
354
 }
355
 
356
@@ -2375,7 +2337,6 @@
357
 {
358
    struct impl *backend = userdata;
359
    const char *path, *interface, *member;
360
-   DBusMessage *r;
361
    DBusHandlerResult res;
362
 
363
    path = dbus_message_get_path(m);
364
@@ -2386,6 +2347,7 @@
365
 
366
    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
367
        const char *xml = PROFILE_INTROSPECT_XML;
368
+       spa_autoptr(DBusMessage) r = NULL;
369
 
370
        if ((r = dbus_message_new_method_return(m)) == NULL)
371
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
372
@@ -2394,7 +2356,6 @@
373
        if (!dbus_connection_send(backend->conn, r, NULL))
374
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
375
 
376
-       dbus_message_unref(r);
377
        res = DBUS_HANDLER_RESULT_HANDLED;
378
    }
379
    else if (dbus_message_is_method_call(m, BLUEZ_PROFILE_INTERFACE, "Release"))
380
@@ -2412,38 +2373,33 @@
381
 static void register_profile_reply(DBusPendingCall *pending, void *user_data)
382
 {
383
    struct impl *backend = user_data;
384
-   DBusMessage *r;
385
 
386
-   r = steal_reply_and_unref(&pending);
387
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
388
    if (r == NULL)
389
        return;
390
 
391
    if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
392
        spa_log_warn(backend->log, "Register profile not supported");
393
-       goto finish;
394
+       return;
395
    }
396
    if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
397
        spa_log_warn(backend->log, "Error registering profile");
398
-       goto finish;
399
+       return;
400
    }
401
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
402
        spa_log_error(backend->log, "RegisterProfile() failed: %s",
403
                dbus_message_get_error_name(r));
404
-       goto finish;
405
+       return;
406
    }
407
-
408
-finish:
409
-   dbus_message_unref(r);
410
 }
411
 
412
 static int register_profile(struct impl *backend, const char *profile, const char *uuid)
413
 {
414
-   DBusMessage *m;
415
+   spa_autoptr(DBusMessage) m = NULL;
416
    DBusMessageIter it4;
417
    dbus_bool_t autoconnect;
418
    dbus_uint16_t version, chan, features;
419
    char *str;
420
-   DBusPendingCall *call;
421
 
422
    if (!(backend->enabled_profiles & spa_bt_profile_from_uuid(uuid)))
423
        return -ECANCELED;
424
@@ -2536,16 +2492,16 @@
425
    }
426
    dbus_message_iter_close_container(&it0, &it1);
427
 
428
-   dbus_connection_send_with_reply(backend->conn, m, &call, -1);
429
-   dbus_pending_call_set_notify(call, register_profile_reply, backend, NULL);
430
-   dbus_message_unref(m);
431
+   if (!send_with_reply(backend->conn, m, register_profile_reply, backend))
432
+       return -EIO;
433
+
434
    return 0;
435
 }
436
 
437
 static void unregister_profile(struct impl *backend, const char *profile)
438
 {
439
-   DBusMessage *m, *r;
440
-   DBusError err;
441
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
442
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
443
 
444
    spa_log_debug(backend->log, "Unregistering Profile %s", profile);
445
 
446
@@ -2556,15 +2512,9 @@
447
 
448
    dbus_message_append_args(m, DBUS_TYPE_OBJECT_PATH, &profile, DBUS_TYPE_INVALID);
449
 
450
-   dbus_error_init(&err);
451
-
452
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
453
-   dbus_message_unref(m);
454
-   m = NULL;
455
-
456
    if (r == NULL) {
457
        spa_log_info(backend->log, "Unregistering Profile %s failed", profile);
458
-       dbus_error_free(&err);
459
        return;
460
    }
461
 
462
@@ -2572,8 +2522,6 @@
463
        spa_log_error(backend->log, "UnregisterProfile() returned error: %s", dbus_message_get_error_name(r));
464
        return;
465
    }
466
-
467
-   dbus_message_unref(r);
468
 }
469
 
470
 static int backend_native_register_profiles(void *data)
471
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
353
 
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
 
202
    if (dbus_message_is_error(r, OFONO_ERROR_INVALID_ARGUMENTS)) {
203
        spa_log_warn(backend->log, "invalid arguments");
204
-       goto finish;
205
+       return -EIO;
206
    }
207
    if (dbus_message_is_error(r, OFONO_ERROR_IN_USE)) {
208
        spa_log_warn(backend->log, "already in use");
209
-       goto finish;
210
+       return -EIO;
211
    }
212
    if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
213
        spa_log_warn(backend->log, "Error registering profile");
214
-       goto finish;
215
+       return -EIO;
216
    }
217
    if (dbus_message_is_error(r, DBUS_ERROR_SERVICE_UNKNOWN)) {
218
        spa_log_info(backend->log, "oFono not available, disabling");
219
-       goto finish;
220
+       return -EIO;
221
    }
222
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
223
        spa_log_error(backend->log, "Register() failed: %s",
224
                dbus_message_get_error_name(r));
225
-       goto finish;
226
+       return -EIO;
227
    }
228
-   dbus_message_unref(r);
229
 
230
    spa_log_debug(backend->log, "registered");
231
 
232
+   return 0;
233
+}
234
+
235
+static int ofono_getcards(struct impl *backend)
236
+{
237
+   spa_autoptr(DBusMessage) m = NULL;
238
+
239
    m = dbus_message_new_method_call(OFONO_SERVICE, "/",
240
            OFONO_HF_AUDIO_MANAGER_INTERFACE, "GetCards");
241
    if (m == NULL)
242
-       goto finish;
243
+       return -ENOMEM;
244
 
245
-   dbus_connection_send_with_reply(backend->conn, m, &call, -1);
246
-   dbus_pending_call_set_notify(call, ofono_getcards_reply, backend, NULL);
247
-   dbus_message_unref(m);
248
+   if (!send_with_reply(backend->conn, m, ofono_getcards_reply, backend))
249
+       return -EIO;
250
 
251
    return 0;
252
+}
253
 
254
-finish:
255
-   dbus_message_unref(r);
256
-   return -EIO;
257
+static int backend_ofono_register(void *data)
258
+{
259
+   int ret = ofono_register(data);
260
+   if (ret < 0)
261
+       return ret;
262
+
263
+   ret = ofono_getcards(data);
264
+   if (ret < 0)
265
+       return ret;
266
+
267
+   return 0;
268
 }
269
 
270
 static DBusHandlerResult ofono_filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
271
 {
272
    struct impl *backend = user_data;
273
-   DBusError err;
274
-
275
-   dbus_error_init(&err);
276
 
277
    if (dbus_message_is_signal(m, OFONO_HF_AUDIO_MANAGER_INTERFACE, "CardAdded")) {
278
            char *p;
279
@@ -781,6 +760,7 @@
280
            return ofono_audio_card_found(backend, p, &props_i);
281
    } else if (dbus_message_is_signal(m, OFONO_HF_AUDIO_MANAGER_INTERFACE, "CardRemoved")) {
282
            const char *p;
283
+           spa_auto(DBusError) err = DBUS_ERROR_INIT;
284
 
285
            if (!dbus_message_get_args(m, &err, DBUS_TYPE_OBJECT_PATH, &p, DBUS_TYPE_INVALID)) {
286
                    spa_log_error(backend->log, "Failed to parse org.ofono.HandsfreeAudioManager.CardRemoved: %s", err.message);
287
@@ -796,18 +776,16 @@
288
 
289
 static int add_filters(struct impl *backend)
290
 {
291
-   DBusError err;
292
-
293
    if (backend->filters_added)
294
        return 0;
295
 
296
-   dbus_error_init(&err);
297
-
298
    if (!dbus_connection_add_filter(backend->conn, ofono_filter_cb, backend, NULL)) {
299
        spa_log_error(backend->log, "failed to add filter function");
300
-       goto fail;
301
+       return -EIO;
302
    }
303
 
304
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
305
+
306
    dbus_bus_add_match(backend->conn,
307
            "type='signal',sender='" OFONO_SERVICE "',"
308
            "interface='" OFONO_HF_AUDIO_MANAGER_INTERFACE "',member='CardAdded'", &err);
309
@@ -818,10 +796,6 @@
310
    backend->filters_added = true;
311
 
312
    return 0;
313
-
314
-fail:
315
-   dbus_error_free(&err);
316
-   return -EIO;
317
 }
318
 
319
 static int backend_ofono_free(void *data)
320
@@ -851,28 +825,19 @@
321
 
322
 static bool is_available(struct impl *backend)
323
 {
324
-   DBusMessage *m, *r;
325
-   DBusError err;
326
-   bool success = false;
327
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
328
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
329
 
330
    m = dbus_message_new_method_call(OFONO_SERVICE, "/",
331
            DBUS_INTERFACE_INTROSPECTABLE, "Introspect");
332
    if (m == NULL)
333
        return false;
334
 
335
-   dbus_error_init(&err);
336
    r = dbus_connection_send_with_reply_and_block(backend->conn, m, -1, &err);
337
-   dbus_message_unref(m);
338
-
339
    if (r && dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_METHOD_RETURN)
340
-       success = true;
341
-
342
-   if (r)
343
-       dbus_message_unref(r);
344
-   else
345
-       dbus_error_free(&err);
346
+       return true;
347
 
348
-   return success;
349
+   return false;
350
 }
351
 
352
 struct spa_bt_backend *backend_ofono_new(struct spa_bt_monitor *monitor,
353
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
1085
 
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
    const char *str;
202
-   int res = -EINVAL;
203
 
204
    /* Lookup vendor/product id for the device, if present */
205
    str = strrchr(d->path, '/');  /* hciXX */
206
    if (str == NULL)
207
-       goto fail;
208
+       return -EINVAL;
209
+
210
    snprintf(path, sizeof(path), "/sys/class/bluetooth/%s/device/modalias", str);
211
-   if ((f = fopen(path, "rbe")) == NULL) {
212
-       res = -errno;
213
-       goto fail;
214
-   }
215
+
216
+   spa_autoptr(FILE) f = fopen(path, "rbe");
217
+   if (f == NULL)
218
+       return -errno;
219
+
220
    if (fscanf(f, "usb:v%04Xp%04X",  &vendor_id, &product_id) != 2)
221
-       goto fail;
222
+       return -EINVAL;
223
+
224
    d->source_id = SOURCE_ID_USB;
225
    d->vendor_id = vendor_id;
226
    d->product_id = product_id;
227
-   fclose(f);
228
 
229
    spa_log_debug(monitor->log, "adapter %p: usb vendor:%04x product:%04x",
230
            d, vendor_id, product_id);
231
    return 0;
232
-
233
-fail:
234
-   if (f)
235
-       fclose(f);
236
-   return res;
237
 }
238
 
239
 static struct spa_bt_adapter *adapter_create(struct spa_bt_monitor *monitor, const char *path)
240
@@ -1591,7 +1548,7 @@
241
                      const char *profile_uuid)
242
 {
243
    struct spa_bt_monitor *monitor = device->monitor;
244
-   DBusMessage *m;
245
+   spa_autoptr(DBusMessage) m = NULL;
246
 
247
    spa_log_info(monitor->log, "device %p %s: profile %s not connected; try ConnectProfile()",
248
                 device, device->path, profile_uuid);
249
@@ -1605,11 +1562,8 @@
250
    if (m == NULL)
251
        return -ENOMEM;
252
    dbus_message_append_args(m, DBUS_TYPE_STRING, &profile_uuid, DBUS_TYPE_INVALID);
253
-   if (!dbus_connection_send(monitor->conn, m, NULL)) {
254
-       dbus_message_unref(m);
255
+   if (!dbus_connection_send(monitor->conn, m, NULL))
256
        return -EIO;
257
-   }
258
-   dbus_message_unref(m);
259
 
260
    return 0;
261
 }
262
@@ -2312,11 +2266,10 @@
263
 {
264
    struct spa_bt_monitor *monitor = device->monitor;
265
    const struct media_codec * const * const media_codecs = monitor->media_codecs;
266
-   const struct media_codec **supported_codecs;
267
+   spa_autofree const struct media_codec **supported_codecs = NULL;
268
    size_t i, j, size;
269
 
270
    *count = 0;
271
-
272
    size = 8;
273
    supported_codecs = malloc(size * sizeof(const struct media_codec *));
274
    if (supported_codecs == NULL)
275
@@ -2337,10 +2290,9 @@
276
 #else
277
            p = realloc(supported_codecs, size * sizeof(const struct media_codec *));
278
 #endif
279
-           if (p == NULL) {
280
-               free(supported_codecs);
281
+           if (p == NULL)
282
                return NULL;
283
-           }
284
+
285
            supported_codecs = p;
286
        }
287
    }
288
@@ -2348,7 +2300,7 @@
289
    supported_codecsj = NULL;
290
    *count = j;
291
 
292
-   return supported_codecs;
293
+   return spa_steal_ptr(supported_codecs);
294
 }
295
 
296
 static struct spa_bt_remote_endpoint *device_remote_endpoint_find(struct spa_bt_device *device, const char *path)
297
@@ -3223,33 +3175,28 @@
298
 {
299
    struct spa_bt_transport *transport = user_data;
300
    struct spa_bt_monitor *monitor = transport->monitor;
301
-   DBusError err = DBUS_ERROR_INIT;
302
-   DBusMessage *r;
303
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
304
 
305
    spa_assert(transport->volume_call == pending);
306
-   r = steal_reply_and_unref(&transport->volume_call);
307
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&transport->volume_call);
308
 
309
    if (dbus_set_error_from_message(&err, r)) {
310
        spa_log_info(monitor->log, "transport %p: set volume failed for transport %s: %s",
311
                transport, transport->path, err.message);
312
-       dbus_error_free(&err);
313
    } else {
314
        spa_log_debug(monitor->log, "transport %p: set volume complete",
315
                transport);
316
    }
317
-
318
-   dbus_message_unref(r);
319
 }
320
 
321
 static void transport_set_property_volume(struct spa_bt_transport *transport, uint16_t value)
322
 {
323
    struct spa_bt_monitor *monitor = transport->monitor;
324
-   DBusMessage *m;
325
+   spa_autoptr(DBusMessage) m = NULL;
326
    DBusMessageIter it2;
327
    const char *interface = BLUEZ_MEDIA_TRANSPORT_INTERFACE;
328
    const char *name = "Volume";
329
    int res = 0;
330
-   dbus_bool_t ret;
331
 
332
    cancel_and_unref(&transport->volume_call);
333
 
334
@@ -3270,17 +3217,8 @@
335
    dbus_message_iter_append_basic(&it1, DBUS_TYPE_UINT16, &value);
336
    dbus_message_iter_close_container(&it0, &it1);
337
 
338
-   ret = dbus_connection_send_with_reply(monitor->conn, m, &transport->volume_call, -1);
339
-   dbus_message_unref(m);
340
-
341
-   if (!ret || !transport->volume_call) {
342
-       res = -EIO;
343
-       goto fail;
344
-   }
345
-
346
-   ret = dbus_pending_call_set_notify(transport->volume_call,
347
-           transport_set_property_volume_reply, transport, NULL);
348
-   if (!ret) {
349
+   transport->volume_call = send_with_reply(monitor->conn, m, transport_set_property_volume_reply, transport);
350
+   if (!transport->volume_call) {
351
        res = -EIO;
352
        goto fail;
353
    }
354
@@ -3373,12 +3311,11 @@
355
    struct spa_bt_monitor *monitor = transport->monitor;
356
    struct spa_bt_device *device = transport->device;
357
    int ret = 0;
358
-   DBusError err;
359
-   DBusMessage *r;
360
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
361
    struct spa_bt_transport *t, *t_linked;
362
 
363
    spa_assert(transport->acquire_call == pending);
364
-   r = steal_reply_and_unref(&transport->acquire_call);
365
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&transport->acquire_call);
366
 
367
    spa_bt_device_update_last_bluez_action_time(device);
368
 
369
@@ -3390,8 +3327,6 @@
370
        goto finish;
371
    }
372
 
373
-   dbus_error_init(&err);
374
-
375
    if (transport->fd >= 0) {
376
        spa_log_error(monitor->log, "transport %p: invalid duplicate acquire", transport);
377
        ret = -EINVAL;
378
@@ -3405,7 +3340,6 @@
379
                   DBUS_TYPE_INVALID)) {
380
        spa_log_error(monitor->log, "Failed to parse Acquire %s reply: %s",
381
                transport->path, err.message);
382
-       dbus_error_free(&err);
383
        ret = -EIO;
384
        goto finish;
385
    }
386
@@ -3418,8 +3352,6 @@
387
    transport_sync_volume(transport);
388
 
389
 finish:
390
-   if (r)
391
-       dbus_message_unref(r);
392
    if (ret < 0)
393
        spa_bt_transport_set_state(transport, SPA_BT_TRANSPORT_STATE_ERROR);
394
    else {
395
@@ -3479,8 +3411,7 @@
396
 static int do_transport_acquire(struct spa_bt_transport *transport)
397
 {
398
    struct spa_bt_monitor *monitor = transport->monitor;
399
-   DBusMessage *m;
400
-   dbus_bool_t ret;
401
+   spa_autoptr(DBusMessage) m = NULL;
402
    struct spa_bt_transport *t_linked;
403
 
404
    spa_list_for_each(t_linked, &transport->bap_transport_linked, bap_transport_linked) {
405
@@ -3505,14 +3436,8 @@
406
    if (m == NULL)
407
        return -ENOMEM;
408
 
409
-   ret = dbus_connection_send_with_reply(monitor->conn, m, &transport->acquire_call, -1);
410
-   dbus_message_unref(m);
411
-
412
-   if (!ret || transport->acquire_call == NULL)
413
-       return -EIO;
414
-
415
-   ret = dbus_pending_call_set_notify(transport->acquire_call, transport_acquire_reply, transport, NULL);
416
-   if (!ret)
417
+   transport->acquire_call = send_with_reply(monitor->conn, m, transport_acquire_reply, transport);
418
+   if (!transport->acquire_call)
419
        return -EIO;
420
 
421
    return 0;
422
@@ -3573,11 +3498,9 @@
423
 static int do_transport_release(struct spa_bt_transport *transport)
424
 {
425
    struct spa_bt_monitor *monitor = transport->monitor;
426
-   DBusMessage *m;
427
+   spa_autoptr(DBusMessage) m = NULL, r = NULL;
428
    struct spa_bt_transport *t_linked;
429
    bool is_idle = (transport->state == SPA_BT_TRANSPORT_STATE_IDLE);
430
-   DBusMessage *r;
431
-   DBusError err;
432
    bool linked = false;
433
 
434
    spa_log_debug(monitor->log, "transport %p: Release %s",
435
@@ -3625,10 +3548,8 @@
436
    if (m == NULL)
437
        return -ENOMEM;
438
 
439
-   dbus_error_init(&err);
440
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
441
    r = dbus_connection_send_with_reply_and_block(monitor->conn, m, -1, &err);
442
-   dbus_message_unref(m);
443
-
444
    if (r == NULL)  {
445
        if (is_idle) {
446
            /* XXX: The fd always needs to be closed. However, Release()
447
@@ -3642,10 +3563,8 @@
448
            spa_log_error(monitor->log, "Failed to release transport %s: %s",
449
                          transport->path, err.message);
450
        }
451
-       dbus_error_free(&err);
452
    } else {
453
        spa_log_info(monitor->log, "Transport %s released", transport->path);
454
-       dbus_message_unref(r);
455
    }
456
 
457
    return 0;
458
@@ -3746,10 +3665,9 @@
459
    const struct media_codec *codec;
460
    uint8_t configA2DP_MAX_CAPS_SIZE;
461
    enum spa_bt_media_direction direction;
462
-   char *local_endpoint = NULL;
463
+   spa_autofree char *local_endpoint = NULL;
464
    int res, config_size;
465
-   dbus_bool_t dbus_ret;
466
-   DBusMessage *m;
467
+   spa_autoptr(DBusMessage) m = NULL;
468
    DBusMessageIter iter, d;
469
    int i;
470
    bool sink;
471
@@ -3766,19 +3684,19 @@
472
    if (ep == NULL || ep->capabilities == NULL || ep->uuid == NULL) {
473
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: endpoint %s not valid, try next",
474
                      sw, *sw->path_iter);
475
-       goto next;
476
+       return false;
477
    }
478
 
479
    /* Setup and check compatible configuration */
480
    if (ep->codec != codec->codec_id) {
481
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: different codec, try next", sw);
482
-       goto next;
483
+       return false;
484
    }
485
 
486
    if (!(sw->profile & spa_bt_profile_from_uuid(ep->uuid))) {
487
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: wrong uuid (%s) for profile, try next",
488
                      sw, ep->uuid);
489
-       goto next;
490
+       return false;
491
    }
492
 
493
    if ((sw->profile & SPA_BT_PROFILE_A2DP_SINK) || (sw->profile & SPA_BT_PROFILE_BAP_SINK) ) {
494
@@ -3790,13 +3708,13 @@
495
    } else {
496
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: bad profile (%d), try next",
497
                      sw, sw->profile);
498
-       goto next;
499
+       return false;
500
    }
501
 
502
    if (media_codec_to_endpoint(codec, direction, &local_endpoint) < 0) {
503
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: no endpoint for codec %s, try next",
504
                      sw, codec->name);
505
-       goto next;
506
+       return false;
507
    }
508
 
509
    /* Each endpoint can be used by only one device at a time (on each adapter) */
510
@@ -3808,7 +3726,7 @@
511
        if (spa_streq(t->endpoint_path, local_endpoint)) {
512
            spa_log_debug(sw->device->monitor->log, "media codec switch %p: endpoint %s in use, try next",
513
                    sw, local_endpoint);
514
-           goto next;
515
+           return false;
516
        }
517
    }
518
 
519
@@ -3818,7 +3736,7 @@
520
    if (res < 0) {
521
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: incompatible capabilities (%d), try next",
522
                      sw, res);
523
-       goto next;
524
+       return false;
525
    }
526
    config_size = res;
527
 
528
@@ -3833,7 +3751,7 @@
529
    m = dbus_message_new_method_call(BLUEZ_SERVICE, ep->path, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration");
530
    if (m == NULL) {
531
        spa_log_debug(sw->device->monitor->log, "media codec switch %p: dbus allocation failure, try next", sw);
532
-       goto next;
533
+       return false;
534
    }
535
 
536
    spa_bt_device_update_last_bluez_action_time(sw->device);
537
@@ -3848,28 +3766,13 @@
538
    dbus_message_iter_close_container(&iter, &d);
539
 
540
    spa_assert(sw->pending == NULL);
541
-   dbus_ret = dbus_connection_send_with_reply(sw->device->monitor->conn, m, &sw->pending, -1);
542
-
543
-   if (!dbus_ret || sw->pending == NULL) {
544
+   sw->pending = send_with_reply(sw->device->monitor->conn, m, media_codec_switch_reply, sw);
545
+   if (!sw->pending) {
546
        spa_log_error(sw->device->monitor->log, "media codec switch %p: dbus call failure, try next", sw);
547
-       dbus_message_unref(m);
548
-       goto next;
549
-   }
550
-
551
-   dbus_ret = dbus_pending_call_set_notify(sw->pending, media_codec_switch_reply, sw, NULL);
552
-   dbus_message_unref(m);
553
-
554
-   if (!dbus_ret) {
555
-       spa_log_error(sw->device->monitor->log, "media codec switch %p: dbus set notify failure", sw);
556
-       goto next;
557
+       return false;
558
    }
559
 
560
-   free(local_endpoint);
561
    return true;
562
-
563
-next:
564
-   free(local_endpoint);
565
-   return false;
566
 }
567
 
568
 static void media_codec_switch_process(struct spa_bt_media_codec_switch *sw)
569
@@ -3957,18 +3860,14 @@
570
 {
571
    struct spa_bt_media_codec_switch *sw = user_data;
572
    struct spa_bt_device *device = sw->device;
573
-   DBusMessage *r;
574
 
575
    spa_assert(sw->pending == pending);
576
-   r = steal_reply_and_unref(&sw->pending);
577
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&sw->pending);
578
 
579
    spa_bt_device_update_last_bluez_action_time(device);
580
 
581
-   if (!media_codec_switch_goto_active(sw)) {
582
-       if (r != NULL)
583
-           dbus_message_unref(r);
584
+   if (!media_codec_switch_goto_active(sw))
585
        return;
586
-   }
587
 
588
    if (r == NULL) {
589
        spa_log_error(sw->device->monitor->log,
590
@@ -3981,12 +3880,9 @@
591
        spa_log_debug(sw->device->monitor->log,
592
                      "media codec switch %p: failed (%s), trying next",
593
                      sw, dbus_message_get_error_name(r));
594
-       dbus_message_unref(r);
595
        goto next;
596
    }
597
 
598
-   dbus_message_unref(r);
599
-
600
    /* Success */
601
    spa_log_info(sw->device->monitor->log, "media codec switch %p: success", sw);
602
    spa_bt_device_emit_codec_switched(sw->device, 0);
603
@@ -4218,7 +4114,7 @@
604
    struct spa_bt_monitor *monitor = userdata;
605
    const char *transport_path, *endpoint;
606
    DBusMessageIter it2;
607
-   DBusMessage *r;
608
+   spa_autoptr(DBusMessage) r = NULL;
609
    struct spa_bt_transport *transport;
610
    const struct media_codec *codec;
611
    int profile;
612
@@ -4327,27 +4223,22 @@
613
    if (!dbus_connection_send(conn, r, NULL))
614
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
615
 
616
-   dbus_message_unref(r);
617
-
618
    return DBUS_HANDLER_RESULT_HANDLED;
619
 }
620
 
621
 static DBusHandlerResult endpoint_clear_configuration(DBusConnection *conn, DBusMessage *m, void *userdata)
622
 {
623
    struct spa_bt_monitor *monitor = userdata;
624
-   DBusError err;
625
-   DBusMessage *r;
626
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
627
+   spa_autoptr(DBusMessage) r = NULL;
628
    const char *transport_path;
629
    struct spa_bt_transport *transport;
630
 
631
-   dbus_error_init(&err);
632
-
633
    if (!dbus_message_get_args(m, &err,
634
                   DBUS_TYPE_OBJECT_PATH, &transport_path,
635
                   DBUS_TYPE_INVALID)) {
636
        spa_log_warn(monitor->log, "Bad ClearConfiguration method call: %s",
637
            err.message);
638
-       dbus_error_free(&err);
639
        return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
640
    }
641
 
642
@@ -4369,25 +4260,14 @@
643
    if (!dbus_connection_send(conn, r, NULL))
644
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
645
 
646
-   dbus_message_unref(r);
647
-
648
    return DBUS_HANDLER_RESULT_HANDLED;
649
 }
650
 
651
 static DBusHandlerResult endpoint_release(DBusConnection *conn, DBusMessage *m, void *userdata)
652
 {
653
-   DBusMessage *r;
654
-
655
-   r = dbus_message_new_error(m,
656
-                  BLUEZ_MEDIA_ENDPOINT_INTERFACE ".Error.NotImplemented",
657
-                  "Method not implemented");
658
-   if (r == NULL)
659
-       return DBUS_HANDLER_RESULT_NEED_MEMORY;
660
-   if (!dbus_connection_send(conn, r, NULL))
661
+   if (!reply_with_error(conn, m, BLUEZ_MEDIA_ENDPOINT_INTERFACE ".Error.NotImplemented", "Method not implemented"))
662
        return DBUS_HANDLER_RESULT_NEED_MEMORY;
663
 
664
-   dbus_message_unref(r);
665
-
666
    return DBUS_HANDLER_RESULT_HANDLED;
667
 }
668
 
669
@@ -4395,7 +4275,6 @@
670
 {
671
    struct spa_bt_monitor *monitor = userdata;
672
    const char *path, *interface, *member;
673
-   DBusMessage *r;
674
    DBusHandlerResult res;
675
 
676
    path = dbus_message_get_path(m);
677
@@ -4406,6 +4285,7 @@
678
 
679
    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
680
        const char *xml = ENDPOINT_INTROSPECT_XML;
681
+       spa_autoptr(DBusMessage) r = NULL;
682
 
683
        if ((r = dbus_message_new_method_return(m)) == NULL)
684
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
685
@@ -4414,7 +4294,6 @@
686
        if (!dbus_connection_send(monitor->conn, r, NULL))
687
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
688
 
689
-       dbus_message_unref(r);
690
        res = DBUS_HANDLER_RESULT_HANDLED;
691
    }
692
    else if (dbus_message_is_method_call(m, BLUEZ_MEDIA_ENDPOINT_INTERFACE, "SetConfiguration"))
693
@@ -4437,26 +4316,22 @@
694
 {
695
    struct spa_bt_adapter *adapter = user_data;
696
    struct spa_bt_monitor *monitor = adapter->monitor;
697
-   DBusMessage *r;
698
 
699
-   r = steal_reply_and_unref(&pending);
700
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
701
    if (r == NULL)
702
        return;
703
 
704
    if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
705
        spa_log_warn(monitor->log, "BlueZ D-Bus ObjectManager not available");
706
-       goto finish;
707
+       return;
708
    }
709
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
710
        spa_log_error(monitor->log, "RegisterEndpoint() failed: %s",
711
                dbus_message_get_error_name(r));
712
-       goto finish;
713
+       return;
714
    }
715
 
716
    adapter->legacy_endpoints_registered = true;
717
-
718
-finish:
719
-   dbus_message_unref(r);
720
 }
721
 
722
 static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant) {
723
@@ -4489,10 +4364,9 @@
724
 {
725
    struct spa_bt_monitor *monitor = adapter->monitor;
726
    const char *path = adapter->path;
727
-   char  *object_path = NULL;
728
-   DBusMessage *m;
729
+   spa_autofree char *object_path = NULL;
730
+   spa_autoptr(DBusMessage) m = NULL;
731
    DBusMessageIter object_it, dict_it;
732
-   DBusPendingCall *call;
733
    uint8_t capsA2DP_MAX_CAPS_SIZE;
734
    int ret, caps_size;
735
    uint16_t codec_id = codec->codec_id;
736
@@ -4502,20 +4376,18 @@
737
 
738
    ret = media_codec_to_endpoint(codec, direction, &object_path);
739
    if (ret < 0)
740
-       goto error;
741
+       return ret;
742
 
743
    ret = caps_size = codec->fill_caps(codec, sink ? MEDIA_CODEC_FLAG_SINK : 0, caps);
744
    if (ret < 0)
745
-       goto error;
746
+       return ret;
747
 
748
    m = dbus_message_new_method_call(BLUEZ_SERVICE,
749
                                     path,
750
                                     BLUEZ_MEDIA_INTERFACE,
751
                                     "RegisterEndpoint");
752
-   if (m == NULL) {
753
-       ret = -EIO;
754
-       goto error;
755
-   }
756
+   if (m == NULL)
757
+       return -EIO;
758
 
759
    dbus_message_iter_init_append(m, &object_it);
760
    dbus_message_iter_append_basic(&object_it, DBUS_TYPE_OBJECT_PATH, &object_path);
761
@@ -4528,17 +4400,10 @@
762
 
763
    dbus_message_iter_close_container(&object_it, &dict_it);
764
 
765
-   dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
766
-   dbus_pending_call_set_notify(call, bluez_register_endpoint_legacy_reply, adapter, NULL);
767
-   dbus_message_unref(m);
768
-
769
-   free(object_path);
770
+   if (!send_with_reply(monitor->conn, m, bluez_register_endpoint_legacy_reply, adapter))
771
+       return -EIO;
772
 
773
    return 0;
774
-
775
-error:
776
-   free(object_path);
777
-   return ret;
778
 }
779
 
780
 static int adapter_register_endpoints_legacy(struct spa_bt_adapter *a)
781
@@ -4635,8 +4500,6 @@
782
    struct spa_bt_monitor *monitor = user_data;
783
    const struct media_codec * const * const media_codecs = monitor->media_codecs;
784
    const char *path, *interface, *member;
785
-   char *endpoint;
786
-   DBusMessage *r;
787
    DBusMessageIter iter, array;
788
    DBusHandlerResult res;
789
    int i;
790
@@ -4649,6 +4512,7 @@
791
 
792
    if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
793
        const char *xml = OBJECT_MANAGER_INTROSPECT_XML;
794
+       spa_autoptr(DBusMessage) r = NULL;
795
 
796
        if ((r = dbus_message_new_method_return(m)) == NULL)
797
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
798
@@ -4657,10 +4521,11 @@
799
        if (!dbus_connection_send(monitor->conn, r, NULL))
800
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
801
 
802
-       dbus_message_unref(r);
803
        res = DBUS_HANDLER_RESULT_HANDLED;
804
    }
805
    else if (dbus_message_is_method_call(m, "org.freedesktop.DBus.ObjectManager", "GetManagedObjects")) {
806
+       spa_autoptr(DBusMessage) r = NULL;
807
+
808
        if ((r = dbus_message_new_method_return(m)) == NULL)
809
            return DBUS_HANDLER_RESULT_NEED_MEMORY;
810
 
811
@@ -4684,13 +4549,13 @@
812
                if (caps_size < 0)
813
                    continue;
814
 
815
+               spa_autofree char *endpoint = NULL;
816
                ret = media_codec_to_endpoint(codec, SPA_BT_MEDIA_SINK, &endpoint);
817
                if (ret == 0) {
818
                    spa_log_info(monitor->log, "register media sink codec %s: %s", media_codecsi->name, endpoint);
819
                    append_media_object(&array, endpoint,
820
                            codec->bap ? SPA_BT_UUID_BAP_SINK : SPA_BT_UUID_A2DP_SINK,
821
                            codec_id, caps, caps_size);
822
-                   free(endpoint);
823
                }
824
            }
825
 
826
@@ -4699,13 +4564,13 @@
827
                if (caps_size < 0)
828
                    continue;
829
 
830
+               spa_autofree char *endpoint = NULL;
831
                ret = media_codec_to_endpoint(codec, SPA_BT_MEDIA_SOURCE, &endpoint);
832
                if (ret == 0) {
833
                    spa_log_info(monitor->log, "register media source codec %s: %s", media_codecsi->name, endpoint);
834
                    append_media_object(&array, endpoint,
835
                            codec->bap ? SPA_BT_UUID_BAP_SOURCE : SPA_BT_UUID_A2DP_SOURCE,
836
                            codec_id, caps, caps_size);
837
-                   free(endpoint);
838
                }
839
            }
840
        }
841
@@ -4735,10 +4600,9 @@
842
 {
843
    struct spa_bt_adapter *adapter = user_data;
844
    struct spa_bt_monitor *monitor = adapter->monitor;
845
-   DBusMessage *r;
846
    bool fallback = true;
847
 
848
-   r = steal_reply_and_unref(&pending);
849
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
850
    if (r == NULL)
851
        return;
852
 
853
@@ -4757,8 +4621,6 @@
854
    adapter->a2dp_application_registered = true;
855
 
856
 finish:
857
-   dbus_message_unref(r);
858
-
859
    if (fallback)
860
        adapter_register_endpoints_legacy(adapter);
861
 }
862
@@ -4767,22 +4629,18 @@
863
 {
864
    struct spa_bt_adapter *adapter = user_data;
865
    struct spa_bt_monitor *monitor = adapter->monitor;
866
-   DBusMessage *r;
867
 
868
-   r = steal_reply_and_unref(&pending);
869
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
870
    if (r == NULL)
871
        return;
872
 
873
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
874
        spa_log_error(monitor->log, "RegisterApplication() failed: %s",
875
                dbus_message_get_error_name(r));
876
-       goto finish;
877
+       return;
878
    }
879
 
880
    adapter->bap_application_registered = true;
881
-
882
-finish:
883
-   dbus_message_unref(r);
884
 }
885
 
886
 static int register_media_endpoint(struct spa_bt_monitor *monitor,
887
@@ -4796,7 +4654,7 @@
888
    if (!endpoint_should_be_registered(monitor, codec, direction))
889
        return 0;
890
 
891
-   char *object_path = NULL;
892
+   spa_autofree char *object_path = NULL;
893
    int ret = media_codec_to_endpoint(codec, direction, &object_path);
894
    if (ret < 0)
895
        return ret;
896
@@ -4806,12 +4664,9 @@
897
    if (!dbus_connection_register_object_path(monitor->conn,
898
                          object_path,
899
                          &vtable_endpoint, monitor))
900
-   {
901
-       ret = -EIO;
902
-   }
903
+       return -EIO;
904
 
905
-   free(object_path);
906
-   return ret;
907
+   return 0;
908
 }
909
 
910
 static int register_media_application(struct spa_bt_monitor * monitor)
911
@@ -4857,7 +4712,7 @@
912
    if (!endpoint_should_be_registered(monitor, codec, direction))
913
        return;
914
 
915
-   char *object_path = NULL;
916
+   spa_autofree char *object_path = NULL;
917
    int ret = media_codec_to_endpoint(codec, direction, &object_path);
918
    if (ret < 0)
919
        return;
920
@@ -4866,8 +4721,6 @@
921
 
922
    if (!dbus_connection_unregister_object_path(monitor->conn, object_path))
923
        spa_log_warn(monitor->log, "failed to unregister %s\n", object_path);
924
-
925
-   free(object_path);
926
 }
927
 
928
 static void unregister_media_application(struct spa_bt_monitor * monitor)
929
@@ -4907,9 +4760,8 @@
930
    const char *object_manager_path = bap ? BAP_OBJECT_MANAGER_PATH : A2DP_OBJECT_MANAGER_PATH;
931
    struct spa_bt_monitor *monitor = a->monitor;
932
    const char *ep_type_name = (bap ? "LE Audio" : "A2DP");
933
-   DBusMessage *m;
934
+   spa_autoptr(DBusMessage) m = NULL;
935
    DBusMessageIter i, d;
936
-   DBusPendingCall *call;
937
 
938
    if (bap && a->bap_application_registered)
939
        return 0;
940
@@ -4943,11 +4795,8 @@
941
    dbus_message_iter_open_container(&i, DBUS_TYPE_ARRAY, "{sv}", &d);
942
    dbus_message_iter_close_container(&i, &d);
943
 
944
-   dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
945
-   dbus_pending_call_set_notify(call,
946
-           bap ? bluez_register_application_bap_reply : bluez_register_application_a2dp_reply,
947
-           a, NULL);
948
-   dbus_message_unref(m);
949
+   if (!send_with_reply(monitor->conn, m, bap ? bluez_register_application_bap_reply : bluez_register_application_a2dp_reply, a))
950
+       return -EIO;
951
 
952
    return 0;
953
 }
954
@@ -5180,29 +5029,28 @@
955
 static void get_managed_objects_reply(DBusPendingCall *pending, void *user_data)
956
 {
957
    struct spa_bt_monitor *monitor = user_data;
958
-   DBusMessage *r;
959
    DBusMessageIter it6;
960
 
961
    spa_assert(monitor->get_managed_objects_call == pending);
962
-   r = steal_reply_and_unref(&monitor->get_managed_objects_call);
963
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&monitor->get_managed_objects_call);
964
    if (r == NULL)
965
        return;
966
 
967
    if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
968
        spa_log_warn(monitor->log, "BlueZ D-Bus ObjectManager not available");
969
-       goto finish;
970
+       return;
971
    }
972
 
973
    if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
974
        spa_log_error(monitor->log, "GetManagedObjects() failed: %s",
975
                dbus_message_get_error_name(r));
976
-       goto finish;
977
+       return;
978
    }
979
 
980
    if (!dbus_message_iter_init(r, &it0) ||
981
        !spa_streq(dbus_message_get_signature(r), "a{oa{sa{sv}}}")) {
982
        spa_log_error(monitor->log, "Invalid reply signature for GetManagedObjects()");
983
-       goto finish;
984
+       return;
985
    }
986
 
987
    dbus_message_iter_recurse(&it0, &it1);
988
@@ -5218,10 +5066,6 @@
989
    reselect_backend(monitor, false);
990
 
991
    monitor->objects_listed = true;
992
-
993
-finish:
994
-   dbus_message_unref(r);
995
-   return;
996
 }
997
 
998
 static void get_managed_objects(struct spa_bt_monitor *monitor)
999
@@ -5229,8 +5073,7 @@
1000
    if (monitor->objects_listed || monitor->get_managed_objects_call)
1001
        return;
1002
 
1003
-   DBusMessage *m;
1004
-   DBusPendingCall *call;
1005
+   spa_autoptr(DBusMessage) m = NULL;
1006
 
1007
    m = dbus_message_new_method_call(BLUEZ_SERVICE,
1008
                     "/",
1009
@@ -5239,22 +5082,16 @@
1010
 
1011
    dbus_message_set_auto_start(m, false);
1012
 
1013
-   dbus_connection_send_with_reply(monitor->conn, m, &call, -1);
1014
-   dbus_pending_call_set_notify(call, get_managed_objects_reply, monitor, NULL);
1015
-   dbus_message_unref(m);
1016
-
1017
-   monitor->get_managed_objects_call = call;
1018
+   monitor->get_managed_objects_call = send_with_reply(monitor->conn, m, get_managed_objects_reply, monitor);
1019
 }
1020
 
1021
 static DBusHandlerResult filter_cb(DBusConnection *bus, DBusMessage *m, void *user_data)
1022
 {
1023
    struct spa_bt_monitor *monitor = user_data;
1024
-   DBusError err;
1025
-
1026
-   dbus_error_init(&err);
1027
 
1028
    if (dbus_message_is_signal(m, "org.freedesktop.DBus", "NameOwnerChanged")) {
1029
        const char *name, *old_owner, *new_owner;
1030
+       spa_auto(DBusError) err = DBUS_ERROR_INIT;
1031
 
1032
        spa_log_debug(monitor->log, "Name owner changed %s", dbus_message_get_path(m));
1033
 
1034
@@ -5264,7 +5101,7 @@
1035
                       DBUS_TYPE_STRING, &new_owner,
1036
                       DBUS_TYPE_INVALID)) {
1037
            spa_log_error(monitor->log, "Failed to parse org.freedesktop.DBus.NameOwnerChanged: %s", err.message);
1038
-           goto fail;
1039
+           goto finish;
1040
        }
1041
 
1042
        if (spa_streq(name, BLUEZ_SERVICE)) {
1043
@@ -5431,26 +5268,22 @@
1044
        }
1045
    }
1046
 
1047
-fail:
1048
-   dbus_error_free(&err);
1049
 finish:
1050
    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
1051
 }
1052
 
1053
 static void add_filters(struct spa_bt_monitor *this)
1054
 {
1055
-   DBusError err;
1056
-
1057
    if (this->filters_added)
1058
        return;
1059
 
1060
-   dbus_error_init(&err);
1061
-
1062
    if (!dbus_connection_add_filter(this->conn, filter_cb, this, NULL)) {
1063
        spa_log_error(this->log, "failed to add filter function");
1064
-       goto fail;
1065
+       return;
1066
    }
1067
 
1068
+   spa_auto(DBusError) err = DBUS_ERROR_INIT;
1069
+
1070
    dbus_bus_add_match(this->conn,
1071
            "type='signal',sender='org.freedesktop.DBus',"
1072
            "interface='org.freedesktop.DBus',member='NameOwnerChanged',"
1073
@@ -5499,11 +5332,6 @@
1074
            "arg0='" BLUEZ_MEDIA_TRANSPORT_INTERFACE "'", &err);
1075
 
1076
    this->filters_added = true;
1077
-
1078
-   return;
1079
-
1080
-fail:
1081
-   dbus_error_free(&err);
1082
 }
1083
 
1084
 static int
1085
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
385
 
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
-   DBusMessage *r;
202
 
203
    free(data);
204
 
205
    spa_assert(this->voice_pending == pending);
206
-   r = steal_reply_and_unref(&this->voice_pending);
207
+   spa_autoptr(DBusMessage) r = steal_reply_and_unref(&this->voice_pending);
208
    if (r == NULL)
209
        return;
210
 
211
@@ -830,8 +786,8 @@
212
 {
213
    struct impl *this = modemmanager;
214
    struct call *call_object, *call_tmp;
215
-   struct dbus_cmd_data *data;
216
-   DBusMessage *m;
217
+   spa_autofree struct dbus_cmd_data *data = NULL;
218
+   spa_autoptr(DBusMessage) m = NULL;
219
 
220
    call_object = NULL;
221
    spa_list_for_each(call_tmp, &this->call_list, link) {
222
@@ -863,22 +819,24 @@
223
            *error = CMEE_AG_FAILURE;
224
        return false;
225
    }
226
-   if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_simple_reply, data)) {
227
+
228
+   call_object->pending = send_with_reply(this->conn, m, mm_get_call_simple_reply, data);
229
+   if (!call_object->pending) {
230
        spa_log_error(this->log, "dbus call failure");
231
        if (error)
232
            *error = CMEE_AG_FAILURE;
233
        return false;
234
    }
235
 
236
-   return true;
237
+   return spa_steal_ptr(data), true;
238
 }
239
 
240
 bool mm_hangup_call(void *modemmanager, void *user_data, enum cmee_error *error)
241
 {
242
    struct impl *this = modemmanager;
243
    struct call *call_object, *call_tmp;
244
-   struct dbus_cmd_data *data;
245
-   DBusMessage *m;
246
+   spa_autofree struct dbus_cmd_data *data= NULL;
247
+   spa_autoptr(DBusMessage) m = NULL;
248
 
249
    call_object = NULL;
250
    spa_list_for_each(call_tmp, &this->call_list, link) {
251
@@ -920,14 +878,16 @@
252
            *error = CMEE_AG_FAILURE;
253
        return false;
254
    }
255
-   if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_simple_reply, data)) {
256
+
257
+   call_object->pending = send_with_reply(this->conn, m, mm_get_call_simple_reply, data);
258
+   if (!call_object->pending) {
259
        spa_log_error(this->log, "dbus call failure");
260
        if (error)
261
            *error = CMEE_AG_FAILURE;
262
        return false;
263
    }
264
 
265
-   return true;
266
+   return spa_steal_ptr(data), true;
267
 }
268
 
269
 static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant) {
270
@@ -953,8 +913,8 @@
271
 bool mm_do_call(void *modemmanager, const char* number, void *user_data, enum cmee_error *error)
272
 {
273
    struct impl *this = modemmanager;
274
-   struct dbus_cmd_data *data;
275
-   DBusMessage *m;
276
+   spa_autofree struct dbus_cmd_data *data = NULL;
277
+   spa_autoptr(DBusMessage) m = NULL;
278
    DBusMessageIter iter, dict;
279
 
280
    for (size_t i = 0; numberi; i++) {
281
@@ -985,22 +945,24 @@
282
    dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
283
    append_basic_variant_dict_entry(&dict, "number", DBUS_TYPE_STRING, "s", &number);
284
    dbus_message_iter_close_container(&iter, &dict);
285
-   if (!mm_dbus_connection_send_with_reply(this, m, &this->voice_pending, mm_get_call_create_reply, data)) {
286
+
287
+   this->voice_pending = send_with_reply(this->conn, m, mm_get_call_create_reply, data);
288
+   if (!this->voice_pending) {
289
        spa_log_error(this->log, "dbus call failure");
290
        if (error)
291
            *error = CMEE_AG_FAILURE;
292
        return false;
293
    }
294
 
295
-   return true;
296
+   return spa_steal_ptr(data), true;
297
 }
298
 
299
 bool mm_send_dtmf(void *modemmanager, const char *dtmf, void *user_data, enum cmee_error *error)
300
 {
301
    struct impl *this = modemmanager;
302
    struct call *call_object, *call_tmp;
303
-   struct dbus_cmd_data *data;
304
-   DBusMessage *m;
305
+   spa_autofree struct dbus_cmd_data *data = NULL;
306
+   spa_autoptr(DBusMessage) m = NULL;
307
 
308
    call_object = NULL;
309
    spa_list_for_each(call_tmp, &this->call_list, link) {
310
@@ -1044,14 +1006,16 @@
311
        return false;
312
    }
313
    dbus_message_append_args(m, DBUS_TYPE_STRING, &dtmf, DBUS_TYPE_INVALID);
314
-   if (!mm_dbus_connection_send_with_reply(this, m, &call_object->pending, mm_get_call_simple_reply, data)) {
315
+
316
+   call_object->pending = send_with_reply(this->conn, m, mm_get_call_simple_reply, data);
317
+   if (!call_object->pending) {
318
        spa_log_error(this->log, "dbus call failure");
319
        if (error)
320
            *error = CMEE_AG_FAILURE;
321
        return false;
322
    }
323
 
324
-   return true;
325
+   return spa_steal_ptr(data), true;
326
 }
327
 
328
 const char *mm_get_incoming_call_number(void *modemmanager)
329
@@ -1084,7 +1048,6 @@
330
 void *mm_register(struct spa_log *log, void *dbus_connection, const struct spa_dict *info,
331
                   const struct mm_ops *ops, void *user_data)
332
 {
333
-   struct impl *this;
334
    const char *modem_device_str = NULL;
335
    bool modem_device_found = false;
336
 
337
@@ -1102,7 +1065,7 @@
338
        return NULL;
339
    }
340
 
341
-   this = calloc(1, sizeof(struct impl));
342
+   spa_autofree struct impl *this = calloc(1, sizeof(*this));
343
    if (this == NULL)
344
        return NULL;
345
 
346
@@ -1114,27 +1077,25 @@
347
        this->allowed_modem_device = strdup(modem_device_str);
348
    spa_list_init(&this->call_list);
349
 
350
-   if (add_filters(this) < 0) {
351
-       goto fail;
352
-   }
353
+   if (add_filters(this) < 0)
354
+       return NULL;
355
 
356
-   DBusMessage *m = dbus_message_new_method_call(MM_DBUS_SERVICE, "/org/freedesktop/ModemManager1",
357
-                             DBUS_INTERFACE_OBJECTMANAGER, "GetManagedObjects");
358
+   spa_autoptr(DBusMessage) m = dbus_message_new_method_call(MM_DBUS_SERVICE,
359
+                                 "/org/freedesktop/ModemManager1",
360
+                                 DBUS_INTERFACE_OBJECTMANAGER,
361
+                                 "GetManagedObjects");
362
    if (m == NULL)
363
-       goto fail;
364
+       return NULL;
365
 
366
    dbus_message_set_auto_start(m, false);
367
 
368
-   if (!mm_dbus_connection_send_with_reply(this, m, &this->pending, mm_get_managed_objects_reply, this)) {
369
+   this->pending = send_with_reply(this->conn, m, mm_get_managed_objects_reply, this);
370
+   if (!this->pending) {
371
        spa_log_error(this->log, "dbus call failure");
372
-       goto fail;
373
+       return NULL;
374
    }
375
 
376
-   return this;
377
-
378
-fail:
379
-   free(this);
380
-   return NULL;
381
+   return spa_steal_ptr(this);
382
 }
383
 
384
 void mm_unregister(void *data)
385
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
595
 
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
        break;
202
    }
203
 }
204
 
205
-static int stop_inotify(struct impl *this)
206
-{
207
-   if (this->notify.fd == -1)
208
-       return 0;
209
-   spa_log_info(this->log, "stop inotify");
210
-   spa_loop_remove_source(this->main_loop, &this->notify);
211
-   close(this->notify.fd);
212
-   this->notify.fd = -1;
213
-   return 0;
214
-}
215
-
216
 static void impl_on_notify_events(struct spa_source *source)
217
 {
218
-   bool deleted = false;
219
-   struct impl *this = source->data;
220
+   struct device *dev = source->data;
221
+   struct impl *impl = dev->impl;
222
    union {
223
        unsigned char namesizeof(struct inotify_event) + NAME_MAX + 1;
224
        struct inotify_event e; /* for appropriate alignment */
225
@@ -411,143 +417,138 @@
226
 
227
        for (p = &buf; p < e;
228
            p = SPA_PTROFF(p, sizeof(struct inotify_event) + event->len, void)) {
229
-           unsigned int id;
230
-           struct device *device;
231
 
232
            event = (const struct inotify_event *) p;
233
 
234
            if ((event->mask & IN_ATTRIB)) {
235
                bool access;
236
-               if (sscanf(event->name, "video%u", &id) != 1)
237
-                   continue;
238
-               if ((device = find_device(this, id)) == NULL)
239
-                   continue;
240
-               access = check_access(this, device);
241
-               if (access && !device->emitted)
242
-                   process_device(this, ACTION_ADD, device->dev);
243
-               else if (!access && device->emitted)
244
-                   process_device(this, ACTION_DISABLE, device->dev);
245
+               access = check_access(dev);
246
+               if (access && !dev->emitted)
247
+                   process_device(impl, ACTION_ADD, dev->dev);
248
+               else if (!access && dev->emitted)
249
+                   process_device(impl, ACTION_DISABLE, dev->dev);
250
            }
251
-           /* /dev/ might have been removed */
252
-           if ((event->mask & (IN_DELETE_SELF | IN_MOVE_SELF)))
253
-               deleted = true;
254
        }
255
    }
256
-   if (deleted)
257
-       stop_inotify(this);
258
 }
259
 
260
-static int start_inotify(struct impl *this)
261
+static int start_inotify(struct device *dev)
262
 {
263
+   struct impl *impl = dev->impl;
264
    int res, notify_fd;
265
+   char name32;
266
 
267
-   if (this->notify.fd != -1)
268
+   if (dev->notify.fd != -1)
269
        return 0;
270
 
271
    if ((notify_fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK)) < 0)
272
        return -errno;
273
 
274
-   res = inotify_add_watch(notify_fd, "/dev",
275
-           IN_ATTRIB | IN_CLOSE_WRITE | IN_DELETE_SELF | IN_MOVE_SELF);
276
+   snprintf(name, sizeof(name), "/dev/video%u", dev->id);
277
+
278
+   res = inotify_add_watch(notify_fd, name, IN_ATTRIB | IN_CLOSE_WRITE);
279
    if (res < 0) {
280
        res = -errno;
281
        close(notify_fd);
282
 
283
        if (res == -ENOENT) {
284
-           spa_log_debug(this->log, "/dev/ does not exist yet");
285
+           spa_log_debug(impl->log, "%s does not exist yet", name);
286
            return 0;
287
        }
288
-       spa_log_error(this->log, "inotify_add_watch() failed: %s", spa_strerror(res));
289
+       spa_log_error(impl->log, "inotify_add_watch() failed: %s", spa_strerror(res));
290
        return res;
291
    }
292
-   spa_log_info(this->log, "start inotify");
293
-   this->notify.func = impl_on_notify_events;
294
-   this->notify.data = this;
295
-   this->notify.fd = notify_fd;
296
-   this->notify.mask = SPA_IO_IN | SPA_IO_ERR;
297
+   spa_log_info(impl->log, "start inotify for %s", name);
298
+   dev->notify.func = impl_on_notify_events;
299
+   dev->notify.data = dev;
300
+   dev->notify.fd = notify_fd;
301
+   dev->notify.mask = SPA_IO_IN | SPA_IO_ERR;
302
 
303
-   spa_loop_add_source(this->main_loop, &this->notify);
304
+   spa_loop_add_source(impl->main_loop, &dev->notify);
305
 
306
    return 0;
307
 }
308
 
309
+static int stop_inotify(struct device *dev)
310
+{
311
+   struct impl *impl = dev->impl;
312
+   if (dev->notify.fd == -1)
313
+       return 0;
314
+   spa_log_info(impl->log, "stop inotify for /dev/video%u", dev->id);
315
+   spa_loop_remove_source(impl->main_loop, &dev->notify);
316
+   close(dev->notify.fd);
317
+   dev->notify.fd = -1;
318
+   return 0;
319
+}
320
+
321
 static void impl_on_fd_events(struct spa_source *source)
322
 {
323
-   struct impl *this = source->data;
324
+   struct impl *impl = source->data;
325
    struct udev_device *dev;
326
    const char *action;
327
 
328
-   dev = udev_monitor_receive_device(this->umonitor);
329
+   dev = udev_monitor_receive_device(impl->umonitor);
330
    if (dev == NULL)
331
        return;
332
 
333
    if ((action = udev_device_get_action(dev)) == NULL)
334
        action = "change";
335
 
336
-   spa_log_debug(this->log, "action %s", action);
337
-
338
-   start_inotify(this);
339
+   spa_log_debug(impl->log, "action %s", action);
340
 
341
    if (spa_streq(action, "add") ||
342
        spa_streq(action, "change")) {
343
-       process_device(this, ACTION_ADD, dev);
344
+       process_device(impl, ACTION_ADD, dev);
345
    } else if (spa_streq(action, "remove")) {
346
-       process_device(this, ACTION_REMOVE, dev);
347
+       process_device(impl, ACTION_REMOVE, dev);
348
    }
349
    udev_device_unref(dev);
350
 }
351
 
352
-static int start_monitor(struct impl *this)
353
+static int start_monitor(struct impl *impl)
354
 {
355
-   int res;
356
-
357
-   if (this->umonitor != NULL)
358
+   if (impl->umonitor != NULL)
359
        return 0;
360
 
361
-   this->umonitor = udev_monitor_new_from_netlink(this->udev, "udev");
362
-   if (this->umonitor == NULL)
363
+   impl->umonitor = udev_monitor_new_from_netlink(impl->udev, "udev");
364
+   if (impl->umonitor == NULL)
365
        return -ENOMEM;
366
 
367
-   udev_monitor_filter_add_match_subsystem_devtype(this->umonitor,
368
+   udev_monitor_filter_add_match_subsystem_devtype(impl->umonitor,
369
                            "video4linux", NULL);
370
-   udev_monitor_enable_receiving(this->umonitor);
371
-
372
-   this->source.func = impl_on_fd_events;
373
-   this->source.data = this;
374
-   this->source.fd = udev_monitor_get_fd(this->umonitor);
375
-   this->source.mask = SPA_IO_IN | SPA_IO_ERR;
376
+   udev_monitor_enable_receiving(impl->umonitor);
377
 
378
-   spa_log_debug(this->log, "monitor %p", this->umonitor);
379
-   spa_loop_add_source(this->main_loop, &this->source);
380
+   impl->source.func = impl_on_fd_events;
381
+   impl->source.data = impl;
382
+   impl->source.fd = udev_monitor_get_fd(impl->umonitor);
383
+   impl->source.mask = SPA_IO_IN | SPA_IO_ERR;
384
 
385
-   if ((res = start_inotify(this)) < 0)
386
-       return res;
387
+   spa_log_debug(impl->log, "monitor %p", impl->umonitor);
388
+   spa_loop_add_source(impl->main_loop, &impl->source);
389
 
390
    return 0;
391
 }
392
 
393
-static int stop_monitor(struct impl *this)
394
+static int stop_monitor(struct impl *impl)
395
 {
396
-   if (this->umonitor == NULL)
397
+   if (impl->umonitor == NULL)
398
        return 0;
399
 
400
-   clear_devices (this);
401
-
402
-   spa_loop_remove_source(this->main_loop, &this->source);
403
-   udev_monitor_unref(this->umonitor);
404
-   this->umonitor = NULL;
405
+   clear_devices(impl);
406
 
407
-   stop_inotify(this);
408
+   spa_loop_remove_source(impl->main_loop, &impl->source);
409
+   udev_monitor_unref(impl->umonitor);
410
+   impl->umonitor = NULL;
411
 
412
    return 0;
413
 }
414
 
415
-static int enum_devices(struct impl *this)
416
+static int enum_devices(struct impl *impl)
417
 {
418
    struct udev_enumerate *enumerate;
419
    struct udev_list_entry *devices;
420
 
421
-   enumerate = udev_enumerate_new(this->udev);
422
+   enumerate = udev_enumerate_new(impl->udev);
423
    if (enumerate == NULL)
424
        return -ENOMEM;
425
 
426
@@ -558,11 +559,11 @@
427
            devices = udev_list_entry_get_next(devices)) {
428
        struct udev_device *dev;
429
 
430
-       dev = udev_device_new_from_syspath(this->udev, udev_list_entry_get_name(devices));
431
+       dev = udev_device_new_from_syspath(impl->udev, udev_list_entry_get_name(devices));
432
        if (dev == NULL)
433
            continue;
434
 
435
-       process_device(this, ACTION_ADD, dev);
436
+       process_device(impl, ACTION_ADD, dev);
437
 
438
        udev_device_unref(dev);
439
    }
440
@@ -577,24 +578,24 @@
441
    { SPA_KEY_API_UDEV_MATCH, "video4linux" },
442
 };
443
 
444
-static void emit_device_info(struct impl *this, bool full)
445
+static void emit_device_info(struct impl *impl, bool full)
446
 {
447
-   uint64_t old = full ? this->info.change_mask : 0;
448
+   uint64_t old = full ? impl->info.change_mask : 0;
449
    if (full)
450
-       this->info.change_mask = this->info_all;
451
-   if (this->info.change_mask) {
452
-       this->info.props = &SPA_DICT_INIT_ARRAY(device_info_items);
453
-       spa_device_emit_info(&this->hooks, &this->info);
454
-       this->info.change_mask = old;
455
+       impl->info.change_mask = impl->info_all;
456
+   if (impl->info.change_mask) {
457
+       impl->info.props = &SPA_DICT_INIT_ARRAY(device_info_items);
458
+       spa_device_emit_info(&impl->hooks, &impl->info);
459
+       impl->info.change_mask = old;
460
    }
461
 }
462
 
463
 static void impl_hook_removed(struct spa_hook *hook)
464
 {
465
-   struct impl *this = hook->priv;
466
-   if (spa_hook_list_is_empty(&this->hooks)) {
467
-       stop_monitor(this);
468
-       impl_udev_close(this);
469
+   struct impl *impl = hook->priv;
470
+   if (spa_hook_list_is_empty(&impl->hooks)) {
471
+       stop_monitor(impl);
472
+       impl_udev_close(impl);
473
    }
474
 }
475
 
476
@@ -603,29 +604,29 @@
477
        const struct spa_device_events *events, void *data)
478
 {
479
    int res;
480
-   struct impl *this = object;
481
+   struct impl *impl = object;
482
         struct spa_hook_list save;
483
 
484
-   spa_return_val_if_fail(this != NULL, -EINVAL);
485
+   spa_return_val_if_fail(impl != NULL, -EINVAL);
486
    spa_return_val_if_fail(events != NULL, -EINVAL);
487
 
488
-   if ((res = impl_udev_open(this)) < 0)
489
+   if ((res = impl_udev_open(impl)) < 0)
490
        return res;
491
 
492
-        spa_hook_list_isolate(&this->hooks, &save, listener, events, data);
493
+        spa_hook_list_isolate(&impl->hooks, &save, listener, events, data);
494
 
495
-   emit_device_info(this, true);
496
+   emit_device_info(impl, true);
497
 
498
-   if ((res = enum_devices(this)) < 0)
499
+   if ((res = enum_devices(impl)) < 0)
500
        return res;
501
 
502
-   if ((res = start_monitor(this)) < 0)
503
+   if ((res = start_monitor(impl)) < 0)
504
        return res;
505
 
506
-        spa_hook_list_join(&this->hooks, &save);
507
+        spa_hook_list_join(&impl->hooks, &save);
508
 
509
    listener->removed = impl_hook_removed;
510
-   listener->priv = this;
511
+   listener->priv = impl;
512
 
513
    return 0;
514
 }
515
@@ -637,15 +638,15 @@
516
 
517
 static int impl_get_interface(struct spa_handle *handle, const char *type, void **interface)
518
 {
519
-   struct impl *this;
520
+   struct impl *impl;
521
 
522
    spa_return_val_if_fail(handle != NULL, -EINVAL);
523
    spa_return_val_if_fail(interface != NULL, -EINVAL);
524
 
525
-   this = (struct impl *) handle;
526
+   impl = (struct impl *) handle;
527
 
528
    if (spa_streq(type, SPA_TYPE_INTERFACE_Device))
529
-       *interface = &this->device;
530
+       *interface = &impl->device;
531
    else
532
        return -ENOENT;
533
 
534
@@ -654,9 +655,9 @@
535
 
536
 static int impl_clear(struct spa_handle *handle)
537
 {
538
-   struct impl *this = (struct impl *) handle;
539
-   stop_monitor(this);
540
-   impl_udev_close(this);
541
+   struct impl *impl = (struct impl *) handle;
542
+   stop_monitor(impl);
543
+   impl_udev_close(impl);
544
    return 0;
545
 }
546
 
547
@@ -674,7 +675,7 @@
548
      const struct spa_support *support,
549
      uint32_t n_support)
550
 {
551
-   struct impl *this;
552
+   struct impl *impl;
553
 
554
    spa_return_val_if_fail(factory != NULL, -EINVAL);
555
    spa_return_val_if_fail(handle != NULL, -EINVAL);
556
@@ -682,27 +683,25 @@
557
    handle->get_interface = impl_get_interface;
558
    handle->clear = impl_clear;
559
 
560
-   this = (struct impl *) handle;
561
-   this->notify.fd = -1;
562
-
563
-   this->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
564
-   this->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
565
+   impl = (struct impl *) handle;
566
+   impl->log = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Log);
567
+   impl->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
568
 
569
-   if (this->main_loop == NULL) {
570
-       spa_log_error(this->log, "a main-loop is needed");
571
+   if (impl->main_loop == NULL) {
572
+       spa_log_error(impl->log, "a main-loop is needed");
573
        return -EINVAL;
574
    }
575
-   spa_hook_list_init(&this->hooks);
576
+   spa_hook_list_init(&impl->hooks);
577
 
578
-   this->device.iface = SPA_INTERFACE_INIT(
579
+   impl->device.iface = SPA_INTERFACE_INIT(
580
            SPA_TYPE_INTERFACE_Device,
581
            SPA_VERSION_DEVICE,
582
-           &impl_device, this);
583
+           &impl_device, impl);
584
 
585
-   this->info = SPA_DEVICE_INFO_INIT();
586
-   this->info_all = SPA_DEVICE_CHANGE_MASK_FLAGS |
587
+   impl->info = SPA_DEVICE_INFO_INIT();
588
+   impl->info_all = SPA_DEVICE_CHANGE_MASK_FLAGS |
589
            SPA_DEVICE_CHANGE_MASK_PROPS;
590
-   this->info.flags = 0;
591
+   impl->info.flags = 0;
592
 
593
    return 0;
594
 }
595
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
391
 
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
-       struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, };
202
-       card = select_object(manager, &sel);
203
-   }
204
-   collect_device_info(o, card, &dev_info, is_monitor, &impl->defs);
205
+   get_device_info(o, &dev_info, direction, is_monitor);
206
 
207
    if (dev_info.have_volume &&
208
        dev_info.volume_info.mute == mute)
209
        goto done;
210
 
211
+   if (dev_info.card_id != SPA_ID_INVALID) {
212
+       struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, };
213
+       card = select_object(manager, &sel);
214
+   }
215
+
216
    if (card != NULL && !is_monitor && dev_info.active_port != SPA_ID_INVALID)
217
        res = set_card_volume_mute_delay(card, dev_info.active_port,
218
                dev_info.device, NULL, &mute, NULL);
219
@@ -3652,24 +3666,22 @@
220
 static bool validate_device_info(struct device_info *dev_info)
221
 {
222
    return sample_spec_valid(&dev_info->ss) &&
223
-          channel_map_valid(&dev_info->map) &&
224
-          volume_valid(&dev_info->volume_info.volume);
225
+       channel_map_valid(&dev_info->map) &&
226
+       volume_valid(&dev_info->volume_info.volume);
227
 }
228
 
229
 static int fill_sink_info(struct client *client, struct message *m,
230
        struct pw_manager_object *o)
231
 {
232
-   struct impl *impl = client->impl;
233
    struct pw_node_info *info = o->info;
234
    struct pw_manager *manager = client->manager;
235
    const char *name, *desc, *str;
236
    char *monitor_name = NULL;
237
    uint32_t module_id = SPA_ID_INVALID;
238
-   uint32_t card_id = SPA_ID_INVALID;
239
    struct pw_manager_object *card = NULL;
240
    uint32_t flags;
241
    struct card_info card_info = CARD_INFO_INIT;
242
-   struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT);
243
+   struct device_info dev_info;
244
    size_t size;
245
 
246
    if (!pw_manager_object_is_sink(o) || info == NULL || info->props == NULL)
247
@@ -3693,19 +3705,8 @@
248
    if (module_id == SPA_ID_INVALID &&
249
        (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL)
250
        module_id = (uint32_t)atoi(str);
251
-   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
252
-       card_id = (uint32_t)atoi(str);
253
-   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
254
-       dev_info.device = (uint32_t)atoi(str);
255
-   if (card_id != SPA_ID_INVALID) {
256
-       struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, };
257
-       card = select_object(manager, &sel);
258
-   }
259
-   if (card)
260
-       collect_card_info(card, &card_info);
261
-
262
-   collect_device_info(o, card, &dev_info, false, &impl->defs);
263
 
264
+   get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, false);
265
    if (!validate_device_info(&dev_info)) {
266
        pw_log_warn("%d: sink not ready: sample:%d map:%d volume:%d",
267
                o->id, sample_spec_valid(&dev_info.ss),
268
@@ -3714,6 +3715,14 @@
269
        return -ENOENT;
270
    }
271
 
272
+
273
+   if (dev_info.card_id != SPA_ID_INVALID) {
274
+       struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, };
275
+       card = select_object(manager, &sel);
276
+   }
277
+   if (card)
278
+       collect_card_info(card, &card_info);
279
+
280
    flags = SINK_LATENCY | SINK_DYNAMIC_LATENCY | SINK_DECIBEL_VOLUME;
281
    if (!pw_manager_object_is_virtual(o))
282
        flags |= SINK_HARDWARE;
283
@@ -3866,7 +3875,6 @@
284
 static int fill_source_info(struct client *client, struct message *m,
285
        struct pw_manager_object *o)
286
 {
287
-   struct impl *impl = client->impl;
288
    struct pw_node_info *info = o->info;
289
    struct pw_manager *manager = client->manager;
290
    bool is_monitor;
291
@@ -3874,11 +3882,10 @@
292
    char *monitor_name = NULL;
293
    char *monitor_desc = NULL;
294
    uint32_t module_id = SPA_ID_INVALID;
295
-   uint32_t card_id = SPA_ID_INVALID;
296
    struct pw_manager_object *card = NULL;
297
    uint32_t flags;
298
    struct card_info card_info = CARD_INFO_INIT;
299
-   struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT);
300
+   struct device_info dev_info;
301
    size_t size;
302
 
303
    is_monitor = pw_manager_object_is_monitor(o);
304
@@ -3904,20 +3911,8 @@
305
    if (module_id == SPA_ID_INVALID &&
306
        (str = spa_dict_lookup(info->props, "pulse.module.id")) != NULL)
307
        module_id = (uint32_t)atoi(str);
308
-   if ((str = spa_dict_lookup(info->props, PW_KEY_DEVICE_ID)) != NULL)
309
-       card_id = (uint32_t)atoi(str);
310
-   if ((str = spa_dict_lookup(info->props, "card.profile.device")) != NULL)
311
-       dev_info.device = (uint32_t)atoi(str);
312
-
313
-   if (card_id != SPA_ID_INVALID) {
314
-       struct selector sel = { .id = card_id, .type = pw_manager_object_is_card, };
315
-       card = select_object(manager, &sel);
316
-   }
317
-   if (card)
318
-       collect_card_info(card, &card_info);
319
-
320
-   collect_device_info(o, card, &dev_info, is_monitor, &impl->defs);
321
 
322
+   get_device_info(o, &dev_info, PW_DIRECTION_INPUT, is_monitor);
323
    if (!validate_device_info(&dev_info)) {
324
        pw_log_warn("%d: source not ready: sample:%d map:%d volume:%d",
325
                o->id, sample_spec_valid(&dev_info.ss),
326
@@ -3927,6 +3922,14 @@
327
    }
328
 
329
    flags = SOURCE_LATENCY | SOURCE_DYNAMIC_LATENCY | SOURCE_DECIBEL_VOLUME;
330
+
331
+   if (dev_info.card_id != SPA_ID_INVALID) {
332
+       struct selector sel = { .id = dev_info.card_id, .type = pw_manager_object_is_card, };
333
+       card = select_object(manager, &sel);
334
+   }
335
+   if (card)
336
+       collect_card_info(card, &card_info);
337
+
338
    if (!pw_manager_object_is_virtual(o))
339
        flags |= SOURCE_HARDWARE;
340
    if (pw_manager_object_is_network(o))
341
@@ -4036,13 +4039,12 @@
342
 static int fill_sink_input_info(struct client *client, struct message *m,
343
        struct pw_manager_object *o)
344
 {
345
-   struct impl *impl = client->impl;
346
    struct pw_node_info *info = o->info;
347
    struct pw_manager *manager = client->manager;
348
    const char *str;
349
    uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID;
350
    uint32_t peer_index;
351
-   struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_OUTPUT);
352
+   struct device_info dev_info;
353
 
354
    if (!pw_manager_object_is_sink_input(o) || info == NULL || info->props == NULL)
355
        return -ENOENT;
356
@@ -4057,8 +4059,7 @@
357
        (str = spa_dict_lookup(info->props, PW_KEY_CLIENT_ID)) != NULL)
358
        client_id = (uint32_t)atoi(str);
359
 
360
-   collect_device_info(o, NULL, &dev_info, false, &impl->defs);
361
-
362
+   get_device_info(o, &dev_info, PW_DIRECTION_OUTPUT, false);
363
    if (!validate_device_info(&dev_info))
364
        return -ENOENT;
365
 
366
@@ -4117,13 +4118,12 @@
367
 static int fill_source_output_info(struct client *client, struct message *m,
368
        struct pw_manager_object *o)
369
 {
370
-   struct impl *impl = client->impl;
371
    struct pw_node_info *info = o->info;
372
    struct pw_manager *manager = client->manager;
373
    const char *str;
374
    uint32_t module_id = SPA_ID_INVALID, client_id = SPA_ID_INVALID;
375
    uint32_t peer_index;
376
-   struct device_info dev_info = DEVICE_INFO_INIT(PW_DIRECTION_INPUT);
377
+   struct device_info dev_info;
378
 
379
    if (!pw_manager_object_is_source_output(o) || info == NULL || info->props == NULL)
380
        return -ENOENT;
381
@@ -4138,8 +4138,7 @@
382
        (str = spa_dict_lookup(info->props, PW_KEY_CLIENT_ID)) != NULL)
383
        client_id = (uint32_t)atoi(str);
384
 
385
-   collect_device_info(o, NULL, &dev_info, false, &impl->defs);
386
-
387
+   get_device_info(o, &dev_info, PW_DIRECTION_INPUT, false);
388
    if (!validate_device_info(&dev_info))
389
        return -ENOENT;
390
 
391
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
329
 
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
+
202
+   hlen = VBAN_HEADER_SIZE;
203
+
204
+   n_frames = hdr->n_frames;
205
+   if (impl->have_sync && impl->n_frames != n_frames) {
206
+       pw_log_info("unexpected frame (%d != %d)",
207
+               n_frames, impl->n_frames);
208
+       impl->have_sync = false;
209
+   }
210
+   impl->n_frames = n_frames + 1;
211
+
212
+   impl->receiving = true;
213
+
214
+   return vban_midi_receive_midi(impl, buffer, hlen, len);
215
+
216
+short_packet:
217
+   pw_log_warn("short packet received");
218
+   return -EINVAL;
219
+invalid_version:
220
+   pw_log_warn("invalid RTP version");
221
+   spa_debug_mem(0, buffer, len);
222
+   return -EPROTO;
223
+}
224
+
225
+static void vban_midi_flush_packets(struct impl *impl,
226
+       struct spa_pod_sequence *sequence, uint32_t timestamp, uint32_t rate)
227
+{
228
+   struct spa_pod_control *c;
229
+   struct vban_header header;
230
+   struct iovec iov2;
231
+   uint32_t len;
232
+
233
+   header = impl->header;
234
+
235
+   iov0.iov_base = &header;
236
+   iov0.iov_len = sizeof(header);
237
+   iov1.iov_base = impl->buffer;
238
+   iov1.iov_len = 0;
239
+
240
+   len = 0;
241
+
242
+   SPA_POD_SEQUENCE_FOREACH(sequence, c) {
243
+       void *ev;
244
+       uint32_t size;
245
+
246
+       if (c->type != SPA_CONTROL_Midi)
247
+           continue;
248
+
249
+       ev = SPA_POD_BODY(&c->value),
250
+                size = SPA_POD_BODY_SIZE(&c->value);
251
+       if (len == 0) {
252
+           /* start new packet */
253
+           header.n_frames++;
254
+       } else if (len + size > impl->mtu) {
255
+           /* flush packet when we have one and when it's too large */
256
+           iov1.iov_len = len;
257
+
258
+           pw_log_debug("sending %d", len);
259
+           vban_stream_emit_send_packet(impl, iov, 2);
260
+           len = 0;
261
+       }
262
+       memcpy(&impl->bufferlen, ev, size);
263
+       len += size;
264
+   }
265
+   if (len > 0) {
266
+       /* flush last packet */
267
+       iov1.iov_len = len;
268
+
269
+       pw_log_debug("sending %d", len);
270
+       vban_stream_emit_send_packet(impl, iov, 2);
271
+   }
272
+   impl->header.n_frames = header.n_frames;
273
+}
274
+
275
+static void vban_midi_process_capture(void *data)
276
+{
277
+   struct impl *impl = data;
278
+   struct pw_buffer *buf;
279
+   struct spa_data *d;
280
+   uint32_t offs, size, timestamp, rate;
281
+   struct spa_pod *pod;
282
+   void *ptr;
283
+
284
+   if ((buf = pw_stream_dequeue_buffer(impl->stream)) == NULL) {
285
+       pw_log_debug("Out of stream buffers: %m");
286
+       return;
287
+   }
288
+   d = buf->buffer->datas;
289
+
290
+   offs = SPA_MIN(d0.chunk->offset, d0.maxsize);
291
+   size = SPA_MIN(d0.chunk->size, d0.maxsize - offs);
292
+
293
+   if (SPA_LIKELY(impl->io_position)) {
294
+       rate = impl->io_position->clock.rate.denom;
295
+       timestamp = impl->io_position->clock.position * impl->rate / rate;
296
+   } else {
297
+       rate = 10000;
298
+       timestamp = 0;
299
+   }
300
+
301
+   ptr = SPA_PTROFF(d0.data, offs, void);
302
+
303
+   if ((pod = spa_pod_from_data(ptr, size, 0, size)) == NULL)
304
+       goto done;
305
+   if (!spa_pod_is_sequence(pod))
306
+       goto done;
307
+
308
+   if (!impl->have_sync) {
309
+       pw_log_info("sync to timestamp:%u n_frames:%u",
310
+               timestamp, impl->n_frames);
311
+       impl->have_sync = true;
312
+   }
313
+
314
+   vban_midi_flush_packets(impl, (struct spa_pod_sequence*)pod, timestamp, rate);
315
+
316
+done:
317
+   pw_stream_queue_buffer(impl->stream, buf);
318
+}
319
+
320
+static int vban_midi_init(struct impl *impl, enum spa_direction direction)
321
+{
322
+   if (direction == SPA_DIRECTION_INPUT)
323
+       impl->stream_events.process = vban_midi_process_capture;
324
+   else
325
+       impl->stream_events.process = vban_midi_process_playback;
326
+   impl->receive_vban = vban_midi_receive;
327
+   return 0;
328
+}
329
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
Refresh

No build results available

Refresh

No rpmlint results available

Request History
Bjørn Lie's avatar

zaitor created request over 1 year ago

New upstream release


Bjørn Lie's avatar

zaitor accepted request over 1 year ago

Xin