[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