mirror of
				https://github.com/SuperBFG7/ympd
				synced 2025-10-30 21:33:00 +00:00 
			
		
		
		
	Feat: first code for mpd idle api
This commit is contained in:
		| @@ -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(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 jcorporation
					jcorporation