mirror of
https://github.com/SuperBFG7/ympd
synced 2024-12-27 03:10:26 +00:00
Feat: first code for mpd idle api
This commit is contained in:
parent
e46c0b200f
commit
a6f63f6cb2
@ -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>
|
||||||
|
|
||||||
@ -74,6 +75,15 @@ 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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
11
src/mympd.c
11
src/mympd.c
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user