[asterisk-commits] qwell: branch qwell/queue_events r390846 - in /team/qwell/queue_events: ./ ap...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Fri Jun 7 09:37:53 CDT 2013
Author: qwell
Date: Fri Jun 7 09:37:40 2013
New Revision: 390846
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=390846
Log:
Multiple revisions 390698,390701,390728-390730,390733-390734,390751,390771,390787,390803-390804,390830
........
r390698 | qwell | 2013-06-06 14:44:45 -0500 (Thu, 06 Jun 2013) | 4 lines
Convert message_router routes to ao2. Add support for removal.
Review: https://reviewboard.asterisk.org/r/2591/
........
r390701 | qwell | 2013-06-06 14:51:12 -0500 (Thu, 06 Jun 2013) | 7 lines
Split AGI manager events, to remove SubEvent field.
This moves them to stasis, in the process.
(closes issue ASTERISK-21470)
Review: https://reviewboard.asterisk.org/r/2587/
........
r390728 | kmoore | 2013-06-06 15:30:56 -0500 (Thu, 06 Jun 2013) | 1 line
Fix documentation that was in review during the great suffix/prefix swap
........
r390729 | qwell | 2013-06-06 15:32:15 -0500 (Thu, 06 Jun 2013) | 4 lines
Remove props that people will yell at me for.
I'm sorry I broke automerge. :(
........
r390730 | kmoore | 2013-06-06 15:37:48 -0500 (Thu, 06 Jun 2013) | 4 lines
Fix documentation generation
Regression from r390701
........
r390733 | rmudgett | 2013-06-06 15:47:10 -0500 (Thu, 06 Jun 2013) | 4 lines
* Fix a couple missed hook installs that need AST_BRIDGE_HOOK_REMOVE_ON_PULL.
* Rename some hook flag parameters to remove_flags.
........
r390734 | rmudgett | 2013-06-06 15:50:25 -0500 (Thu, 06 Jun 2013) | 1 line
Fix compiler warning.
........
r390751 | mmichelson | 2013-06-06 16:40:35 -0500 (Thu, 06 Jun 2013) | 21 lines
Refactor the features configuration scheme.
Features configuration is handled in its own API in
features_config.h and features_config.c. This way, features
configuration is accessible to anything that needs it.
In addition, features configuration has been altered to
be more channel-oriented. Most callers of features API
code will be supplying a channel so that the individual
channel's settings will be acquired rather than the global
setting.
Missing from this commit is XML documentation for the
features configuration. That will be handled in a separate
commit.
Review: https://reviewboard.asterisk.org/r/2578/
(issue ASTERISK-21542)
........
r390771 | rmudgett | 2013-06-06 17:46:54 -0500 (Thu, 06 Jun 2013) | 30 lines
Reimplement bridging and DTMF features related channel variables in the bridging core.
* The channel variable ATTENDED_TRANSFER_COMPLETE_SOUND is no longer
channel driver specific. If the channel variable is set on the
transferrer channel, the sound will be played to the target of an attended
transfer.
* The channel variable BRIDGEPEER becomes a comma separated list of peers
in a multi-party bridge. The BRIDGEPEER value can have a maximum of 10
peers listed. Any more peers in the bridge will not be included in the
list. BRIDGEPEER is not valid in holding bridges like parking since those
channels do not talk to each other even though they are in a bridge.
* The channel variable BRIDGEPVTCALLID is only valid for two party bridges
and will contain a value if the BRIDGEPEER's channel driver supports it.
* The channel variable DYNAMIC_PEERNAME is redundant with BRIDGEPEER and
is removed. The more useful DYNAMIC_WHO_ACTIVATED gives the channel name
that activated the dynamic feature.
* The channel variables DYNAMIC_FEATURENAME and DYNAMIC_WHO_ACTIVATED are
set only on the channel executing the dynamic feature. Executing a
dynamic feature on the bridge peer in a multi-party bridge will execute it
on all peers of the activating channel.
(closes issue ASTERISK-21555)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2582/
........
r390787 | mmichelson | 2013-06-06 18:32:13 -0500 (Thu, 06 Jun 2013) | 8 lines
Conditionally reject duplicate entries in applicationmap containers.
When reading from a config file, it's important to reject duplicates. Otherwise,
featuregroups will have ambiguity when pointing to applicationmap items. However,
when constructing the channel's current applicationmap, we don't care about duplicate
names since it's the DTMF that identifies a feature, not the name.
........
r390803 | rmudgett | 2013-06-06 19:33:20 -0500 (Thu, 06 Jun 2013) | 8 lines
Tweak applicationmap and featuregroup config containers.
* Change applicationmap and featuregroup to replace duplicate config items
rather than reject them.
* Remove some unneeded warning messages when getting the applicationmap
allows duplicates from DYNAMIC_FEATURES.
........
r390804 | rmudgett | 2013-06-06 20:06:49 -0500 (Thu, 06 Jun 2013) | 10 lines
Refactor chan_dahdi/sig_analog/sig_pri and chan_misdn to use the common transfer functions.
(closes issue ASTERISK-21523)
Reported by: Matt Jordan
(closes issue ASTERISK-21524)
Reported by: Matt Jordan
Review: https://reviewboard.asterisk.org/r/2600/
........
r390830 | kmoore | 2013-06-07 07:56:56 -0500 (Fri, 07 Jun 2013) | 16 lines
Rework stasis cache clear events
Stasis cache clear message payloads now consist of a stasis_message
representative of the message to be cleared from the cache. This allows
multiple parallel caches to coexist and be cleared properly by the same
cache clear message even when keyed on different fields.
This change fixes a bug where multiple cache clears could be posted for
channels. The cache clear is now produced in the destructor instead of
ast_hangup.
Additionally, dummy channels are no longer capable of producing channel
snapshots.
Review: https://reviewboard.asterisk.org/r/2596
........
Merged revisions 390698,390701,390728-390730,390733-390734,390751,390771,390787,390803-390804,390830 from http://svn.asterisk.org/svn/asterisk/trunk
Added:
team/qwell/queue_events/include/asterisk/features_config.h
- copied unchanged from r390830, trunk/include/asterisk/features_config.h
team/qwell/queue_events/main/features_config.c
- copied unchanged from r390830, trunk/main/features_config.c
Modified:
team/qwell/queue_events/ (props changed)
team/qwell/queue_events/CHANGES
team/qwell/queue_events/UPGRADE.txt
team/qwell/queue_events/apps/app_bridgewait.c
team/qwell/queue_events/apps/app_dial.c
team/qwell/queue_events/bridges/bridge_builtin_features.c
team/qwell/queue_events/channels/chan_dahdi.c
team/qwell/queue_events/channels/chan_mgcp.c
team/qwell/queue_events/channels/chan_misdn.c
team/qwell/queue_events/channels/chan_sip.c
team/qwell/queue_events/channels/chan_unistim.c
team/qwell/queue_events/channels/sig_analog.c
team/qwell/queue_events/channels/sig_pri.c
team/qwell/queue_events/channels/sig_pri.h
team/qwell/queue_events/channels/sip/include/sip.h
team/qwell/queue_events/configs/chan_dahdi.conf.sample
team/qwell/queue_events/configs/iax.conf.sample
team/qwell/queue_events/configs/sip.conf.sample
team/qwell/queue_events/configs/skinny.conf.sample
team/qwell/queue_events/include/asterisk/bridging.h
team/qwell/queue_events/include/asterisk/bridging_features.h
team/qwell/queue_events/include/asterisk/channel.h
team/qwell/queue_events/include/asterisk/features.h
team/qwell/queue_events/include/asterisk/stasis.h
team/qwell/queue_events/include/asterisk/stasis_message_router.h
team/qwell/queue_events/main/bridging.c
team/qwell/queue_events/main/channel.c
team/qwell/queue_events/main/endpoints.c
team/qwell/queue_events/main/features.c
team/qwell/queue_events/main/manager.c
team/qwell/queue_events/main/stasis_cache.c
team/qwell/queue_events/main/stasis_channels.c
team/qwell/queue_events/main/stasis_message_router.c
team/qwell/queue_events/res/parking/parking_manager.c
team/qwell/queue_events/res/res_agi.c
team/qwell/queue_events/tests/test_stasis.c
Propchange: team/qwell/queue_events/
------------------------------------------------------------------------------
automerge = *
Propchange: team/qwell/queue_events/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Fri Jun 7 09:37:40 2013
@@ -1,1 +1,1 @@
-/trunk:1-390689
+/trunk:1-390845
Modified: team/qwell/queue_events/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/CHANGES?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/CHANGES (original)
+++ team/qwell/queue_events/CHANGES Fri Jun 7 09:37:40 2013
@@ -111,6 +111,14 @@
information about each channel. The (infamous) "Join" and "Leave" AMI
events have been changed to "QueueCallerJoin" and "QueueCallerLeave".
+=======
+AGI (Asterisk Gateway Interface)
+------------------
+ * The manager event AGIExec has been split into AGIExecStart and AGIExecEnd.
+
+ * The manager event AsyncAGI has been split into AsyncAGIStart, AsyncAGIExec,
+ and AsyncAGIEnd.
+
Channel Drivers
------------------
* When a channel driver is configured to enable jiterbuffers, they are now
@@ -243,6 +251,31 @@
reason to any string. It also allows for custom strings to be read as the
redirecting reason from SIP Diversion headers.
+ * For DTMF blind and attended transfers, the channel variable TRANSFER_CONTEXT
+ must be on the channel initiating the transfer to have any effect.
+
+ * The channel variable ATTENDED_TRANSFER_COMPLETE_SOUND is no longer channel
+ driver specific. If the channel variable is set on the transferrer channel,
+ the sound will be played to the target of an attended transfer.
+
+ * The channel variable BRIDGEPEER becomes a comma separated list of peers in
+ a multi-party bridge. The BRIDGEPEER value can have a maximum of 10 peers
+ listed. Any more peers in the bridge will not be included in the list.
+ BRIDGEPEER is not valid in holding bridges like parking since those channels
+ do not talk to each other even though they are in a bridge.
+
+ * The channel variable BRIDGEPVTCALLID is only valid for two party bridges
+ and will contain a value if the BRIDGEPEER's channel driver supports it.
+
+ * The channel variable DYNAMIC_PEERNAME is redundant with BRIDGEPEER and is
+ removed. The more useful DYNAMIC_WHO_ACTIVATED gives the channel name that
+ activated the dynamic feature.
+
+ * The channel variables DYNAMIC_FEATURENAME and DYNAMIC_WHO_ACTIVATED are set
+ only on the channel executing the dynamic feature. Executing a dynamic
+ feature on the bridge peer in a multi-party bridge will execute it on all
+ peers of the activating channel.
+
Realtime
------------------
* Dynamic realtime tables for SIP Users can now include a 'path' field. This
@@ -250,7 +283,7 @@
tables can also use the 'supportpath' field to enable Path header support.
* LDAP realtime configurations for SIP Users now have the AstAccountPathSupport
- objectIdentifier. This maps to the supportpath option in sip.conf.
+ objectIdentifier. This maps to the supportpath option in sip.conf.
RTP
------------------
Modified: team/qwell/queue_events/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/UPGRADE.txt?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/UPGRADE.txt (original)
+++ team/qwell/queue_events/UPGRADE.txt Fri Jun 7 09:37:40 2013
@@ -37,6 +37,11 @@
CEL:
- The Uniqueid field for a channel is now a stable identifier, and will not
change due to transfers, parking, etc.
+
+Core:
+ - The following channel variables have changed behavior which is described in
+ the CHANGES file: TRANSFER_CONTEXT, BRIDGEPEER, BRIDGEPVTCALLID,
+ ATTENDED_TRANSFER_COMPLETE_SOUND, DYNAMIC_FEATURENAME, and DYNAMIC_PEERNAME.
Queues:
- Queue logging for PAUSEALL/UNPAUSEALL now only occurs if the interface this is
@@ -86,9 +91,12 @@
Features:
- The features.conf [applicationmap] <FeatureName> ActivatedBy option is
- no longer honored. The feature is activated by which channel
- DYNAMIC_FEATURES includes the feature is on. Use predial to set different
- values of DYNAMIC_FEATURES on the channels
+ no longer honored. The feature is always activated by the channel that has
+ DYNAMIC_FEATURES defined on it when it enters the bridge. Use predial to set
+ different values of DYNAMIC_FEATURES on the channels
+
+ - Executing a dynamic feature on the bridge peer in a multi-party bridge will
+ execute it on all peers of the activating channel.
Parking:
- The arguments for the Park, ParkedCall, and ParkAndAnnounce applications have
Modified: team/qwell/queue_events/apps/app_bridgewait.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/apps/app_bridgewait.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/apps/app_bridgewait.c (original)
+++ team/qwell/queue_events/apps/app_bridgewait.c Fri Jun 7 09:37:40 2013
@@ -141,7 +141,7 @@
/* Limits struct holds time as milliseconds, so muliply 1000x */
hold_limits.duration *= 1000;
- ast_bridge_features_set_limits(features, &hold_limits, 1 /* remove_on_pull */);
+ ast_bridge_features_set_limits(features, &hold_limits, AST_BRIDGE_HOOK_REMOVE_ON_PULL);
ast_bridge_features_limits_destroy(&hold_limits);
return 0;
Modified: team/qwell/queue_events/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/apps/app_dial.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/apps/app_dial.c (original)
+++ team/qwell/queue_events/apps/app_dial.c Fri Jun 7 09:37:40 2013
@@ -69,6 +69,7 @@
#include "asterisk/dial.h"
#include "asterisk/stasis_channels.h"
#include "asterisk/bridging.h"
+#include "asterisk/features_config.h"
/*** DOCUMENTATION
<application name="Dial" language="en_US">
@@ -1074,7 +1075,7 @@
int caller_entertained = outgoing
&& ast_test_flag64(outgoing, OPT_MUSICBACK | OPT_RINGBACK);
struct ast_party_connected_line connected_caller;
- struct ast_str *featurecode = ast_str_alloca(FEATURE_MAX_LEN + 1);
+ struct ast_str *featurecode = ast_str_alloca(AST_FEATURE_MAX_LEN + 1);
int cc_recall_core_id;
int is_cc_recall;
int cc_frame_received = 0;
@@ -1701,22 +1702,31 @@
static int detect_disconnect(struct ast_channel *chan, char code, struct ast_str **featurecode)
{
- struct ast_flags features = { AST_FEATURE_DISCONNECT }; /* only concerned with disconnect feature */
- struct ast_call_feature feature = { 0, };
+ char disconnect_code[AST_FEATURE_MAX_LEN];
int res;
ast_str_append(featurecode, 1, "%c", code);
- res = ast_feature_detect(chan, &features, ast_str_buffer(*featurecode), &feature);
-
- if (res != AST_FEATURE_RETURN_STOREDIGITS) {
+ res = ast_get_builtin_feature(chan, "disconnect", disconnect_code, sizeof(disconnect_code));
+ if (res) {
ast_str_reset(*featurecode);
- }
- if (feature.feature_mask & AST_FEATURE_DISCONNECT) {
- return 1;
- }
-
- return 0;
+ return 0;
+ }
+
+ if (strlen(disconnect_code) > ast_str_strlen(*featurecode)) {
+ /* Could be a partial match, anyway */
+ if (strncmp(disconnect_code, ast_str_buffer(*featurecode), ast_str_strlen(*featurecode))) {
+ ast_str_reset(*featurecode);
+ }
+ return 0;
+ }
+
+ if (strcmp(disconnect_code, ast_str_buffer(*featurecode))) {
+ ast_str_reset(*featurecode);
+ return 0;
+ }
+
+ return 1;
}
/* returns true if there is a valid privacy reply */
Modified: team/qwell/queue_events/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/bridges/bridge_builtin_features.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/bridges/bridge_builtin_features.c (original)
+++ team/qwell/queue_events/bridges/bridge_builtin_features.c Fri Jun 7 09:37:40 2013
@@ -49,6 +49,7 @@
#include "asterisk/astobj2.h"
#include "asterisk/pbx.h"
#include "asterisk/parking.h"
+#include "asterisk/features_config.h"
/*!
* \brief Helper function that presents dialtone and grabs extension
@@ -59,6 +60,18 @@
static int grab_transfer(struct ast_channel *chan, char *exten, size_t exten_len, const char *context)
{
int res;
+ int digit_timeout;
+ RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, ao2_cleanup);
+
+ ast_channel_lock(chan);
+ xfer_cfg = ast_get_chan_features_xfer_config(chan);
+ if (!xfer_cfg) {
+ ast_log(LOG_ERROR, "Unable to get transfer configuration\n");
+ ast_channel_unlock(chan);
+ return -1;
+ }
+ digit_timeout = xfer_cfg->transferdigittimeout;
+ ast_channel_unlock(chan);
/* Play the simple "transfer" prompt out and wait */
res = ast_stream_and_wait(chan, "pbx-transfer", AST_DIGIT_ANY);
@@ -73,8 +86,7 @@
}
/* Drop to dialtone so they can enter the extension they want to transfer to */
-/* BUGBUG the timeout needs to be configurable from features.conf. */
- res = ast_app_dtget(chan, context, exten, exten_len, exten_len - 1, 3000);
+ res = ast_app_dtget(chan, context, exten, exten_len, exten_len - 1, digit_timeout);
if (res < 0) {
/* Hangup or error */
res = -1;
@@ -122,6 +134,9 @@
return NULL;
}
+ /* Who is transferring the call. */
+ pbx_builtin_setvar_helper(chan, "TRANSFERERNAME", ast_channel_name(caller));
+
/* Before we actually dial out let's inherit appropriate information. */
copy_caller_data(chan, caller);
@@ -263,8 +278,14 @@
struct ast_bridge_features caller_features;
int xfer_failed;
struct ast_bridge_features_attended_transfer *attended_transfer = hook_pvt;
+ const char *complete_sound;
const char *context;
enum atxfer_code transfer_code = ATXFER_INCOMPLETE;
+ const char *atxfer_abort;
+ const char *atxfer_threeway;
+ const char *atxfer_complete;
+ const char *fail_sound;
+ RAII_VAR(struct ast_features_xfer_config *, xfer_cfg, NULL, ao2_cleanup);
ast_bridge_channel_write_hold(bridge_channel, NULL);
@@ -273,6 +294,22 @@
ast_channel_lock(bridge_channel->chan);
context = ast_strdupa(get_transfer_context(bridge_channel->chan,
attended_transfer ? attended_transfer->context : NULL));
+ xfer_cfg = ast_get_chan_features_xfer_config(bridge_channel->chan);
+ if (!xfer_cfg) {
+ ast_log(LOG_ERROR, "Unable to get transfer configuration options\n");
+ ast_channel_unlock(bridge_channel->chan);
+ return 0;
+ }
+ if (attended_transfer) {
+ atxfer_abort = ast_strdupa(S_OR(attended_transfer->abort, xfer_cfg->atxferabort));
+ atxfer_threeway = ast_strdupa(S_OR(attended_transfer->threeway, xfer_cfg->atxferthreeway));
+ atxfer_complete = ast_strdupa(S_OR(attended_transfer->complete, xfer_cfg->atxfercomplete));
+ } else {
+ atxfer_abort = ast_strdupa(xfer_cfg->atxferabort);
+ atxfer_threeway = ast_strdupa(xfer_cfg->atxferthreeway);
+ atxfer_complete = ast_strdupa(xfer_cfg->atxfercomplete);
+ }
+ fail_sound = ast_strdupa(xfer_cfg->xferfailsound);
ast_channel_unlock(bridge_channel->chan);
/* Grab the extension to transfer to */
@@ -288,36 +325,27 @@
if (!peer) {
ast_bridge_merge_inhibit(bridge, -1);
ao2_ref(bridge, -1);
-/* BUGBUG beeperr needs to be configurable from features.conf */
- ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
- ast_bridge_channel_write_unhold(bridge_channel);
- return 0;
- }
-
-/* BUGBUG bridging API features does not support features.conf featuremap */
+ ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
+ ast_bridge_channel_write_unhold(bridge_channel);
+ return 0;
+ }
+
/* BUGBUG bridging API features does not support the features.conf atxfer bounce between C & B channels */
/* Setup a DTMF menu to control the transfer. */
if (ast_bridge_features_init(&caller_features)
|| ast_bridge_hangup_hook(&caller_features,
attended_transfer_complete, &transfer_code, NULL, 0)
- || ast_bridge_dtmf_hook(&caller_features,
- attended_transfer && !ast_strlen_zero(attended_transfer->abort)
- ? attended_transfer->abort : "*1",
+ || ast_bridge_dtmf_hook(&caller_features, atxfer_abort,
attended_transfer_abort, &transfer_code, NULL, 0)
- || ast_bridge_dtmf_hook(&caller_features,
- attended_transfer && !ast_strlen_zero(attended_transfer->complete)
- ? attended_transfer->complete : "*2",
+ || ast_bridge_dtmf_hook(&caller_features, atxfer_complete,
attended_transfer_complete, &transfer_code, NULL, 0)
- || ast_bridge_dtmf_hook(&caller_features,
- attended_transfer && !ast_strlen_zero(attended_transfer->threeway)
- ? attended_transfer->threeway : "*3",
+ || ast_bridge_dtmf_hook(&caller_features, atxfer_threeway,
attended_transfer_threeway, &transfer_code, NULL, 0)) {
ast_bridge_features_cleanup(&caller_features);
ast_hangup(peer);
ast_bridge_merge_inhibit(bridge, -1);
ao2_ref(bridge, -1);
-/* BUGBUG beeperr needs to be configurable from features.conf */
- ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
+ ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
ast_bridge_channel_write_unhold(bridge_channel);
return 0;
}
@@ -330,8 +358,7 @@
ast_hangup(peer);
ast_bridge_merge_inhibit(bridge, -1);
ao2_ref(bridge, -1);
-/* BUGBUG beeperr needs to be configurable from features.conf */
- ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
+ ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
ast_bridge_channel_write_unhold(bridge_channel);
return 0;
}
@@ -345,8 +372,7 @@
ast_hangup(peer);
ast_bridge_merge_inhibit(bridge, -1);
ao2_ref(bridge, -1);
-/* BUGBUG beeperr needs to be configurable from features.conf */
- ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
+ ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
ast_bridge_channel_write_unhold(bridge_channel);
return 0;
}
@@ -385,6 +411,20 @@
ast_bridge_destroy(attended_bridge);
ast_bridge_features_cleanup(&caller_features);
+ /* Is there a courtesy sound to play to the peer? */
+ ast_channel_lock(bridge_channel->chan);
+ complete_sound = pbx_builtin_getvar_helper(bridge_channel->chan,
+ "ATTENDED_TRANSFER_COMPLETE_SOUND");
+ if (!ast_strlen_zero(complete_sound)) {
+ complete_sound = ast_strdupa(complete_sound);
+ } else {
+ complete_sound = NULL;
+ }
+ ast_channel_unlock(bridge_channel->chan);
+ if (complete_sound) {
+ pbx_builtin_setvar_helper(peer, "BRIDGE_PLAY_SOUND", complete_sound);
+ }
+
xfer_failed = -1;
switch (transfer_code) {
case ATXFER_INCOMPLETE:
@@ -415,7 +455,7 @@
if (xfer_failed) {
ast_hangup(peer);
if (!ast_check_hangup_locked(bridge_channel->chan)) {
- ast_stream_and_wait(bridge_channel->chan, "beeperr", AST_DIGIT_NONE);
+ ast_stream_and_wait(bridge_channel->chan, fail_sound, AST_DIGIT_NONE);
}
ast_bridge_channel_write_unhold(bridge_channel);
}
Modified: team/qwell/queue_events/channels/chan_dahdi.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/channels/chan_dahdi.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/channels/chan_dahdi.c (original)
+++ team/qwell/queue_events/channels/chan_dahdi.c Fri Jun 7 09:37:40 2013
@@ -130,6 +130,8 @@
#include "asterisk/paths.h"
#include "asterisk/ccss.h"
#include "asterisk/data.h"
+#include "asterisk/features_config.h"
+#include "asterisk/bridging.h"
/*** DOCUMENTATION
<application name="DAHDISendKeypadFacility" language="en_US">
@@ -7840,55 +7842,49 @@
static void *analog_ss_thread(void *data);
+/*!
+ * \internal
+ * \brief Attempt to transfer 3-way call.
+ *
+ * \param p DAHDI private structure.
+ *
+ * \note On entry these locks are held: real-call, private, 3-way call.
+ * \note On exit these locks are held: real-call, private.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
static int attempt_transfer(struct dahdi_pvt *p)
{
- /* In order to transfer, we need at least one of the channels to
- actually be in a call bridge. We can't conference two applications
- together (but then, why would we want to?) */
- if (ast_bridged_channel(p->subs[SUB_REAL].owner)) {
- /* The three-way person we're about to transfer to could still be in MOH, so
- stop it now */
- ast_queue_unhold(p->subs[SUB_THREEWAY].owner);
- if (ast_channel_state(p->subs[SUB_REAL].owner) == AST_STATE_RINGING) {
- ast_queue_control(p->subs[SUB_REAL].owner, AST_CONTROL_RINGING);
- }
- if (ast_channel_state(p->subs[SUB_THREEWAY].owner) == AST_STATE_RING) {
- tone_zone_play_tone(p->subs[SUB_THREEWAY].dfd, DAHDI_TONE_RINGTONE);
- }
- if (ast_channel_masquerade(p->subs[SUB_THREEWAY].owner, ast_bridged_channel(p->subs[SUB_REAL].owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_channel_name(ast_bridged_channel(p->subs[SUB_REAL].owner)), ast_channel_name(p->subs[SUB_THREEWAY].owner));
- return -1;
- }
- /* Orphan the channel after releasing the lock */
- ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
- unalloc_sub(p, SUB_THREEWAY);
- } else if (ast_bridged_channel(p->subs[SUB_THREEWAY].owner)) {
- ast_queue_unhold(p->subs[SUB_REAL].owner);
- if (ast_channel_state(p->subs[SUB_THREEWAY].owner) == AST_STATE_RINGING) {
- ast_queue_control(p->subs[SUB_THREEWAY].owner, AST_CONTROL_RINGING);
- }
- if (ast_channel_state(p->subs[SUB_REAL].owner) == AST_STATE_RING) {
- tone_zone_play_tone(p->subs[SUB_REAL].dfd, DAHDI_TONE_RINGTONE);
- }
- if (ast_channel_masquerade(p->subs[SUB_REAL].owner, ast_bridged_channel(p->subs[SUB_THREEWAY].owner))) {
- ast_log(LOG_WARNING, "Unable to masquerade %s as %s\n",
- ast_channel_name(ast_bridged_channel(p->subs[SUB_THREEWAY].owner)), ast_channel_name(p->subs[SUB_REAL].owner));
- return -1;
- }
- /* Three-way is now the REAL */
- swap_subs(p, SUB_THREEWAY, SUB_REAL);
- ast_channel_unlock(p->subs[SUB_REAL].owner);
- unalloc_sub(p, SUB_THREEWAY);
- /* Tell the caller not to hangup */
- return 1;
- } else {
- ast_debug(1, "Neither %s nor %s are in a bridge, nothing to transfer\n",
- ast_channel_name(p->subs[SUB_REAL].owner), ast_channel_name(p->subs[SUB_THREEWAY].owner));
- ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
- return -1;
- }
- return 0;
+ struct ast_channel *owner_real;
+ struct ast_channel *owner_3way;
+ enum ast_transfer_result xfer_res;
+ int res = 0;
+
+ owner_real = ast_channel_ref(p->subs[SUB_REAL].owner);
+ owner_3way = ast_channel_ref(p->subs[SUB_THREEWAY].owner);
+
+ ast_verb(3, "TRANSFERRING %s to %s\n",
+ ast_channel_name(owner_3way), ast_channel_name(owner_real));
+
+ ast_channel_unlock(owner_real);
+ ast_channel_unlock(owner_3way);
+ ast_mutex_unlock(&p->lock);
+
+ xfer_res = ast_bridge_transfer_attended(owner_3way, owner_real);
+ if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
+ ast_softhangup(owner_3way, AST_SOFTHANGUP_DEV);
+ res = -1;
+ }
+
+ /* Must leave with these locked. */
+ ast_channel_lock(owner_real);
+ ast_mutex_lock(&p->lock);
+
+ ast_channel_unref(owner_real);
+ ast_channel_unref(owner_3way);
+
+ return res;
}
static int check_for_conference(struct dahdi_pvt *p)
@@ -8398,17 +8394,13 @@
p->owner = NULL;
/* Ring the phone */
dahdi_ring_phone(p);
- } else {
- if ((res = attempt_transfer(p)) < 0) {
- ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
- if (p->subs[SUB_THREEWAY].owner)
- ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
- } else if (res) {
- /* Don't actually hang up at this point */
- if (p->subs[SUB_THREEWAY].owner)
- ast_channel_unlock(p->subs[SUB_THREEWAY].owner);
- break;
- }
+ } else if (!attempt_transfer(p)) {
+ /*
+ * Transfer successful. Don't actually hang up at this point.
+ * Let our channel legs of the calls die off as the transfer
+ * percolates through the core.
+ */
+ break;
}
} else {
ast_channel_softhangup_internal_flag_add(p->subs[SUB_THREEWAY].owner, AST_SOFTHANGUP_DEV);
@@ -10137,15 +10129,15 @@
return 0;
}
-static int canmatch_featurecode(const char *exten)
+static int canmatch_featurecode(const char *pickupexten, const char *exten)
{
int extlen = strlen(exten);
- const char *pickup_ext;
+
if (!extlen) {
return 1;
}
- pickup_ext = ast_pickup_ext();
- if (extlen < strlen(pickup_ext) && !strncmp(pickup_ext, exten, extlen)) {
+
+ if (extlen < strlen(pickupexten) && !strncmp(pickupexten, exten, extlen)) {
return 1;
}
/* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */
@@ -10191,6 +10183,8 @@
int res;
int idx;
struct ast_format tmpfmt;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
ast_mutex_lock(&ss_thread_lock);
ss_thread_count++;
@@ -10210,6 +10204,17 @@
ast_hangup(chan);
goto quit;
}
+
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ pickupexten = ast_strdupa(pickup_cfg->pickupexten);
+ }
+ ast_channel_unlock(chan);
+
if (p->dsp)
ast_dsp_digitreset(p->dsp);
switch (p->sig) {
@@ -10576,7 +10581,7 @@
memset(exten, 0, sizeof(exten));
timeout = firstdigittimeout;
- } else if (!strcmp(exten,ast_pickup_ext())) {
+ } else if (!strcmp(exten, pickupexten)) {
/* Scan all channels and see if there are any
* ringing channels that have call groups
* that equal this channels pickup group
@@ -10708,7 +10713,7 @@
}
} else if (!ast_canmatch_extension(chan, ast_channel_context(chan), exten, 1,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, NULL))
- && !canmatch_featurecode(exten)) {
+ && !canmatch_featurecode(pickupexten, exten)) {
ast_debug(1, "Can't match %s from '%s' in context %s\n", exten,
S_COR(ast_channel_caller(chan)->id.number.valid, ast_channel_caller(chan)->id.number.str, "<Unknown Caller>"),
ast_channel_context(chan));
Modified: team/qwell/queue_events/channels/chan_mgcp.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/channels/chan_mgcp.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/channels/chan_mgcp.c (original)
+++ team/qwell/queue_events/channels/chan_mgcp.c Fri Jun 7 09:37:40 2013
@@ -84,6 +84,7 @@
#include "asterisk/pktccops.h"
#include "asterisk/stasis.h"
#include "asterisk/bridging.h"
+#include "asterisk/features_config.h"
/*
* Define to work around buggy dlink MGCP phone firmware which
@@ -2971,8 +2972,20 @@
int res= 0;
int getforward = 0;
int loop_pause = 100;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
len = strlen(p->dtmf_buf);
+
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ pickupexten = ast_strdupa(pickup_cfg->pickupexten);
+ }
+ ast_channel_unlock(chan);
while (len < AST_MAX_EXTENSION - 1) {
ast_debug(1, "Dtmf buffer '%s' for '%s@%s'\n", p->dtmf_buf, p->name, p->parent->name);
@@ -3065,7 +3078,7 @@
len = 0;
memset(p->dtmf_buf, 0, sizeof(p->dtmf_buf));
timeout = firstdigittimeout;
- } else if (!strcmp(p->dtmf_buf,ast_pickup_ext())) {
+ } else if (!strcmp(p->dtmf_buf, pickupexten)) {
/* Scan all channels and see if any there
* ringing channqels with that have call groups
* that equal this channels pickup group
Modified: team/qwell/queue_events/channels/chan_misdn.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/channels/chan_misdn.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/channels/chan_misdn.c (original)
+++ team/qwell/queue_events/channels/chan_misdn.c Fri Jun 7 09:37:40 2013
@@ -102,6 +102,8 @@
#include "asterisk/causes.h"
#include "asterisk/format.h"
#include "asterisk/format_cap.h"
+#include "asterisk/features_config.h"
+#include "asterisk/bridging.h"
#include "chan_misdn_config.h"
#include "isdn_lib.h"
@@ -8591,10 +8593,9 @@
static int misdn_attempt_transfer(struct chan_list *active_ch, struct chan_list *held_ch)
{
int retval;
- struct ast_channel *target;
- struct ast_channel *transferee;
- struct ast_party_connected_line target_colp;
- struct ast_party_connected_line transferee_colp;
+ enum ast_transfer_result xfer_res;
+ struct ast_channel *to_target;
+ struct ast_channel *to_transferee;
switch (active_ch->state) {
case MISDN_PROCEEDING:
@@ -8607,59 +8608,24 @@
}
ast_channel_lock_both(held_ch->ast, active_ch->ast);
-
- transferee = ast_bridged_channel(held_ch->ast);
- if (!transferee) {
- /*
- * Could not transfer. Held channel is not bridged anymore.
- * Held party probably got tired of waiting and hung up.
- */
- ast_channel_unlock(held_ch->ast);
- ast_channel_unlock(active_ch->ast);
- return -1;
- }
-
- target = active_ch->ast;
+ to_target = active_ch->ast;
+ to_transferee = held_ch->ast;
chan_misdn_log(1, held_ch->hold.port, "TRANSFERRING %s to %s\n",
- ast_channel_name(held_ch->ast), ast_channel_name(target));
-
- ast_party_connected_line_init(&target_colp);
- ast_party_connected_line_copy(&target_colp, ast_channel_connected(target));
-
- /* Reset any earlier private connected id representation */
- ast_party_id_reset(&target_colp.priv);
-
- ast_party_connected_line_init(&transferee_colp);
- ast_party_connected_line_copy(&transferee_colp, ast_channel_connected(held_ch->ast));
-
- /* Reset any earlier private connected id representation*/
- ast_party_id_reset(&transferee_colp.priv);
-
+ ast_channel_name(to_transferee), ast_channel_name(to_target));
held_ch->hold.state = MISDN_HOLD_TRANSFER;
-
- /*
- * Before starting a masquerade, all channel and pvt locks must
- * be unlocked. Any recursive channel locks held before
- * ast_channel_transfer_masquerade() invalidates deadlock
- * avoidance. Since we are unlocking both the pvt and its owner
- * channel it is possible for "target" and "transferee" to be
- * destroyed by their pbx threads. To prevent this we must give
- * "target" and "transferee" a reference before any unlocking
- * takes place.
- */
- ao2_ref(target, +1);
- ao2_ref(transferee, +1);
- ast_channel_unlock(held_ch->ast);
- ast_channel_unlock(active_ch->ast);
-
- /* Setup transfer masquerade. */
- retval = ast_channel_transfer_masquerade(target, &target_colp, 0,
- transferee, &transferee_colp, 1);
-
- ast_party_connected_line_free(&target_colp);
- ast_party_connected_line_free(&transferee_colp);
- ao2_ref(target, -1);
- ao2_ref(transferee, -1);
+ ast_channel_ref(to_target);
+ ast_channel_ref(to_transferee);
+ ast_channel_unlock(to_target);
+ ast_channel_unlock(to_transferee);
+
+ retval = 0;
+ xfer_res = ast_bridge_transfer_attended(to_transferee, to_target);
+ if (xfer_res != AST_BRIDGE_TRANSFER_SUCCESS) {
+ retval = -1;
+ }
+
+ ast_channel_unref(to_target);
+ ast_channel_unref(to_transferee);
return retval;
}
@@ -10071,6 +10037,9 @@
}
if (ch->state == MISDN_WAITING4DIGS) {
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
+
/* Ok, incomplete Setup, waiting till extension exists */
if (ast_strlen_zero(bc->info_dad) && ! ast_strlen_zero(bc->keypad)) {
chan_misdn_log(1, bc->port, " --> using keypad as info\n");
@@ -10080,8 +10049,18 @@
strncat(bc->dialed.number, bc->info_dad, sizeof(bc->dialed.number) - strlen(bc->dialed.number) - 1);
ast_channel_exten_set(ch->ast, bc->dialed.number);
+ ast_channel_lock(ch->ast);
+ pickup_cfg = ast_get_chan_features_pickup_config(ch->ast);
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ pickupexten = ast_strdupa(pickup_cfg->pickupexten);
+ }
+ ast_channel_unlock(ch->ast);
+
/* Check for Pickup Request first */
- if (!strcmp(ast_channel_exten(ch->ast), ast_pickup_ext())) {
+ if (!strcmp(ast_channel_exten(ch->ast), pickupexten)) {
if (ast_pickup_call(ch->ast)) {
hangup_chan(ch, bc);
} else {
@@ -10169,6 +10148,8 @@
int ai;
int im;
int append_msn = 0;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, NULL, ao2_cleanup);
+ const char *pickupexten;
if (ch) {
switch (ch->state) {
@@ -10223,6 +10204,16 @@
ast_log(LOG_ERROR, "cb_events: misdn_new failed!\n");
return RESPONSE_RELEASE_SETUP;
}
+
+ ast_channel_lock(chan);
+ pickup_cfg = ast_get_chan_features_pickup_config(chan);
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ pickupexten = ast_strdupa(pickup_cfg->pickupexten);
+ }
+ ast_channel_unlock(chan);
if ((exceed = add_in_calls(bc->port))) {
char tmp[16];
@@ -10315,7 +10306,7 @@
}
/* Check for Pickup Request first */
- if (!strcmp(ast_channel_exten(chan), ast_pickup_ext())) {
+ if (!strcmp(ast_channel_exten(chan), pickupexten)) {
if (!ch->noautorespond_on_setup) {
/* Sending SETUP_ACK */
misdn_lib_send_event(bc, EVENT_SETUP_ACKNOWLEDGE);
Modified: team/qwell/queue_events/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/qwell/queue_events/channels/chan_sip.c?view=diff&rev=390846&r1=390845&r2=390846
==============================================================================
--- team/qwell/queue_events/channels/chan_sip.c (original)
+++ team/qwell/queue_events/channels/chan_sip.c Fri Jun 7 09:37:40 2013
@@ -296,6 +296,7 @@
#include "asterisk/app.h"
#include "asterisk/bridging.h"
#include "asterisk/stasis_endpoints.h"
+#include "asterisk/features_config.h"
/*** DOCUMENTATION
<application name="SIPDtmfMode" language="en_US">
@@ -17662,6 +17663,16 @@
char tmpf[256] = "", *from = NULL;
struct sip_request *req;
char *decoded_uri;
+ RAII_VAR(struct ast_features_pickup_config *, pickup_cfg, ast_get_chan_features_pickup_config(p->owner), ao2_cleanup);
+ const char *pickupexten;
+
+ if (!pickup_cfg) {
+ ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
+ pickupexten = "";
+ } else {
+ /* Don't need to duplicate since channel is locked for the duration of this function */
+ pickupexten = pickup_cfg->pickupexten;
+ }
req = oreq;
if (!req) {
@@ -17772,7 +17783,7 @@
return SIP_GET_DEST_EXTEN_FOUND;
}
if (ast_exists_extension(NULL, p->context, decoded_uri, 1, S_OR(p->cid_num, from))
- || !strcmp(decoded_uri, ast_pickup_ext())) {
+ || !strcmp(decoded_uri, pickupexten)) {
if (!oreq) {
ast_string_field_set(p, exten, decoded_uri);
}
@@ -17800,7 +17811,7 @@
if (ast_test_flag(&global_flags[1], SIP_PAGE2_ALLOWOVERLAP)
&& (ast_canmatch_extension(NULL, p->context, uri, 1, S_OR(p->cid_num, from))
[... 6641 lines stripped ...]
More information about the asterisk-commits
mailing list