Initial revision
[monky] / libmpdclient.h
1 /* libmpdclient
2    (c)2003-2004 by Warren Dukes (shank@mercury.chem.pitt.edu)
3    This project's homepage is: http://www.musicpd.org
4   
5    Redistribution and use in source and binary forms, with or without
6    modification, are permitted provided that the following conditions
7    are met:
8                                                                                 
9    - Redistributions of source code must retain the above copyright
10    notice, this list of conditions and the following disclaimer.
11                                                                                 
12    - Redistributions in binary form must reproduce the above copyright
13    notice, this list of conditions and the following disclaimer in the
14    documentation and/or other materials provided with the distribution.
15                                                                                 
16    - Neither the name of the Music Player Daemon nor the names of its
17    contributors may be used to endorse or promote products derived from
18    this software without specific prior written permission.
19                                                                                 
20    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21    ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23    A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
24    CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25    EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26    PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27    PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28    LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29    NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30    SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31
32 */
33
34 #ifndef LIBMPDCLIENT_H
35 #define LIBMPDCLIENT_H
36
37 #include <sys/time.h>
38
39 #define MPD_BUFFER_MAX_LENGTH   50000
40 #define MPD_WELCOME_MESSAGE     "OK MPD "
41
42 #define MPD_ERROR_TIMEOUT       10      /* timeout trying to talk to mpd */
43 #define MPD_ERROR_SYSTEM        11      /* system error */
44 #define MPD_ERROR_UNKHOST       12      /* unknown host */
45 #define MPD_ERROR_CONNPORT      13      /* problems connecting to port on host */
46 #define MPD_ERROR_NOTMPD        14      /* mpd not running on port at host */
47 #define MPD_ERROR_NORESPONSE    15      /* no response on attempting to connect */
48 #define MPD_ERROR_SENDING       16      /* error sending command */
49 #define MPD_ERROR_CONNCLOSED    17      /* connection closed by mpd */
50 #define MPD_ERROR_ACK           18      /* ACK returned! */
51 #define MPD_ERROR_BUFFEROVERRUN 19      /* Buffer was overrun! */
52
53 #define MPD_ACK_ERROR_UNK       -1
54 #define MPD_ERROR_AT_UNK        -1
55
56 #define MPD_ACK_ERROR_NOT_LIST                  1
57 #define MPD_ACK_ERROR_ARG                       2
58 #define MPD_ACK_ERROR_PASSWORD                  3
59 #define MPD_ACK_ERROR_PERMISSION                4
60 #define MPD_ACK_ERROR_UNKNOWN_CMD               5
61
62 #define MPD_ACK_ERROR_NO_EXIST                  50
63 #define MPD_ACK_ERROR_PLAYLIST_MAX              51
64 #define MPD_ACK_ERROR_SYSTEM                    52
65 #define MPD_ACK_ERROR_PLAYLIST_LOAD             53
66 #define MPD_ACK_ERROR_UPDATE_ALREADY            54
67 #define MPD_ACK_ERROR_PLAYER_SYNC               55
68 #define MPD_ACK_ERROR_EXIST                     56
69
70 #ifdef __cplusplus
71 extern "C" {
72 #endif
73
74 /* internal stuff don't touch this struct */
75         typedef struct _mpd_ReturnElement {
76                 char *name;
77                 char *value;
78         } mpd_ReturnElement;
79
80 /* mpd_Connection
81  * holds info about connection to mpd
82  * use error, and errorStr to detect errors
83  */
84         typedef struct _mpd_Connection {
85                 /* use this to check the version of mpd */
86                 int version[3];
87                 /* IMPORTANT, you want to get the error messages from here */
88                 char errorStr[MPD_BUFFER_MAX_LENGTH + 1];
89                 int errorCode;
90                 int errorAt;
91                 /* this will be set to MPD_ERROR_* if there is an error, 0 if not */
92                 int error;
93                 /* DON'T TOUCH any of the rest of this stuff */
94                 int sock;
95                 char buffer[MPD_BUFFER_MAX_LENGTH + 1];
96                 int buflen;
97                 int bufstart;
98                 int doneProcessing;
99                 int listOks;
100                 int doneListOk;
101                 int commandList;
102                 mpd_ReturnElement *returnElement;
103                 struct timeval timeout;
104         } mpd_Connection;
105
106 /* mpd_newConnection
107  * use this to open a new connection
108  * you should use mpd_closeConnection, when your done with the connection,
109  * even if an error has occurred
110  * _timeout_ is the connection timeout period in seconds
111  */
112         mpd_Connection *mpd_newConnection(const char *host, int port,
113                                           float timeout);
114
115         void mpd_setConnectionTimeout(mpd_Connection * connection,
116                                       float timeout);
117
118 /* mpd_closeConnection
119  * use this to close a connection and free'ing subsequent memory
120  */
121         void mpd_closeConnection(mpd_Connection * connection);
122
123 /* mpd_clearError
124  * clears error
125  */
126         void mpd_clearError(mpd_Connection * connection);
127
128 /* STATUS STUFF */
129
130 /* use these with status.state to determine what state the player is in */
131 #define MPD_STATUS_STATE_UNKNOWN        0
132 #define MPD_STATUS_STATE_STOP           1
133 #define MPD_STATUS_STATE_PLAY           2
134 #define MPD_STATUS_STATE_PAUSE          3
135
136 /* us this with status.volume to determine if mpd has volume support */
137 #define MPD_STATUS_NO_VOLUME            -1
138
139 /* mpd_Status
140  * holds info return from status command
141  */
142         typedef struct mpd_Status {
143                 /* 0-100, or MPD_STATUS_NO_VOLUME when there is no volume support */
144                 int volume;
145                 /* 1 if repeat is on, 0 otherwise */
146                 int repeat;
147                 /* 1 if random is on, 0 otherwise */
148                 int random;
149                 /* playlist length */
150                 int playlistLength;
151                 /* playlist, use this to determine when the playlist has changed */
152                 long long playlist;
153                 /* use with MPD_STATUS_STATE_* to determine state of player */
154                 int state;
155                 /* crossfade setting in seconds */
156                 int crossfade;
157                 /* if a song is currently selected (always the case when state is
158                  * PLAY or PAUSE), this is the position of the currently
159                  * playing song in the playlist, beginning with 0
160                  */
161                 int song;
162                 /* Song ID of the currently selected song */
163                 int songid;
164                 /* time in seconds that have elapsed in the currently playing/paused
165                  * song
166                  */
167                 int elapsedTime;
168                 /* length in seconds of the currently playing/paused song */
169                 int totalTime;
170                 /* current bit rate in kbs */
171                 int bitRate;
172                 /* audio sample rate */
173                 unsigned int sampleRate;
174                 /* audio bits */
175                 int bits;
176                 /* audio channels */
177                 int channels;
178                 /* 1 if mpd is updating, 0 otherwise */
179                 int updatingDb;
180                 /* error */
181                 char *error;
182         } mpd_Status;
183
184         void mpd_sendStatusCommand(mpd_Connection * connection);
185
186 /* mpd_getStatus
187  * returns status info, be sure to free it with mpd_freeStatus()
188  * call this after mpd_sendStatusCommand()
189  */
190         mpd_Status *mpd_getStatus(mpd_Connection * connection);
191
192 /* mpd_freeStatus
193  * free's status info malloc'd and returned by mpd_getStatus
194  */
195         void mpd_freeStatus(mpd_Status * status);
196
197         typedef struct _mpd_Stats {
198                 int numberOfArtists;
199                 int numberOfAlbums;
200                 int numberOfSongs;
201                 unsigned long uptime;
202                 unsigned long dbUpdateTime;
203                 unsigned long playTime;
204                 unsigned long dbPlayTime;
205         } mpd_Stats;
206
207         void mpd_sendStatsCommand(mpd_Connection * connection);
208
209         mpd_Stats *mpd_getStats(mpd_Connection * connection);
210
211         void mpd_freeStats(mpd_Stats * stats);
212
213 /* SONG STUFF */
214
215 #define MPD_SONG_NO_TIME        -1
216 #define MPD_SONG_NO_NUM         -1
217 #define MPD_SONG_NO_ID          -1
218
219 /* mpd_Song
220  * for storing song info returned by mpd
221  */
222         typedef struct _mpd_Song {
223                 /* filename of song */
224                 char *file;
225                 /* artist, maybe NULL if there is no tag */
226                 char *artist;
227                 /* title, maybe NULL if there is no tag */
228                 char *title;
229                 /* album, maybe NULL if there is no tag */
230                 char *album;
231                 /* track, maybe NULL if there is no tag */
232                 char *track;
233                 /* name, maybe NULL if there is no tag; it's the name of the current
234                  * song, f.e. the icyName of the stream */
235                 char *name;
236                 /* length of song in seconds, check that it is not MPD_SONG_NO_TIME  */
237                 int time;
238                 /* if plchanges/playlistinfo/playlistid used, is the position of the 
239                  * song in the playlist */
240                 int pos;
241                 /* song id for a song in the playlist */
242                 int id;
243         } mpd_Song;
244
245 /* mpd_newSong
246  * use to allocate memory for a new mpd_Song
247  * file, artist, etc all initialized to NULL
248  * if your going to assign values to file, artist, etc
249  * be sure to malloc or strdup the memory
250  * use mpd_freeSong to free the memory for the mpd_Song, it will also
251  * free memory for file, artist, etc, so don't do it yourself
252  */
253         mpd_Song *mpd_newSong();
254
255 /* mpd_freeSong
256  * use to free memory allocated by mpd_newSong
257  * also it will free memory pointed to by file, artist, etc, so be careful
258  */
259         void mpd_freeSong(mpd_Song * song);
260
261 /* mpd_songDup
262  * works like strDup, but for a mpd_Song
263  */
264         mpd_Song *mpd_songDup(mpd_Song * song);
265
266 /* DIRECTORY STUFF */
267
268 /* mpd_Directory
269  * used to store info fro directory (right now that just the path)
270  */
271         typedef struct _mpd_Directory {
272                 char *path;
273         } mpd_Directory;
274
275 /* mpd_newDirectory
276  * allocates memory for a new directory
277  * use mpd_freeDirectory to free this memory
278  */
279         mpd_Directory *mpd_newDirectory();
280
281 /* mpd_freeDirectory
282  * used to free memory allocated with mpd_newDirectory, and it frees
283  * path of mpd_Directory, so be careful
284  */
285         void mpd_freeDirectory(mpd_Directory * directory);
286
287 /* mpd_directoryDup
288  * works like strdup, but for mpd_Directory
289  */
290         mpd_Directory *mpd_directoryDup(mpd_Directory * directory);
291
292 /* PLAYLISTFILE STUFF */
293
294 /* mpd_PlaylistFile
295  * stores info about playlist file returned by lsinfo
296  */
297         typedef struct _mpd_PlaylistFile {
298                 char *path;
299         } mpd_PlaylistFile;
300
301 /* mpd_newPlaylistFile
302  * allocates memory for new mpd_PlaylistFile, path is set to NULL
303  * free this memory with mpd_freePlaylistFile
304  */
305         mpd_PlaylistFile *mpd_newPlaylistFile();
306
307 /* mpd_freePlaylist
308  * free memory allocated for freePlaylistFile, will also free
309  * path, so be careful
310  */
311         void mpd_freePlaylistFile(mpd_PlaylistFile * playlist);
312
313 /* mpd_playlistFileDup
314  * works like strdup, but for mpd_PlaylistFile
315  */
316         mpd_PlaylistFile *mpd_playlistFileDup(mpd_PlaylistFile * playlist);
317
318 /* INFO ENTITY STUFF */
319
320 /* the type of entity returned from one of the commands that generates info
321  * use in conjunction with mpd_InfoEntity.type
322  */
323 #define MPD_INFO_ENTITY_TYPE_DIRECTORY          0
324 #define MPD_INFO_ENTITY_TYPE_SONG               1
325 #define MPD_INFO_ENTITY_TYPE_PLAYLISTFILE       2
326
327 /* mpd_InfoEntity
328  * stores info on stuff returned info commands
329  */
330         typedef struct mpd_InfoEntity {
331                 /* the type of entity, use with MPD_INFO_ENTITY_TYPE_* to determine
332                  * what this entity is (song, directory, etc...)
333                  */
334                 int type;
335                 /* the actual data you want, mpd_Song, mpd_Directory, etc */
336                 union {
337                         mpd_Directory *directory;
338                         mpd_Song *song;
339                         mpd_PlaylistFile *playlistFile;
340                 } info;
341         } mpd_InfoEntity;
342
343         mpd_InfoEntity *mpd_newInfoEntity();
344
345         void mpd_freeInfoEntity(mpd_InfoEntity * entity);
346
347 /* INFO COMMANDS AND STUFF */
348
349 /* use this function to loop over after calling Info/Listall functions */
350         mpd_InfoEntity *mpd_getNextInfoEntity(mpd_Connection * connection);
351
352 /* fetches the currently seeletect song (the song referenced by status->song
353  * and status->songid*/
354         void mpd_sendCurrentSongCommand(mpd_Connection * connection);
355
356 /* songNum of -1, means to display the whole list */
357         void mpd_sendPlaylistInfoCommand(mpd_Connection * connection,
358                                          int songNum);
359
360 /* use this to get the changes in the playlist since version _playlist_ */
361         void mpd_sendPlChangesCommand(mpd_Connection * connection,
362                                       long long playlist);
363
364 /* recursivel fetches all songs/dir/playlists in "dir* (no metadata is 
365  * returned) */
366         void mpd_sendListallCommand(mpd_Connection * connection,
367                                     const char *dir);
368
369 /* same as sendListallCommand, but also metadata is returned */
370         void mpd_sendListallInfoCommand(mpd_Connection * connection,
371                                         const char *dir);
372
373 /* non-recursive version of ListallInfo */
374         void mpd_sendLsInfoCommand(mpd_Connection * connection,
375                                    const char *dir);
376
377 #define MPD_TABLE_ARTIST        0
378 #define MPD_TABLE_ALBUM         1
379 #define MPD_TABLE_TITLE         2
380 #define MPD_TABLE_FILENAME      3
381
382         void mpd_sendSearchCommand(mpd_Connection * connection, int table,
383                                    const char *str);
384
385         void mpd_sendFindCommand(mpd_Connection * connection, int table,
386                                  const char *str);
387
388 /* LIST TAG COMMANDS */
389
390 /* use this function fetch next artist entry, be sure to free the returned 
391  * string.  NULL means there are no more.  Best used with sendListArtists
392  */
393         char *mpd_getNextArtist(mpd_Connection * connection);
394
395         char *mpd_getNextAlbum(mpd_Connection * connection);
396
397 /* list artist or albums by artist, arg1 should be set to the artist if
398  * listing albums by a artist, otherwise NULL for listing all artists or albums
399  */
400         void mpd_sendListCommand(mpd_Connection * connection, int table,
401                                  const char *arg1);
402
403 /* SIMPLE COMMANDS */
404
405         void mpd_sendAddCommand(mpd_Connection * connection,
406                                 const char *file);
407
408         void mpd_sendDeleteCommand(mpd_Connection * connection,
409                                    int songNum);
410
411         void mpd_sendDeleteIdCommand(mpd_Connection * connection,
412                                      int songNum);
413
414         void mpd_sendSaveCommand(mpd_Connection * connection,
415                                  const char *name);
416
417         void mpd_sendLoadCommand(mpd_Connection * connection,
418                                  const char *name);
419
420         void mpd_sendRmCommand(mpd_Connection * connection,
421                                const char *name);
422
423         void mpd_sendShuffleCommand(mpd_Connection * connection);
424
425         void mpd_sendClearCommand(mpd_Connection * connection);
426
427 /* use this to start playing at the beginning, useful when in random mode */
428 #define MPD_PLAY_AT_BEGINNING   -1
429
430         void mpd_sendPlayCommand(mpd_Connection * connection, int songNum);
431
432         void mpd_sendPlayIdCommand(mpd_Connection * connection,
433                                    int songNum);
434
435         void mpd_sendStopCommand(mpd_Connection * connection);
436
437         void mpd_sendPauseCommand(mpd_Connection * connection,
438                                   int pauseMode);
439
440         void mpd_sendNextCommand(mpd_Connection * connection);
441
442         void mpd_sendPrevCommand(mpd_Connection * connection);
443
444         void mpd_sendMoveCommand(mpd_Connection * connection, int from,
445                                  int to);
446
447         void mpd_sendMoveIdCommand(mpd_Connection * connection, int from,
448                                    int to);
449
450         void mpd_sendSwapCommand(mpd_Connection * connection, int song1,
451                                  int song2);
452
453         void mpd_sendSwapIdCommand(mpd_Connection * connection, int song1,
454                                    int song2);
455
456         void mpd_sendSeekCommand(mpd_Connection * connection, int song,
457                                  int time);
458
459         void mpd_sendSeekIdCommand(mpd_Connection * connection, int song,
460                                    int time);
461
462         void mpd_sendRepeatCommand(mpd_Connection * connection,
463                                    int repeatMode);
464
465         void mpd_sendRandomCommand(mpd_Connection * connection,
466                                    int randomMode);
467
468         void mpd_sendSetvolCommand(mpd_Connection * connection,
469                                    int volumeChange);
470
471 /* WARNING: don't use volume command, its depreacted */
472         void mpd_sendVolumeCommand(mpd_Connection * connection,
473                                    int volumeChange);
474
475         void mpd_sendCrossfadeCommand(mpd_Connection * connection,
476                                       int seconds);
477
478         void mpd_sendUpdateCommand(mpd_Connection * connection,
479                                    char *path);
480
481 /* returns the update job id, call this after a update command*/
482         int mpd_getUpdateId(mpd_Connection * connection);
483
484         void mpd_sendPasswordCommand(mpd_Connection * connection,
485                                      const char *pass);
486
487 /* after executing a command, when your done with it to get its status
488  * (you want to check connection->error for an error)
489  */
490         void mpd_finishCommand(mpd_Connection * connection);
491
492 /* command list stuff, use this to do things like add files very quickly */
493         void mpd_sendCommandListBegin(mpd_Connection * connection);
494
495         void mpd_sendCommandListOkBegin(mpd_Connection * connection);
496
497         void mpd_sendCommandListEnd(mpd_Connection * connection);
498
499 /* advance to the next listOk 
500  * returns 0 if advanced to the next list_OK,
501  * returns -1 if it advanced to an OK or ACK */
502         int mpd_nextListOkCommand(mpd_Connection * connection);
503
504 #ifdef __cplusplus
505 }
506 #endif
507 #endif