[asterisk-commits] dlee: branch dlee/playback r388212 - in /team/dlee/playback: include/asterisk...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Thu May 9 13:24:00 CDT 2013


Author: dlee
Date: Thu May  9 13:23:56 2013
New Revision: 388212

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=388212
Log:
Post playback snapshots to the channel's topic.

Modified:
    team/dlee/playback/include/asterisk/stasis_app.h
    team/dlee/playback/include/asterisk/stasis_app_playback.h
    team/dlee/playback/include/asterisk/stasis_channels.h
    team/dlee/playback/main/stasis_channels.c
    team/dlee/playback/res/res_stasis.c
    team/dlee/playback/res/res_stasis_playback.c
    team/dlee/playback/res/stasis/control.c
    team/dlee/playback/res/stasis/control.h
    team/dlee/playback/res/stasis_http/resource_channels.h
    team/dlee/playback/rest-api/api-docs/channels.json

Modified: team/dlee/playback/include/asterisk/stasis_app.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/include/asterisk/stasis_app.h?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/include/asterisk/stasis_app.h (original)
+++ team/dlee/playback/include/asterisk/stasis_app.h Thu May  9 13:23:56 2013
@@ -161,6 +161,15 @@
 struct ast_channel_snapshot *stasis_app_control_get_snapshot(
 	const struct stasis_app_control *control);
 
+/*!
+ * \brief Publish a message to the \a control's channel's topic.
+ *
+ * \param control Control to publish to
+ * \param message Message to publish
+ */
+void stasis_app_control_publish(
+	struct stasis_app_control *control, struct stasis_message *message);
+
 /*! @} */
 
 #endif /* _ASTERISK_STASIS_APP_H */

Modified: team/dlee/playback/include/asterisk/stasis_app_playback.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/include/asterisk/stasis_app_playback.h?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/include/asterisk/stasis_app_playback.h (original)
+++ team/dlee/playback/include/asterisk/stasis_app_playback.h Thu May  9 13:23:56 2013
@@ -36,11 +36,11 @@
 /*! State of a playback operation */
 enum stasis_app_playback_state {
 	/*! The playback has not started yet */
-	STASIS_PLAYBACK_QUEUED,
+	STASIS_PLAYBACK_STATE_QUEUED,
 	/*! The media is currently playing */
-	STASIS_PLAYBACK_PLAYING,
+	STASIS_PLAYBACK_STATE_PLAYING,
 	/*! The media has stopped playing */
-	STASIS_PLAYBACK_COMPLETE,
+	STASIS_PLAYBACK_STATE_COMPLETE,
 };
 
 enum stasis_app_playback_media_control {
@@ -69,12 +69,20 @@
 	struct stasis_app_control *control, const char *file,
 	const char *language);
 
+/*!
+ * \brief Gets the current state of a playback operation.
+ */
 enum stasis_app_playback_state stasis_app_playback_get_state(
-	struct stasis_app_playback *control);
+	struct stasis_app_playback *playback);
+
 const char *stasis_app_playback_get_id(
-	struct stasis_app_playback *control);
+	struct stasis_app_playback *playback);
+
 struct stasis_app_playback *stasis_app_playback_find_by_id(const char *id);
+
 int stasis_app_playback_control(struct stasis_app_playback *playback,
-	enum stasis_app_playback_media_control);
+	enum stasis_app_playback_media_control control);
+
+struct stasis_message_type *stasis_app_playback_snapshot_type(void);
 
 #endif /* _ASTERISK_STASIS_APP_PLAYBACK_H */

Modified: team/dlee/playback/include/asterisk/stasis_channels.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/include/asterisk/stasis_channels.h?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/include/asterisk/stasis_channels.h (original)
+++ team/dlee/playback/include/asterisk/stasis_channels.h Thu May  9 13:23:56 2013
@@ -125,6 +125,17 @@
 
 /*!
  * \since 12
+ * \brief Get the most recent snapshot for channel with the given \a uniqueid.
+ *
+ * \param uniqueid Uniqueid of the snapshot to fetch.
+ * \return Most recent channel snapshot
+ * \return \c NULL on error
+ */
+struct ast_channel_snapshot *ast_channel_snapshot_get_latest(
+	const char *uniqueid);
+
+/*!
+ * \since 12
  * \brief Creates a \ref ast_channel_blob message.
  *
  * The given \a blob should be treated as immutable and not modified after it is
@@ -140,6 +151,23 @@
  */
 struct stasis_message *ast_channel_blob_create(struct ast_channel *chan,
 	struct stasis_message_type *type, struct ast_json *blob);
