]> git.webhop.me Git - lcd4linux.git/commitdiff
git-svn-id: https://ssl.bulix.org/svn/lcd4linux/trunk@848 3ae390bd-cb1e-0410-b409...
authormichux <michux@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Thu, 24 Jan 2008 12:39:55 +0000 (12:39 +0000)
committermichux <michux@3ae390bd-cb1e-0410-b409-cd5a39f66f1f>
Thu, 24 Jan 2008 12:39:55 +0000 (12:39 +0000)
plugin_mpd.c

index 5a950c8ba5645d6d2176e2b1a10481a724782b9b..0daa1d146d69520a3110698590f4a2ed4673bf7e 100644 (file)
@@ -1,11 +1,11 @@
 /* $Id$
  * $URL$
  *
- * mpd informations
+ * mpd informations v0.7
  *
  * Copyright (C) 2006 Stefan Kuhne <sk-privat@gmx.net>
  * Copyright (C) 2007 Robert Buchholz <rbu@gentoo.org>
- * Copyright (C) 2007 Michael Vogt <michu@neophob.com>
+ * Copyright (C) 2008 Michael Vogt <michu@neophob.com>
  * Copyright (C) 2006 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
  *
  * This file is part of LCD4Linux.
  * int plugin_init_sample (void)
  *  adds various functions
  *
+ * changelog v0.5 (20.11.2007):
+ *   changed:  mpd::artist(), mpd::title(), mpd::album()
+ *              init code, call only if a function is used.
+ *   removed:  "old style" functions, duplicate code
+ *   fixed:    strdup() mem leaks
+ *   added:    getstate, function which return player status: play/pause/stop
+ *             getVolume, funtcion which returns the mpd volume
+ *             getFilename, return current filename
+ *
+ * 
+ * changelog v0.6 (05.12.2007):
+ *  changed:    -connection handling
+ *              -verbose "NO TAG" messages
+ *              -init code
+ *  added:      -added password support (MPD_PASSWORD env variable)
+ *              -mpd::getSongsInDb - how many songs are in the mpd db?
+ *              -mpd::getMpdUptime - uptime of mpd
+ *              -mpd::getMpdPlayTime - playtime of mpd
+ *              -mpd::getMpdDbPlayTime - playtime of all songs in mpd db
+ *              -basic error handler..
+ *             -mpd configuration in lcd4linux.conf
+ *             -formatTime* - use those functions to format time values
+ *  removed:    -reprand method
+ *
+ *
+ * changelog v0.7 (14.12.2007):
+ *  changed:   -connection handling improved, do not disconnect/reconnect for each query
+ *               -> uses less ressources
+ *
  */
 
+/*
+
+TODO: 
+ -what happens if the db is updating? int mpd_status_db_is_updating() 0/1
+ -port configuration to lcd4linux.cfg (like mysql)
+
+*/
 
 #include "config.h"
 #include <stdio.h>
 
 #include "debug.h"
 #include "plugin.h"
+#include "cfg.h"
+/* struct timeval */
+#include <sys/time.h>
+
 
+/* you need libmpd to compile this plugin! http://sarine.nl/libmpd */
 #include <libmpd/libmpd.h>
 
 #ifdef WITH_DMALLOC
 #include <dmalloc.h>
 #endif
 
