diff options
author | David M. Lee <dlee@digium.com> | 2013-05-23 20:11:35 +0000 |
---|---|---|
committer | David M. Lee <dlee@digium.com> | 2013-05-23 20:11:35 +0000 |
commit | 10ba6bf8a8114278ca974861ecebcb3a827d8d5b (patch) | |
tree | 1406ede124cf9665cb9f9244f9339b6cb522aa8b /main | |
parent | 3464e0919afe398717b93b20fff37560c6d4478f (diff) |
This patch implements the REST API's for POST /channels/{channelId}/play
and GET /playback/{playbackId}.
This allows an external application to initiate playback of a sound on a
channel while the channel is in the Stasis application.
/play commands are issued asynchronously, and return immediately with
the URL of the associated /playback resource. Playback commands queue up,
playing in succession. The /playback resource shows the state of a
playback operation as enqueued, playing or complete. (Although the
operation will only be in the 'complete' state for a very short time,
since it is almost immediately freed up).
(closes issue ASTERISK-21283)
(closes issue ASTERISK-21586)
Review: https://reviewboard.asterisk.org/r/2531/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389587 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r-- | main/channel_internal_api.c | 31 | ||||
-rw-r--r-- | main/stasis_channels.c | 83 |
2 files changed, 94 insertions, 20 deletions
diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 42aaada6d..87551f72f 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -414,15 +414,17 @@ int ast_channel_data_cmp_structure(const struct ast_data_search *tree, /* ACCESSORS */ -#define DEFINE_STRINGFIELD_SETTERS_FOR(field) \ +#define DEFINE_STRINGFIELD_SETTERS_FOR(field, publish) \ void ast_channel_##field##_set(struct ast_channel *chan, const char *value) \ { \ ast_string_field_set(chan, field, value); \ + if (publish) ast_channel_publish_snapshot(chan); \ } \ \ void ast_channel_##field##_build_va(struct ast_channel *chan, const char *fmt, va_list ap) \ { \ ast_string_field_build_va(chan, field, fmt, ap); \ + if (publish) ast_channel_publish_snapshot(chan); \ } \ void ast_channel_##field##_build(struct ast_channel *chan, const char *fmt, ...) \ { \ @@ -430,19 +432,20 @@ void ast_channel_##field##_build(struct ast_channel *chan, const char *fmt, ...) va_start(ap, fmt); \ ast_channel_##field##_build_va(chan, fmt, ap); \ va_end(ap); \ -} - -DEFINE_STRINGFIELD_SETTERS_FOR(name); -DEFINE_STRINGFIELD_SETTERS_FOR(language); -DEFINE_STRINGFIELD_SETTERS_FOR(musicclass); -DEFINE_STRINGFIELD_SETTERS_FOR(accountcode); -DEFINE_STRINGFIELD_SETTERS_FOR(peeraccount); -DEFINE_STRINGFIELD_SETTERS_FOR(userfield); -DEFINE_STRINGFIELD_SETTERS_FOR(call_forward); -DEFINE_STRINGFIELD_SETTERS_FOR(uniqueid); -DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot); -DEFINE_STRINGFIELD_SETTERS_FOR(hangupsource); -DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext); + if (publish) ast_channel_publish_snapshot(chan); \ +} + +DEFINE_STRINGFIELD_SETTERS_FOR(name, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(language, 1); +DEFINE_STRINGFIELD_SETTERS_FOR(musicclass, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(accountcode, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(peeraccount, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(userfield, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(call_forward, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(uniqueid, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(parkinglot, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(hangupsource, 0); +DEFINE_STRINGFIELD_SETTERS_FOR(dialcontext, 0); #define DEFINE_STRINGFIELD_GETTER_FOR(field) const char *ast_channel_##field(const struct ast_channel *chan) \ { \ diff --git a/main/stasis_channels.c b/main/stasis_channels.c index 0b2ccbc1f..f8c9be327 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -134,6 +134,7 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *cha S_COR(ast_channel_connected(chan)->id.name.valid, ast_channel_connected(chan)->id.name.str, "")); ast_string_field_set(snapshot, connected_number, S_COR(ast_channel_connected(chan)->id.number.valid, ast_channel_connected(chan)->id.number.str, "")); + ast_string_field_set(snapshot, language, ast_channel_language(chan)); snapshot->creationtime = ast_channel_creationtime(chan); snapshot->state = ast_channel_state(chan); @@ -149,6 +150,28 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *cha 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) { @@ -207,7 +230,8 @@ void ast_channel_publish_dial(struct ast_channel *caller, struct ast_channel *pe publish_message_for_channel_topics(msg, caller); } -struct stasis_message *ast_channel_blob_create(struct ast_channel *chan, +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); @@ -222,11 +246,9 @@ struct stasis_message *ast_channel_blob_create(struct ast_channel *chan, return NULL; } - if (chan) { - obj->snapshot = ast_channel_snapshot_create(chan); - if (obj->snapshot == NULL) { - return NULL; - } + if (snapshot) { + ao2_ref(snapshot, +1); + obj->snapshot = snapshot; } obj->blob = ast_json_ref(blob); @@ -240,6 +262,35 @@ struct stasis_message *ast_channel_blob_create(struct ast_channel *chan, 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_snapshot *, snapshot, NULL, ao2_cleanup); + + if (chan != NULL) { + snapshot = ast_channel_snapshot_create(chan); + if (snapshot == NULL) { + return NULL; + } + } + + 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 */ struct channel_role_snapshot { struct ast_channel_snapshot *snapshot; /*!< A channel snapshot */ @@ -389,6 +440,26 @@ struct ast_json *ast_multi_channel_blob_get_json(struct ast_multi_channel_blob * return obj->blob; } +void ast_channel_publish_snapshot(struct ast_channel *chan) +{ + RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup); + RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); + + snapshot = ast_channel_snapshot_create(chan); + if (!snapshot) { + return; + } + + message = stasis_message_create(ast_channel_snapshot_type(), snapshot); + if (!message) { + return; + } + + ast_assert(ast_channel_topic(chan) != NULL); + stasis_publish(ast_channel_topic(chan), message); +} + + void ast_channel_publish_varset(struct ast_channel *chan, const char *name, const char *value) { RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); |