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;
}
예제 #5
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;

}
예제 #7
0
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;
}
예제 #8
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;
}
예제 #9
0
파일: services.c 프로젝트: PieVo/airushare
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;
}
예제 #10
0
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;
}
예제 #13
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);
}
예제 #14
0
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;
}
예제 #17
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;
}
예제 #18
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;
}
예제 #19
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;
}