File: connection.h

package info (click to toggle)
libmpdclient 2.22-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 896 kB
  • sloc: ansic: 9,923; makefile: 9
file content (294 lines) | stat: -rw-r--r-- 9,402 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
// SPDX-License-Identifier: BSD-3-Clause
// Copyright The Music Player Daemon Project

/*! \file
 * \brief MPD client library
 *
 * Do not include this header directly.  Use mpd/client.h instead.
 */

#ifndef MPD_CONNECTION_H
#define MPD_CONNECTION_H

#include "protocol.h"
#include "error.h"
#include "compiler.h"

#include <stdbool.h>

struct mpd_async;

/**
 * \struct mpd_connection
 *
 * This opaque object represents a connection to a MPD server.  Call
 * mpd_connection_new() to create a new instance.  To free an
 * instance, call mpd_connection_free().  Example:
 *
 *     struct mpd_connection *conn = mpd_connection_new(NULL, 0, 0);
 *
 *     // error handling
 *     if (conn == NULL) {
 *         fprintf(stderr, "Out of memory\n");
 *         return;
 *     }
 *     if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) {
 *         fprintf(stderr, "%s\n", mpd_connection_get_error_message(c));
 *         mpd_connection_free(c);
 *         return;
 *     }
 *
 *     // we can now use the connection
 *     mpd_run_next(conn);
 *
 *     // close the connection and free memory
 *     mpd_connection_free(conn);
 *
 * Error handling: most functions return a `bool` indicating success
 * or failure.  In this case, you may query the nature of the error
 * with the functions mpd_connection_get_error(),
 * mpd_connection_get_error_message(),
 * mpd_connection_get_server_error().
 *
 * Some errors can be cleared by calling mpd_connection_clear_error(),
 * like #MPD_ERROR_SERVER, #MPD_ERROR_ARGUMENT.  Most others are
 * fatal, and cannot be recovered, like #MPD_ERROR_CLOSED -
 * mpd_connection_clear_error() returns false.
 *
 * Some functions like mpd_recv_pair() cannot differentiate between
 * "end of response" and "error".  If this function returns `NULL`, you
 * have to check mpd_connection_get_error().
 *
 * To integrate this object in a non-blocking event I/O loop, use
 * mpd_connection_get_fd() to obtain the underlying socket descriptor.
 */
struct mpd_connection;

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Opens a new connection to a MPD server.  Both the name server
 * lookup and the `connect()` call are done synchronously.  After this
 * function has returned, you should check if the connection was
 * successful with mpd_connection_get_error().
 *
 * @param host the server's host name, IP address or Unix socket path.
 * If the resolver returns more than one IP address for a host name,
 * this functions tries all of them until one accepts the connection.
 * `NULL` is allowed here, which will connect to the default host
 * (using the `MPD_HOST` environment variable if present).
 * @param port the TCP port to connect to, 0 for default port (using
 * the `MPD_PORT` environment variable if present).  If "host" is a Unix
 * socket path, this parameter is ignored.
 * @param timeout_ms the timeout in milliseconds, 0 for the default
 * timeout (the environment variable `MPD_TIMEOUT` may specify a timeout
 * in seconds); you may modify it later with
 * mpd_connection_set_timeout()
 * @return a mpd_connection object (which may have failed to connect),
 * or `NULL` on out-of-memory
 *
 * @since libmpdclient 2.3 added support for `MPD_HOST`, `MPD_PORT`
 * and `MPD_TIMEOUT`.
 */
mpd_malloc
struct mpd_connection *
mpd_connection_new(const char *host, unsigned port, unsigned timeout_ms);

/**
 * Creates a #mpd_connection object based on an existing asynchronous
 * MPD connection.  You should not continue to use the #mpd_async
 * object.  Note that mpd_connection_free() also frees your #mpd_async
 * object!
 *
 * This function does not block at all, which is why you have to pass
 * the welcome message to it.
 *
 * @param async a #mpd_async instance
 * @param welcome the first line sent by MPD (the welcome message)
 * @return a mpd_connection object, or `NULL` on out-of-memory
 */
mpd_malloc
struct mpd_connection *
mpd_connection_new_async(struct mpd_async *async, const char *welcome);

/**
 * Close the connection and free all memory.
 *
 * @param connection the connection to MPD
 */
void mpd_connection_free(struct mpd_connection *connection);

/**
 * Returns the settings which were used to connect to the server.  May
 * be `NULL` if the settings are not known.
 *
 * @since libmpdclient 2.4
 */
const struct mpd_settings *
mpd_connection_get_settings(const struct mpd_connection *connection);