-/* Struct Pointer */
-
-struct Pointer {
-    mpd_Connection *conn;
-    mpd_Status *status;
-    mpd_InfoEntity *entity;
-};
-
-
-
-static struct Pointer connect()
+/* current song */
+#define TAGLEN 512
+#define MAX_PATH 1024
+static char *artist[TAGLEN];
+static char *album[TAGLEN];
+static char *title[TAGLEN];
+static char *filename[MAX_PATH];
+static long l_totalTimeSec;
+static long l_elapsedTimeSec;
+static int l_bitRate;
+static int l_repeatEnabled;
+static int l_randomEnabled;
+static int l_state;
+static int l_volume;
+static int l_songsInDb;
+static long l_mpdUptime;
+static long l_mpdPlaytime;
+static long l_mpdDbPlaytime;
+static long l_mpdPlaylistLength;
+static int l_currentSongPos;
+
+/* connection information */
+static char host[255];
+static char pw[255];
+static int iport;
+static int waittime;
+struct timeval timestamp;
+
+static MpdObj *mi = NULL;
+static char Section[] = "Plugin:MPD";
+
+
+static void error_callback( __attribute__ ((unused)) MpdObj * mi, int errorid, char *msg, __attribute__ ((unused))
+                   void *userdata)
 {
-    char *host = "localhost";
-    char *port = "6600";
-    int iport;
-    char *test;
-
-    struct Pointer mpd = {
-       .conn = NULL,
-       .status = NULL,
-       .entity = NULL
-    };
-
-    if ((test = getenv("MPD_HOST"))) {
-       host = test;
-    }
-
-    if ((test = getenv("MPD_PORT"))) {
-       port = test;
-    }
-
-    iport = strtol(port, &test, 10);
-
-    if ((iport < 0) || (*test != '\0')) {
-       fprintf(stderr, "[MPD] MPD_PORT \"%s\" is not a positive integer\n", port);
-       exit(EXIT_FAILURE);
-    }
-
-    mpd.conn = mpd_newConnection(host, iport, 10);
-
-    mpd_sendCommandListOkBegin(mpd.conn);
-    mpd_sendStatusCommand(mpd.conn);
-    mpd_sendCurrentSongCommand(mpd.conn);
-    mpd_sendCommandListEnd(mpd.conn);
-
-    if ((mpd.status = mpd_getStatus(mpd.conn)) == NULL) {
-       fprintf(stderr, "[MPD] error when getting status: %s\n", mpd.conn->errorStr);
-       mpd_closeConnection(mpd.conn);
-       mpd.conn = NULL;
-    } else if (mpd.status->error) {
-       printf("[MPD] status error when connecting: %s\n", mpd.status->error);
-    } else if (mpd.conn->error) {
-       fprintf(stderr, "[MPD] error when connecting: %s\n", mpd.conn->errorStr);
-       mpd_freeStatus(mpd.status);
-       mpd_closeConnection(mpd.conn);
-       mpd.conn = NULL;
-    }
-
-    return mpd;
+    debug("[MPD] caught error %i: '%s'", errorid, msg);
 }
 
 
-static void disconnect(struct Pointer mpd)
+static int configure_mpd(void)
 {
-    if (mpd.conn->error) {
-       fprintf(stderr, "[MPD] error when disconnecting: %s\n", mpd.conn->errorStr);
-       mpd_freeStatus(mpd.status);
-       mpd_closeConnection(mpd.conn);
-       return;
-    }
+    static int configured = 0;
 
-    mpd_finishCommand(mpd.conn);
-    if (mpd.conn->error) {
-       fprintf(stderr, "[MPD] error when disconnecting: %s\n", mpd.conn->errorStr);
-    }
+    char *s;
 
-    mpd_freeStatus(mpd.status);
-    mpd_closeConnection(mpd.conn);
-}
+    if (configured != 0)
+       return configured;
 
+    /* read server */
+    s = cfg_get(Section, "server", "localhost");
+    if (*s == '\0') {
+       info("[MPD] empty '%s.server' entry from %s, assuming 'localhost'", Section, cfg_source());
+       strcpy(host, "localhost");
+    } else
+       strcpy(host, s);
 
+    free(s);
 
