1 /* PipeWire
2 *
3 * Copyright © 2020 Wim Taymans
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25 #ifndef PULSE_SERVER_DEFS_H
26 #define PULSE_SERVER_DEFS_H
27
28 #include <pipewire/node.h>
29
30 #define FLAG_SHMDATA 0x80000000LU
31 #define FLAG_SHMDATA_MEMFD_BLOCK 0x20000000LU
32 #define FLAG_SHMRELEASE 0x40000000LU
33 #define FLAG_SHMREVOKE 0xC0000000LU
34 #define FLAG_SHMMASK 0xFF000000LU
35 #define FLAG_SEEKMASK 0x000000FFLU
36 #define FLAG_SHMWRITABLE 0x00800000LU
37
38 #define SEEK_RELATIVE 0
39 #define SEEK_ABSOLUTE 1
40 #define SEEK_RELATIVE_ON_READ 2
41 #define SEEK_RELATIVE_END 3
42
43 #define FRAME_SIZE_MAX_ALLOW (1024*1024*16)
44
45 #define PROTOCOL_FLAG_MASK 0xffff0000u
46 #define PROTOCOL_VERSION_MASK 0x0000ffffu
47 #define PROTOCOL_VERSION 35
48
49 #define NATIVE_COOKIE_LENGTH 256
50 #define MAX_TAG_SIZE (64*1024)
51
52 #define MIN_BUFFERS 1u
53 #define MAX_BUFFERS 4u
54
55 #define MAXLENGTH (4*1024*1024) /* 4MB */
56
57 #define SCACHE_ENTRY_SIZE_MAX (1024*1024*16)
58
59 #define INDEX_MASK 0xffffu
60 #define MONITOR_FLAG (1u << 16)
61 #define EXTENSION_FLAG (1u << 17)
62 #define MODULE_FLAG (1u << 18)
63
64 #define DEFAULT_SINK "@DEFAULT_SINK@"
65 #define DEFAULT_SOURCE "@DEFAULT_SOURCE@"
66 #define DEFAULT_MONITOR "@DEFAULT_MONITOR@"
67
68 enum error_code {
69 ERR_OK = 0, /**< No error */
70 ERR_ACCESS, /**< Access failure */
71 ERR_COMMAND, /**< Unknown command */
72 ERR_INVALID, /**< Invalid argument */
73 ERR_EXIST, /**< Entity exists */
74 ERR_NOENTITY, /**< No such entity */
75 ERR_CONNECTIONREFUSED, /**< Connection refused */
76 ERR_PROTOCOL, /**< Protocol error */
77 ERR_TIMEOUT, /**< Timeout */
78 ERR_AUTHKEY, /**< No authentication key */
79 ERR_INTERNAL, /**< Internal error */
80 ERR_CONNECTIONTERMINATED, /**< Connection terminated */
81 ERR_KILLED, /**< Entity killed */
82 ERR_INVALIDSERVER, /**< Invalid server */
83 ERR_MODINITFAILED, /**< Module initialization failed */
84 ERR_BADSTATE, /**< Bad state */
85 ERR_NODATA, /**< No data */
86 ERR_VERSION, /**< Incompatible protocol version */
87 ERR_TOOLARGE, /**< Data too large */
88 ERR_NOTSUPPORTED, /**< Operation not supported \since 0.9.5 */
89 ERR_UNKNOWN, /**< The error code was unknown to the client */
90 ERR_NOEXTENSION, /**< Extension does not exist. \since 0.9.12 */
91 ERR_OBSOLETE, /**< Obsolete functionality. \since 0.9.15 */
92 ERR_NOTIMPLEMENTED, /**< Missing implementation. \since 0.9.15 */
93 ERR_FORKED, /**< The caller forked without calling execve() and tried to reuse the context. \since 0.9.15 */
94 ERR_IO, /**< An IO error happened. \since 0.9.16 */
95 ERR_BUSY, /**< Device or resource busy. \since 0.9.17 */
96 ERR_MAX /**< Not really an error but the first invalid error code */
97 };
98
res_to_err(int res)99 static inline int res_to_err(int res)
100 {
101 switch (res) {
102 case 0: return ERR_OK;
103 case -EACCES: case -EPERM: return ERR_ACCESS;
104 case -ENOTTY: return ERR_COMMAND;
105 case -EINVAL: return ERR_INVALID;
106 case -EEXIST: return ERR_EXIST;
107 case -ENOENT: case -ESRCH: case -ENXIO: case -ENODEV: return ERR_NOENTITY;
108 case -ECONNREFUSED:
109 #ifdef ENONET
110 case -ENONET:
111 #endif
112 case -EHOSTDOWN: case -ENETDOWN: return ERR_CONNECTIONREFUSED;
113 case -EPROTO: case -EBADMSG: return ERR_PROTOCOL;
114 case -ETIMEDOUT:
115 #ifdef ETIME
116 case -ETIME:
117 #endif
118 return ERR_TIMEOUT;
119 #ifdef ENOKEY
120 case -ENOKEY: return ERR_AUTHKEY;
121 #endif
122 case -ECONNRESET: case -EPIPE: return ERR_CONNECTIONTERMINATED;
123 #ifdef EBADFD
124 case -EBADFD: return ERR_BADSTATE;
125 #endif
126 #ifdef ENODATA
127 case -ENODATA: return ERR_NODATA;
128 #endif
129 case -EOVERFLOW: case -E2BIG: case -EFBIG:
130 case -ERANGE: case -ENAMETOOLONG: return ERR_TOOLARGE;
131 case -ENOTSUP: case -EPROTONOSUPPORT: case -ESOCKTNOSUPPORT: return ERR_NOTSUPPORTED;
132 case -ENOSYS: return ERR_NOTIMPLEMENTED;
133 case -EIO: return ERR_IO;
134 case -EBUSY: return ERR_BUSY;
135 case -ENFILE: case -EMFILE: return ERR_INTERNAL;
136 }
137 return ERR_UNKNOWN;
138 }
139
140 enum {
141 SUBSCRIPTION_MASK_NULL = 0x0000U,
142 SUBSCRIPTION_MASK_SINK = 0x0001U,
143 SUBSCRIPTION_MASK_SOURCE = 0x0002U,
144 SUBSCRIPTION_MASK_SINK_INPUT = 0x0004U,
145 SUBSCRIPTION_MASK_SOURCE_OUTPUT = 0x0008U,
146 SUBSCRIPTION_MASK_MODULE = 0x0010U,
147 SUBSCRIPTION_MASK_CLIENT = 0x0020U,
148 SUBSCRIPTION_MASK_SAMPLE_CACHE = 0x0040U,
149 SUBSCRIPTION_MASK_SERVER = 0x0080U,
150 SUBSCRIPTION_MASK_AUTOLOAD = 0x0100U,
151 SUBSCRIPTION_MASK_CARD = 0x0200U,
152 SUBSCRIPTION_MASK_ALL = 0x02ffU
153 };
154
155 enum {
156 SUBSCRIPTION_EVENT_SINK = 0x0000U,
157 SUBSCRIPTION_EVENT_SOURCE = 0x0001U,
158 SUBSCRIPTION_EVENT_SINK_INPUT = 0x0002U,
159 SUBSCRIPTION_EVENT_SOURCE_OUTPUT = 0x0003U,
160 SUBSCRIPTION_EVENT_MODULE = 0x0004U,
161 SUBSCRIPTION_EVENT_CLIENT = 0x0005U,
162 SUBSCRIPTION_EVENT_SAMPLE_CACHE = 0x0006U,
163 SUBSCRIPTION_EVENT_SERVER = 0x0007U,
164 SUBSCRIPTION_EVENT_AUTOLOAD = 0x0008U,
165 SUBSCRIPTION_EVENT_CARD = 0x0009U,
166 SUBSCRIPTION_EVENT_FACILITY_MASK = 0x000FU,
167
168 SUBSCRIPTION_EVENT_NEW = 0x0000U,
169 SUBSCRIPTION_EVENT_CHANGE = 0x0010U,
170 SUBSCRIPTION_EVENT_REMOVE = 0x0020U,
171 SUBSCRIPTION_EVENT_TYPE_MASK = 0x0030U
172 };
173
174 enum {
175 STATE_INVALID = -1,
176 STATE_RUNNING = 0,
177 STATE_IDLE = 1,
178 STATE_SUSPENDED = 2,
179 STATE_INIT = -2,
180 STATE_UNLINKED = -3
181 };
182
node_state(enum pw_node_state state)183 static inline int node_state(enum pw_node_state state)
184 {
185 switch (state) {
186 case PW_NODE_STATE_ERROR:
187 return STATE_UNLINKED;
188 case PW_NODE_STATE_CREATING:
189 return STATE_INIT;
190 case PW_NODE_STATE_SUSPENDED:
191 return STATE_SUSPENDED;
192 case PW_NODE_STATE_IDLE:
193 return STATE_IDLE;
194 case PW_NODE_STATE_RUNNING:
195 return STATE_RUNNING;
196 }
197 return STATE_INVALID;
198 }
199
200 enum {
201 SINK_HW_VOLUME_CTRL = 0x0001U,
202 SINK_LATENCY = 0x0002U,
203 SINK_HARDWARE = 0x0004U,
204 SINK_NETWORK = 0x0008U,
205 SINK_HW_MUTE_CTRL = 0x0010U,
206 SINK_DECIBEL_VOLUME = 0x0020U,
207 SINK_FLAT_VOLUME = 0x0040U,
208 SINK_DYNAMIC_LATENCY = 0x0080U,
209 SINK_SET_FORMATS = 0x0100U,
210 };
211
212 enum {
213 SOURCE_HW_VOLUME_CTRL = 0x0001U,
214 SOURCE_LATENCY = 0x0002U,
215 SOURCE_HARDWARE = 0x0004U,
216 SOURCE_NETWORK = 0x0008U,
217 SOURCE_HW_MUTE_CTRL = 0x0010U,
218 SOURCE_DECIBEL_VOLUME = 0x0020U,
219 SOURCE_DYNAMIC_LATENCY = 0x0040U,
220 SOURCE_FLAT_VOLUME = 0x0080U,
221 };
222
223 static const char * const port_types[] = {
224 "unknown",
225 "aux",
226 "speaker",
227 "headphones",
228 "line",
229 "mic",
230 "headset",
231 "handset",
232 "earpiece",
233 "spdif",
234 "hdmi",
235 "tv",
236 "radio",
237 "video",
238 "usb",
239 "bluetooth",
240 "portable",
241 "handsfree",
242 "car",
243 "hifi",
244 "phone",
245 "network",
246 "analog",
247 };
248
port_type_value(const char * port_type)249 static inline uint32_t port_type_value(const char *port_type)
250 {
251 uint32_t i;
252 for (i = 0; i < SPA_N_ELEMENTS(port_types); i++) {
253 if (strcmp(port_types[i], port_type) == 0)
254 return i;
255 }
256 return 0;
257 }
258
259 #define METADATA_DEFAULT_SINK "default.audio.sink"
260 #define METADATA_DEFAULT_SOURCE "default.audio.source"
261 #define METADATA_CONFIG_DEFAULT_SINK "default.configured.audio.sink"
262 #define METADATA_CONFIG_DEFAULT_SOURCE "default.configured.audio.source"
263 #define METADATA_TARGET_NODE "target.node"
264
265 #endif /* PULSE_SERVER_DEFS_H */
266