+
+/*!
+ * \since 12
+ * \brief Create a \ref ast_channel_blob message, pulling channel state from
+ *        the cache.
+ *
+ * \param uniqueid Uniqueid of the channel.
+ * \param type Message type for this blob.
+ * \param blob JSON object representing the data, or \c NULL for no data. If
+ *             \c NULL, ast_json_null() is put into the object.
+ *
+ * \return \ref ast_channel_blob message.
+ * \return \c NULL on error
+ */
+struct stasis_message *ast_channel_blob_create_from_cache(
+	const char *uniqueid, struct stasis_message_type *type,
+	struct ast_json *blob);
 
 /*!
  * \since 12

Modified: team/dlee/playback/main/stasis_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/main/stasis_channels.c?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/main/stasis_channels.c (original)
+++ team/dlee/playback/main/stasis_channels.c Thu May  9 13:23:56 2013
@@ -150,6 +150,28 @@
 	return snapshot;
 }
 
+struct ast_channel_snapshot *ast_channel_snapshot_get_latest(
+	const char *uniqueid)
+{
+        RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+	struct ast_channel_snapshot *snapshot;
+
+	msg = stasis_cache_get(ast_channel_topic_all_cached(),
+		ast_channel_snapshot_type(), uniqueid);
+
+	if (!msg) {
+		return NULL;
+	}
+
+	snapshot = stasis_message_data(msg);
+	if (!snapshot) {
+		return NULL;
+	}
+
+	ao2_ref(snapshot, +1);
+	return snapshot;
+}
+
 static void publish_message_for_channel_topics(struct stasis_message *message, struct ast_channel *chan)
 {
 	if (chan) {
@@ -209,37 +231,65 @@
 	publish_message_for_channel_topics(msg, caller);
 }
 
+static struct stasis_message *channel_blob_create(
+	struct ast_channel_snapshot *snapshot,
+	struct stasis_message_type *type, struct ast_json *blob)
+{
+	RAII_VAR(struct ast_channel_blob *, obj, NULL, ao2_cleanup);
+	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
+
+	if (blob == NULL) {
+		blob = ast_json_null();
+	}
+
+	obj = ao2_alloc(sizeof(*obj), channel_blob_dtor);
+	if (!obj) {
+		return NULL;
+	}
+
+	if (snapshot) {
+		ao2_ref(snapshot, +1);
+		obj->snapshot = snapshot;
+	}
+
+	obj->blob = ast_json_ref(blob);
+
+	msg = stasis_message_create(type, obj);
+	if (!msg) {
+		return NULL;
+	}
+
+	ao2_ref(msg, +1);
+	return msg;
+}
+
 struct stasis_message *ast_channel_blob_create(struct ast_channel *chan,
 	struct stasis_message_type *type, struct ast_json *blob)
 {
-	RAII_VAR(struct ast_channel_blob *, obj, NULL, ao2_cleanup);
-	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
-
-	if (blob == NULL) {
-		blob = ast_json_null();
-	}
-
-	obj = ao2_alloc(sizeof(*obj), channel_blob_dtor);
-	if (!obj) {
-		return NULL;
-	}
-
-	if (chan) {
-		obj->snapshot = ast_channel_snapshot_create(chan);
-		if (obj->snapshot == NULL) {
+	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+
+	if (chan != NULL) {
+		snapshot = ast_channel_snapshot_create(chan);
+		if (snapshot == NULL) {
 			return NULL;
 		}
 	}
 
-	obj->blob = ast_json_ref(blob);
-
-	msg = stasis_message_create(type, obj);
-	if (!msg) {
-		return NULL;
-	}
-
-	ao2_ref(msg, +1);
-	return msg;
+	return channel_blob_create(snapshot, type, blob);
+}
+
+struct stasis_message *ast_channel_blob_create_from_cache(
+	const char *uniqueid, struct stasis_message_type *type,
+	struct ast_json *blob)
+{
+	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+
+	snapshot = ast_channel_snapshot_get_latest(uniqueid);
+	if (snapshot == NULL) {
+		return NULL;
+	}
+
+	return channel_blob_create(snapshot, type, blob);
 }
 
 /*! \brief A channel snapshot wrapper object used in \ref ast_multi_channel_blob objects */

