[asterisk-commits] mmichelson: branch mmichelson/transfer_stasis r391405 - in /team/mmichelson/t...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jun 11 11:11:57 CDT 2013
Author: mmichelson
Date: Tue Jun 11 11:11:55 2013
New Revision: 391405
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=391405
Log:
Resolve conflicts and reset automerge.
Added:
team/mmichelson/transfer_stasis/res/res_stasis_bridge_add.c
- copied unchanged from r391403, trunk/res/res_stasis_bridge_add.c
team/mmichelson/transfer_stasis/res/res_stasis_bridge_add.exports.in
- copied unchanged from r391403, trunk/res/res_stasis_bridge_add.exports.in
Modified:
team/mmichelson/transfer_stasis/ (props changed)
team/mmichelson/transfer_stasis/UPGRADE.txt
team/mmichelson/transfer_stasis/apps/app_queue.c
team/mmichelson/transfer_stasis/channels/chan_iax2.c
team/mmichelson/transfer_stasis/channels/chan_skinny.c
team/mmichelson/transfer_stasis/channels/chan_unistim.c
team/mmichelson/transfer_stasis/configs/queues.conf.sample
team/mmichelson/transfer_stasis/include/asterisk/stasis.h
team/mmichelson/transfer_stasis/include/asterisk/stasis_app.h
team/mmichelson/transfer_stasis/include/asterisk/stasis_bridging.h
team/mmichelson/transfer_stasis/main/features_config.c
team/mmichelson/transfer_stasis/main/loader.c
team/mmichelson/transfer_stasis/main/manager.c
team/mmichelson/transfer_stasis/main/manager_channels.c
team/mmichelson/transfer_stasis/main/parking.c
team/mmichelson/transfer_stasis/main/stasis_bridging.c
team/mmichelson/transfer_stasis/main/stasis_channels.c
team/mmichelson/transfer_stasis/main/stasis_message.c
team/mmichelson/transfer_stasis/res/res_agi.c
team/mmichelson/transfer_stasis/res/res_stasis.c
team/mmichelson/transfer_stasis/res/res_stasis_json_events.c
team/mmichelson/transfer_stasis/res/res_stasis_json_events.exports.in
team/mmichelson/transfer_stasis/res/stasis/app.c
team/mmichelson/transfer_stasis/res/stasis/app.h
team/mmichelson/transfer_stasis/res/stasis/control.c
team/mmichelson/transfer_stasis/res/stasis_http/resource_bridges.c
team/mmichelson/transfer_stasis/res/stasis_http/resource_bridges.h
team/mmichelson/transfer_stasis/res/stasis_json/resource_events.h
team/mmichelson/transfer_stasis/rest-api/api-docs/bridges.json
team/mmichelson/transfer_stasis/rest-api/api-docs/events.json
team/mmichelson/transfer_stasis/tests/test_stasis.c
team/mmichelson/transfer_stasis/tests/test_stasis_channels.c
Propchange: team/mmichelson/transfer_stasis/
------------------------------------------------------------------------------
automerge = *
Propchange: team/mmichelson/transfer_stasis/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.
Propchange: team/mmichelson/transfer_stasis/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jun 11 11:11:55 2013
@@ -1,1 +1,1 @@
-/trunk:1-391171
+/trunk:1-391404
Modified: team/mmichelson/transfer_stasis/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/UPGRADE.txt?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/UPGRADE.txt (original)
+++ team/mmichelson/transfer_stasis/UPGRADE.txt Tue Jun 11 11:11:55 2013
@@ -20,7 +20,6 @@
=== UPGRADE-11.txt -- Upgrade info for 10 to 11
===
===========================================================
-
AMI:
- The SIP SIPqualifypeer action now sends a response indicating it will qualify
@@ -55,6 +54,11 @@
Queue member being paused would result in a disposition of BUSY.
- Removed the queues.conf check_state_unknown option. It is no longer
necessary.
+ - It is now possible to play the Queue prompts to the first user waiting in a
+ call queue. Note that this may impact the ability for agents to talk with
+ users, as a prompt may still be playing when an agent connects to the user.
+ This ability is disabled by default but can be enabled on an individual
+ queue using the 'announce-to-first-user' option.
Dial:
- Now recognizes 'W' to pause sending DTMF for one second in addition to
Modified: team/mmichelson/transfer_stasis/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/apps/app_queue.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/apps/app_queue.c (original)
+++ team/mmichelson/transfer_stasis/apps/app_queue.c Tue Jun 11 11:11:55 2013
@@ -1517,6 +1517,7 @@
struct ast_str *sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS];
unsigned int dead:1;
unsigned int ringinuse:1;
+ unsigned int announce_to_first_user:1; /*!< Whether or not we announce to the first user in a queue */
unsigned int setinterfacevar:1;
unsigned int setqueuevar:1;
unsigned int setqueueentryvar:1;
@@ -2370,6 +2371,7 @@
q->roundingseconds = 0; /* Default - don't announce seconds */
q->servicelevel = 0;
q->ringinuse = 1;
+ q->announce_to_first_user = 0;
q->setinterfacevar = 0;
q->setqueuevar = 0;
q->setqueueentryvar = 0;
@@ -2648,6 +2650,8 @@
ast_string_field_set(q, sound_reporthold, val);
} else if (!strcasecmp(param, "announce-frequency")) {
q->announcefrequency = atoi(val);
+ } else if (!strcasecmp(param, "announce-to-first-user")) {
+ q->announce_to_first_user = ast_true(val);
} else if (!strcasecmp(param, "min-announce-frequency")) {
q->minannouncefrequency = atoi(val);
ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
@@ -4820,12 +4824,12 @@
}
/* Make a position announcement, if enabled */
- if (qe->parent->announcefrequency) {
+ if (qe->parent->announcefrequency && qe->parent->announce_to_first_user) {
say_position(qe, ringing);
}
/* Make a periodic announcement, if enabled */
- if (qe->parent->periodicannouncefrequency) {
+ if (qe->parent->periodicannouncefrequency && qe->parent->announce_to_first_user) {
say_periodic_announcement(qe, ringing);
}
@@ -9661,6 +9665,7 @@
MEMBER(call_queue, sound_reporthold, AST_DATA_STRING) \
MEMBER(call_queue, dead, AST_DATA_BOOLEAN) \
MEMBER(call_queue, ringinuse, AST_DATA_BOOLEAN) \
+ MEMBER(call_queue, announce_to_first_user, AST_DATA_BOOLEAN) \
MEMBER(call_queue, setinterfacevar, AST_DATA_BOOLEAN) \
MEMBER(call_queue, setqueuevar, AST_DATA_BOOLEAN) \
MEMBER(call_queue, setqueueentryvar, AST_DATA_BOOLEAN) \
Modified: team/mmichelson/transfer_stasis/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/channels/chan_iax2.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/channels/chan_iax2.c (original)
+++ team/mmichelson/transfer_stasis/channels/chan_iax2.c Tue Jun 11 11:11:55 2013
@@ -11204,15 +11204,28 @@
}
break;
case IAX_COMMAND_TXREJ:
- iaxs[fr->callno]->transferring = 0;
+ if (iaxs[fr->callno]->bridgecallno) {
+ while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
+ DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
+ }
+ if (!iaxs[fr->callno]) {
+ break;
+ }
+ }
+
+ iaxs[fr->callno]->transferring = TRANSFER_NONE;
ast_verb(3, "Channel '%s' unable to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
memset(&iaxs[fr->callno]->transfer, 0, sizeof(iaxs[fr->callno]->transfer));
- if (iaxs[fr->callno]->bridgecallno) {
- if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
- iaxs[iaxs[fr->callno]->bridgecallno]->transferring = 0;
- send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
- }
+
+ if (!iaxs[fr->callno]->bridgecallno) {
+ break;
}
+
+ if (iaxs[iaxs[fr->callno]->bridgecallno]->transferring) {
+ iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_NONE;
+ send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, NULL, 0, -1);
+ }
+ ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
break;
case IAX_COMMAND_TXREADY:
if (iaxs[fr->callno]->bridgecallno) {
Modified: team/mmichelson/transfer_stasis/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/channels/chan_skinny.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/channels/chan_skinny.c (original)
+++ team/mmichelson/transfer_stasis/channels/chan_skinny.c Tue Jun 11 11:11:55 2013
@@ -81,6 +81,7 @@
#include "asterisk/event.h"
#include "asterisk/indications.h"
#include "asterisk/linkedlists.h"
+#include "asterisk/bridging.h"
/*** DOCUMENTATION
<manager name="SKINNYdevices" language="en_US">
@@ -952,6 +953,7 @@
static const uint8_t soft_key_default_offhook[] = {
SOFTKEY_REDIAL,
SOFTKEY_ENDCALL,
+ SOFTKEY_TRNSFER,
SOFTKEY_CFWDALL,
SOFTKEY_CFWDBUSY,
SOFTKEY_CFWDNOANSWER,
@@ -971,6 +973,7 @@
static const uint8_t soft_key_default_dadfd[] = {
SOFTKEY_BKSPC,
SOFTKEY_ENDCALL,
+ SOFTKEY_TRNSFER,
SOFTKEY_FORCEDIAL,
};
@@ -1375,6 +1378,7 @@
#define DIALTYPE_NORMAL 1<<0
#define DIALTYPE_CFWD 1<<1
+#define DIALTYPE_XFER 1<<2
struct skinny_subchannel {
ast_mutex_t lock;
@@ -1656,7 +1660,6 @@
};
static int skinny_extensionstate_cb(char *context, char *id, struct ast_state_cb_info *info, void *data);
-static int skinny_transfer(struct skinny_subchannel *sub);
static struct skinny_line *skinny_line_alloc(void)
{
@@ -5008,14 +5011,6 @@
int res = 0;
struct skinny_subchannel *sub = ast_channel_tech_pvt(ast);
- if (sub->blindxfer) {
- SKINNY_DEBUG(DEBUG_SUB, 3, "skinny_answer(%s) on %s@%s-%d with BlindXFER, transferring\n",
- ast_channel_name(ast), sub->line->name, sub->line->device->name, sub->callid);
- ast_setstate(ast, AST_STATE_UP);
- skinny_transfer(sub);
- return 0;
- }
-
sub->cxmode = SKINNY_CX_SENDRECV;
SKINNY_DEBUG(DEBUG_SUB, 3, "skinny_answer(%s) on %s@%s-%d\n",
@@ -5242,64 +5237,52 @@
}
}
-static int skinny_transfer(struct skinny_subchannel *sub)
-{
- struct skinny_subchannel *xferor; /* the sub doing the transferring */
- struct skinny_subchannel *xferee; /* the sub being transferred */
- struct ast_tone_zone_sound *ts = NULL;
-
- if (ast_bridged_channel(sub->owner) || ast_bridged_channel(sub->related->owner)) {
- if (sub->xferor) {
- xferor = sub;
- xferee = sub->related;
- } else {
- xferor = sub;
- xferee = sub->related;
- }
-
- SKINNY_DEBUG(DEBUG_SUB, 3, "Transferee channels (local/remote): %s and %s\n",
- ast_channel_name(xferee->owner), ast_bridged_channel(xferee->owner) ? ast_channel_name(ast_bridged_channel(xferee->owner)) : "");
- SKINNY_DEBUG(DEBUG_SUB, 3, "Transferor channels (local/remote): %s and %s\n",
- ast_channel_name(xferor->owner), ast_bridged_channel(xferor->owner) ? ast_channel_name(ast_bridged_channel(xferor->owner)) : "");
-
- if (ast_bridged_channel(xferor->owner)) {
- ast_queue_unhold(xferee->owner);
- if (ast_channel_state(xferor->owner) == AST_STATE_RING) {
- /* play ringing inband */
- if ((ts = ast_get_indication_tone(ast_channel_zone(xferor->owner), "ring"))) {
- ast_playtones_start(xferor->owner, 0, ts->data, 1);
- ts = ast_tone_zone_sound_unref(ts);
- }
- }
- SKINNY_DEBUG(DEBUG_SUB, 3, "Transfer Masquerading %s to %s\n",
- ast_channel_name(xferee->owner), ast_bridged_channel(xferor->owner) ? ast_channel_name(ast_bridged_channel(xferor->owner)) : "");
- if (ast_channel_masquerade(xferee->owner, ast_bridged_channel(xferor->owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_channel_name(ast_bridged_channel(xferor->owner)), ast_channel_name(xferee->owner));
- return -1;
- }
- } else if (ast_bridged_channel(xferee->owner)) {
- ast_queue_unhold(xferee->owner);
- if (ast_channel_state(xferor->owner) == AST_STATE_RING) {
- /* play ringing inband */
- if ((ts = ast_get_indication_tone(ast_channel_zone(xferor->owner), "ring"))) {
- ast_playtones_start(xferor->owner, 0, ts->data, 1);
- ts = ast_tone_zone_sound_unref(ts);
- }
- }
- SKINNY_DEBUG(DEBUG_SUB, 3, "Transfer Masquerading %s to %s\n",
- ast_channel_name(xferor->owner), ast_bridged_channel(xferee->owner) ? ast_channel_name(ast_bridged_channel(xferee->owner)) : "");
- if (ast_channel_masquerade(xferor->owner, ast_bridged_channel(xferee->owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_channel_name(ast_bridged_channel(xferee->owner)), ast_channel_name(xferor->owner));
- return -1;
- }
- } else {
- ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
- ast_channel_name(xferor->owner), ast_channel_name(xferee->owner));
- }
- }
- return 0;
+static void skinny_transfer_attended(struct skinny_subchannel *sub)
+{
+ struct skinny_subchannel *xferee;
+ struct skinny_subchannel *xferor;
+ enum ast_transfer_result res;
+
+ if (sub->xferor) {
+ xferor = sub;
+ xferee = sub->related;
+ } else {
+ xferor = sub;
+ xferee = sub->related;
+ }
+
+ ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
+ if (ast_channel_state(xferor->owner) == AST_STATE_RINGING) {
+ ast_queue_control(xferee->owner, AST_CONTROL_RINGING);
+ }
+ res = ast_bridge_transfer_attended(xferee->owner, xferor->owner);
+
+ if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
+ SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d failed to transfer %d to '%s'@'%s' - %d\n",
+ xferor->callid, xferee->callid, xferor->exten, xferor->line->context, res);
+ send_displayprinotify(xferor->line->device, "Transfer failed", NULL, 10, 5);
+ ast_queue_control(xferee->owner, AST_CONTROL_HOLD);
+ }
+}
+
+static void skinny_transfer_blind(struct skinny_subchannel *sub)
+{
+ struct skinny_subchannel *xferee = sub->related;
+ enum ast_transfer_result res;
+
+ sub->related = NULL;
+ xferee->related = NULL;
+
+ ast_queue_control(xferee->owner, AST_CONTROL_UNHOLD);
+ res = ast_bridge_transfer_blind(xferee->owner, sub->exten, sub->line->context, NULL, NULL);
+
+ if (res != AST_BRIDGE_TRANSFER_SUCCESS) {
+ SKINNY_DEBUG(DEBUG_SUB, 3, "Sub %d failed to blind transfer %d to '%s'@'%s' - %d\n",
+ sub->callid, xferee->callid, sub->exten, sub->line->context, res);
+ send_displayprinotify(sub->line->device, "Transfer failed", NULL, 10, 5);
+ ast_queue_control(xferee->owner, AST_CONTROL_HOLD);
+ }
+ dumpsub(sub, 1);
}
static int skinny_indicate(struct ast_channel *ast, int ind, const void *data, size_t datalen)
@@ -5318,12 +5301,6 @@
control2str(ind), ast_channel_name(ast), sub->callid);
switch(ind) {
case AST_CONTROL_RINGING:
- if (sub->blindxfer) {
- SKINNY_DEBUG(DEBUG_SUB, 3, "Channel %s (Sub %d) set up for Blind Xfer, so Xfer rather than ring device\n",
- ast_channel_name(ast), sub->callid);
- skinny_transfer(sub);
- break;
- }
setsubstate(sub, SUBSTATE_RINGOUT);
return (d->earlyrtp ? -1 : 0); /* Tell asterisk to provide inband signalling if rtp started */
case AST_CONTROL_BUSY:
@@ -6059,6 +6036,9 @@
dumpsub(sub, 1);
transmit_cfwdstate(d, l);
transmit_displaynotify(d, "CFwd enabled", 10);
+ } else if (sub->dialType == DIALTYPE_XFER) {
+ ast_copy_string(sub->exten, exten, sizeof(sub->exten));
+ skinny_transfer_blind(sub);
}
}
@@ -6117,21 +6097,14 @@
}
} else {
/* We already have a related sub so we can either complete XFER or go into BLINDXFER (or cancel BLINDXFER */
- if (sub->blindxfer) {
- /* toggle blindxfer off */
- sub->blindxfer = 0;
- sub->related->blindxfer = 0;
- /* we really need some indications */
+ if (sub->substate == SUBSTATE_OFFHOOK) {
+ if (sub->dialType == DIALTYPE_XFER) {
+ sub->dialType = DIALTYPE_NORMAL;
+ } else {
+ sub->dialType = DIALTYPE_XFER;
+ }
} else {
- /* We were doing attended transfer */
- if (ast_channel_state(sub->owner) == AST_STATE_DOWN || ast_channel_state(sub->related->owner) == AST_STATE_DOWN) {
- /* one of the subs so we cant transfer yet, toggle blindxfer on */
- sub->blindxfer = 1;
- sub->related->blindxfer = 1;
- } else {
- /* big assumption we have two channels, lets transfer */
- skinny_transfer(sub);
- }
+ skinny_transfer_attended(sub);
}
}
return 0;
Modified: team/mmichelson/transfer_stasis/channels/chan_unistim.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/channels/chan_unistim.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/channels/chan_unistim.c (original)
+++ team/mmichelson/transfer_stasis/channels/chan_unistim.c Tue Jun 11 11:11:55 2013
@@ -4792,7 +4792,7 @@
struct unistim_line *l;
struct unistim_device *d;
struct unistimsession *s;
- int i;
+ int i,end_call = 1;
s = channel_to_session(ast);
sub = ast_channel_tech_pvt(ast);
@@ -4835,10 +4835,8 @@
unistim_unalloc_sub(d, sub);
return 0;
}
-
if (sub->subtype == SUB_REAL) {
sub_stop_silence(s, sub);
- send_end_call(s); /* Send end call packet only if ending active call, in other way sound should be loosed */
} else if (sub->subtype == SUB_RING) {
send_no_ring(s);
for (i = 0; i < FAVNUM; i++) {
@@ -4849,8 +4847,16 @@
if (is_key_line(d, i) && !strcmp(l->name, d->sline[i]->name)) {
send_favorite_short(i, FAV_LINE_ICON, s);
d->ssub[i] = NULL;
- }
- }
+ continue;
+ }
+ if (d->ssub[i] != NULL) { /* Found other subchannel active other then hangup'ed one */
+ ast_log(LOG_WARNING, "There is not only one call here %p %p %i\n",d->ssub[i], sub, i);
+ end_call = 0;
+ }
+ }
+ }
+ if (end_call) {
+ send_end_call(s); /* Send end call packet only if ending active call, in other way sound should be loosed */
}
sub->moh = 0;
if (sub->softkey >= 0) {
@@ -6141,7 +6147,7 @@
return 0;
}
if (d->softkeyicon[p] != 0) {
- ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used\n:", p);
+ ast_log(LOG_WARNING, "Invalid position %d for bookmark : already used:\n", p);
return 0;
}
memmove(line, line + 2, sizeof(line) - 2);
Modified: team/mmichelson/transfer_stasis/configs/queues.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/configs/queues.conf.sample?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/configs/queues.conf.sample (original)
+++ team/mmichelson/transfer_stasis/configs/queues.conf.sample Tue Jun 11 11:11:55 2013
@@ -316,6 +316,13 @@
; will have their position announced.
;
;announce-position = yes
+;
+; If enabled, play announcements to the first user waiting in the Queue. This may mean
+; that announcements are played when an agent attempts to connect to the waiting user,
+; which may delay the time before the agent and the user can communicate. Disabled by
+; default.
+;
+; announce-to-first-user = no
;
; If you have specified "limit" or "more" for the announce-position option, then the following
; value is what is used to determine what announcement to play to waiting callers. If you have
Modified: team/mmichelson/transfer_stasis/include/asterisk/stasis.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/include/asterisk/stasis.h?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/include/asterisk/stasis.h (original)
+++ team/mmichelson/transfer_stasis/include/asterisk/stasis.h Tue Jun 11 11:11:55 2013
@@ -154,6 +154,8 @@
* certain loads.
*/
+#include "asterisk/json.h"
+#include "asterisk/manager.h"
#include "asterisk/utils.h"
/*! @{ */
@@ -165,17 +167,58 @@
struct stasis_message_type;
/*!
- * \brief Register a new message type.
+ * \brief Opaque type for a Stasis message.
+ * \since 12
+ */
+struct stasis_message;
+
+/*!
+ * \brief Virtual table providing methods for messages.
+ * \since 12
+ */
+struct stasis_message_vtable {
+ /*!
+ * \brief Build the JSON representation of the message.
+ *
+ * May be \c NULL, or may return \c NULL, to indicate no representation.
+ * The returned object should be ast_json_unref()'ed.
+ *
+ * \param message Message to convert to JSON string.
+ * \return Newly allocated JSON message.
+ * \return \c NULL on error.
+ * \return \c NULL if JSON format is not supported.
+ */
+ struct ast_json *(*to_json)(struct stasis_message *message);
+
+ /*!
+ * \brief Build the AMI representation of the message.
+ *
+ * May be \c NULL, or may return \c NULL, to indicate no representation.
+ * The returned object should be ao2_cleankup()'ed.
+ *
+ * \param message Message to convert to AMI string.
+ * \return Newly allocated \ref ast_manager_event_blob.
+ * \return \c NULL on error.
+ * \return \c NULL if AMI format is not supported.
+ */
+ struct ast_manager_event_blob *(*to_ami)(
+ struct stasis_message *message);
+};
+
+/*!
+ * \brief Create a new message type.
*
* \ref stasis_message_type is an AO2 object, so ao2_cleanup() when you're done
* with it.
*
* \param name Name of the new type.
+ * \param vtable Virtual table of message methods. May be \c NULL.
* \return Pointer to the new type.
* \return \c NULL on error.
* \since 12
*/
-struct stasis_message_type *stasis_message_type_create(const char *name);
+struct stasis_message_type *stasis_message_type_create(const char *name,
+ struct stasis_message_vtable *vtable);
/*!
* \brief Gets the name of a given message type
@@ -187,12 +230,6 @@
const char *stasis_message_type_name(const struct stasis_message_type *type);
/*!
- * \brief Opaque type for a Stasis message.
- * \since 12
- */
-struct stasis_message;
-
-/*!
* \brief Create a new message.
*
* This message is an \c ao2 object, and must be ao2_cleanup()'ed when you are done
@@ -233,6 +270,32 @@
* \since 12
*/
const struct timeval *stasis_message_timestamp(const struct stasis_message *msg);
+
+/*!
+ * \brief Build the JSON representation of the message.
+ *
+ * May return \c NULL, to indicate no representation. The returned object should
+ * be ast_json_unref()'ed.
+ *
+ * \param message Message to convert to JSON string.
+ * \return Newly allocated string with JSON message.
+ * \return \c NULL on error.
+ * \return \c NULL if JSON format is not supported.
+ */
+struct ast_json *stasis_message_to_json(struct stasis_message *message);
+
+/*!
+ * \brief Build the AMI representation of the message.
+ *
+ * May return \c NULL, to indicate no representation. The returned object should
+ * be ao2_cleanup()'ed.
+ *
+ * \param message Message to convert to AMI.
+ * \return \c NULL on error.
+ * \return \c NULL if AMI format is not supported.
+ */
+struct ast_manager_event_blob *stasis_message_to_ami(
+ struct stasis_message *message);
/*! @} */
@@ -635,20 +698,37 @@
/*!
* \brief Boiler-plate removing macro for defining message types.
*
+ * \code
+ * STASIS_MESSAGE_TYPE_DEFN(ast_foo_type,
+ * .to_ami = foo_to_ami,
+ * .to_json = foo_to_json,
+ * );
+ * \endcode
+ *
* \param name Name of message type.
- * \since 12
- */
-#define STASIS_MESSAGE_TYPE_DEFN(name) \
- static struct stasis_message_type *_priv_ ## name; \
- struct stasis_message_type *name(void) { \
- if (_priv_ ## name == NULL) { \
- stasis_log_bad_type_access(#name); \
- } \
- return _priv_ ## name; \
+ * \param ... Virtual table methods for messages of this type.
+ * \since 12
+ */
+#define STASIS_MESSAGE_TYPE_DEFN(name, ...) \
+ static struct stasis_message_vtable _priv_ ## name ## _v = { \
+ __VA_ARGS__ \
+ }; \
+ static struct stasis_message_type *_priv_ ## name; \
+ struct stasis_message_type *name(void) { \
+ if (_priv_ ## name == NULL) { \
+ stasis_log_bad_type_access(#name); \
+ } \
+ return _priv_ ## name; \
}
/*!
- * \brief Boiler-plate removing macro for initializing message types.
+* \brief Boiler-plate removing macro for initializing message types.
+ *
+ * \code
+ * if (STASIS_MESSAGE_TYPE_INIT(ast_foo_type) != 0) {
+ * return -1;
+ * }
+ * \endcode
*
* \param name Name of message type.
* \return 0 if initialization is successful.
@@ -658,8 +738,9 @@
#define STASIS_MESSAGE_TYPE_INIT(name) \
({ \
ast_assert(_priv_ ## name == NULL); \
- _priv_ ## name = stasis_message_type_create(#name); \
- _priv_ ## name ? 0 : -1; \
+ _priv_ ## name = stasis_message_type_create(#name, \
+ &_priv_ ## name ## _v); \
+ _priv_ ## name ? 0 : -1; \
})
/*!
Modified: team/mmichelson/transfer_stasis/include/asterisk/stasis_app.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/include/asterisk/stasis_app.h?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/include/asterisk/stasis_app.h (original)
+++ team/mmichelson/transfer_stasis/include/asterisk/stasis_app.h Tue Jun 11 11:11:55 2013
@@ -187,6 +187,56 @@
enum ast_control_frame_type frame_type);
/*!
+ * \brief Create a bridge of the specified type.
+ *
+ * \param type The type of bridge to be created
+ *
+ * \return New bridge.
+ * \return \c NULL on error.
+ */
+struct ast_bridge *stasis_app_bridge_create(const char *type);
+
+/*!
+ * \brief Returns the bridge with the given id.
+ * \param bridge_id Uniqueid of the bridge.
+ * \return NULL bridge not created by a Stasis application, or bridge does not exist.
+ * \return Pointer to bridge.
+ */
+struct ast_bridge *stasis_app_bridge_find_by_id(
+ const char *bridge_id);
+
+/*!
+ * \brief Add a channel to the bridge.
+ *
+ * \param control Control whose channel should be added to the bridge
+ * \param bridge Pointer to the bridge
+ */
+void stasis_app_control_add_channel_to_bridge(
+ struct stasis_app_control *control, struct ast_bridge *bridge);
+
+/*!
+ * \brief Remove a channel from the bridge.
+ *
+ * \param control Control whose channel should be removed from the bridge
+ * \param bridge Pointer to the bridge
+ *
+ * \retval non-zero on failure
+ * \retval zero on success
+ */
+int stasis_app_control_remove_channel_from_bridge(
+ struct stasis_app_control *control, struct ast_bridge *bridge);
+
+/*!
+ * \brief Destroy the bridge.
+ *
+ * \param bridge_id Uniqueid of bridge to be destroyed
+ *
+ * \retval non-zero on failure
+ * \retval zero on success
+ */
+void stasis_app_bridge_destroy(const char *bridge_id);
+
+/*!
* \brief Increment the res_stasis reference count.
*
* This ensures graceful shutdown happens in the proper order.
Modified: team/mmichelson/transfer_stasis/include/asterisk/stasis_bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/include/asterisk/stasis_bridging.h?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/include/asterisk/stasis_bridging.h (original)
+++ team/mmichelson/transfer_stasis/include/asterisk/stasis_bridging.h Tue Jun 11 11:11:55 2013
@@ -392,6 +392,18 @@
struct ast_bridge_channel_pair *locals[2]);
/*!
+ * \brief Returns the most recent snapshot for the bridge.
+ *
+ * The returned pointer is AO2 managed, so ao2_cleanup() when you're done.
+ *
+ * \param bridge_id Uniqueid of the bridge for which to get the snapshot.
+ * \return Most recent snapshot. ao2_cleanup() when done.
+ * \return \c NULL if channel isn't in cache.
+ */
+struct ast_bridge_snapshot *ast_bridge_snapshot_get_latest(
+ const char *bridge_id);
+
+/*!
* \brief Initialize the stasis bridging topic and message types
* \retval 0 on success
* \retval -1 on failure
Modified: team/mmichelson/transfer_stasis/main/features_config.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/features_config.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/features_config.c (original)
+++ team/mmichelson/transfer_stasis/main/features_config.c Tue Jun 11 11:11:55 2013
@@ -1168,6 +1168,13 @@
return pickup_set(pickup, var->name, var->value);
}
+static int unsupported_handler(const struct aco_option *opt,
+ struct ast_variable *var, void *obj)
+{
+ ast_log(LOG_WARNING, "The option '%s' is no longer configurable in features.conf.\n", var->name);
+ return 0;
+}
+
static int featuremap_handler(const struct aco_option *opt,
struct ast_variable *var, void *obj)
{
@@ -1378,6 +1385,41 @@
aco_option_register_custom(&cfg_info, "pickupfailsound", ACO_EXACT, global_options,
DEFAULT_PICKUPFAILSOUND, pickup_handler, 0);
+ aco_option_register_custom(&cfg_info, "context", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkext", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkext_exclusive", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkinghints", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedmusicclass", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkingtime", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkpos", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "findslot", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcalltransfers", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcallreparking", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcallhangup", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkedcallrecording", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "comebackcontext", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "comebacktoorigin", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "comebackdialtime", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "parkeddynamic", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+ aco_option_register_custom(&cfg_info, "adsipark", ACO_EXACT, global_options,
+ "", unsupported_handler, 0);
+
aco_option_register_custom(&cfg_info, "blindxfer", ACO_EXACT, featuremap_options,
DEFAULT_FEATUREMAP_BLINDXFER, featuremap_handler, 0);
aco_option_register_custom(&cfg_info, "disconnect", ACO_EXACT, featuremap_options,
Modified: team/mmichelson/transfer_stasis/main/loader.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/loader.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/loader.c (original)
+++ team/mmichelson/transfer_stasis/main/loader.c Tue Jun 11 11:11:55 2013
@@ -750,7 +750,7 @@
event_object = ast_json_pack("{s: s, s: s}",
"Module", S_OR(name, "All"),
"Status", res_buffer);
- json_object = ast_json_pack("{s: s, s: i, s: o}",
+ json_object = ast_json_pack("{s: s, s: i, s: O}",
"type", "Reload",
"class_type", EVENT_FLAG_SYSTEM,
"event", event_object);
Modified: team/mmichelson/transfer_stasis/main/manager.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/manager.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/manager.c (original)
+++ team/mmichelson/transfer_stasis/main/manager.c Tue Jun 11 11:11:55 2013
@@ -1311,6 +1311,23 @@
}
return output_str;
+}
+
+static void manager_default_msg_cb(void *data, struct stasis_subscription *sub,
+ struct stasis_topic *topic,
+ struct stasis_message *message)
+{
+ RAII_VAR(struct ast_manager_event_blob *, ev, NULL, ao2_cleanup);
+
+ ev = stasis_message_to_ami(message);
+
+ if (ev == NULL) {
+ /* Not and AMI message; disregard */
+ return;
+ }
+
+ manager_event(ev->event_flags, ev->manager_event, "%s",
+ ev->extra_fields);
}
static void manager_generic_msg_cb(void *data, struct stasis_subscription *sub,
@@ -7686,7 +7703,12 @@
*/
static int manager_subscriptions_init(void)
{
- STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type);
+ int res;
+
+ res = STASIS_MESSAGE_TYPE_INIT(ast_manager_get_generic_type);
+ if (res != 0) {
+ return -1;
+ }
manager_topic = stasis_topic_create("manager_topic");
if (!manager_topic) {
return -1;
@@ -7696,10 +7718,13 @@
return -1;
}
- if (stasis_message_router_add(stasis_router,
- ast_manager_get_generic_type(),
- manager_generic_msg_cb,
- NULL)) {
+ res |= stasis_message_router_set_default(stasis_router,
+ manager_default_msg_cb, NULL);
+
+ res |= stasis_message_router_add(stasis_router,
+ ast_manager_get_generic_type(), manager_generic_msg_cb, NULL);
+
+ if (res != 0) {
return -1;
}
return 0;
Modified: team/mmichelson/transfer_stasis/main/manager_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/manager_channels.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/manager_channels.c (original)
+++ team/mmichelson/transfer_stasis/main/manager_channels.c Tue Jun 11 11:11:55 2013
@@ -710,49 +710,6 @@
}
}
-static void channel_varset_cb(void *data, struct stasis_subscription *sub,
- struct stasis_topic *topic, struct stasis_message *message)
-{
- struct ast_channel_blob *obj = stasis_message_data(message);
- RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
- const char *variable = ast_json_string_get(ast_json_object_get(obj->blob, "variable"));
- const char *value = ast_json_string_get(ast_json_object_get(obj->blob, "value"));
-
- if (obj->snapshot) {
- channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
- } else {
- channel_event_string = ast_str_create(35);
- ast_str_set(&channel_event_string, 0,
- "Channel: none\r\n"
- "Uniqueid: none\r\n");
- }
-
- if (!channel_event_string) {
- return;
- }
-
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when a variable is set to a particular value.</synopsis>
- <syntax>
- <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
- <parameter name="Variable">
- <para>The variable being set.</para>
- </parameter>
- <parameter name="Value">
- <para>The new value of the variable.</para>
- </parameter>
- </syntax>
- </managerEventInstance>
- ***/
- manager_event(EVENT_FLAG_DIALPLAN, "VarSet",
- "%s"
- "Variable: %s\r\n"
- "Value: %s\r\n",
- ast_str_buffer(channel_event_string),
- variable, value);
-}
-
static int userevent_exclusion_cb(const char *key)
{
if (!strcmp("type", key)) {
@@ -1280,11 +1237,6 @@
NULL);
ret |= stasis_message_router_add(message_router,
- ast_channel_varset_type(),
- channel_varset_cb,
- NULL);
-
- ret |= stasis_message_router_add(message_router,
ast_channel_user_event_type(),
channel_user_event_cb,
NULL);
Modified: team/mmichelson/transfer_stasis/main/parking.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/parking.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/parking.c (original)
+++ team/mmichelson/transfer_stasis/main/parking.c Tue Jun 11 11:11:55 2013
@@ -35,7 +35,7 @@
#include "asterisk/channel.h"
/*! \brief Message type for parked calls */
-static struct stasis_message_type *parked_call_type;
+STASIS_MESSAGE_TYPE_DEFN(ast_parked_call_type);
/*! \brief Topic for parking lots */
static struct stasis_topic *parking_topic;
@@ -48,26 +48,20 @@
void ast_parking_stasis_init(void)
{
- parked_call_type = stasis_message_type_create("ast_parked_call");
+ STASIS_MESSAGE_TYPE_INIT(ast_parked_call_type);
parking_topic = stasis_topic_create("ast_parking");
}
void ast_parking_stasis_disable(void)
{
- ao2_cleanup(parked_call_type);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_parked_call_type);
ao2_cleanup(parking_topic);
- parked_call_type = NULL;
parking_topic = NULL;
}
struct stasis_topic *ast_parking_topic(void)
{
return parking_topic;
-}
-
-struct stasis_message_type *ast_parked_call_type(void)
-{
- return parked_call_type;
}
/*! \brief Destructor for parked_call_payload objects */
Modified: team/mmichelson/transfer_stasis/main/stasis_bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/stasis_bridging.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/stasis_bridging.c (original)
+++ team/mmichelson/transfer_stasis/main/stasis_bridging.c Tue Jun 11 11:11:55 2013
@@ -539,6 +539,28 @@
stasis_publish(ast_bridge_topic_all(), msg);
}
+struct ast_bridge_snapshot *ast_bridge_snapshot_get_latest(const char *uniqueid)
+{
+ RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+ struct ast_bridge_snapshot *snapshot;
+
+ ast_assert(!ast_strlen_zero(uniqueid));
+
+ message = stasis_cache_get(ast_bridge_topic_all_cached(),
+ ast_bridge_snapshot_type(),
+ uniqueid);
+ if (!message) {
+ return NULL;
+ }
+
+ snapshot = stasis_message_data(message);
+ if (!snapshot) {
+ return NULL;
+ }
+ ao2_ref(snapshot, +1);
+ return snapshot;
+}
+
static void stasis_bridging_cleanup(void)
{
ao2_cleanup(bridge_topic_all);
Modified: team/mmichelson/transfer_stasis/main/stasis_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/transfer_stasis/main/stasis_channels.c?view=diff&rev=391405&r1=391404&r2=391405
==============================================================================
--- team/mmichelson/transfer_stasis/main/stasis_channels.c (original)
+++ team/mmichelson/transfer_stasis/main/stasis_channels.c Tue Jun 11 11:11:55 2013
@@ -36,29 +36,24 @@
#include "asterisk/astobj2.h"
#include "asterisk/stasis_channels.h"
+/*** DOCUMENTATION
+ <managerEvent language="en_US" name="VarSet">
+ <managerEventInstance class="EVENT_FLAG_DIALPLAN">
+ <synopsis>Raised when a variable is set to a particular value.</synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ <parameter name="Variable">
+ <para>The variable being set.</para>
+ </parameter>
+ <parameter name="Value">
+ <para>The new value of the variable.</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+***/
+
#define NUM_MULTI_CHANNEL_BLOB_BUCKETS 7
-
-/*!
- * @{ \brief Define channel message types.
- */
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_snapshot_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_dial_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_varset_type);
-STASIS_MESSAGE_TYPE_DEFN(ast_channel_user_event_type);
[... 1685 lines stripped ...]
More information about the asterisk-commits
mailing list