void mpd_poll(struct mg_server *s) { switch (mpd.conn_state) { case MPD_DISCONNECTED: /* Try to connect */ fprintf(stdout, "MPD Connecting to %s:%d\n", mpd.host, mpd.port); mpd.conn = mpd_connection_new(mpd.host, mpd.port, 3000); if (mpd.conn == NULL) { fprintf(stderr, "Out of memory."); mpd.conn_state = MPD_FAILURE; return; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) { fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn)); mg_iterate_over_connections(s, mpd_notify_callback, (void *)mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return; } if(mpd.password && !mpd_run_password(mpd.conn, mpd.password)) { fprintf(stderr, "MPD connection: %s\n", mpd_connection_get_error_message(mpd.conn)); mg_iterate_over_connections(s, mpd_notify_callback, (void *)mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return; } fprintf(stderr, "MPD connected.\n"); mpd_connection_set_timeout(mpd.conn, 10000); mpd.conn_state = MPD_CONNECTED; break; case MPD_FAILURE: fprintf(stderr, "MPD connection failed.\n"); case MPD_DISCONNECT: case MPD_RECONNECT: if(mpd.conn != NULL) mpd_connection_free(mpd.conn); mpd.conn = NULL; mpd.conn_state = MPD_DISCONNECTED; break; case MPD_CONNECTED: mpd.buf_size = mpd_put_state(mpd.buf, &mpd.song_id, &mpd.queue_version); mg_iterate_over_connections(s, mpd_notify_callback, NULL); break; } }
int mpd_put_state(char *buffer, int *current_song_id, unsigned *queue_version) { struct mpd_status *status; int len; status = mpd_run_status(mpd.conn); if (!status) { fprintf(stderr, "MPD mpd_run_status: %s\n", mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return 0; } len = snprintf(buffer, MAX_SIZE, "{\"type\":\"state\", \"data\":{" " \"state\":%d, \"volume\":%d, \"repeat\":%d," " \"single\":%d, \"consume\":%d, \"random\":%d, " " \"songpos\": %d, \"elapsedTime\": %d, \"totalTime\":%d, " " \"currentsongid\": %d" "}}", mpd_status_get_state(status), mpd_status_get_volume(status), mpd_status_get_repeat(status), mpd_status_get_single(status), mpd_status_get_consume(status), mpd_status_get_random(status), mpd_status_get_song_pos(status), mpd_status_get_elapsed_time(status), mpd_status_get_total_time(status), mpd_status_get_song_id(status)); *current_song_id = mpd_status_get_song_id(status); *queue_version = mpd_status_get_queue_version(status); mpd_status_free(status); return len; }
bool Gui::setTheme(const char *path) { this->bg_left = this->loadThemeImage(path, "bg_left.png"); this->bg_middle = this->loadThemeImage(path, "bg_middle.png"); this->bg_right = this->loadThemeImage(path, "bg_right.png"); this->bg_submenu_left = this->loadThemeImage(path, "bg_submenu_left.png"); this->bg_submenu_middle = this->loadThemeImage(path, "bg_submenu_middle.png"); this->bg_submenu_right = this->loadThemeImage(path, "bg_submenu_right.png"); this->background = this->loadThemeImage(path, "background.png"); this->main_menu_bg = this->loadThemeImage(path, "main_menu_bg.png"); this->status_bar_bg = this->loadThemeImage(path, "status_bar.png"); this->dialogue_bg = this->loadThemeImage(path, "dialogue_box.png"); this->play = this->loadThemeImage(path, "play.png"); this->pause = this->loadThemeImage(path, "pause.png"); this->default_font = this->loadThemeFont(path, "font.ttf", 14); this->small_font = this->loadThemeFont(path, "font.ttf", 12); this->mpd_conn = mpd_connection_new(NULL, 0, 30000); panic_if (this->mpd_conn == NULL, "Out of memory"); panic_if (mpd_connection_get_error(this->mpd_conn) != MPD_ERROR_SUCCESS, "MPD conn error: %s", mpd_connection_get_error_message(this->mpd_conn)); /* Create the views */ this->status_bar = new StatusBar(); this->mv = new MainView(); this->pv = new PlayView(); this->fv = new FileView(false); this->plv = new FileView(true); return true; }
void mpd_put_state(void) { struct mpd_status *status; int len; unsigned queue_len; int song_pos, next_song_pos; status = mpd_run_status(mpd.conn); if (!status) { syslog(LOG_ERR, "%s mpd_run_status: %s\n", __func__, mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return; } mpd.song_pos = mpd_status_get_song_pos(status); mpd.next_song_pos = song_pos+1; //TODO: mpd_status_get_next_song_pos(status); mpd.queue_len = mpd_status_get_queue_length(status); mpd.volume = mpd_status_get_volume(status); mpd.state = mpd_status_get_state(status); mpd.repeat = mpd_status_get_repeat(status); mpd.single = mpd_status_get_single(status); mpd.consume = mpd_status_get_consume(status); mpd.random = mpd_status_get_random(status); mpd.elapsed_time = mpd_status_get_elapsed_time(status); mpd.total_time = mpd_status_get_total_time(status); mpd.song_id = mpd_status_get_song_id(status); // printf("%d\n", mpd.song_id); mpd_status_free(status); }
int mpd_put_outputs(char *buffer, int names) { struct mpd_output *out; int nout; char *str, *strend; str = buffer; strend = buffer+MAX_SIZE; str += snprintf(str, strend-str, "{\"type\":\"%s\", \"data\":{", names ? "outputnames" : "outputs"); mpd_send_outputs(mpd.conn); nout = 0; while ((out = mpd_recv_output(mpd.conn)) != NULL) { if (nout++) *str++ = ','; if (names) str += snprintf(str, strend - str, " \"%d\":\"%s\"", mpd_output_get_id(out), mpd_output_get_name(out)); else str += snprintf(str, strend-str, " \"%d\":%d", mpd_output_get_id(out), mpd_output_get_enabled(out)); mpd_output_free(out); } if (!mpd_response_finish(mpd.conn)) { fprintf(stderr, "MPD outputs: %s\n", mpd_connection_get_error_message(mpd.conn)); mpd_connection_clear_error(mpd.conn); return 0; } str += snprintf(str, strend-str, " }}"); return str-buffer; }
static int handle_error(struct mpd_connection *c) { assert(mpd_connection_get_error(c) != MPD_ERROR_SUCCESS); fprintf(stderr, "%s\n", mpd_connection_get_error_message(c)); mpd_connection_free(c); return EXIT_FAILURE; }
/* * pgmpc_lsplaylists * List all playlists of remote server. */ Datum pgmpc_lsplaylists(PG_FUNCTION_ARGS) { TupleDesc tupdesc; Tuplestorestate *tupstore; /* Initialize function context */ pgmpc_init_setof_single(fcinfo, TEXTOID, "playlist", &tupdesc, &tupstore); /* * Run the command to get all the songs. */ pgmpc_init(); if (!mpd_send_list_playlists(mpd_conn)) pgmpc_print_error(); /* Now get all the songs and send them back to caller */ while (true) { Datum values[1]; bool nulls[1]; struct mpd_playlist *playlist = mpd_recv_playlist(mpd_conn); /* Leave if done */ if (playlist == NULL) break; /* Assign song name */ nulls[0] = false; values[0] = CStringGetTextDatum(mpd_playlist_get_path(playlist)); /* Save values */ tuplestore_putvalues(tupstore, tupdesc, values, nulls); /* Clean up for the next one */ mpd_playlist_free(playlist); } /* We may be in error state, so check for it */ if (mpd_connection_get_error(mpd_conn) != MPD_ERROR_SUCCESS) { const char *message = mpd_connection_get_error_message(mpd_conn); pgmpc_reset(); ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("mpd command failed: %s", message))); } /* Clean up */ pgmpc_reset(); /* clean up and return the tuplestore */ tuplestore_donestoring(tupstore); return (Datum) 0; }
int mgr_handle_mpd_error() { if (conn != NULL) { fprintf(stderr, "MPD ERROR: %s\n", mpd_connection_get_error_message(conn)); mpd_connection_free(conn); conn = NULL; } else fprintf(stderr, "MPD ERROR: unknown error (mgr_handle_mpd_error)\n"); return EXIT_FAILURE; }
static void lmc_failure(void) { char *msg = g_strescape(mpd_connection_get_error_message(g_mpd), NULL); g_warning("mpd error (%u): %s\n", mpd_connection_get_error(g_mpd), msg); g_free(msg); mpd_connection_free(g_mpd); g_mpd = NULL; }
static void mpd_report_error(void) { const gchar *error = mpd_connection_get_error_message(mpd.conn); g_warning("MPD error: %s", error); irc_say("MPD error: %s", error); if (mpd_connection_clear_error(mpd.conn)) { g_warning("Unable to recover, reconnecting"); mpd_disconnect(); mpd_schedule_reconnect(); } }
static bool check_error(struct mpd_connection *client) { if (mpd_connection_get_error(client) != MPD_ERROR_SUCCESS) { printf("Error: %s (Retry in 1 second...)\n", mpd_connection_get_error_message(client)); if (!mpd_connection_clear_error(client)) { mpd_connection_free(client); sleep(1); return true; } } return (client == NULL); }
int cmd_add (int argc, char ** argv, struct mpd_connection *conn ) { if (contains_absolute_path(argc, argv) && !path_prepare(conn)) printErrorAndExit(conn); int i; if (!mpd_command_list_begin(conn, false)) printErrorAndExit(conn); for(i=0;i<argc;i++) { strip_trailing_slash(argv[i]); const char *path = argv[i]; const char *relative_path = to_relative_path(path); if (relative_path != NULL) path = relative_path; if (options.verbosity >= V_VERBOSE) printf("adding: %s\n", path); mpd_send_add(conn, charset_to_utf8(path)); } if (!mpd_command_list_end(conn)) printErrorAndExit(conn); if (!mpd_response_finish(conn)) { #if LIBMPDCLIENT_CHECK_VERSION(2,4,0) if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER) { /* check which of the arguments has failed */ unsigned location = mpd_connection_get_server_error_location(conn); if (location < (unsigned)argc) { /* we've got a valid location from the server */ const char *message = mpd_connection_get_error_message(conn); message = charset_from_utf8(message); fprintf(stderr, "error adding %s: %s\n", argv[location], message); exit(EXIT_FAILURE); } } #endif printErrorAndExit(conn); } return 0; }
int main(int argc, char *argv[]) { char *password = NULL; struct mpd_connection *conn = mpd_connection_new(mpd_check_host(NULL, &password), 0, 0); if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) { fprintf(stderr,"%s: %s\n", argv[0], mpd_connection_get_error_message(conn)); return 1; } if (password != NULL) { if (mpd_run_password(conn, password) == false) { fprintf(stderr, "%s: mpd_run_password %s\n", argv[0], mpd_connection_get_error_message(conn)); free(password); return 2; } } if (notify_init("MPD_Notification") == 0) { fprintf(stderr, "%s: Cannot initialize libnotify.\n", argv[0]); return 3; } infinite_loop(conn); mpd_connection_free(conn); free(password); notify_uninit(); return 0; }
bool mpd_is_in_queue(const char *uri) { bool res = false; struct mpd_entity *entity; struct mpd_connection *conn = mpd_connection_new(NULL, NULL, 3000); if (conn == NULL) { syslog(LOG_ERR, "%s - Out of memory.", __func__); goto DONE; } if (mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS) { syslog(LOG_ERR, "%s - MPD connection: %s\n", __func__, mpd_connection_get_error_message(conn)); goto DONE; } if (!mpd_send_list_queue_meta(conn)) { syslog(LOG_ERR, "%s: %s", __func__, mpd_connection_get_error_message(conn)); mpd_connection_clear_error(conn); goto DONE; } while((entity = mpd_recv_entity(conn)) != NULL) { const struct mpd_song *song; if(mpd_entity_get_type(entity) == MPD_ENTITY_TYPE_SONG && !res) { song = mpd_entity_get_song(entity); if (strcmp(mpd_song_get_uri(song), uri) == 0) { syslog(LOG_INFO, "%s: %s is already in the queue", __func__, uri); res = true; } } mpd_entity_free(entity); } DONE: if(conn != NULL) mpd_connection_free(conn); return res; }
void printErrorAndExit(struct mpd_connection *conn) { assert(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS); const char *message = mpd_connection_get_error_message(conn); #if 0 if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER) /* messages received from the server are UTF-8; the rest is either US-ASCII or locale */ message = charset_from_utf8(message); #endif fprintf(stderr, "mpd error: %s\n", message); mpd_connection_free(conn); exit(EXIT_FAILURE); }
bool check_error(struct mpd_connection *con, FILE *logfile, bool exit_on_failure) { if (mpd_connection_get_error(con) != MPD_ERROR_SUCCESS) { if (logfile) fprintf(logfile, "MPD error: %s\n", mpd_connection_get_error_message(con)); if (exit_on_failure || !mpd_connection_clear_error(con)) { mpd_connection_free(con); exit(EXIT_FAILURE); } return true; } return false; }
void mpd_poll() { // printf("%d\n", mpd.conn_state); switch (mpd.conn_state) { case MPD_DISCONNECTED: syslog(LOG_INFO, "%s - MPD Connecting...\n", __func__); mpd.conn = mpd_connection_new(NULL, NULL, 3000); if (mpd.conn == NULL) { syslog(LOG_ERR, "%s - Out of memory.", __func__); mpd.conn_state = MPD_FAILURE; return; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) { syslog(LOG_ERR, "%s - MPD connection: %s\n", __func__, mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return; } syslog(LOG_INFO, "%s - MPD connected.\n", __func__); mpd_connection_set_timeout(mpd.conn, 10000); mpd.conn_state = MPD_CONNECTED; break; case MPD_FAILURE: case MPD_DISCONNECT: case MPD_RECONNECT: syslog(LOG_ERR, "%s - MPD (dis)reconnect or failure\n", __func__); if(mpd.conn != NULL) mpd_connection_free(mpd.conn); mpd.conn = NULL; mpd.conn_state = MPD_DISCONNECTED; break; case MPD_CONNECTED: mpd_put_state(); //TODO: display status /* if (queue_is_empty) { queue_is_empty = 0; get_random_song(mpd.conn, str, rcm.file_path); if (strcmp(str, "") != 0) { syslog(LOG_DEBUG, "%s: add random song %s\n", __func__, str); mpd_run_add(mpd.conn, str); } }*/ break; default: syslog(LOG_INFO, "%s - mpd.conn_state %i\n", __func__, mpd.conn_state); } }
gboolean mpd_connect(void) { mpd.conn = mpd_connection_new(prefs.mpd_server, prefs.mpd_port, 10000); mpd.idle_source = 0; if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) { g_warning("Failed to connect to MPD: %s", mpd_connection_get_error_message(mpd.conn)); return FALSE; } else if (mpd_connection_cmp_server_version(mpd.conn, 0, 14, 0) < 0) { g_critical("MPD too old, please upgrade to 0.14 or newer"); return FALSE; } else { GIOChannel *channel; mpd_command_list_begin(mpd.conn, TRUE); if (prefs.mpd_password) mpd_send_password(mpd.conn, prefs.mpd_password); mpd_send_status(mpd.conn); mpd_send_current_song(mpd.conn); mpd_command_list_end(mpd.conn); mpd.status = mpd_recv_status(mpd.conn); if (!mpd_response_next(mpd.conn)) { mpd_report_error(); return FALSE; } mpd.song = mpd_recv_song(mpd.conn); if (!mpd_response_finish(mpd.conn)) { mpd_report_error(); return FALSE; } g_message("Connected to MPD"); irc_say("Connected to MPD"); mpd_send_idle_mask(mpd.conn, MPD_IDLE_PLAYER); channel = g_io_channel_unix_new( mpd_connection_get_fd(mpd.conn)); mpd.idle_source = g_io_add_watch(channel, G_IO_IN, (GIOFunc) mpd_parse, NULL); g_io_channel_unref(channel); return TRUE; } }
static void mpd_printerror(const char *cmd) { const char *s; if (conn) { //assert(mpd_connection_get_error(conn) != MPD_ERROR_SUCCESS); s = mpd_connection_get_error_message(conn); if (mpd_connection_get_error(conn) == MPD_ERROR_SERVER) /* messages received from the server are UTF-8; the rest is either US-ASCII or locale */ s = charset_from_utf8(s); error("[MPD] %s to [%s]:[%i] failed : [%s]", cmd, host, iport, s); mpd_connection_free(conn); conn = NULL; } }
/*new_connection*/ int new_connection(struct mpd_connection **conn) { *conn = mpd_connection_new(NULL, 0, 30000); if (*conn == NULL) { printf("nd new_connection %s\n", "Out of memory"); return -1; } if (mpd_connection_get_error(*conn) != MPD_ERROR_SUCCESS) { printf("nd new_connection %s\n", mpd_connection_get_error_message(*conn)); mpd_connection_free(*conn); *conn = NULL; return -1; } return 0; }
void Connection::checkErrors() const { mpd_error code = mpd_connection_get_error(m_connection.get()); if (code != MPD_ERROR_SUCCESS) { std::string msg = mpd_connection_get_error_message(m_connection.get()); if (code == MPD_ERROR_SERVER) { mpd_server_error server_code = mpd_connection_get_server_error(m_connection.get()); bool clearable = mpd_connection_clear_error(m_connection.get()); throw ServerError(server_code, msg, clearable); } else { bool clearable = mpd_connection_clear_error(m_connection.get()); throw ClientError(code, msg, clearable); } } }
static int connect(struct mpd_connection **conn) { *conn = mpd_connection_new(NULL, 0, 30000); if (*conn == NULL) { LOG_ERROR("%s", "Out of memory"); return -1; } if (mpd_connection_get_error(*conn) != MPD_ERROR_SUCCESS) { LOG_ERROR("%s", mpd_connection_get_error_message(*conn)); mpd_connection_free(*conn); *conn = NULL; return -1; } return 1; }
/* * pgmpc_print_error * * Relay an error from mpd to Postgres. */ static void pgmpc_print_error(void) { const char *message; Assert(mpd_connection_get_error(mpd_conn) != MPD_ERROR_SUCCESS); /* Obtain error message */ message = mpd_connection_get_error_message(mpd_conn); /* Cleanup */ pgmpc_reset(); /* Report error */ ereport(ERROR, (errcode(ERRCODE_SYSTEM_ERROR), errmsg("mpd command failed: %s", message))); }
bool CMPD::Connect() { if(_conn) mpd_connection_free(_conn); _conn = mpd_connection_new(_cfg->Get("host").c_str(), _cfg->GetInt("port"), 0); _connected = _conn && mpd_connection_get_error(_conn) == MPD_ERROR_SUCCESS; if(_connected && _cfg->Get("mpdpassword").size() > 0) { _connected &= mpd_run_password(_conn, _cfg->Get("mpdpassword").c_str()); } else if(!_connected) { eprintf("MPD connection error: %s", mpd_connection_get_error_message(_conn)); } if(_connected) mpd_run_subscribe(_conn, "mpdas"); return _connected; }
/*get_mpc_quere_len*/ int get_mpc_quere_len(struct mpd_connection *conn) { int quere_len = 0; pthread_mutex_lock(&mutex); struct mpd_status *status; status = mpd_run_status(conn); if (!status) { printf("nd get_mpc_quere_len erro %s\n", mpd_connection_get_error_message(conn)); return -1; } quere_len = mpd_status_get_queue_length(status); mpd_status_free(status); mpd_response_finish(conn); //CHECK_CONNECTION(conn); pthread_mutex_unlock(&mutex); return quere_len; }
/*my_mpd_run_pause*/ void my_mpd_run_pause(void) { struct mpd_status *status = NULL; pthread_mutex_lock(&mutex); status = mpd_run_status(conn); if (!status) { printf("nd my_mpd_run_pause mpd_run_status1 %s \n", mpd_connection_get_error_message(conn)); } else { if (mpd_status_get_state(status) == MPD_STATE_PLAY) { mpd_run_pause(conn, true); } mpd_status_free(status); } pthread_mutex_unlock(&mutex); }
/*btn3_short_press*/ void btn3_short_press(void) { int res = json_type_null; json_object * pjson_obj_read = NULL; struct mpd_status *status = NULL; ncurrt_time = 0; system("killall aplay"); system("killall xfchat"); pthread_rwlock_wrlock(&json_rwlock_voice); pjson_obj_read = json_object_from_file(PLAY_VOICE_JSON_PATH); pthread_rwlock_unlock(&json_rwlock_voice); res = json_object_get_type(pjson_obj_read); printf("json_type: %u \n", json_object_get_type(pjson_obj_read)); // printf("json_length: %u \n", json_object_array_length(pjson_obj_read)); json_object_put(pjson_obj_read); if ((json_type_array == res) && (0 < json_object_array_length(pjson_obj_read)) && (!bplay_audio)) { printf("nd btn3_short_press ret: %d, bplay_audio: %d\n", res, bplay_audio); my_mpd_run_pause(); bplay_audio = true; } else { int quere_len = 0; int online_size = 0; bplay_audio = false; online_size = get_file_size(ONLINE_LIST_PATH); if (online_size > 0) { quere_len = get_mpc_quere_len(conn); pthread_mutex_lock(&mutex); if (quere_len > 0) { mpd_run_stop(conn); mpd_run_clear(conn); } bool mpc_load = mpd_run_load(conn, "online.lst"); bool mpc_list_clear = mpd_run_playlist_clear(conn, "online.lst"); printf("nd btn3_short_press mpc_load: %d, mpc_list_clear: %d\n", mpc_load, mpc_list_clear); pthread_mutex_unlock(&mutex); res = i2c_smbus_write_byte_data(i2c_file, 0x00, BLUE_OFF); if (res < 0) { printf("nd btn3_short_press i2c_smbus_write_byte_data BLUE_OFF failed, ret: %d\n", res); } } quere_len = get_mpc_quere_len(conn); if (quere_len > 0) { printf("nd btn3_short_press get_mpc_quere_len quere_len: %d\n", quere_len); pthread_mutex_lock(&mutex); status = mpd_run_status(conn); if (!status) { printf("nd btn3_short_press mpd_run_status2 %s \n", mpd_connection_get_error_message(conn)); } else { if (mpd_status_get_state(status) == MPD_STATE_PLAY) { printf("nd btn3_short_press mpd_status_get_state MPD_STATE_PLAY\n"); mpd_run_pause(conn, true); } else { printf("nd btn3_short_press mpd_status_get_state other state\n"); mpd_run_play(conn); } mpd_status_free(status); } pthread_mutex_unlock(&mutex); } } }
int mpd_put_browse(char *buffer, char *path, unsigned int offset) { char *cur = buffer; const char *end = buffer + MAX_SIZE; struct mpd_entity *entity; unsigned int entity_count = 0; if (!mpd_send_list_meta(mpd.conn, path)) RETURN_ERROR_AND_RECOVER("mpd_send_list_meta"); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"browse\",\"data\":[ "); while((entity = mpd_recv_entity(mpd.conn)) != NULL) { const struct mpd_song *song; const struct mpd_directory *dir; const struct mpd_playlist *pl; if(offset > entity_count) { mpd_entity_free(entity); entity_count++; continue; } else if(offset + MAX_ELEMENTS_PER_PAGE - 1 < entity_count) { mpd_entity_free(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"wrap\",\"count\":"); cur += json_emit_int(cur, end - cur, entity_count); cur += json_emit_raw_str(cur, end - cur, "} "); break; } switch (mpd_entity_get_type(entity)) { case MPD_ENTITY_TYPE_UNKNOWN: break; case MPD_ENTITY_TYPE_SONG: song = mpd_entity_get_song(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"song\",\"uri\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_song_get_uri(song)); cur += json_emit_raw_str(cur, end - cur, ",\"duration\":"); cur += json_emit_int(cur, end - cur, mpd_song_get_duration(song)); cur += json_emit_raw_str(cur, end - cur, ",\"title\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_get_title(song)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_DIRECTORY: dir = mpd_entity_get_directory(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"directory\",\"dir\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_directory_get_path(dir)); cur += json_emit_raw_str(cur, end - cur, "},"); break; case MPD_ENTITY_TYPE_PLAYLIST: pl = mpd_entity_get_playlist(entity); cur += json_emit_raw_str(cur, end - cur, "{\"type\":\"playlist\",\"plist\":"); cur += json_emit_quoted_str(cur, end - cur, mpd_playlist_get_path(pl)); cur += json_emit_raw_str(cur, end - cur, "},"); break; } mpd_entity_free(entity); entity_count++; } if (mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS || !mpd_response_finish(mpd.conn)) { fprintf(stderr, "MPD mpd_send_list_meta: %s\n", mpd_connection_get_error_message(mpd.conn)); mpd.conn_state = MPD_FAILURE; return 0; } /* remove last ',' */ cur--; cur += json_emit_raw_str(cur, end - cur, "]}"); return cur - buffer; }
int callback_mpd(struct mg_connection *c) { enum mpd_cmd_ids cmd_id = get_cmd_id(c->content); size_t n = 0; unsigned int uint_buf, uint_buf_2; int int_buf; char *p_charbuf = NULL, *token; if(cmd_id == -1) return MG_TRUE; if(mpd.conn_state != MPD_CONNECTED && cmd_id != MPD_API_SET_MPDHOST && cmd_id != MPD_API_GET_MPDHOST && cmd_id != MPD_API_SET_MPDPASS && cmd_id != MPD_API_GET_DIRBLEAPITOKEN) return MG_TRUE; switch(cmd_id) { case MPD_API_UPDATE_DB: mpd_run_update(mpd.conn, NULL); break; case MPD_API_SET_PAUSE: mpd_run_toggle_pause(mpd.conn); break; case MPD_API_SET_PREV: mpd_run_previous(mpd.conn); break; case MPD_API_SET_NEXT: mpd_run_next(mpd.conn); break; case MPD_API_SET_PLAY: mpd_run_play(mpd.conn); break; case MPD_API_SET_STOP: mpd_run_stop(mpd.conn); break; case MPD_API_RM_ALL: mpd_run_clear(mpd.conn); break; case MPD_API_RM_TRACK: if(sscanf(c->content, "MPD_API_RM_TRACK,%u", &uint_buf)) mpd_run_delete_id(mpd.conn, uint_buf); break; case MPD_API_PLAY_TRACK: if(sscanf(c->content, "MPD_API_PLAY_TRACK,%u", &uint_buf)) mpd_run_play_id(mpd.conn, uint_buf); break; case MPD_API_TOGGLE_RANDOM: if(sscanf(c->content, "MPD_API_TOGGLE_RANDOM,%u", &uint_buf)) mpd_run_random(mpd.conn, uint_buf); break; case MPD_API_TOGGLE_REPEAT: if(sscanf(c->content, "MPD_API_TOGGLE_REPEAT,%u", &uint_buf)) mpd_run_repeat(mpd.conn, uint_buf); break; case MPD_API_TOGGLE_CONSUME: if(sscanf(c->content, "MPD_API_TOGGLE_CONSUME,%u", &uint_buf)) mpd_run_consume(mpd.conn, uint_buf); break; case MPD_API_TOGGLE_SINGLE: if(sscanf(c->content, "MPD_API_TOGGLE_SINGLE,%u", &uint_buf)) mpd_run_single(mpd.conn, uint_buf); break; case MPD_API_TOGGLE_CROSSFADE: if(sscanf(c->content, "MPD_API_TOGGLE_CROSSFADE,%u", &uint_buf)) mpd_run_crossfade(mpd.conn, uint_buf); break; case MPD_API_GET_OUTPUTS: mpd.buf_size = mpd_put_outputs(mpd.buf, 1); c->callback_param = NULL; mpd_notify_callback(c, MG_POLL); break; case MPD_API_TOGGLE_OUTPUT: if (sscanf(c->content, "MPD_API_TOGGLE_OUTPUT,%u,%u", &uint_buf, &uint_buf_2)) { if (uint_buf_2) mpd_run_enable_output(mpd.conn, uint_buf); else mpd_run_disable_output(mpd.conn, uint_buf); } break; case MPD_API_SET_VOLUME: if(sscanf(c->content, "MPD_API_SET_VOLUME,%ud", &uint_buf) && uint_buf <= 100) mpd_run_set_volume(mpd.conn, uint_buf); break; case MPD_API_SET_SEEK: if(sscanf(c->content, "MPD_API_SET_SEEK,%u,%u", &uint_buf, &uint_buf_2)) mpd_run_seek_id(mpd.conn, uint_buf, uint_buf_2); break; case MPD_API_GET_QUEUE: if(sscanf(c->content, "MPD_API_GET_QUEUE,%u", &uint_buf)) n = mpd_put_queue(mpd.buf, uint_buf); break; case MPD_API_GET_BROWSE: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_GET_BROWSE")) goto out_browse; uint_buf = strtoul(strtok(NULL, ","), NULL, 10); if((token = strtok(NULL, ",")) == NULL) goto out_browse; free(p_charbuf); p_charbuf = strdup(c->content); n = mpd_put_browse(mpd.buf, get_arg2(p_charbuf), uint_buf); out_browse: free(p_charbuf); break; case MPD_API_ADD_TRACK: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_TRACK")) goto out_add_track; if((token = strtok(NULL, ",")) == NULL) goto out_add_track; free(p_charbuf); p_charbuf = strdup(c->content); mpd_run_add(mpd.conn, get_arg1(p_charbuf)); out_add_track: free(p_charbuf); break; case MPD_API_ADD_PLAY_TRACK: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAY_TRACK")) goto out_play_track; if((token = strtok(NULL, ",")) == NULL) goto out_play_track; free(p_charbuf); p_charbuf = strdup(c->content); int_buf = mpd_run_add_id(mpd.conn, get_arg1(p_charbuf)); if(int_buf != -1) mpd_run_play_id(mpd.conn, int_buf); out_play_track: free(p_charbuf); break; case MPD_API_ADD_PLAYLIST: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_ADD_PLAYLIST")) goto out_playlist; if((token = strtok(NULL, ",")) == NULL) goto out_playlist; free(p_charbuf); p_charbuf = strdup(c->content); mpd_run_load(mpd.conn, get_arg1(p_charbuf)); out_playlist: free(p_charbuf); break; case MPD_API_SAVE_QUEUE: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_SAVE_QUEUE")) goto out_save_queue; if((token = strtok(NULL, ",")) == NULL) goto out_save_queue; free(p_charbuf); p_charbuf = strdup(c->content); mpd_run_save(mpd.conn, get_arg1(p_charbuf)); out_save_queue: free(p_charbuf); break; case MPD_API_SEARCH: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_SEARCH")) goto out_search; if((token = strtok(NULL, ",")) == NULL) goto out_search; free(p_charbuf); p_charbuf = strdup(c->content); n = mpd_search(mpd.buf, get_arg1(p_charbuf)); out_search: free(p_charbuf); break; #ifdef WITH_MPD_HOST_CHANGE /* Commands allowed when disconnected from MPD server */ case MPD_API_SET_MPDHOST: int_buf = 0; p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_SET_MPDHOST")) goto out_host_change; if((int_buf = strtol(strtok(NULL, ","), NULL, 10)) <= 0) goto out_host_change; if((token = strtok(NULL, ",")) == NULL) goto out_host_change; strncpy(mpd.host, token, sizeof(mpd.host)); mpd.port = int_buf; mpd.conn_state = MPD_RECONNECT; free(p_charbuf); return MG_TRUE; out_host_change: free(p_charbuf); break; case MPD_API_GET_MPDHOST: n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"mpdhost\", \"data\": " "{\"host\" : \"%s\", \"port\": \"%d\", \"passwort_set\": %s}" "}", mpd.host, mpd.port, mpd.password ? "true" : "false"); break; case MPD_API_GET_DIRBLEAPITOKEN: n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"dirbleapitoken\", \"" "data\": \"%s\"}", dirble_api_token); break; case MPD_API_SET_MPDPASS: p_charbuf = strdup(c->content); if(strcmp(strtok(p_charbuf, ","), "MPD_API_SET_MPDPASS")) goto out_set_pass; if((token = strtok(NULL, ",")) == NULL) goto out_set_pass; if(mpd.password) free(mpd.password); mpd.password = strdup(token); mpd.conn_state = MPD_RECONNECT; free(p_charbuf); return MG_TRUE; out_set_pass: free(p_charbuf); break; #endif } if(mpd.conn_state == MPD_CONNECTED && mpd_connection_get_error(mpd.conn) != MPD_ERROR_SUCCESS) { n = snprintf(mpd.buf, MAX_SIZE, "{\"type\":\"error\", \"data\": \"%s\"}", mpd_connection_get_error_message(mpd.conn)); /* Try to recover error */ if (!mpd_connection_clear_error(mpd.conn)) mpd.conn_state = MPD_FAILURE; } if(n > 0) mg_websocket_write(c, 1, mpd.buf, n); return MG_TRUE; }
/* Execute the given command. In fact, it just will ask MPD to do it. * You will have to check the next "status" or "playlist" update (using the corresponding slot) * to know if the command has really been executed. */ void Player::executeCmd(EMSPlayerCmd cmd) { bool waitResponse = true; /* Wait the responase by default */ bool error = false; if (conn == NULL) { return; } /* Dispatch execution depending on the action */ switch (cmd.action) { case ACTION_ADD: { if(searchTrackInPlaylist(cmd.track) >= 0) { qDebug() << "Do not add track in the playlist as it already exist"; return; } QString filename = getMPDFilename(cmd.track); mpd_send_add(conn, filename.toStdString().c_str()); break; } case ACTION_DEL: { int pos = searchTrackInPlaylist(cmd.track); if (pos >= 0) { mpd_send_delete(conn, pos); } break; } case ACTION_DEL_ALL: { mpd_send_clear(conn); break; } case ACTION_PLAY_POS: { mutex.lock(); int size = playlist.tracks.size(); mutex.unlock(); if (size <= 0 || cmd.uintValue >= (unsigned int)size) { qDebug() << "Asked to play a track after the end of the current playlist"; error = true; break; } mpd_send_play_pos(conn, cmd.uintValue); break; } case ACTION_PLAY_TRACK: { int position = searchTrackInPlaylist(cmd.track); if (position < 0) { qDebug() << "Asked to play a track which is not in the current playlist"; error = true; break; } mpd_send_play_pos(conn, position); break; } case ACTION_PLAY: { mpd_send_play(conn); break; } case ACTION_SEEK: { /* Get current position */ int songId = getCurrentPos(); if (songId >= 0) { mpd_send_seek_pos(conn, songId, cmd.uintValue); } break; } case ACTION_PAUSE: { mpd_send_pause(conn, true); break; } case ACTION_TOGGLE: { mpd_send_toggle_pause(conn); break; } case ACTION_STOP: { mpd_send_stop(conn); break; } case ACTION_NEXT: { mpd_send_next(conn); break; } case ACTION_PREV: { mpd_send_previous(conn); break; } case ACTION_REPEAT: { mutex.lock(); bool repeatTmp = status.repeat; mutex.unlock(); if (cmd.boolValue != repeatTmp) { mpd_send_repeat(conn, cmd.boolValue); } break; } case ACTION_RANDOM: { mutex.lock(); bool randomTmp = status.random; mutex.unlock(); if (cmd.boolValue != randomTmp) { mpd_send_random(conn, cmd.boolValue); } break; } case ACTION_ENABLE_OUTPUT: { if (cmd.uintValue >= 1) { mpd_send_enable_output(conn, cmd.uintValue-1); } break; } case ACTION_DISABLE_OUTPUT: { if (cmd.uintValue >= 1) { mpd_send_disable_output(conn, cmd.uintValue-1); } break; } default: { qCritical() << "Unhandled action in the current command."; waitResponse = false; break; } } if (waitResponse && !mpd_response_finish(conn)) { error = true; qCritical() << "MPD could not execute the current command."; enum mpd_error errorMpd = mpd_connection_get_error(conn); if (errorMpd == MPD_ERROR_SERVER || errorMpd == MPD_ERROR_ARGUMENT) /* Problem with the command */ { QString errorMessage = QString::fromUtf8(mpd_connection_get_error_message(conn)); qCritical() << "Command error : " << errorMessage; if (!mpd_connection_clear_error(conn)) { qCritical() << "This error cannot be cleared, reconnecting..."; connectToMpd(); } } else if (errorMpd == MPD_ERROR_TIMEOUT || errorMpd == MPD_ERROR_RESOLVER || errorMpd == MPD_ERROR_MALFORMED || errorMpd == MPD_ERROR_CLOSED ) /* Assume there is a connection problem, try to reconnect... */ { QString errorMessage = QString::fromUtf8(mpd_connection_get_error_message(conn)); qCritical() << "Connexion error : " << errorMessage; qCritical() << "Reconnecting..."; connectToMpd(); mutex.lock(); queue.push_front(cmd); mutex.unlock(); cmdAvailable.release(1); } } /* Post-action depending on the command * Do the minimum here as the whole status will be * retrieve here. But for playlist ADD/DEL, we need to * store the EMSTrack structure. */ if(!error) { switch (cmd.action) { case ACTION_ADD: { EMSPlaylist newPlaylist; mutex.lock(); playlist.tracks.append(cmd.track); newPlaylist = playlist; mutex.unlock(); emit playlistChanged(newPlaylist); break; } case ACTION_DEL: { int pos = searchTrackInPlaylist(cmd.track); if (pos >= 0) { EMSPlaylist newPlaylist; mutex.lock(); playlist.tracks.removeAt(pos); newPlaylist = playlist; mutex.unlock(); emit playlistChanged(newPlaylist); } break; } case ACTION_DEL_ALL: { EMSPlaylist newPlaylist; mutex.lock(); playlist.tracks.clear(); newPlaylist = playlist; mutex.unlock(); emit playlistChanged(newPlaylist); break; } case ACTION_ENABLE_OUTPUT: { mutex.lock(); for(int i=0; i<outputs.size(); i++) { if (outputs.at(i).id_mpd == cmd.uintValue) { EMSSndCard card = outputs.at(i); card.enabled = true; outputs.replace(i, card); } } emit outputsChanged(outputs); mutex.unlock(); break; } case ACTION_DISABLE_OUTPUT: { mutex.lock(); for(int i=0; i<outputs.size(); i++) { if (outputs.at(i).id_mpd == cmd.uintValue) { EMSSndCard card = outputs.at(i); card.enabled = false; outputs.replace(i, card); } } emit outputsChanged(outputs); mutex.unlock(); break; } default: break; } } }