Modified: team/dlee/playback/res/res_stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/res/res_stasis.c?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/res/res_stasis.c (original)
+++ team/dlee/playback/res/res_stasis.c Thu May  9 13:23:56 2013
@@ -209,7 +209,7 @@
 		return -1;
 	}
 
-	control = control_create(ast_channel_uniqueid(chan));
+	control = control_create(chan);
 	if (!control) {
 		ast_log(LOG_ERROR, "Allocated failed\n");
 		return -1;

Modified: team/dlee/playback/res/res_stasis_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/res/res_stasis_playback.c?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/res/res_stasis_playback.c (original)
+++ team/dlee/playback/res/res_stasis_playback.c Thu May  9 13:23:56 2013
@@ -38,6 +38,7 @@
 #include "asterisk/module.h"
 #include "asterisk/stasis_app_impl.h"
 #include "asterisk/stasis_app_playback.h"
+#include "asterisk/stasis_channels.h"
 #include "asterisk/stringfields.h"
 #include "asterisk/uuid.h"
 
@@ -59,6 +60,8 @@
 		);
 	/*! Current playback state */
 	enum stasis_app_playback_state state;
+	/*! Control object for the channel we're playing back to */
+	struct stasis_app_control *control;
 };
 
 static int playback_hash(const void *obj, int flags)
@@ -81,11 +84,71 @@
 	}
 }
 
+static struct ast_json *playback_to_json(struct stasis_app_playback *playback)
+{
+	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+	char *state = "?";
+
+	if (playback == NULL) {
+		return NULL;
+	}
+
+	switch (playback->state) {
+	case STASIS_PLAYBACK_STATE_QUEUED:
+		state = "queued";
+		break;
+	case STASIS_PLAYBACK_STATE_PLAYING:
+		state = "playing";
+		break;
+	case STASIS_PLAYBACK_STATE_COMPLETE:
+		state = "complete";
+		break;
+	}
+
+	json = ast_json_pack("{s: s, s: s, s: s, s: s, s: s}",
+		"id", playback->id,
+		"media_uri", playback->media,
+		"language", playback->language,
+		"state", state);
+
+	return ast_json_ref(json);
+}
+
+static void playback_publish(struct stasis_app_playback *playback)
+{
+	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
+	RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
+	RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+
+	ast_assert(playback != NULL);
+
+	json = playback_to_json(playback);
+	if (json == NULL) {
+		return;
+	}
+
+	message = ast_channel_blob_create_from_cache(
+		stasis_app_control_get_channel_id(playback->control),
+		stasis_app_playback_snapshot_type(), json);
+	if (message == NULL) {
+		return;
+	}
+
+	stasis_app_control_publish(playback->control, message);
+}
+
+static void playback_set_state(struct stasis_app_playback *playback,
+	enum stasis_app_playback_state state)
+{
+	SCOPED_AO2LOCK(lock, playback);
+
+	playback->state = state;
+	playback_publish(playback);
+}
+
 static void playback_cleanup(struct stasis_app_playback *playback)
 {
-	ao2_lock(playback);
-	playback->state = STASIS_PLAYBACK_COMPLETE;
-	ao2_unlock(playback);
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_COMPLETE);
 
 	ao2_unlink_flags(playbacks, playback,
 		OBJ_POINTER | OBJ_UNLINK | OBJ_NODATA);
@@ -96,15 +159,14 @@
 {
 	RAII_VAR(struct stasis_app_playback *, playback, NULL,
 		playback_cleanup);
+	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
 	const char *file;
 	int res;
 
 	playback = data;
 	ast_assert(playback != NULL);
 
-	ao2_lock(playback);
-	playback->state = STASIS_PLAYBACK_PLAYING;
-	ao2_unlock(playback);
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_PLAYING);
 
 	if (ast_channel_state(chan) != AST_STATE_UP) {
 		ast_answer(chan);
@@ -154,11 +216,15 @@
 	ast_string_field_set(playback, id, id);
 	ast_string_field_set(playback, media, uri);
 	ast_string_field_set(playback, language, language);
-
+	playback->control = control;
 	ao2_link(playbacks, playback);
+
+	playback_set_state(playback, STASIS_PLAYBACK_STATE_QUEUED);
+
 	ao2_ref(playback, +1);
 	stasis_app_send_command_async(
 		control, __app_control_play_uri, playback);
+
 
 	ao2_ref(playback, +1);
 	return playback;

Modified: team/dlee/playback/res/stasis/control.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/res/stasis/control.c?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/res/stasis/control.c (original)
+++ team/dlee/playback/res/stasis/control.c Thu May  9 13:23:56 2013
@@ -37,24 +37,26 @@
 	 * When set, /c app_stasis should exit and continue in the dialplan.
 	 */
 	int is_done:1;
-	/*! Uniqueid of the associated channel */
-	char channel_id[];
+	/*!
+	 * The associated channel.
+	 * Be very careful with the threading associated w/ manipulating
+	 * the channel.
+	 */
+	struct ast_channel *channel;
 };
 
