[asterisk-commits] mmichelson: branch mmichelson/features_config_docs r391478 - in /team/mmichel...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jun 11 20:02:04 CDT 2013
Author: mmichelson
Date: Tue Jun 11 20:02:02 2013
New Revision: 391478
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=391478
Log:
Get merged up. This code is ready for review!
Added:
team/mmichelson/features_config_docs/include/asterisk/backtrace.h
- copied unchanged from r391455, trunk/include/asterisk/backtrace.h
team/mmichelson/features_config_docs/main/backtrace.c
- copied unchanged from r391455, trunk/main/backtrace.c
team/mmichelson/features_config_docs/res/res_stasis_bridge_add.c
- copied unchanged from r391455, trunk/res/res_stasis_bridge_add.c
team/mmichelson/features_config_docs/res/res_stasis_bridge_add.exports.in
- copied unchanged from r391455, trunk/res/res_stasis_bridge_add.exports.in
Modified:
team/mmichelson/features_config_docs/ (props changed)
team/mmichelson/features_config_docs/UPGRADE.txt
team/mmichelson/features_config_docs/apps/app_queue.c
team/mmichelson/features_config_docs/bridges/bridge_native_rtp.c
team/mmichelson/features_config_docs/channels/chan_iax2.c
team/mmichelson/features_config_docs/channels/chan_skinny.c
team/mmichelson/features_config_docs/channels/chan_unistim.c
team/mmichelson/features_config_docs/configs/queues.conf.sample
team/mmichelson/features_config_docs/include/asterisk/framehook.h
team/mmichelson/features_config_docs/include/asterisk/lock.h
team/mmichelson/features_config_docs/include/asterisk/logger.h
team/mmichelson/features_config_docs/include/asterisk/stasis.h
team/mmichelson/features_config_docs/include/asterisk/stasis_app.h
team/mmichelson/features_config_docs/include/asterisk/stasis_bridging.h
team/mmichelson/features_config_docs/main/app.c
team/mmichelson/features_config_docs/main/astmm.c
team/mmichelson/features_config_docs/main/astobj2.c
team/mmichelson/features_config_docs/main/bridging.c
team/mmichelson/features_config_docs/main/features_config.c
team/mmichelson/features_config_docs/main/framehook.c
team/mmichelson/features_config_docs/main/loader.c
team/mmichelson/features_config_docs/main/logger.c
team/mmichelson/features_config_docs/main/manager.c
team/mmichelson/features_config_docs/main/manager_channels.c
team/mmichelson/features_config_docs/main/parking.c
team/mmichelson/features_config_docs/main/stasis_bridging.c
team/mmichelson/features_config_docs/main/stasis_channels.c
team/mmichelson/features_config_docs/main/stasis_message.c
team/mmichelson/features_config_docs/res/res_agi.c
team/mmichelson/features_config_docs/res/res_stasis.c
team/mmichelson/features_config_docs/res/res_stasis_json_events.c
team/mmichelson/features_config_docs/res/res_stasis_json_events.exports.in
team/mmichelson/features_config_docs/res/stasis/app.c
team/mmichelson/features_config_docs/res/stasis/app.h
team/mmichelson/features_config_docs/res/stasis/control.c
team/mmichelson/features_config_docs/res/stasis_http/resource_bridges.c
team/mmichelson/features_config_docs/res/stasis_http/resource_bridges.h
team/mmichelson/features_config_docs/res/stasis_json/resource_events.h
team/mmichelson/features_config_docs/rest-api/api-docs/bridges.json
team/mmichelson/features_config_docs/rest-api/api-docs/events.json
team/mmichelson/features_config_docs/tests/test_stasis.c
team/mmichelson/features_config_docs/tests/test_stasis_channels.c
team/mmichelson/features_config_docs/utils/extconf.c
Propchange: team/mmichelson/features_config_docs/
------------------------------------------------------------------------------
Binary property 'branch-11-merged' - no diff available.
Propchange: team/mmichelson/features_config_docs/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jun 11 20:02:02 2013
@@ -1,1 +1,1 @@
-/trunk:1-391009
+/trunk:1-391477
Modified: team/mmichelson/features_config_docs/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/UPGRADE.txt?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/UPGRADE.txt (original)
+++ team/mmichelson/features_config_docs/UPGRADE.txt Tue Jun 11 20:02:02 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/features_config_docs/apps/app_queue.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/apps/app_queue.c?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/apps/app_queue.c (original)
+++ team/mmichelson/features_config_docs/apps/app_queue.c Tue Jun 11 20:02:02 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/features_config_docs/bridges/bridge_native_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/bridges/bridge_native_rtp.c?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/bridges/bridge_native_rtp.c (original)
+++ team/mmichelson/features_config_docs/bridges/bridge_native_rtp.c Tue Jun 11 20:02:02 2013
@@ -87,7 +87,7 @@
{
if (ast_channel_monitor(chan) || (ast_channel_audiohooks(chan) &&
!ast_audiohook_write_list_empty(ast_channel_audiohooks(chan))) ||
- !ast_framehook_list_is_empty(ast_channel_framehooks(chan))) {
+ !ast_framehook_list_contains_no_active(ast_channel_framehooks(chan))) {
return 0;
} else {
return 1;
@@ -317,7 +317,8 @@
glue1->get_codec(c1->chan, cap1);
}
- if (native_type == AST_RTP_GLUE_RESULT_LOCAL) {
+ switch (native_type) {
+ case AST_RTP_GLUE_RESULT_LOCAL:
if (ast_rtp_instance_get_engine(instance0)->local_bridge) {
ast_rtp_instance_get_engine(instance0)->local_bridge(instance0, instance1);
}
@@ -326,9 +327,14 @@
}
ast_rtp_instance_set_bridged(instance0, instance1);
ast_rtp_instance_set_bridged(instance1, instance0);
- } else {
+ break;
+
+ case AST_RTP_GLUE_RESULT_REMOTE:
glue0->update_peer(c0->chan, instance1, vinstance1, tinstance1, cap1, 0);
glue1->update_peer(c1->chan, instance0, vinstance0, tinstance0, cap0, 0);
+ break;
+ case AST_RTP_GLUE_RESULT_FORBID:
+ break;
}
return 0;
@@ -354,7 +360,8 @@
native_type = native_rtp_bridge_get(c0->chan, c1 ? c1->chan : NULL, &glue0, &glue1, &instance0, &instance1, &vinstance0, &vinstance1);
- if (native_type == AST_RTP_GLUE_RESULT_LOCAL) {
+ switch (native_type) {
+ case AST_RTP_GLUE_RESULT_LOCAL:
if (ast_rtp_instance_get_engine(instance0)->local_bridge) {
ast_rtp_instance_get_engine(instance0)->local_bridge(instance0, NULL);
}
@@ -365,11 +372,15 @@
if (instance1) {
ast_rtp_instance_set_bridged(instance1, instance0);
}
- } else {
+ break;
+ case AST_RTP_GLUE_RESULT_REMOTE:
glue0->update_peer(c0->chan, NULL, NULL, NULL, NULL, 0);
if (glue1) {
glue1->update_peer(c1->chan, NULL, NULL, NULL, NULL, 0);
}
+ break;
+ case AST_RTP_GLUE_RESULT_FORBID:
+ break;
}
}
Modified: team/mmichelson/features_config_docs/channels/chan_iax2.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/channels/chan_iax2.c?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/channels/chan_iax2.c (original)
+++ team/mmichelson/features_config_docs/channels/chan_iax2.c Tue Jun 11 20:02:02 2013
@@ -11204,65 +11204,99 @@
}
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) {
+ 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) {
- 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);
+ while (ast_mutex_trylock(&iaxsl[iaxs[fr->callno]->bridgecallno])) {
+ DEADLOCK_AVOIDANCE(&iaxsl[fr->callno]);
+ }
+ if (!iaxs[fr->callno]) {
+ break;
}
}
- break;
- case IAX_COMMAND_TXREADY:
- if ((iaxs[fr->callno]->transferring == TRANSFER_BEGIN) ||
- (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)) {
- if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN)
- iaxs[fr->callno]->transferring = TRANSFER_MREADY;
- else
- iaxs[fr->callno]->transferring = TRANSFER_READY;
- ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
+
+ if (iaxs[fr->callno]->transferring == TRANSFER_BEGIN) {
+ iaxs[fr->callno]->transferring = TRANSFER_READY;
+ } else if (iaxs[fr->callno]->transferring == TRANSFER_MBEGIN) {
+ iaxs[fr->callno]->transferring = TRANSFER_MREADY;
+ } else {
if (iaxs[fr->callno]->bridgecallno) {
- if ((iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) ||
- (iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
- /* They're both ready, now release them. */
- if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
- ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
- iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
-
- iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
- iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
-
- memset(&ied0, 0, sizeof(ied0));
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
- send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
- } else {
- ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
- iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
-
- iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
- iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
- ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
- ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
-
- /* Stop doing lag & ping requests */
- stop_stuff(fr->callno);
- stop_stuff(iaxs[fr->callno]->bridgecallno);
-
- memset(&ied0, 0, sizeof(ied0));
- memset(&ied1, 0, sizeof(ied1));
- iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
- iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
- send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
- send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
- }
-
- }
+ ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
}
+ break;
}
+ ast_verb(3, "Channel '%s' ready to transfer\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>");
+
+ if (!iaxs[fr->callno]->bridgecallno) {
+ break;
+ }
+
+ if (!(iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_READY) &&
+ !(iaxs[iaxs[fr->callno]->bridgecallno]->transferring == TRANSFER_MREADY)) {
+ ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
+ break;
+ }
+
+ /* Both sides are ready */
+
+ /* XXX what isn't checked here is that both sides match transfer types. */
+
+ if (iaxs[fr->callno]->transferring == TRANSFER_MREADY) {
+ ast_verb(3, "Attempting media bridge of %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
+ iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
+
+ iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_MEDIA;
+ iaxs[fr->callno]->transferring = TRANSFER_MEDIA;
+
+ memset(&ied0, 0, sizeof(ied0));
+ memset(&ied1, 0, sizeof(ied1));
+ iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
+ iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
+ send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied0.buf, ied0.pos, -1);
+ send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXMEDIA, 0, ied1.buf, ied1.pos, -1);
+ } else {
+ ast_verb(3, "Releasing %s and %s\n", iaxs[fr->callno]->owner ? ast_channel_name(iaxs[fr->callno]->owner) : "<Unknown>",
+ iaxs[iaxs[fr->callno]->bridgecallno]->owner ? ast_channel_name(iaxs[iaxs[fr->callno]->bridgecallno]->owner) : "<Unknown>");
+
+ iaxs[iaxs[fr->callno]->bridgecallno]->transferring = TRANSFER_RELEASED;
+ iaxs[fr->callno]->transferring = TRANSFER_RELEASED;
+ ast_set_flag64(iaxs[iaxs[fr->callno]->bridgecallno], IAX_ALREADYGONE);
+ ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
+
+ /* Stop doing lag & ping requests */
+ stop_stuff(fr->callno);
+ stop_stuff(iaxs[fr->callno]->bridgecallno);
+
+ memset(&ied0, 0, sizeof(ied0));
+ memset(&ied1, 0, sizeof(ied1));
+ iax_ie_append_short(&ied0, IAX_IE_CALLNO, iaxs[iaxs[fr->callno]->bridgecallno]->peercallno);
+ iax_ie_append_short(&ied1, IAX_IE_CALLNO, iaxs[fr->callno]->peercallno);
+ send_command(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied0.buf, ied0.pos, -1);
+ send_command(iaxs[iaxs[fr->callno]->bridgecallno], AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied1.buf, ied1.pos, -1);
+ }
+ ast_mutex_unlock(&iaxsl[iaxs[fr->callno]->bridgecallno]);
break;
case IAX_COMMAND_TXREQ:
try_transfer(iaxs[fr->callno], &ies);
Modified: team/mmichelson/features_config_docs/channels/chan_skinny.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/channels/chan_skinny.c?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/channels/chan_skinny.c (original)
+++ team/mmichelson/features_config_docs/channels/chan_skinny.c Tue Jun 11 20:02:02 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/features_config_docs/channels/chan_unistim.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/channels/chan_unistim.c?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/channels/chan_unistim.c (original)
+++ team/mmichelson/features_config_docs/channels/chan_unistim.c Tue Jun 11 20:02:02 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/features_config_docs/configs/queues.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/configs/queues.conf.sample?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/configs/queues.conf.sample (original)
+++ team/mmichelson/features_config_docs/configs/queues.conf.sample Tue Jun 11 20:02:02 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/features_config_docs/include/asterisk/framehook.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/include/asterisk/framehook.h?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/include/asterisk/framehook.h (original)
+++ team/mmichelson/features_config_docs/include/asterisk/framehook.h Tue Jun 11 20:02:02 2013
@@ -222,7 +222,7 @@
* \param chan ast_channel The channel to attach the hook on to.
* \param i framehook interface, The framehook's callback functions and stored data.
*
- * \pre XXX The Channel must be locked during this function all.
+ * \pre The Channel must be locked during this function all.
*
* \note The data pointer is never touched by the framehook API except to
* provide it during the event and destruction callbacks. It is entirely up to the
@@ -237,7 +237,7 @@
* \brief Detach an framehook from a channel.
* \since 1.8
*
- * \pre XXX The Channel must be locked during this function all.
+ * \pre The Channel must be locked during this function all.
* If this function is never called after attaching an framehook,
* the framehook will be detached and destroyed during channel
* destruction.
@@ -256,7 +256,7 @@
* framehooks on a channel during channel destruction.
* \since 1.8
*
- * \pre XXX The Channel must be locked during this function all.
+ * \pre The Channel must be locked during this function all.
*
* \param chan channel containing the framehook list to destroy.
* \retval 0 success
@@ -272,7 +272,7 @@
* even NULL. There is nothing to keep up with after this function. If the frame is modified, the
* framehook callback is in charge of any memory management associated with that modification.
*
- * \pre XXX The Channel must be locked during this function all.
+ * \pre The Channel must be locked during this function all.
*
* \param framehooks list to push event to.
* \param frame being pushed to the framehook list.
@@ -289,7 +289,7 @@
* even NULL. There is nothing to keep up with after this function. If the frame is modified, the
* framehook callback is in charge of any memory management associated with that modification.
*
- * \pre XXX The Channel must be locked during this function all.
+ * \pre The Channel must be locked during this function all.
*
* \param framehooks list to push event to.
* \param frame being pushed to the framehook list.
@@ -301,11 +301,26 @@
/*!
* \brief Determine if an framehook list is empty or not
* \since 1.8
- * \pre XXX The Channel must be locked during this function all.
+ * \pre The Channel must be locked during this function all.
*
* \param framehooks the framehook list
* \retval 0, not empty
* \retval 1, is empty
*/
int ast_framehook_list_is_empty(struct ast_framehook_list *framehooks);
+
+/*!
+ * \brief Determine if a framehook list is free of active framehooks or not
+ * \since 12.0.0
+ * \pre The channel must be locked during this function all.
+ *
+ * \param framehooks the framehook list
+ * \retval 0, not empty
+ * \retval 1, is empty (aside from dying framehooks)
+ *
+ * \note This function is very similar to ast_framehook_list_is_empty, but it checks individual
+ * framehooks to see if they have been marked for destruction and doesn't count them if they are.
+ */
+int ast_framehook_list_contains_no_active(struct ast_framehook_list *framehooks);
+
#endif /* _AST_FRAMEHOOK_H */
Modified: team/mmichelson/features_config_docs/include/asterisk/lock.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/include/asterisk/lock.h?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/include/asterisk/lock.h (original)
+++ team/mmichelson/features_config_docs/include/asterisk/lock.h Tue Jun 11 20:02:02 2013
@@ -59,6 +59,7 @@
#include "asterisk/time.h"
#endif
+#include "asterisk/backtrace.h"
#include "asterisk/logger.h"
#include "asterisk/compiler.h"
Modified: team/mmichelson/features_config_docs/include/asterisk/logger.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/include/asterisk/logger.h?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/include/asterisk/logger.h (original)
+++ team/mmichelson/features_config_docs/include/asterisk/logger.h Tue Jun 11 20:02:02 2013
@@ -80,7 +80,10 @@
void ast_log_callid(int level, const char *file, int line, const char *function, struct ast_callid *callid, const char *fmt, ...)
__attribute__((format(printf, 6, 7)));
-void ast_backtrace(void);
+/*!
+ * \brief Log a backtrace of the current thread's execution stack to the Asterisk log
+ */
+void ast_log_backtrace(void);
/*! \brief Reload logger without rotating log files */
int logger_reload(void);
@@ -362,63 +365,6 @@
#define ast_verb(level, ...) __ast_verbose(__FILE__, __LINE__, __PRETTY_FUNCTION__, level, __VA_ARGS__)
#define ast_verb_callid(level, callid, ...) __ast_verbose_callid(__FILE__, __LINE__, __PRETTY_FUNCTION__, level, callid, __VA_ARGS__)
-#ifndef _LOGGER_BACKTRACE_H
-#define _LOGGER_BACKTRACE_H
-#ifdef HAVE_BKTR
-#define AST_MAX_BT_FRAMES 32
-/* \brief
- *
- * A structure to hold backtrace information. This structure provides an easy means to
- * store backtrace information or pass backtraces to other functions.
- */
-struct ast_bt {
- /*! The addresses of the stack frames. This is filled in by calling the glibc backtrace() function */
- void *addresses[AST_MAX_BT_FRAMES];
- /*! The number of stack frames in the backtrace */
- int num_frames;
- /*! Tells if the ast_bt structure was dynamically allocated */
- unsigned int alloced:1;
-};
-
-/* \brief
- * Allocates memory for an ast_bt and stores addresses and symbols.
- *
- * \return Returns NULL on failure, or the allocated ast_bt on success
- * \since 1.6.1
- */
-struct ast_bt *ast_bt_create(void);
-
-/* \brief
- * Fill an allocated ast_bt with addresses
- *
- * \retval 0 Success
- * \retval -1 Failure
- * \since 1.6.1
- */
-int ast_bt_get_addresses(struct ast_bt *bt);
-
-/* \brief
- *
- * Free dynamically allocated portions of an ast_bt
- *
- * \retval NULL.
- * \since 1.6.1
- */
-void *ast_bt_destroy(struct ast_bt *bt);
-
-/* \brief Retrieve symbols for a set of backtrace addresses
- *
- * \param addresses A list of addresses, such as the ->addresses structure element of struct ast_bt.
- * \param num_frames Number of addresses in the addresses list
- * \retval NULL Unable to allocate memory
- * \return List of strings
- * \since 1.6.2.16
- */
-char **ast_bt_get_symbols(void **addresses, size_t num_frames);
-
-#endif /* HAVE_BKTR */
-#endif /* _LOGGER_BACKTRACE_H */
-
#if defined(__cplusplus) || defined(c_plusplus)
}
#endif
Modified: team/mmichelson/features_config_docs/include/asterisk/stasis.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/features_config_docs/include/asterisk/stasis.h?view=diff&rev=391478&r1=391477&r2=391478
==============================================================================
--- team/mmichelson/features_config_docs/include/asterisk/stasis.h (original)
+++ team/mmichelson/features_config_docs/include/asterisk/stasis.h Tue Jun 11 20:02:02 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.
[... 2595 lines stripped ...]
More information about the asterisk-commits
mailing list