/**
 * Enables (or disables) TCP keepalives.
 *
 * Keepalives are enabled using the SO_KEEPALIVE socket option.  They may be
 * required for long-idled connections to persist on some networks that
 * would otherwise terminate inactive TCP sessions.
 *
 * The default value is false.
 *
 * @param connection the connection to MPD
 * @param keepalive whether TCP keepalives should be enabled
 * @return true on success, false if setsockopt failed
 *
 * @since libmpdclient 2.10
 */
bool
mpd_connection_set_keepalive(struct mpd_connection *connection,
			     bool keepalive);

/**
 * Sets the timeout for synchronous operations.  If the MPD server
 * does not send a response during this time span, the operation is
 * aborted by libmpdclient.
 *
 * The initial value is the one passed to mpd_connection_new().  If
 * you have used mpd_connection_new_async(), then the default value is
 * 30 seconds.
 *
 * @param connection the connection to MPD
 * @param timeout_ms the desired timeout in milliseconds; must not be 0
 */
void mpd_connection_set_timeout(struct mpd_connection *connection,
				unsigned timeout_ms);

/**
 * Returns the file descriptor which should be polled by the caller.
 * Do not use the file descriptor for anything except polling!  The
 * file descriptor never changes during the lifetime of this
 * #mpd_connection object.
 *
 * To integrate this library in a non-blocking event I/O loop, use
 * this function to obtain the underlying socket descriptor and
 * register it in the event loop.  As soon as it becomes ready for
 * reading, use this library's functions to receive responses from
 * MPD.  Example:
 *
 *     if (!mpd_send_idle(conn))
 *         return handle_error();
 *     register_socket(mpd_connection_get_fd(conn));
 *
 * And in the event callback:
 *
 *     enum mpd_idle events = mpd_recv_idle(conn);
 *     // handle the events
 *     // .. and then call mpd_send_idle() again to keep listening
 */
mpd_pure
int
mpd_connection_get_fd(const struct mpd_connection *connection);

/**
 * Returns the underlying #mpd_async object.  This can be used to send
 * commands asynchronously.  During an asynchronous command, you must
 * not use synchronous #mpd_connection functions until the
 * asynchronous response has been finished.
 *
 * If an error occurs while using #mpd_async, you must close the
 * #mpd_connection.
 */
mpd_pure
struct mpd_async *
mpd_connection_get_async(struct mpd_connection *connection);

/**
 * Returns the libmpdclient error code.  MPD_ERROR_SUCCESS means no
 * error occurred.
 */
mpd_pure
enum mpd_error
mpd_connection_get_error(const struct mpd_connection *connection);

/**
 * Returns the human-readable (English) libmpdclient error message.
 * Calling this function is only valid if an error really occurred.
 * Check with mpd_connection_get_error().
 *
 * For #MPD_ERROR_SERVER, the error message is encoded in UTF-8.
 * #MPD_ERROR_SYSTEM obtains its error message from the operating
 * system, and thus the locale's character set (and probably language)
 * is used.  Keep that in mind when you print error messages.
 */
mpd_pure
const char *
mpd_connection_get_error_message(const struct mpd_connection *connection);

/**
 * Returns the error code returned from the server.  Calling this
 * function is only valid if mpd_connection_get_error() returned
 * #MPD_ERROR_SERVER.
 */
mpd_pure
enum mpd_server_error
mpd_connection_get_server_error(const struct mpd_connection *connection);

/**
 * Returns the location of the server error, i.e. an index within the
 * command list.  Calling this function is only valid in a command
 * list response, and if mpd_connection_get_error() returned
 * #MPD_ERROR_SERVER.
 *
 * @since libmpdclient 2.4
 */
mpd_pure
unsigned
mpd_connection_get_server_error_location(const struct mpd_connection *connection);

/**
 * Returns the error code from the operating system; on most operating
 * systems, this is the errno value.  Calling this function is only
 * valid if mpd_connection_get_error() returned #MPD_ERROR_SYSTEM.
 *
 * May be 0 if the operating system did not specify an error code.
 */
mpd_pure
int
mpd_connection_get_system_error(const struct mpd_connection *connection);

/**
 * Attempts to recover from an error condition.  This function must be
 * called after a non-fatal error before you can continue using this
 * object.
 *
 * @return true on success, false if the error is fatal and cannot be
 * recovered
 */
bool
mpd_connection_clear_error(struct mpd_connection *connection);

/**
 * Returns a three-tuple containing the major, minor and patch version
 * of the MPD protocol.
 */
mpd_pure
const unsigned *
mpd_connection_get_server_version(const struct mpd_connection *connection);

/**
 * Compares the MPD protocol version with the specified triple.
 *
 * @return -1 if the server is older, 1 if it is newer, 0 if it is
 * equal
 */
mpd_pure
int
mpd_connection_cmp_server_version(const struct mpd_connection *connection,
				  unsigned major, unsigned minor,
				  unsigned patch);

#ifdef __cplusplus
}
#endif

#endif