-struct stasis_app_control *control_create(const char *uniqueid)
+struct stasis_app_control *control_create(struct ast_channel *channel)
 {
 	struct stasis_app_control *control;
-	size_t size;
 
-	size = sizeof(*control) + strlen(uniqueid) + 1;
-	control = ao2_alloc(size, NULL);
+	control = ao2_alloc(sizeof(*control), NULL);
 	if (!control) {
 		return NULL;
 	}
 
 	control->command_queue = ao2_container_alloc_list(0, 0, NULL, NULL);
 
-	strncpy(control->channel_id, uniqueid, size - sizeof(*control));
+	control->channel = channel;
 
 	return control;
 }
@@ -62,7 +64,7 @@
 const char *stasis_app_control_get_channel_id(
 	const struct stasis_app_control *control)
 {
-	return control->channel_id;
+	return ast_channel_uniqueid(control->channel);
 }
 
 static struct stasis_app_command *exec_command(
@@ -120,6 +122,15 @@
 	return 0;
 }
 
+void stasis_app_control_publish(
+	struct stasis_app_control *control, struct stasis_message *message)
+{
+	if (!control || !control->channel || !message) {
+		return;
+	}
+	stasis_publish(ast_channel_topic(control->channel), message);
+}
+
 int control_is_done(struct stasis_app_control *control)
 {
 	/* Called from stasis_app_exec thread; no lock needed */
@@ -148,8 +159,7 @@
 
 	SCOPED_AO2LOCK(lock, control);
 
-	ast_assert(
-		strcmp(control->channel_id, ast_channel_uniqueid(chan)) == 0);
+	ast_assert(control->channel == chan);
 
 	i = ao2_iterator_init(control->command_queue, AO2_ITERATOR_UNLINK);
 

Modified: team/dlee/playback/res/stasis/control.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/res/stasis/control.h?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/res/stasis/control.h (original)
+++ team/dlee/playback/res/stasis/control.h Thu May  9 13:23:56 2013
@@ -32,11 +32,11 @@
 /*!
  * \brief Create a control object.
  *
- * \param uniqueid Uniqueid of the associated channel.
+ * \param channel Channel to control.
  * \return New control object.
  * \return \c NULL on error.
  */
-struct stasis_app_control *control_create(const char *uniqueid);
+struct stasis_app_control *control_create(struct ast_channel *channel);
 
 /*!
  * \brief Dispatch all commands enqueued to this control.

Modified: team/dlee/playback/res/stasis_http/resource_channels.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/res/stasis_http/resource_channels.h?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/res/stasis_http/resource_channels.h (original)
+++ team/dlee/playback/res/stasis_http/resource_channels.h Thu May  9 13:23:56 2013
@@ -252,11 +252,11 @@
  * Dialed
  * Originated
  * Playback
- * - status: string (required)
  * - language: string 
  * - media_uri: string (required)
  * - id: string (required)
  * - target_uri: string (required)
+ * - state: string (required)
  * DialplanCEP
  * - priority: long (required)
  * - exten: string (required)

Modified: team/dlee/playback/rest-api/api-docs/channels.json
URL: http://svnview.digium.com/svn/asterisk/team/dlee/playback/rest-api/api-docs/channels.json?view=diff&rev=388212&r1=388211&r2=388212
==============================================================================
--- team/dlee/playback/rest-api/api-docs/channels.json (original)
+++ team/dlee/playback/rest-api/api-docs/channels.json Thu May  9 13:23:56 2013
@@ -672,9 +672,9 @@
 					"type": "string",
 					"description": "For media types that support multiple languages, the language requested for playback."
 				},
-				"status": {
-					"type": "string",
-					"description": "Current status of the playback operation.",
+				"state": {
+					"type": "string",
+					"description": "Current state of the playback operation.",
 					"required": true,
 					"allowableValues": {
 						"valueType": "LIST",




More information about the asterisk-commits mailing list