static int set_avtransport_uri(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *uri = upnp_get_string(event, "CurrentURI"); if (uri == NULL) { return -1; } service_lock(); char *meta = upnp_get_string(event, "CurrentURIMetaData"); // Transport URI/Meta set now, current URI/Meta when it starts playing. int requires_meta_update = replace_transport_uri_and_meta(uri, meta); if (transport_state_ == TRANSPORT_PLAYING) { // Uh, wrong state. // Usually, this should not be called while we are PLAYING, only // STOPPED or PAUSED. But if actually some controller sets this // while playing, probably the best is to update the current // current URI/Meta as well to reflect the state best. replace_current_uri_and_meta(uri, meta); } output_set_uri(uri, (requires_meta_update ? update_meta_from_stream : NULL)); service_unlock(); free(uri); free(meta); return 0; }
static int set_avtransport_uri(struct action_event *event) { int rc = 0; ENTER(); if (obtain_instanceid(event, NULL)) { LEAVE(); return -1; } char *uri = upnp_get_string(event, "CurrentURI"); if (uri == NULL) { LEAVE(); return -1; } service_lock(); char *meta = upnp_get_string(event, "CurrentURIMetaData"); int requires_meta_update = replace_transport_uri_and_meta(uri, meta); output_set_uri(uri, (requires_meta_update ? update_meta_from_stream : NULL)); notify_changed_uris(); service_unlock(); free(uri); free(meta); LEAVE(); return rc; }
static int set_next_avtransport_uri(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *next_uri = upnp_get_string(event, "NextURI"); if (next_uri == NULL) { return -1; } int rc = 0; service_lock(); output_set_next_uri(next_uri); replace_var(TRANSPORT_VAR_NEXT_AV_URI, next_uri); char *next_uri_meta = upnp_get_string(event, "NextURIMetaData"); if (next_uri_meta == NULL) { rc = -1; } else { replace_var(TRANSPORT_VAR_NEXT_AV_URI_META, next_uri_meta); } service_unlock(); free(next_uri); free(next_uri_meta); return rc; }
static int seek(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *unit = upnp_get_string(event, "Unit"); if (strcmp(unit, "REL_TIME") == 0) { // This is the only thing we support right now. char *target = upnp_get_string(event, "Target"); gint64 nanos = parse_upnp_time(target); service_lock(); if (output_seek(nanos) == 0) { // TODO(hzeller): Seeking might take some time, // pretend to already be there. Should we go into // TRANSITION mode ? // (gstreamer will go into PAUSE, then PLAYING) replace_var(TRANSPORT_VAR_REL_TIME_POS, target); } service_unlock(); free(target); } free(unit); return 0; }
DBG_STATIC int set_avtransport_uri(struct action_event *event) { char *value; int rc = 0; if (upnp_obtain_instanceid(event, NULL)) { upnp_set_error(event, UPNP_TRANSPORT_E_INVALID_IID, "ID non-zero invalid"); return -1; } value = upnp_get_string(event, "CurrentURI"); if (value == NULL) return -1; ithread_mutex_lock(&transport_mutex); DBG_PRINT(DBG_LVL4, "%s: Set URI to '%s'\n", __FUNCTION__, value); // do the work output_set_uri(value); transport_set_var(TRANSPORT_VAR_AV_URI, value); free(value); value = upnp_get_string(event, "CurrentURIMetaData"); if (value != NULL) { DBG_PRINT(DBG_LVL4, "%s: Set URI MetaData to '%s'\n", __FUNCTION__, value); // First set new value so we may extract some information about // the stream (Ex: track_duration) transport_set_var(TRANSPORT_VAR_AV_URI_META, value); free(value); // Locate duration attribute in 'res' element under 'item' value = (char *)transport_get_attr_metadata("duration"); if (value) { transport_set_var(TRANSPORT_VAR_CUR_TRACK_DUR, value); free(value); } } else { rc = -1; } transport_state = TRANSPORT_STOPPED; transport_set_var(TRANSPORT_VAR_TRANSPORT_STATE, "STOPPED"); transport_notify_lastchange(event, transport_get_state_lastchange()); ithread_mutex_unlock(&transport_mutex); return rc; }
static int set_streaming_playlist(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *playlistdata = upnp_get_string(event, "PlaylistData"); if (playlistdata == NULL) { return -1; } int playlistdatalength = atoi(upnp_get_string(event, "PlaylistDataLength")); /*char *playlistmimetype = upnp_get_string(event, "PlaylistMIMEType"); if (playlistmimetype == NULL) { free(playlistdata); return -1; } */ char *playliststep = upnp_get_string(event, "PlaylistStep"); //Initial Continue Stop Reset if (playliststep == NULL) { free(playlistdata); // free(playlistmimetype); return -1; } int rc = 0; service_lock(); if(strcmp(playliststep, "Initial") == 0){ //TODO: rc = write_playlist(event, playlistdata, playlistdatalength, "w"); } if(strcmp(playliststep, "Continue") == 0){ rc = write_playlist(event, playlistdata, playlistdatalength, "a"); } if(strcmp(playliststep, "Stop") == 0){ //TODO: Indicates that the current streaming playlist operation will end when all pending playlist data at then device is consumed. if(playlistdata) rc = write_playlist(event, playlistdata, playlistdatalength, "a"); output_set_playlist(M3U_STREAMINGPLAYLIST_PATH); } if(strcmp(playliststep, "Reset") == 0){ //TODO: Indicates that processing of the current streaming playlist ends immediately. any pending playlist data for the streaming playlist is discarded. output_set_playlist(M3U_STREAMINGPLAYLIST_PATH); } if(!rc) replace_var(TRANSPORT_VAR_AAT_PLAYLIST_STEP, playliststep); service_unlock(); if(playlistdata) free(playlistdata); free(playliststep); return rc; }
static int set_mute(struct action_event *event) { const char *value = upnp_get_string(event, "DesiredMute"); service_lock(); const int do_mute = atoi(value); set_mute_toggle(do_mute); change_var_and_notify(event, CONTROL_VAR_MUTE, do_mute ? "1" : "0"); service_unlock(); return 0; }
static int set_volume_db(struct action_event *event) { const char *str_decibel_in = upnp_get_string(event, "DesiredVolume"); service_lock(); float raw_decibel_in = atof(str_decibel_in); float decibel = change_volume_decibel(event, raw_decibel_in); output_set_volume(exp(decibel / 20 * log(10))); service_unlock(); return 0; }
int upnp_get_ui4 (struct Upnp_Action_Request *request, const char *key) { char *value; int val; if (!request || !key) return 0; value = upnp_get_string (request, key); if (!value && !strcmp (key, ARG_OBJECT_ID)) value = upnp_get_string (request, ARG_CONTAINER_ID); if (!value) return 0; val = atoi (value); free (value); return val; }
DBG_STATIC int xseek(struct action_event *event) { char *value, *mode; int rc = 0; if (upnp_obtain_instanceid(event, NULL)) { upnp_set_error(event, UPNP_TRANSPORT_E_INVALID_IID, "ID non-zero invalid"); return -1; } mode = upnp_get_string(event, "Unit"); if (mode == NULL) return -1; value = upnp_get_string(event, "Target"); if (value == NULL) { free(mode); return -1; } // Check MPD connection if (check_mpd_connection(TRUE) == STATUS_FAIL) return -1; // Attempt to seek player (doesn't work for streams) rc = output_seekto(mode, value); free(mode); free(value); if (rc != 0) { upnp_set_error(event, UPNP_TRANSPORT_E_ILL_SEEKTARGET, "Player Seek failed"); return -1; } return rc; }
static int set_next_avtransport_uri(struct action_event *event) { int rc = 0; char *value; ENTER(); if (obtain_instanceid(event, NULL)) { LEAVE(); return -1; } value = upnp_get_string(event, "NextURI"); if (value == NULL) { LEAVE(); return -1; } service_lock(); output_set_next_uri(value); change_var_and_notify(TRANSPORT_VAR_NEXT_AV_URI, value); printf("%s: NextURI='%s'\n", __FUNCTION__, value); free(value); value = upnp_get_string(event, "NextURIMetaData"); if (value == NULL) { rc = -1; } else { change_var_and_notify(TRANSPORT_VAR_NEXT_AV_URI_META, value); free(value); } service_unlock(); LEAVE(); return rc; }
static int obtain_instanceid(struct action_event *event, int *instance) { char *value = upnp_get_string(event, "InstanceID"); if (value == NULL) { upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS, "Missing InstanceID"); return -1; } free(value); // TODO - parse value, and store in *instance, if instance!=NULL return 0; }
static int cmd_obtain_variable(struct action_event *event, int varnum, const char *paramname) { char *value; value = upnp_get_string(event, "InstanceID"); if (value == NULL) { return -1; } printf("%s: InstanceID='%s'\n", __FUNCTION__, value); free(value); return upnp_append_variable(event, varnum, paramname); }
static int cmd_obtain_variable(struct action_event *event, control_variable_t varnum, const char *paramname) { char *instance = upnp_get_string(event, "InstanceID"); if (instance == NULL) { return -1; } Log_info("control", "%s: %s for instance %s\n", __FUNCTION__, paramname, instance); free(instance); // we don't care about that value for now. upnp_append_variable(event, varnum, paramname); return 0; }
static int get_playlist_info(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *playlisttype = upnp_get_string(event, "PlaylistType"); if (playlisttype == NULL) { return -1; } //fprintf(stderr, "InstanceID = %s \n", unit); free(playlisttype); return 0; }
//TODO:FIXME static int set_playmode(struct action_event *event) { if (obtain_instanceid(event, NULL) < 0) { return -1; } char *playmode = upnp_get_string(event, "NewPlayMode"); if (playmode == NULL) { return -1; } //TODO: support this playmode? error 712 // This is the only thing we support right now. service_lock(); replace_var(TRANSPORT_VAR_CUR_PLAY_MODE, playmode); service_unlock(); free(playmode); return 0; }
static int set_volume(struct action_event *event) { const char *volume = upnp_get_string(event, "DesiredVolume"); service_lock(); int volume_level = atoi(volume); // range 0..100 if (volume_level < volume_range.min) volume_level = volume_range.min; if (volume_level > volume_range.max) volume_level = volume_range.max; const float decibel = volume_level_to_decibel(volume_level); char db_volume[10]; snprintf(db_volume, sizeof(db_volume), "%d", (int) (256 * decibel)); const double fraction = exp(decibel / 20 * log(10)); fprintf(stderr, "Setting volume to #%d = %.2fdb (%.4f)\n", volume_level, decibel, fraction); change_volume_and_notify(event, volume, db_volume); output_set_volume(fraction); set_mute_toggle(volume_level == 0); service_unlock(); return 0; }
static int set_volume(struct action_event *event) { const char *volume = upnp_get_string(event, "DesiredVolume"); service_lock(); int volume_level = atoi(volume); // range 0..100 if (volume_level < volume_range.min) volume_level = volume_range.min; if (volume_level > volume_range.max) volume_level = volume_range.max; const float decibel = volume_level_to_decibel(volume_level); char db_volume[10]; snprintf(db_volume, sizeof(db_volume), "%d", (int) (256 * decibel)); Log_info("control", "Setting %d volume-db to %d" , volume_level,(int)decibel); const double fraction = exp(decibel / 20 * log(10)); change_volume(volume, db_volume); output_set_volume(fraction, volume_level); set_mute_toggle(volume_level == 0); service_unlock(); return 0; }
DBG_STATIC int xplaymode(struct action_event *event) { char *newmode; int rc = 0; if (upnp_obtain_instanceid(event, NULL)) { upnp_set_error(event, UPNP_TRANSPORT_E_INVALID_IID, "ID non-zero invalid"); return -1; } newmode = upnp_get_string(event, "NewPlayMode"); DBG_PRINT(DBG_LVL4, "Set NewPlayMode: %s\n", newmode); // Check MPD connection if (check_mpd_connection(TRUE) == STATUS_FAIL) return -1; ithread_mutex_lock(&transport_mutex); rc = output_playmode(newmode); if (rc != 0) { free(newmode); upnp_set_error(event, UPNP_TRANSPORT_E_PLAYMODE_NS, "Set playmode failed"); goto out; } transport_change_var(event, TRANSPORT_VAR_CUR_PLAY_MODE, newmode); free(newmode); out: ithread_mutex_unlock(&transport_mutex); return rc; }
static int obtain_instanceid(struct action_event *event, int *instance) { char *value; int rc = 0; ENTER(); value = upnp_get_string(event, "InstanceID"); if (value == NULL) { #ifdef HAVE_LIBUPNP upnp_set_error(event, UPNP_SOAP_E_INVALID_ARGS, "Missing InstanceID"); #endif return -1; } //printf("%s: InstanceID='%s'\n", __FUNCTION__, value); free(value); // TODO - parse value, and store in *instance, if instance!=NULL LEAVE(); return rc; }
static int get_media_info(struct action_event *event) { char *value; int rc; ENTER(); value = upnp_get_string(event, "InstanceID"); if (value == NULL) { rc = -1; goto out; } printf("%s: InstanceID='%s'\n", __FUNCTION__, value); free(value); rc = upnp_append_variable(event, TRANSPORT_VAR_NR_TRACKS, "NrTracks"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_CUR_MEDIA_DUR, "MediaDuration"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_AV_URI, "CurrentURI"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_AV_URI_META, "CurrentURIMetaData"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_NEXT_AV_URI, "NextURI"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_NEXT_AV_URI_META, "NextURIMetaData"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_REC_MEDIA, "PlayMedium"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_REC_MEDIUM, "RecordMedium"); if (rc) goto out; rc = upnp_append_variable(event, TRANSPORT_VAR_REC_MEDIUM_WR_STATUS, "WriteStatus"); if (rc) goto out; out: return rc; }