]>
Commit | Line | Data |
---|---|---|
796b7da0 MB |
1 | #ifdef __cplusplus |
2 | extern "C" { | |
3 | #endif | |
4 | ||
a2fb5d21 JL |
5 | #ifndef _COMMON_H |
6 | #define _COMMON_H | |
7 | ||
064bd293 | 8 | #include <libconfig.h> |
c8c70b60 | 9 | #include <pthread.h> |
3198ec42 | 10 | #include <signal.h> |
a2fb5d21 | 11 | #include <stdint.h> |
4a752e67 | 12 | #include <sys/socket.h> |
86b72a98 | 13 | #include <sys/stat.h> |
d692fab9 | 14 | #include <unistd.h> |
e73657d6 | 15 | |
a2fb5d21 | 16 | #include "audio.h" |
064bd293 | 17 | #include "config.h" |
88c55066 | 18 | #include "definitions.h" |
958fceb6 | 19 | #include "mdns.h" |
a2fb5d21 | 20 | |
4a752e67 JL |
21 | // struct sockaddr_in6 is bigger than struct sockaddr. derp |
22 | #ifdef AF_INET6 | |
87a0475c MB |
23 | #define SOCKADDR struct sockaddr_storage |
24 | #define SAFAMILY ss_family | |
4a752e67 | 25 | #else |
87a0475c MB |
26 | #define SOCKADDR struct sockaddr |
27 | #define SAFAMILY sa_family | |
4a752e67 JL |
28 | #endif |
29 | ||
c9b3d2a2 | 30 | #if defined(CONFIG_DBUS_INTERFACE) || defined(CONFIG_MPRIS_INTERFACE) |
85ba78b6 | 31 | typedef enum { |
74f41a17 | 32 | DBT_system = 0, // use the session bus |
bafdd94e | 33 | DBT_session, // use the system bus |
85ba78b6 | 34 | } dbus_session_type; |
74f41a17 MB |
35 | #endif |
36 | ||
4963c65a MB |
37 | typedef enum { |
38 | TOE_normal, | |
39 | TOE_emergency, | |
d6536a8e MB |
40 | TOE_dbus // a request was made on a D-Bus interface (the native D-Bus or MPRIS interfaces)-- don't |
41 | // wait for the dbus thread to exit | |
4963c65a MB |
42 | } type_of_exit_type; |
43 | ||
6f8b35d1 MB |
44 | #define sps_extra_code_output_stalled 32768 |
45 | #define sps_extra_code_output_state_cannot_make_ready 32769 | |
9d5ff22f | 46 | |
aac57c9c | 47 | // yeah/no/auto |
f7717745 | 48 | typedef enum { YNA_AUTO = -1, YNA_NO = 0, YNA_YES = 1 } yna_type; |
aac57c9c MB |
49 | |
50 | // yeah/no/dont-care | |
f7717745 | 51 | typedef enum { YNDK_DONT_KNOW = -1, YNDK_NO = 0, YNDK_YES = 1 } yndk_type; |
1244bc49 | 52 | |
f7717745 | 53 | typedef enum { |
b8b5b7fa MB |
54 | SS_LITTLE_ENDIAN = 0, |
55 | SS_PDP_ENDIAN, | |
56 | SS_BIG_ENDIAN, | |
57 | } endian_type; | |
58 | ||
f7717745 | 59 | typedef enum { |
7860d692 | 60 | ST_basic = 0, // straight deletion or insertion of a frame in a 352-frame packet |
e513e533 | 61 | ST_soxr, // use libsoxr to make a 352 frame packet one frame longer or shorter |
c8b0be30 | 62 | ST_auto, // use soxr if compiled for it and if the soxr_index is low enough |
f7717745 | 63 | } stuffing_type; |
b9e59fc1 | 64 | |
f7717745 | 65 | typedef enum { |
1bb56b4c MB |
66 | ST_stereo = 0, |
67 | ST_mono, | |
945483d9 MB |
68 | ST_reverse_stereo, |
69 | ST_left_only, | |
70 | ST_right_only, | |
1bb56b4c MB |
71 | } playback_mode_type; |
72 | ||
f7717745 | 73 | typedef enum { |
f83b86ec MB |
74 | VCP_standard = 0, |
75 | VCP_flat, | |
ebe1ca17 | 76 | VCP_dasl_tapered, |
f83b86ec MB |
77 | } volume_control_profile_type; |
78 | ||
f7717745 | 79 | typedef enum { |
945483d9 MB |
80 | decoder_hammerton = 0, |
81 | decoder_apple_alac, | |
82 | } decoders_supported_type; | |
a1519f2a | 83 | |
f7717745 | 84 | typedef enum { |
c86823c3 | 85 | disable_standby_off = 0, |
83c0405d | 86 | disable_standby_auto, |
c86823c3 | 87 | disable_standby_always |
f7717745 | 88 | } disable_standby_mode_type; |
c86823c3 | 89 | |
e513e533 MB |
90 | // the following enum is for the formats recognised -- currently only S16LE is recognised for input, |
91 | // so these are output only for the present | |
a1519f2a | 92 | |
f7717745 | 93 | typedef enum { |
0499743b MB |
94 | SPS_FORMAT_UNKNOWN = 0, |
95 | SPS_FORMAT_S8, | |
064bd293 | 96 | SPS_FORMAT_U8, |
0499743b | 97 | SPS_FORMAT_S16, |
1d32976d MB |
98 | SPS_FORMAT_S16_LE, |
99 | SPS_FORMAT_S16_BE, | |
0499743b | 100 | SPS_FORMAT_S24, |
1d32976d | 101 | SPS_FORMAT_S24_LE, |
c8b0be30 | 102 | SPS_FORMAT_S24_BE, |
b5ee350b MB |
103 | SPS_FORMAT_S24_3LE, |
104 | SPS_FORMAT_S24_3BE, | |
0499743b | 105 | SPS_FORMAT_S32, |
1d32976d MB |
106 | SPS_FORMAT_S32_LE, |
107 | SPS_FORMAT_S32_BE, | |
83c0405d | 108 | SPS_FORMAT_AUTO, |
1d32976d | 109 | SPS_FORMAT_INVALID, |
a1519f2a MB |
110 | } sps_format_t; |
111 | ||
f7717745 | 112 | const char *sps_format_description_string(sps_format_t format); |
1d32976d | 113 | |
a2fb5d21 | 114 | typedef struct { |
54d761ff MB |
115 | double missing_port_dacp_scan_interval_seconds; // if no DACP port number can be found, check at |
116 | // these intervals | |
117 | double resend_control_first_check_time; // wait this long before asking for a missing packet to be | |
118 | // resent | |
686fc2a5 | 119 | double resend_control_check_interval_time; // wait this long between making requests |
54d761ff MB |
120 | double resend_control_last_check_time; // if the packet is missing this close to the time of use, |
121 | // give up | |
db8f10cf | 122 | pthread_mutex_t lock; |
87a0475c | 123 | config_t *cfg; |
1d32976d | 124 | int endianness; |
ea46a09a | 125 | double airplay_volume; // stored here for reloading when necessary |
8201903a MB |
126 | double default_airplay_volume; |
127 | double high_threshold_airplay_volume; | |
128 | uint64_t last_access_to_volume_info_time; | |
129 | int limit_to_high_volume_threshold_time_in_minutes; // revert to the high threshold volume level | |
130 | // if the existing volume level exceeds this | |
131 | // and hasn't been used for this amount of | |
132 | // time (0 means never revert) | |
133 | char *appName; // normally the app is called shairport-syn, but it may be symlinked | |
87a0475c | 134 | char *password; |
064bd293 MB |
135 | char *service_name; // the name for the shairport service, e.g. "Shairport Sync Version %v running |
136 | // on host %h" | |
c8c70b60 | 137 | |
9ba3ed39 | 138 | #ifdef CONFIG_PA |
54d761ff | 139 | char *pa_server; // the pulseaudio server address that Shairport Sync will play on. |
e513e533 MB |
140 | char *pa_application_name; // the name under which Shairport Sync shows up as an "Application" in |
141 | // the Sound Preferences in most desktop Linuxes. | |
e0a4e5cd | 142 | // Defaults to "Shairport Sync". Shairport Sync must be playing to see it. |
947a0ca2 | 143 | |
e0a4e5cd | 144 | char *pa_sink; // the name (or id) of the sink that Shairport Sync will play on. |
9ba3ed39 | 145 | #endif |
75f3f912 | 146 | #ifdef CONFIG_METADATA |
87a0475c MB |
147 | int metadata_enabled; |
148 | char *metadata_pipename; | |
fd567805 | 149 | char *metadata_sockaddr; |
150 | int metadata_sockport; | |
8991f342 | 151 | size_t metadata_sockmsglength; |
87a0475c | 152 | int get_coverart; |
7c1a5fd0 | 153 | double metadata_progress_interval; // 0 means no progress reports |
02694948 | 154 | #endif |
c9b3d2a2 | 155 | #ifdef CONFIG_MQTT |
02694948 TZ |
156 | int mqtt_enabled; |
157 | char *mqtt_hostname; | |
158 | int mqtt_port; | |
159 | char *mqtt_username; | |
160 | char *mqtt_password; | |
161 | char *mqtt_capath; | |
162 | char *mqtt_cafile; | |
163 | char *mqtt_certfile; | |
164 | char *mqtt_keyfile; | |
165 | char *mqtt_topic; | |
166 | int mqtt_publish_raw; | |
167 | int mqtt_publish_parsed; | |
168 | int mqtt_publish_cover; | |
169 | int mqtt_enable_remote; | |
3d720d65 | 170 | char *mqtt_empty_payload_substitute; |
75f3f912 | 171 | #endif |
d6536a8e | 172 | uint8_t ap1_prefix[6]; |
966d68bd | 173 | uint8_t hw_addr[8]; // only needs 6 but 8 is handy when converting this to a number |
87a0475c | 174 | int port; |
8c55f603 MB |
175 | int udp_port_base; |
176 | int udp_port_range; | |
87a0475c | 177 | int ignore_volume_control; |
cf29625d | 178 | int volume_max_db_set; // set to 1 if a maximum volume db has been set |
2a4a4ed2 | 179 | int volume_max_db; |
8201903a MB |
180 | int no_sync; // disable synchronisation, even if it's available |
181 | int no_mmap; // disable use of mmap-based output, even if it's available | |
182 | double resync_threshold; // if it gets out of whack by more than this number of seconds, do a | |
183 | // resync. if zero, never do a resync. | |
d2ca8c84 MB |
184 | double resync_recovery_time; // if sync is late, drop the delay but also drop the following frames |
185 | // up to the resync_recovery_time | |
87a0475c MB |
186 | int allow_session_interruption; |
187 | int timeout; // while in play mode, exit if no packets of audio come in for more than this number | |
188 | // of seconds . Zero means never exit. | |
3a386a6a | 189 | int dont_check_timeout; // this is used to maintain backward compatibility with the old -t option |
87a0475c MB |
190 | // behaviour; only set by -t 0, cleared by everything else |
191 | char *output_name; | |
192 | audio_output *output; | |
193 | char *mdns_name; | |
194 | mdns_backend *mdns; | |
195 | int buffer_start_fill; | |
de071aef MB |
196 | uint32_t userSuppliedLatency; // overrides all other latencies -- use with caution |
197 | uint32_t fixedLatencyOffset; // add this to all automatic latencies supplied to get the actual | |
e0a4e5cd | 198 | // total latency |
c8b0be30 | 199 | // the total latency will be limited to the min and max-latency values, if supplied |
e76cfa69 | 200 | #ifdef CONFIG_LIBDAEMON |
87a0475c | 201 | int daemonise; |
e513e533 MB |
202 | int daemonise_store_pid; // don't try to save a PID file |
203 | char *piddir; | |
5d5802db | 204 | char *computed_piddir; // the actual pid directory to create, if any |
e76cfa69 MB |
205 | char *pidfile; |
206 | #endif | |
4aaa8d19 | 207 | |
ca562872 MB |
208 | int log_fd; // file descriptor of the file or pipe to log stuff to. |
209 | char *log_file_path; // path to file or pipe to log to, if any | |
a0bb2993 MB |
210 | int logOutputLevel; // log output level |
211 | int debugger_show_elapsed_time; // in the debug message, display the time since startup | |
212 | int debugger_show_relative_time; // in the debug message, display the time since the last one | |
db8f10cf | 213 | int debugger_show_file_and_line; // in the debug message, display the filename and line number |
064bd293 | 214 | int statistics_requested, use_negotiated_latencies; |
f7717745 | 215 | playback_mode_type playback_mode; |
277d401d | 216 | char *cmd_start, *cmd_stop, *cmd_set_volume, *cmd_unfixable; |
2e181f93 | 217 | char *cmd_active_start, *cmd_active_stop; |
3e9e2285 | 218 | int cmd_blocking, cmd_start_returns_output; |
ae84366e | 219 | double tolerance; // allow this much drift before attempting to correct it |
f7717745 | 220 | stuffing_type packet_stuffing; |
9aa8f91c | 221 | int soxr_delay_index; |
c8b0be30 MB |
222 | int soxr_delay_threshold; // the soxr delay must be less or equal to this for soxr interpolation |
223 | // to be enabled under the auto setting | |
945483d9 | 224 | int decoders_supported; |
064bd293 MB |
225 | int use_apple_decoder; // set to 1 if you want to use the apple decoder instead of the original by |
226 | // David Hammerton | |
890cdd68 MB |
227 | // char *logfile; |
228 | // char *errfile; | |
87a0475c | 229 | char *configfile; |
064bd293 | 230 | char *regtype; // The regtype is the service type followed by the protocol, separated by a dot, by |
e1034e11 | 231 | // default “_raop._tcp.” for AirPlay 1. |
a109b587 MB |
232 | char *regtype2; // The regtype is the service type followed by the protocol, separated by a dot, |
233 | // by default “_raop._tcp.” for AirPlay 2. | |
234 | char *interface; // a string containg the interface name, or NULL if nothing specified | |
235 | int interface_index; // only valid if the interface string is non-NULL | |
ae84366e MB |
236 | double audio_backend_buffer_desired_length; // this will be the length in seconds of the |
237 | // audio backend buffer -- the DAC buffer for ALSA | |
80f15e1f MB |
238 | double audio_backend_buffer_interpolation_threshold_in_seconds; // below this, soxr interpolation |
239 | // will not occur -- it'll be | |
240 | // basic interpolation instead. | |
a8faacd3 MB |
241 | double disable_standby_mode_silence_threshold; // below this, silence will be added to the output |
242 | // buffer | |
243 | double disable_standby_mode_silence_scan_interval; // check the threshold this often | |
2e442853 | 244 | |
064bd293 MB |
245 | double audio_backend_latency_offset; // this will be the offset in seconds to compensate for any |
246 | // fixed latency there might be in the audio path | |
54d761ff MB |
247 | int audio_backend_silent_lead_in_time_auto; // true if the lead-in time should be from as soon as |
248 | // packets are received | |
9ba3ed39 | 249 | double audio_backend_silent_lead_in_time; // the length of the silence that should precede a play. |
54d761ff MB |
250 | uint32_t minimum_free_buffer_headroom; // when effective latency is calculated, ensure this number |
251 | // of buffers are unallocated | |
5af61798 | 252 | double active_state_timeout; // the amount of time from when play ends to when the system leaves |
c8b0be30 MB |
253 | // into the "active" mode. |
254 | uint32_t volume_range_db; // the range, in dB, from max dB to min dB. Zero means use the mixer's | |
255 | // native range. | |
256 | int volume_range_hw_priority; // when extending the volume range by combining sw and hw | |
257 | // attenuators, lowering the volume, use all the hw attenuation | |
258 | // before using | |
c5ff0dfe | 259 | // sw attenuation |
f7717745 | 260 | volume_control_profile_type volume_control_profile; |
83c0405d | 261 | |
c8b0be30 | 262 | int output_format_auto_requested; // true if the configuration requests auto configuration |
f7717745 | 263 | sps_format_t output_format; |
c8b0be30 | 264 | int output_rate_auto_requested; // true if the configuration requests auto configuration |
f13f22d8 | 265 | unsigned int output_rate; |
e513e533 | 266 | |
7b9cd28e YP |
267 | #ifdef CONFIG_CONVOLUTION |
268 | int convolution; | |
78c9331c MB |
269 | int convolver_valid; |
270 | char *convolution_ir_file; | |
7b9cd28e YP |
271 | float convolution_gain; |
272 | int convolution_max_length; | |
273 | #endif | |
e513e533 | 274 | |
7b9cd28e YP |
275 | int loudness; |
276 | float loudness_reference_volume_db; | |
e66a4794 | 277 | int alsa_use_hardware_mute; |
45ce9092 | 278 | double alsa_maximum_stall_time; |
f7717745 | 279 | disable_standby_mode_type disable_standby_mode; |
4ba0947d | 280 | volatile int keep_dac_busy; |
f7717745 | 281 | yna_type use_precision_timing; // defaults to no |
e5452e51 | 282 | |
c9b3d2a2 | 283 | #if defined(CONFIG_DBUS_INTERFACE) |
85ba78b6 | 284 | dbus_session_type dbus_service_bus_type; |
74f41a17 | 285 | #endif |
c9b3d2a2 | 286 | #if defined(CONFIG_MPRIS_INTERFACE) |
85ba78b6 | 287 | dbus_session_type mpris_service_bus_type; |
74f41a17 | 288 | #endif |
e513e533 | 289 | |
69642bb7 | 290 | #ifdef CONFIG_METADATA_HUB |
4aaa8d19 | 291 | char *cover_art_cache_dir; |
aa57f06c MB |
292 | int retain_coverart; |
293 | ||
4aab0a6f MB |
294 | int scan_interval_when_active; // number of seconds between DACP server scans when playing |
295 | // something (1) | |
296 | int scan_interval_when_inactive; // number of seconds between DACP server scans playing nothing | |
297 | // (3) | |
298 | int scan_max_bad_response_count; // number of successive bad results to ignore before giving up | |
299 | // (10) | |
300 | int scan_max_inactive_count; // number of scans to do before stopping if not made active again | |
301 | // (about 15 minutes worth) | |
4aaa8d19 | 302 | #endif |
a0bb2993 | 303 | int disable_resend_requests; // set this to stop resend request being made for missing packets |
d9c9009f MB |
304 | double diagnostic_drop_packet_fraction; // pseudo randomly drop this fraction of packets, for |
305 | // debugging. Currently audio packets only... | |
959aa08b | 306 | #ifdef CONFIG_JACK |
0b589cbe | 307 | char *jack_client_name; |
bd5cfd35 | 308 | char *jack_autoconnect_pattern; |
7285b1ee | 309 | #ifdef CONFIG_SOXR |
32646f22 | 310 | int jack_soxr_resample_quality; |
7285b1ee | 311 | #endif |
959aa08b | 312 | #endif |
ca562872 MB |
313 | void *gradients; // a linked list of the clock gradients discovered for all DACP IDs |
314 | // can't use IP numbers as they might be given to different devices | |
315 | // can't get hold of MAC addresses. | |
316 | // can't define the nvll linked list struct here | |
796b7da0 MB |
317 | |
318 | #ifdef CONFIG_AIRPLAY_2 | |
319 | uint64_t airplay_features; | |
ba73111a | 320 | uint32_t airplay_statusflags; |
796b7da0 | 321 | char *airplay_device_id; // for the Bonjour advertisement and the GETINFO PList |
ba73111a | 322 | char *airplay_pin; // non-NULL, 4 char PIN, if required for pairing |
f5cd4238 | 323 | char *airplay_pi; // UUID in the Bonjour advertisement and the GETINFO Plist |
966d68bd | 324 | char *nqptp_shared_memory_interface_name; // client name for nqptp service |
796b7da0 | 325 | #endif |
d6536a8e | 326 | int unfixable_error_reported; // only report once. |
a2fb5d21 JL |
327 | } shairport_cfg; |
328 | ||
796b7da0 MB |
329 | uint32_t nctohl(const uint8_t *p); // read 4 characters from *p and do ntohl on them |
330 | uint16_t nctohs(const uint8_t *p); // read 2 characters from *p and do ntohs on them | |
331 | uint64_t nctoh64(const uint8_t *p); // read 8 characters from *p to a uint64_t | |
8bf83c14 | 332 | |
9d9b0a18 MB |
333 | void memory_barrier(); |
334 | ||
6406c296 MB |
335 | void log_to_stderr(); // call this to direct logging to stderr; |
336 | void log_to_stdout(); // call this to direct logging to stdout; | |
337 | void log_to_syslog(); // call this to direct logging to the system log; | |
ca562872 | 338 | void log_to_file(); // call this to direct logging to a file or (pre-existing) pipe; |
fce6b513 | 339 | |
87a0475c | 340 | // true if Shairport Sync is supposed to be sending output to the output device, false otherwise |
eef08e49 MB |
341 | |
342 | int get_requested_connection_state_to_output(); | |
343 | ||
344 | void set_requested_connection_state_to_output(int v); | |
345 | ||
ca562872 MB |
346 | int try_to_open_pipe_for_writing( |
347 | const char *pathname); // open it without blocking if it's not hooked up | |
1b52e26f | 348 | |
064bd293 MB |
349 | /* from |
350 | * http://coding.debuntu.org/c-implementing-str_replace-replace-all-occurrences-substring#comment-722 | |
351 | */ | |
352 | char *str_replace(const char *string, const char *substr, const char *replacement); | |
4849c1d4 MB |
353 | |
354 | // based on http://burtleburtle.net/bob/rand/smallprng.html | |
355 | ||
356 | void r64init(uint64_t seed); | |
8d008fa2 MB |
357 | uint64_t r64u(); |
358 | int64_t r64i(); | |
4849c1d4 | 359 | |
093bf1dd MB |
360 | // if you are breaking in to a session, you need to avoid the ports of the current session |
361 | // if you are law-abiding, then you can reuse the ports. | |
362 | // so, you can reset the free UDP ports minder when you're legit, and leave it otherwise | |
363 | ||
364 | // the downside of using different ports each time is that it might make the firewall | |
365 | // rules a bit more complex, as they need to allow more than the minimum three ports. | |
366 | // a range of 10 is suggested anyway | |
367 | ||
368 | void resetFreeUDPPort(); | |
369 | uint16_t nextFreeUDPPort(); | |
370 | ||
f7717745 | 371 | extern volatile int debuglev; |
a8fe3bd1 | 372 | |
db8f10cf MB |
373 | void _die(const char *filename, const int linenumber, const char *format, ...); |
374 | void _warn(const char *filename, const int linenumber, const char *format, ...); | |
375 | void _inform(const char *filename, const int linenumber, const char *format, ...); | |
376 | void _debug(const char *filename, const int linenumber, int level, const char *format, ...); | |
377 | ||
378 | #define die(...) _die(__FILE__, __LINE__, __VA_ARGS__) | |
379 | #define debug(...) _debug(__FILE__, __LINE__, __VA_ARGS__) | |
380 | #define warn(...) _warn(__FILE__, __LINE__, __VA_ARGS__) | |
381 | #define inform(...) _inform(__FILE__, __LINE__, __VA_ARGS__) | |
a2fb5d21 JL |
382 | |
383 | uint8_t *base64_dec(char *input, int *outlen); | |
384 | char *base64_enc(uint8_t *input, int length); | |
385 | ||
386 | #define RSA_MODE_AUTH (0) | |
87a0475c | 387 | #define RSA_MODE_KEY (1) |
a2fb5d21 JL |
388 | uint8_t *rsa_apply(uint8_t *input, int inlen, int *outlen, int mode); |
389 | ||
f83b86ec | 390 | // given a volume (0 to -30) and high and low attenuations in dB*100 (e.g. 0 to -6000 for 0 to -60 |
1a555377 | 391 | // dB), return an attenuation depending on a linear interpolation along the range |
f83b86ec MB |
392 | double flat_vol2attn(double vol, long max_db, long min_db); |
393 | ||
b7d9c22d MB |
394 | // The intention behind dasl_tapered is that a given percentage change in volume should result in |
395 | // the same percentage change in perceived loudness. For instance, doubling the volume level should | |
396 | // result in doubling the perceived loudness. With the range of AirPlay volume being from -30 to 0, | |
397 | // doubling the volume from -22.5 to -15 results in an increase of 10 dB. Similarly, doubling the | |
398 | // volume from -15 to 0 results in an increase of 10 dB. For compatibility with mixers having a | |
399 | // restricted attenuation range (e.g. 30 dB), "dasl_tapered" will switch to a flat profile at low | |
400 | // AirPlay volumes. | |
ebe1ca17 | 401 | double dasl_tapered_vol2attn(double vol, long max_db, long min_db); |
87a0475c MB |
402 | // given a volume (0 to -30) and high and low attenuations in dB*100 (e.g. 0 to -6000 for 0 to -60 |
403 | // dB), return an attenuation depending on the transfer function | |
34c52224 MB |
404 | double vol2attn(double vol, long max_db, long min_db); |
405 | ||
e0983421 | 406 | // return a time in nanoseconds |
56bef8e7 MB |
407 | #ifdef COMPILE_FOR_LINUX_AND_FREEBSD_AND_CYGWIN_AND_OPENBSD |
408 | // Not defined for macOS | |
409 | uint64_t get_realtime_in_ns(void); | |
410 | #endif | |
411 | uint64_t get_absolute_time_in_ns(void); // monotonic_raw or monotonic | |
412 | uint64_t get_monotonic_time_in_ns(void); // NTP-disciplined | |
b9e59fc1 | 413 | |
a0bb2993 | 414 | // time at startup for debugging timing |
67e9b1b6 | 415 | extern uint64_t ns_time_at_startup, ns_time_at_last_debug_message; |
a0bb2993 | 416 | |
c2383d49 MB |
417 | // this is for reading an unsigned 32 bit number, such as an RTP timestamp |
418 | ||
419 | uint32_t uatoi(const char *nptr); | |
420 | ||
f7717745 MB |
421 | extern shairport_cfg config; |
422 | extern config_t config_file_stuff; | |
4963c65a | 423 | extern int type_of_exit_cleanup; // normal, emergency, dbus requested... |
b9e59fc1 | 424 | |
6c6dda9c MB |
425 | int config_set_lookup_bool(config_t *cfg, char *where, int *dst); |
426 | ||
b9e59fc1 MB |
427 | void command_start(void); |
428 | void command_stop(void); | |
44830377 | 429 | void command_execute(const char *command, const char *extra_argument, const int block); |
e37c277b | 430 | void command_set_volume(double volume); |
a2fb5d21 | 431 | |
4aaa8d19 MB |
432 | int mkpath(const char *path, mode_t mode); |
433 | ||
0b07f99f | 434 | void shairport_shutdown(); |
1eca354f | 435 | |
b98e6a9a B |
436 | extern sigset_t pselect_sigset; |
437 | ||
f7717745 | 438 | extern pthread_mutex_t the_conn_lock; |
db8f10cf MB |
439 | |
440 | #define conn_lock(arg) \ | |
441 | pthread_mutex_lock(&the_conn_lock); \ | |
442 | arg; \ | |
443 | pthread_mutex_unlock(&the_conn_lock); | |
444 | ||
fba40733 | 445 | // wait for the specified time in microseconds -- it checks every 20 milliseconds |
2dc6af2d MB |
446 | // int sps_pthread_mutex_timedlock(pthread_mutex_t *mutex, useconds_t dally_time, |
447 | // const char *debugmessage, int debuglevel); | |
18b37ea2 MB |
448 | // wait for the specified time, checking every 20 milliseconds, and block if it can't acquire the |
449 | // lock | |
ccc4fe09 MB |
450 | int _debug_mutex_lock(pthread_mutex_t *mutex, useconds_t dally_time, const char *mutexName, |
451 | const char *filename, const int line, int debuglevel); | |
18b37ea2 | 452 | |
ccc4fe09 | 453 | #define debug_mutex_lock(mu, t, d) _debug_mutex_lock(mu, t, #mu, __FILE__, __LINE__, d) |
13931664 | 454 | |
ccc4fe09 MB |
455 | int _debug_mutex_unlock(pthread_mutex_t *mutex, const char *mutexName, const char *filename, |
456 | const int line, int debuglevel); | |
93f41059 | 457 | |
f7342a70 | 458 | #define debug_mutex_unlock(mu, d) _debug_mutex_unlock(mu, #mu, __FILE__, __LINE__, d) |
93f41059 | 459 | |
ea20840d MB |
460 | void pthread_cleanup_debug_mutex_unlock(void *arg); |
461 | ||
76c5dd92 | 462 | #define pthread_cleanup_debug_mutex_lock(mu, t, d) \ |
ccc4fe09 | 463 | if (_debug_mutex_lock(mu, t, #mu, __FILE__, __LINE__, d) == 0) \ |
76c5dd92 | 464 | pthread_cleanup_push(pthread_cleanup_debug_mutex_unlock, (void *)mu) |
ea20840d | 465 | |
db8f10cf MB |
466 | #define config_lock \ |
467 | if (pthread_mutex_trylock(&config.lock) != 0) { \ | |
468 | debug(1, "config_lock: cannot acquire config.lock"); \ | |
469 | } | |
470 | ||
471 | #define config_unlock pthread_mutex_unlock(&config.lock) | |
472 | ||
f7717745 | 473 | extern pthread_mutex_t r64_mutex; |
db8f10cf MB |
474 | |
475 | #define r64_lock pthread_mutex_lock(&r64_mutex) | |
476 | ||
477 | #define r64_unlock pthread_mutex_unlock(&r64_mutex) | |
478 | ||
6dc30c6c MB |
479 | char *get_version_string(); // mallocs a string space -- remember to free it afterwards |
480 | ||
f7717745 | 481 | int64_t generate_zero_frames(char *outp, size_t number_of_frames, sps_format_t format, |
4046c0e7 | 482 | int with_dither, int64_t random_number_in); |
69b3b5d7 | 483 | |
dd1b8538 MB |
484 | void malloc_cleanup(void *arg); |
485 | ||
86b6d7bf MB |
486 | int string_update_with_size(char **str, int *flag, char *s, size_t len); |
487 | ||
5decc1bb | 488 | // from https://stackoverflow.com/questions/13663617/memdup-function-in-c, with thanks |
ca562872 | 489 | void *memdup(const void *mem, size_t size); |
5decc1bb | 490 | |
8a73d597 MB |
491 | int bind_socket_and_port(int type, int ip_family, const char *self_ip_address, uint32_t scope_id, |
492 | uint16_t *port, int *sock); | |
493 | ||
494 | uint16_t bind_UDP_port(int ip_family, const char *self_ip_address, uint32_t scope_id, int *sock); | |
495 | ||
796b7da0 MB |
496 | void socket_cleanup(void *arg); |
497 | void mutex_unlock(void *arg); | |
498 | void mutex_cleanup(void *arg); | |
499 | void cv_cleanup(void *arg); | |
500 | void thread_cleanup(void *arg); | |
e8e81a8b | 501 | #ifdef CONFIG_AIRPLAY_2 |
7ae72d79 | 502 | void plist_cleanup(void *arg); |
e8e81a8b | 503 | #endif |
796b7da0 MB |
504 | |
505 | char *debug_malloc_hex_cstring(void *packet, size_t nread); | |
506 | ||
507 | // from https://stackoverflow.com/questions/13663617/memdup-function-in-c, with thanks | |
508 | // allocates memory and copies the content to it | |
509 | // analogous to strndup; | |
510 | void *memdup(const void *mem, size_t size); | |
511 | ||
512 | // the difference between two unsigned 32-bit modulo values as a signed 32-bit result | |
513 | // now, if the two numbers are constrained to be within 2^(n-1)-1 of one another, | |
514 | // we can use their as a signed 2^n bit number which will be positive | |
515 | // if the first number is the same or "after" the second, and | |
516 | // negative otherwise | |
517 | ||
518 | int32_t mod32Difference(uint32_t a, uint32_t b); | |
e1034e11 MB |
519 | |
520 | int get_device_id(uint8_t *id, int int_length); | |
521 | ||
522 | #ifdef CONFIG_USE_GIT_VERSION_STRING | |
523 | extern char git_version_string[]; | |
524 | #endif | |
525 | ||
a2fb5d21 | 526 | #endif // _COMMON_H |
796b7da0 MB |
527 | |
528 | #ifdef __cplusplus | |
529 | } | |
530 | #endif |