-static void artist(RESULT * result, RESULT * query)
-{
-    char *value = NULL;
-    struct Pointer mpd = connect();
-    if (mpd.conn == NULL) {
-       SetResult(&result, R_STRING, " ");
-       return;
+    /* read port */
+    if (cfg_number(Section, "port", 6600, 1, 65536, &iport) < 1) {
+       info("[MPD] no '%s.port' entry from %s using MPD's default", Section, cfg_source());
     }
 
-    mpd_nextListOkCommand(mpd.conn);
-
-    while ((mpd.entity = mpd_getNextInfoEntity(mpd.conn))) {
-       mpd_Song *song = mpd.entity->info.song;
+    /* read minUpdateTime in ms */
+    if (cfg_number(Section, "minUpdateTime", 500, 1, 10000, &waittime) < 1) {
+       info("[MPD] no '%s.minUpdateTime' entry from %s using MPD's default", Section, cfg_source());
+    }
 
-       if (mpd.entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
-           mpd_freeInfoEntity(mpd.entity);
-           continue;
-       }
 
-       if (!value && song->artist) {
-           /* we found our first song */
-           value = strdup(song->artist);
-           /* add comment */
-           if (query) {
-               char *myarg;
-               myarg = strdup(R2S(query));
-               value = strcat(value, myarg);
-               free(myarg);
-           }
-       }
-       mpd_freeInfoEntity(mpd.entity);
+    /* read password */
+    s = cfg_get(Section, "password", "");
+    if (*s == '\0') {
+       info("[MPD] empty '%s.password' entry in %s, assuming none", Section, cfg_source());
+       memset(pw, 0, sizeof(pw));
+    } else {
+       strcpy(pw, s);
+       free(s);
     }
 
-    disconnect(mpd);
+    debug("[MPD] connection detail: [%s:%d]", host, iport);
 
-    /* store result, value must not be NULL */
-    SetResult(&result, R_STRING, value ? value : " ");
+    mi = mpd_new(host, iport, pw);
+    mpd_signal_connect_error(mi, (ErrorCallback) error_callback, NULL);
+    mpd_set_connection_timeout(mi, 5);
 
-    free(value);
+    configured = 1;
+    return configured;
 }
 
 
-static void title(RESULT * result)
+static int mpd_update()
 {
-    char *value = NULL;
-    struct Pointer mpd = connect();
-    if (mpd.conn == NULL) {
-       SetResult(&result, R_STRING, " ");
-       return;
+    int ret = -1;
+    mpd_Song *song;
+    static char *notagArt = "No artist tag";
+    static char *notagTit = "No title tag";
+    static char *notagAlb = "No album tag";
+    static char *nofilename = "No Filename";
+    struct timeval now;
+    int len;
+
+    //check if configured
+    if (configure_mpd() < 0) {
+       return -1;
     }
 
-    mpd_nextListOkCommand(mpd.conn);
-
-    while ((mpd.entity = mpd_getNextInfoEntity(mpd.conn))) {
-       mpd_Song *song = mpd.entity->info.song;
-
-       if (mpd.entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
-           mpd_freeInfoEntity(mpd.entity);
-           continue;
-       }
+    /* reread every 1000 msec only */
+    gettimeofday(&now, NULL);    
+    int timedelta = (now.tv_sec - timestamp.tv_sec) * 1000 + (now.tv_usec - timestamp.tv_usec) / 1000;
+    if (timedelta < waittime) {
+       return 1;
+    }
 
-       if (!value && song->title) {
-           value = strdup(song->title);
+    //debug("[MPD] time delta: %i", timedelta);
+
+    //send password if enabled
+    if (pw[0] != 0)
+       mpd_send_password(mi);
+    
+    //check if connected
+    if (mpd_check_connected(mi) != 1) {
+       debug("[MPD] not connected, try to reconnect...");
+       mpd_connect(mi);
+       
+       if (mpd_check_connected(mi) != 1) {
+           debug("[MPD] connection failed, give up...");
+           return -1;
        }
-       mpd_freeInfoEntity(mpd.entity);
+       debug("[MPD] connection ok...");
     }
 
-    disconnect(mpd);
-
-    /* store result, value must not be NULL  */
-    SetResult(&result, R_STRING, value ? value : " ");
+    ret = 0;
+    
+    mpd_status_update(mi);
+
+    l_elapsedTimeSec   = mpd_status_get_elapsed_song_time(mi);
+    l_bitRate          = mpd_status_get_bitrate(mi);
+    l_totalTimeSec     = mpd_status_get_total_song_time(mi);
+    l_repeatEnabled    = mpd_player_get_repeat(mi);
+    l_randomEnabled    = mpd_player_get_random(mi);
+    l_state            = mpd_player_get_state(mi);
+    l_volume           = mpd_status_get_volume(mi);
+    l_songsInDb        = mpd_stats_get_total_songs(mi);
+    l_mpdUptime        = mpd_stats_get_uptime(mi);
+    l_mpdPlaytime      = mpd_stats_get_playtime(mi);
+    l_mpdDbPlaytime    = mpd_stats_get_db_playtime(mi);
+    l_mpdPlaylistLength = mpd_playlist_get_playlist_length(mi);
+    l_currentSongPos   = mpd_player_get_current_song_pos(mi);
+
+    /* dummy checks */
+    if (l_volume < 0 || l_volume > 100)
+       l_volume = 0;
+
+    song = mpd_playlist_get_current_song(mi);
+    if (song) {
+
+           /* copy song information to local variables */
+           memset(album, 0, TAGLEN);
+           if (song->album != 0) {
+               len = strlen(song->album);
+               if (len > TAGLEN)
+                   len = TAGLEN;
+               memcpy(album, song->album, len);
+
+           } else
+               memcpy(album, notagAlb, strlen(notagAlb));
+
+           memset(artist, 0, TAGLEN);
+           if (song->artist != 0) {
+               len = strlen(song->artist);
+               if (len > TAGLEN)
+                   len = TAGLEN;
+               memcpy(artist, song->artist, len);
+           } else
+               memcpy(artist, notagArt, strlen(notagArt));
+
+           memset(title, 0, TAGLEN);
+           if (song->title != 0) {
+               len = strlen(song->title);
+               if (len > TAGLEN)
+                   len = TAGLEN;
+               memcpy(title, song->title, len);
+           } else
+               memcpy(title, notagTit, strlen(notagTit));
+
+           memset(filename, 0, MAX_PATH);
+           if (song->file != 0) {
+               len = strlen(song->file);
+               if (len > MAX_PATH)
+                   len = MAX_PATH;
+               memcpy(filename, song->file, len);
+           } else
+               memcpy(filename, nofilename, strlen(nofilename));
+    }
+    
+//    mpd_disconnect(mi);              /* you need to disconnect here */
+    gettimeofday(&timestamp, NULL);
 
-    free(value);
+    return ret;
 }
 
 
-static void album(RESULT * result)
+static void elapsedTimeSec(RESULT * result)
 {
-    char *value = NULL;
-    struct Pointer mpd = connect();
-    if (mpd.conn == NULL) {
-       SetResult(&result, R_STRING, " ");
-       return;
-    }
-
-    mpd_nextListOkCommand(mpd.conn);
-
-    while ((mpd.entity = mpd_getNextInfoEntity(mpd.conn))) {
-       mpd_Song *song = mpd.entity->info.song;
+    double d;
+    mpd_update();
+    d = (double)l_elapsedTimeSec;
+    SetResult(&result, R_NUMBER, &d);
+}
 
-       if (mpd.entity->type != MPD_INFO_ENTITY_TYPE_SONG) {
-           mpd_freeInfoEntity(mpd.entity);
-           continue;
-       }
 
-       if (!value && song->album) {
-           value = strdup(song->album);
-       }
-       mpd_freeInfoEntity(mpd.entity);
-    }
+static void totalTimeSec(RESULT * result)
+{
+    double d;
+    mpd_update();
+    d = (double)l_totalTimeSec;
+    SetResult(&result, R_NUMBER, &d);
+}
 
-    disconnect(mpd);
+static void bitRate(RESULT * result)
+{
+    double d;
+    mpd_update();
+    d = (double)l_bitRate;
+    SetResult(&result, R_NUMBER, &d);
+}
 
-    /* store result, value must not be NULL */
-    SetResult(&result, R_STRING, value ? value : " ");
 
-    free(value);
+static void getRepeatInt(RESULT * result)
+{
+    double d;
+    mpd_update();
+    d = (double)l_repeatEnabled;
+    SetResult(&result, R_NUMBER, &d);
 }
 
-#define _mpd_dummy                             000
-#define _mpd_status_get_elapsed_song_time      001
-#define _mpd_status_get_bitrate                        002
-#define _mpd_status_get_total_song_time         003
-#define _mpd_player_get_repeat                  004
-#define _mpd_player_get_random                 005
 
-void error_callback( __attribute__ ((unused)) MpdObj * mi, int errorid, char *msg, __attribute__ ((unused))
-                   void *userdata)
+static void getRandomInt(RESULT * result)
 {
-    printf("[MPD] caught error %i: '%s'\n", errorid, msg);
+    double d;
+    mpd_update();
+    d = (double)l_randomEnabled;
+    SetResult(&result, R_NUMBER, &d);
 }
 
-static int mpd_get(int function)
+static void getArtist(RESULT * result)
 {
-    int ret = -1;
-    MpdObj *mi = NULL;
-
-    char *host = "localhost";
-    char *port = "6600";
-    int iport;
-    char *test;
-
-    if ((test = getenv("MPD_HOST"))) {
-       host = test;
+    int cSong = mpd_update();
+    if (cSong != 0) {          /* inform user this information is cached... */
+//     debug("[MPD] use cached artist information...");
     }
+    SetResult(&result, R_STRING, artist);
+}
 
-    if ((test = getenv("MPD_PORT"))) {
-       port = test;
+static void getTitle(RESULT * result)
+{
+    int cSong = mpd_update();
+    if (cSong != 0) {          /* inform user this information is cached... */
+//     debug("[MPD] use cached title information...");
     }
+    SetResult(&result, R_STRING, title);
+}
 
-    iport = strtol(port, &test, 10);
-
-    if ((iport < 0) || (*test != '\0')) {
-       fprintf(stderr, "[MPD] MPD_PORT \"%s\" is not a positive integer\n", port);
-       exit(EXIT_FAILURE);
+static void getAlbum(RESULT * result)
+{
+    int cSong = mpd_update();
+    if (cSong != 0) {          /* inform user this information is cached... */
+//     debug("[MPD] use cached album information...");
     }
+    SetResult(&result, R_STRING, album);
+}
 
-    mi = mpd_new(host, iport, NULL);
-    mpd_signal_connect_error(mi, (ErrorCallback) error_callback, NULL);
-    mpd_set_connection_timeout(mi, 5);
-
-    if (!mpd_connect(mi)) {
-       switch (function) {
-       case _mpd_dummy:
-           ret = 1;
-           break;
-       case _mpd_status_get_elapsed_song_time:
-           ret = mpd_status_get_elapsed_song_time(mi);
-           break;
-       case _mpd_status_get_bitrate:
-           ret = mpd_status_get_bitrate(mi);
-           break;
-       case _mpd_status_get_total_song_time:
-           ret = mpd_status_get_total_song_time(mi);
-           break;
-       case _mpd_player_get_repeat:
-           ret = mpd_player_get_repeat(mi);
-           break;
-       case _mpd_player_get_random:
-           ret = mpd_player_get_random(mi);
-           break;
-       }
-
-       mpd_disconnect(mi);
-       mpd_free(mi);
+static void getFilename(RESULT * result)
+{
+    int cSong = mpd_update();
+    if (cSong != 0) {          /* inform user this information is cached... */
+//     debug("[MPD] use cached filename information...");
     }
-    return ret;
+    SetResult(&result, R_STRING, filename);
 }
 
-static void elapsedTime(RESULT * result)
+/*  
+    return player state:
+       0=unknown
+       1=play
+       2=pause
+       3=stop
+*/
+static void getStateInt(RESULT * result)
 {
-    char myTime[6] = " ";
-
-    const int playTime = mpd_get(_mpd_status_get_elapsed_song_time);
-
-    if ((playTime >= 0) && (playTime < 6000)) {
-       const int minutes = (int) (playTime / 60);
-       const int seconds = (int) (playTime % 60);
-       sprintf(myTime, "%02d:%02d", minutes, seconds);
-    } else if (playTime >= 6000) {
-       strcpy(myTime, "LONG");
+    double ret;
+
+    mpd_update();
+
+    switch (l_state) {
+    case MPD_PLAYER_PLAY:
+       ret = 1;
+       break;
+    case MPD_PLAYER_PAUSE:
+       ret = 2;
+       break;
+    case MPD_PLAYER_STOP:
+       ret = 3;
+       break;
+    default:
+       ret = 0;
+       break;
     }
 
-    /* store result */
-    SetResult(&result, R_STRING, myTime);
+    SetResult(&result, R_NUMBER, &ret);
 }
 
-static void elapsedTimeSec(RESULT * result)
-{
-    const int playTime = mpd_get(_mpd_status_get_elapsed_song_time);
-    double d = 0.0;
-
-    if (playTime != -1)
-       d = playTime;
 
-    /* store result */
+static void getVolume(RESULT * result)
+{
+    double d;
+    mpd_update();
+    d = (double)l_volume;
+    /* return 0..100 or < 0 when failed */
     SetResult(&result, R_NUMBER, &d);
 }
 
-static void totalTime(RESULT * result)
+/* return the # of songs in thr mpd db .. */
+static void getSongsInDb(RESULT * result)
 {
-    char myTime[6] = "ERROR";
-
-    const int totTime = mpd_get(_mpd_status_get_total_song_time);
-    if ((totTime >= 0) && (totTime < 6000)) {
-       const int minutes = (int) (totTime / 60);
-       const int seconds = (int) (totTime % 60);
-       sprintf(myTime, "%02d:%02d", minutes, seconds);
-    } else if (totTime >= 6000) {
-       strcpy(myTime, "LONG");
-    }
-
-    /* store result */
-    SetResult(&result, R_STRING, myTime);
+    double d;
+    mpd_update();
+    d = (double)l_songsInDb;
+    /* return 0..100 or < 0 when failed */
+    SetResult(&result, R_NUMBER, &d);
 }
 
-static void totalTimeSec(RESULT * result)
+static void getMpdUptime(RESULT * result)
 {
-    const int totTime = mpd_get(_mpd_status_get_total_song_time);
-    double d = 0.0;
-
-    if (totTime != -1)
-       d = totTime;
-
-    /* store result */
+    double d;
+    mpd_update();
+    d = (double)l_mpdUptime;
     SetResult(&result, R_NUMBER, &d);
 }
 
-static void bitRate(RESULT * result)
+static void getMpdPlayTime(RESULT * result)
 {
-    char rateStr[4];
-
-    const int rate = mpd_get(_mpd_status_get_bitrate);
-
-    if ((rate >= 0) && (rate < 1000)) {
-       sprintf(rateStr, "%03d", rate);
-    }
-
-    /* store result */
-    SetResult(&result, R_STRING, rateStr);
+    double d;
+    mpd_update();
+    d = (double)l_mpdPlaytime;
+    SetResult(&result, R_NUMBER, &d);
 }
 
-static void getRepeat(RESULT * result)
+static void getMpdDbPlayTime(RESULT * result)
 {
-    char *value = " ";
+    double d;
+    mpd_update();
+    d = (double)l_mpdDbPlaytime;
+    SetResult(&result, R_NUMBER, &d);
+}
 
-    const int rep = mpd_get(_mpd_player_get_repeat);
+static void getMpdPlaylistLength(RESULT * result)
+{
+    double d;
+    mpd_update();
+    d = (double)l_mpdPlaylistLength;
+    SetResult(&result, R_NUMBER, &d);
+}
 
-    if (rep != -1) {
-       if (rep)
-           value = "REP";
-       /* else value = strdup("   "); */
-    }
-    /* store result */
-    SetResult(&result, R_STRING, value);
+static void getCurrentSongPos(RESULT * result)
+{
+    double d;
+    mpd_update();
+    d = (double)l_currentSongPos;
+    SetResult(&result, R_NUMBER, &d);
 }
 
 
-static void getRandom(RESULT * result)
+
+static void formatTimeMMSS(RESULT * result, RESULT * param)
 {
-    char *value = " ";
+    long sec;
+    char myTime[6] = " ";
 
-    const int ran = mpd_get(_mpd_player_get_random);
+    sec = R2N(param);
+
+    if ((sec >= 0) && (sec < 6000)) {
+       const int minutes = (int) (sec / 60);
+       const int seconds = (int) (sec % 60);
+       sprintf(myTime, "%02d:%02d", minutes, seconds);
+    } else if (sec >= 6000) {
+       strcpy(myTime, "LONG");
+    } else
+       strcpy(myTime, "ERROR");
 
-    if (ran != -1) {
-       if (ran)
-           value = strdup("RND");
-       /* else value = strdup("   "); */
-    }
     /* store result */
-    SetResult(&result, R_STRING, value);
+    SetResult(&result, R_STRING, myTime);
 }
 
-static void getRepRand(RESULT * result)
+static void formatTimeDDHHMM(RESULT * result, RESULT * param)
 {
-    char str[9] = " ";
+    long sec;
+    char myTime[16] = " ";
 
-    const int ran = mpd_get(_mpd_player_get_random);
-    const int rep = mpd_get(_mpd_player_get_repeat);
+    sec = R2N(param);
 
-    if (ran != -1 && rep != -1) {
+    if (sec >= 0) {
+       int days = sec / 86400;
+       int hours = (sec % 86400) / 3600;
+       int minutes = (sec % 3600) / 60;
+       sprintf(myTime, "%dd%02dh%02dm", days, hours, minutes); /* 3d 12:33h */
+    } else
+       strcpy(myTime, "ERROR");
 
-       if (rep)
-           sprintf(str, "REP/");
-       else
-           sprintf(str, "---/");
-       if (ran)
-           sprintf(str, "%sRND", str);
-       else
-           sprintf(str, "%s---", str);
-    }
     /* store result */
-    SetResult(&result, R_STRING, str);
+    SetResult(&result, R_STRING, myTime);
 }
 
+
+
 int plugin_init_mpd(void)
 {
-    /* Check for File */
-    if (mpd_get(_mpd_dummy) != 1) {
-       error("[MPD] Error: Cannot connect to MPD! Is MPD started?");
-       return -1;
-    }
-
-    AddFunction("mpd::artist", 1, artist);
-    AddFunction("mpd::title", 0, title);
-    AddFunction("mpd::album", 0, album);
-    AddFunction("mpd::totalTime", 0, totalTime);
+    int check;
+    debug("[MPD] v0.7, check lcd4linux configuration file...");
+
+    check = configure_mpd();
+    if (check)
+       debug("[MPD] done");
+    else
+       debug("[MPD] error!");
+
+    memset(album, 0, TAGLEN);
+    memset(artist, 0, TAGLEN);
+    memset(title, 0, TAGLEN);
+    memset(filename, 0, MAX_PATH);
+    
+    gettimeofday(&timestamp, NULL);    
+
+    AddFunction("mpd::artist", 0, getArtist);
+    AddFunction("mpd::title", 0, getTitle);
+    AddFunction("mpd::album", 0, getAlbum);
+    AddFunction("mpd::file", 0, getFilename);
     AddFunction("mpd::totalTimeSec", 0, totalTimeSec);
-    AddFunction("mpd::elapsedTime", 0, elapsedTime);
     AddFunction("mpd::elapsedTimeSec", 0, elapsedTimeSec);
     AddFunction("mpd::bitRate", 0, bitRate);
-    AddFunction("mpd::getRepeat", 0, getRepeat);
-    AddFunction("mpd::getRandom", 0, getRandom);
-    AddFunction("mpd::getRepRand", 0, getRepRand);
+    AddFunction("mpd::getRepeatInt", 0, getRepeatInt);
+    AddFunction("mpd::getRandomInt", 0, getRandomInt);
+    AddFunction("mpd::getStateInt", 0, getStateInt);
+    AddFunction("mpd::getVolume", 0, getVolume);
+    AddFunction("mpd::getSongsInDb", 0, getSongsInDb);
+    AddFunction("mpd::getMpdUptime", 0, getMpdUptime);
+    AddFunction("mpd::getMpdPlayTime", 0, getMpdPlayTime);
+    AddFunction("mpd::getMpdDbPlayTime", 0, getMpdDbPlayTime);
+    AddFunction("mpd::getMpdPlaylistLength", 0, getMpdPlaylistLength);
+    AddFunction("mpd::getMpdPlaylistGetCurrentId", 0, getCurrentSongPos);
+
+    AddFunction("mpd::formatTimeMMSS", 1, formatTimeMMSS);
+    AddFunction("mpd::formatTimeDDHHMM", 1, formatTimeDDHHMM);
+
     return 0;
 }
 
 
 void plugin_exit_mpd(void)
 {
-    /* empty */
+    debug("[MPD] disconnect from mpd");
+    mpd_free(mi);
 }