1
0
mirror of https://github.com/SuperBFG7/ympd synced 2024-12-26 11:00:27 +00:00

Feat: first code for mpd idle api

This commit is contained in:
jcorporation 2018-08-09 22:15:00 +01:00
parent e46c0b200f
commit a6f63f6cb2
3 changed files with 85 additions and 16 deletions

View File

@ -29,6 +29,7 @@
#include <libgen.h> #include <libgen.h>
#include <ctype.h> #include <ctype.h>
#include <libgen.h> #include <libgen.h>
#include <poll.h>
#include <mpd/client.h> #include <mpd/client.h>
#include <mpd/message.h> #include <mpd/message.h>
@ -73,7 +74,16 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
if (cmd_id == -1) if (cmd_id == -1)
cmd_id = get_cmd_id("MPD_API_UNKNOWN"); cmd_id = get_cmd_id("MPD_API_UNKNOWN");
mpd_send_noidle(mpd.conn);
mpd_response_finish(mpd.conn);
/*
enum mpd_idle idle_event;
mpd_connection_set_timeout(mpd.conn, 1);
idle_event = mpd_recv_idle(mpd.conn, false);
*/
mpd_connection_set_timeout(mpd.conn, mpd.timeout);
switch(cmd_id) { switch(cmd_id) {
case MPD_API_UNKNOWN: case MPD_API_UNKNOWN:
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Unknown request\"}"); n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"Unknown request\"}");
@ -468,6 +478,8 @@ void callback_mympd(struct mg_connection *nc, const struct mg_str msg) {
mpd.conn_state = MPD_FAILURE; mpd.conn_state = MPD_FAILURE;
} }
mpd_send_idle(mpd.conn);
if (n == 0) if (n == 0)
n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"No response for cmd %s\"}", cmd); n = snprintf(mpd.buf, MAX_SIZE, "{\"type\": \"error\", \"data\": \"No response for cmd %s\"}", cmd);
@ -547,12 +559,15 @@ static int mympd_notify_callback(struct mg_connection *c, const char *param) {
return 0; return 0;
} }
void mympd_poll(struct mg_mgr *s) { void mympd_poll(struct mg_mgr *s, int timeout) {
struct pollfd fds[1];
int pollrc;
switch (mpd.conn_state) { switch (mpd.conn_state) {
case MPD_DISCONNECTED: case MPD_DISCONNECTED:
/* Try to connect */ /* Try to connect */
fprintf(stdout, "MPD Connecting to %s: %d\n", config.mpdhost, config.mpdport); fprintf(stdout, "MPD Connecting to %s: %d\n", config.mpdhost, config.mpdport);
mpd.conn = mpd_connection_new(config.mpdhost, config.mpdport, 3000); mpd.conn = mpd_connection_new(config.mpdhost, config.mpdport, mpd.timeout);
if (mpd.conn == NULL) { if (mpd.conn == NULL) {
fprintf(stderr, "Out of memory."); fprintf(stderr, "Out of memory.");
mpd.conn_state = MPD_FAILURE; mpd.conn_state = MPD_FAILURE;
@ -578,8 +593,9 @@ void mympd_poll(struct mg_mgr *s) {
} }
fprintf(stderr, "MPD connected.\n"); fprintf(stderr, "MPD connected.\n");
mpd_connection_set_timeout(mpd.conn, 10000); mpd_connection_set_timeout(mpd.conn, mpd.timeout);
mpd.conn_state = MPD_CONNECTED; mpd.conn_state = MPD_CONNECTED;
mpd_send_idle(mpd.conn);
break; break;
case MPD_FAILURE: case MPD_FAILURE:
@ -594,14 +610,68 @@ void mympd_poll(struct mg_mgr *s) {
break; break;
case MPD_CONNECTED: case MPD_CONNECTED:
mpd.buf_size = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version); fds[0].fd = mpd_connection_get_fd(mpd.conn);
for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c)) { fds[0].events = POLLIN;
mympd_notify_callback(c, NULL); pollrc = poll(fds, 1, timeout);
if (pollrc > 0) {
mpd_send_noidle(mpd.conn);
mympd_parse_idle(s);
mpd_send_idle(mpd.conn);
} }
break; break;
} }
} }
void mympd_parse_idle(struct mg_mgr *s) {
mpd_connection_set_timeout(mpd.conn, 100);
enum mpd_idle idle_bitmask = mpd_recv_idle(mpd.conn, false);
for (unsigned j = 0;; ++j) {
enum mpd_idle idle_event = 1 << j;
const char *idle_name = mpd_idle_name(idle_event);
if (idle_name == NULL)
break;
if (idle_bitmask & idle_event) {
#ifdef DEBUG
fprintf(stderr,"IDLE: %s\n",idle_name);
#endif
switch(idle_event) {
case MPD_IDLE_DATABASE:
break;
case MPD_IDLE_STORED_PLAYLIST:
break;
case MPD_IDLE_QUEUE:
break;
case MPD_IDLE_PLAYER:
break;
case MPD_IDLE_MIXER:
break;
case MPD_IDLE_OUTPUT:
break;
case MPD_IDLE_OPTIONS:
break;
case MPD_IDLE_UPDATE:
break;
case MPD_IDLE_STICKER:
break;
case MPD_IDLE_SUBSCRIPTION:
break;
case MPD_IDLE_MESSAGE:
break;
}
}
}
//old behaviour
if (idle_bitmask > 0) {
mpd_connection_set_timeout(mpd.conn, mpd.timeout);
mpd.buf_size = mympd_put_state(mpd.buf, &mpd.song_id, &mpd.next_song_id, &mpd.queue_version);
for (struct mg_connection *c = mg_next(s, NULL); c != NULL; c = mg_next(s, c))
mympd_notify_callback(c, NULL);
}
}
char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) { char* mympd_get_tag(struct mpd_song const *song, enum mpd_tag_type tag) {
char *str; char *str;
str = (char *)mpd_song_get_tag(song, tag, 0); str = (char *)mpd_song_get_tag(song, tag, 0);
@ -1432,5 +1502,5 @@ int mympd_put_stats(char *buffer) {
void mympd_disconnect() { void mympd_disconnect() {
mpd.conn_state = MPD_DISCONNECT; mpd.conn_state = MPD_DISCONNECT;
mympd_poll(NULL); mympd_poll(NULL, 100);
} }

View File

@ -117,6 +117,7 @@ struct t_mpd {
int song_id; int song_id;
int next_song_id; int next_song_id;
unsigned queue_version; unsigned queue_version;
int timeout;
} mpd; } mpd;
typedef struct { typedef struct {
@ -146,7 +147,8 @@ struct t_mpd_client_session {
unsigned queue_version; unsigned queue_version;
}; };
void mympd_poll(struct mg_mgr *s); void mympd_poll(struct mg_mgr *sm, int timeout);
void mympd_parse_idle(struct mg_mgr *s);
void callback_mympd(struct mg_connection *nc, const struct mg_str msg); void callback_mympd(struct mg_connection *nc, const struct mg_str msg);
int mympd_close_handler(struct mg_connection *c); int mympd_close_handler(struct mg_connection *c);
int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version); int mympd_put_state(char *buffer, int *current_song_id, int *next_song_id, unsigned *queue_version);

View File

@ -149,7 +149,6 @@ int main(int argc, char **argv) {
struct mg_mgr mgr; struct mg_mgr mgr;
struct mg_connection *nc; struct mg_connection *nc;
struct mg_connection *nc_http; struct mg_connection *nc_http;
unsigned int current_timer = 0, last_timer = 0;
struct mg_bind_opts bind_opts; struct mg_bind_opts bind_opts;
const char *err; const char *err;
@ -171,6 +170,8 @@ int main(int argc, char **argv) {
config.coverimage = "folder.jpg"; config.coverimage = "folder.jpg";
config.statefile = "/var/lib/mympd/mympd.state"; config.statefile = "/var/lib/mympd/mympd.state";
mpd.timeout = 3000;
if (argc == 2) { if (argc == 2) {
if (ini_parse(argv[1], inihandler, &config) < 0) { if (ini_parse(argv[1], inihandler, &config) < 0) {
printf("Can't load '%s'\n", argv[1]); printf("Can't load '%s'\n", argv[1]);
@ -255,12 +256,8 @@ int main(int argc, char **argv) {
printf("myMPD started on ssl port %s\n", config.sslport); printf("myMPD started on ssl port %s\n", config.sslport);
while (s_signal_received == 0) { while (s_signal_received == 0) {
mg_mgr_poll(&mgr, 200); mympd_poll(&mgr, 100);
current_timer = time(NULL); mg_mgr_poll(&mgr, 100);
if (current_timer - last_timer) {
last_timer = current_timer;
mympd_poll(&mgr);
}
} }
mg_mgr_free(&mgr); mg_mgr_free(&mgr);
mympd_disconnect(); mympd_disconnect();