[asterisk-commits] jrose: branch jrose/bridge_projects r385267 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Apr 10 14:34:58 CDT 2013
Author: jrose
Date: Wed Apr 10 14:34:56 2013
New Revision: 385267
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=385267
Log:
Actually act on the various parked_____ options for parking lots
These include: parkedplay + courtesytone, parkedcalltransfers,
parkedcallreparking, parkedcallhangup, parkedcallrecording
Modified:
team/jrose/bridge_projects/include/asterisk/features.h
team/jrose/bridge_projects/main/features.c
team/jrose/bridge_projects/res/parking/parking_applications.c
team/jrose/bridge_projects/res/parking/parking_bridge.c
team/jrose/bridge_projects/res/parking/parking_controller.c
team/jrose/bridge_projects/res/parking/res_parking.h
Modified: team/jrose/bridge_projects/include/asterisk/features.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/features.h?view=diff&rev=385267&r1=385266&r2=385267
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/features.h (original)
+++ team/jrose/bridge_projects/include/asterisk/features.h Wed Apr 10 14:34:56 2013
@@ -26,6 +26,7 @@
#include "asterisk/pbx.h"
#include "asterisk/linkedlists.h"
+#include "asterisk/bridging.h"
#define FEATURE_MAX_LEN 11
#define FEATURE_APP_LEN 64
@@ -181,6 +182,18 @@
*/
void ast_bridge_end_dtmf(struct ast_channel *chan, char digit, struct timeval start, const char *why);
+/*!
+ * \brief Setup bridge channel features.
+ * \since 12.0.0
+ *
+ * \param features Bridge features to setup.
+ * \param flags DTMF features to enable.
+ *
+ * \retval 0 on success.
+ * \retval -1 on failure.
+ */
+int ast_setup_bridge_channel_features(struct ast_bridge_features *features, struct ast_flags *flags);
+
/*! \brief Bridge a call, optionally allowing redirection */
int ast_bridge_call(struct ast_channel *chan, struct ast_channel *peer,struct ast_bridge_config *config);
Modified: team/jrose/bridge_projects/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/features.c?view=diff&rev=385267&r1=385266&r2=385267
==============================================================================
--- team/jrose/bridge_projects/main/features.c (original)
+++ team/jrose/bridge_projects/main/features.c Wed Apr 10 14:34:56 2013
@@ -4136,18 +4136,7 @@
digit, ast_channel_name(chan), why, duration);
}
-/*!
- * \internal
- * \brief Setup bridge channel features.
- * \since 12.0.0
- *
- * \param features Bridge features to setup.
- * \param flags DTMF features to enable.
- *
- * \retval 0 on success.
- * \retval -1 on failure.
- */
-static int setup_bridge_channel_features(struct ast_bridge_features *features, struct ast_flags *flags)
+int ast_setup_bridge_channel_features(struct ast_bridge_features *features, struct ast_flags *flags)
{
struct ast_call_feature *dtmf;
int res = 0;
@@ -4386,8 +4375,8 @@
res = ast_bridge_features_init(&chan_features);
peer_features = ast_bridge_features_new();
if (res || !peer_features
- || setup_bridge_channel_features(peer_features, &config->features_callee)
- || setup_bridge_channel_features(&chan_features, &config->features_caller)) {
+ || ast_setup_bridge_channel_features(peer_features, &config->features_callee)
+ || ast_setup_bridge_channel_features(&chan_features, &config->features_caller)) {
ast_bridge_features_destroy(peer_features);
ast_bridge_features_cleanup(&chan_features);
bridge_failed_peer_goto(chan, peer);
Modified: team/jrose/bridge_projects/res/parking/parking_applications.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_applications.c?view=diff&rev=385267&r1=385266&r2=385267
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_applications.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_applications.c Wed Apr 10 14:34:56 2013
@@ -37,6 +37,7 @@
#include "asterisk/module.h"
#include "asterisk/app.h"
#include "asterisk/say.h"
+#include "asterisk/features.h"
/*** DOCUMENTATION
<application name="Park" language="en_US">
@@ -217,13 +218,14 @@
return 0;
}
-int park_common_setup(struct parking_lot_state **lot, struct ast_bridge **parking_bridge, struct parked_user **pu,
+int park_common_setup(struct parking_lot_state **lot_state, struct ast_bridge **parking_bridge, struct parked_user **pu,
struct ast_channel *parker, struct ast_channel *parkee, const char *app_data)
{
int silence_announcements = 0;
int use_ringing = 0;
int randomize = 0;
int time_limit = -1;
+ int find_lot_mode = 0;
RAII_VAR(char *, comeback_override, NULL, ast_free);
RAII_VAR(char *, lot_name, NULL, ast_free);
@@ -232,22 +234,28 @@
park_app_parse_data(app_data, &silence_announcements, &use_ringing, &randomize, &time_limit, &comeback_override, &lot_name);
}
- /* Now find out which parking lot we want to park it into. */
+ /* Now find out which parking lot_state we want to park it into. */
if (ast_strlen_zero(lot_name)) {
- *lot = channel_find_parking_lot_state(parker);
+ *lot_state = channel_find_parking_lot_state(parker);
} else {
- *lot = parking_lot_state_find_by_name(lot_name);
- }
-
- if (!*lot) {
- ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
+ *lot_state = parking_lot_state_find_by_name(lot_name);
+ find_lot_mode = 1;
+ }
+
+ if (!*lot_state) {
+ if (find_lot_mode) {
+ ast_log(LOG_ERROR, "Could not find requested parking lot: '%s'\n", lot_name);
+ } else {
+ ast_log(LOG_ERROR, "Could not find parking lot specified by channel variable PARKINGLOT "
+ "(or 'default' if that variable does not exist for channel '%s')\n", ast_channel_name(parker));
+ }
ast_stream_and_wait(parker, "pbx-parkingfailed", "");
return -1;
}
- ao2_lock(*lot);
- *parking_bridge = parking_lot_state_get_bridge(*lot);
- ao2_unlock(*lot);
+ ao2_lock(*lot_state);
+ *parking_bridge = parking_lot_state_get_bridge(*lot_state);
+ ao2_unlock(*lot_state);
if (!*parking_bridge) {
ast_log(LOG_ERROR, "Could not acquire holding bridge to park into\n");
@@ -255,7 +263,7 @@
return -1;
}
- *pu = generate_parked_user(*lot, parkee, parker, randomize, time_limit);
+ *pu = generate_parked_user(*lot_state, parkee, parker, randomize, time_limit);
if (!*pu) {
ast_log(LOG_ERROR, "Failed to create parked user for channel %s, can not park.\n", ast_channel_name(parkee));
@@ -269,7 +277,7 @@
}
/* Apply relevant bridge roles and such to the parking channel */
- parking_channel_set_roles(parkee, *lot, use_ringing);
+ parking_channel_set_roles(parkee, *lot_state, use_ringing);
/* If we need to go somewhere special after timeout, set special comeback arguments */
if (!ast_strlen_zero(comeback_override)) {
@@ -281,7 +289,7 @@
int park_app_exec(struct ast_channel *chan, const char *data)
{
- RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
+ RAII_VAR(struct parking_lot_state *, lot_state, NULL, ao2_cleanup);
RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup);
RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
@@ -294,12 +302,18 @@
}
/* Handle all the common aprking setup stuff */
- if (park_common_setup(&lot, &parking_bridge, &pu, chan, chan, data)) {
+ if (park_common_setup(&lot_state, &parking_bridge, &pu, chan, chan, data)) {
+ return -1;
+ }
+
+ /* Initialize bridge features for the channel. */
+ res = ast_bridge_features_init(&chan_features);
+ if (res) {
+ ast_bridge_features_cleanup(&chan_features);
return -1;
}
/* Now for the fun part... park it! */
- ast_bridge_features_init(&chan_features);
ast_bridge_join(parking_bridge, chan, NULL, &chan_features, NULL, 0);
/*
@@ -322,14 +336,13 @@
int parked_call_app_exec(struct ast_channel *chan, const char *data)
{
- RAII_VAR(struct parking_lot_state *, lot, NULL, ao2_cleanup);
+ RAII_VAR(struct parking_lot_state *, lot_state, NULL, ao2_cleanup);
RAII_VAR(struct parked_user *, pu, NULL, ao2_cleanup); /* Parked user being retrieved */
RAII_VAR(struct ast_bridge *, parking_bridge, NULL, ao2_cleanup);
+ struct ast_bridge *retrieval_bridge;
+ int res;
int target_space = -1;
-
- struct ast_bridge *bridge;
-
- //struct ast_bridge_features chan_features;
+ struct ast_bridge_features chan_features;
char *parse;
AST_DECLARE_APP_ARGS(args,
@@ -341,13 +354,18 @@
parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
+ /* Answer the channel if needed */
+ if (ast_channel_state(chan) != AST_STATE_UP) {
+ ast_answer(chan);
+ }
+
+ /* Figure out which parking lot we should be retrieving from and if it exists. */
if (ast_strlen_zero(args.lot_name)) {
- lot = channel_find_parking_lot_state(chan);
+ lot_state = channel_find_parking_lot_state(chan);
} else {
- lot = parking_lot_state_find_by_name(args.lot_name);
- }
-
- if (!lot) {
+ lot_state = parking_lot_state_find_by_name(args.lot_name);
+ }
+ if (!lot_state) {
ast_log(LOG_ERROR, "Could not find the requested parking lot\n");
ast_stream_and_wait(chan, "pbx-invalidpark", "");
return -1;
@@ -361,34 +379,46 @@
}
}
- bridge = ast_bridge_base_new(
+ /* Attempt to get the parked user from the parking lot */
+ pu = parking_lot_state_retrieve_parked_user(lot_state, target_space);
+ if (!pu) {
+ ast_stream_and_wait(chan, "pbx-invalidpark", "");
+ return -1;
+ }
+
+ /* Create bridge */
+ retrieval_bridge = ast_bridge_base_new(
AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_MULTIMIX,
AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_SMART);
-
- if (!bridge) {
- return -1;
- }
-
- /* answer the channel if needed */
- if (ast_channel_state(chan) != AST_STATE_UP) {
- ast_answer(chan);
- }
-
- pu = parking_lot_state_retrieve_parked_user(lot, target_space);
-
- if (!pu) {
- ast_stream_and_wait(chan, "pbx-invalidpark", "");
+ if (!retrieval_bridge) {
return -1;
}
/* Move the parkee into the new bridge */
- if (ast_bridge_move(lot->parking_bridge, bridge, pu->chan)) {
- ast_bridge_destroy(bridge);
- return -1;
+ if (ast_bridge_move(lot_state->parking_bridge, retrieval_bridge, pu->chan)) {
+ ast_bridge_destroy(retrieval_bridge);
+ return -1;
+ }
+
+ /* Initialize our bridge features */
+ res = ast_bridge_features_init(&chan_features);
+ if (res) {
+ ast_bridge_features_cleanup(&chan_features);
+ return -1;
+ }
+
+ /* Set the features */
+ parked_call_retrieve_enable_features(&chan_features, lot_state, AST_FEATURE_FLAG_BYCALLER);
+
+ /* If the parkedplay option is set for the caller to hear, play that tone now. */
+ if (lot_state->parkedplay & AST_FEATURE_FLAG_BYCALLER) {
+ ast_stream_and_wait(chan, lot_state->courtesytone, NULL);
}
/* Now we should try to join the new bridge ourselves... */
- ast_bridge_join(bridge, chan, NULL, /* XXX features go here! */ NULL, NULL, 1);
+ ast_bridge_join(retrieval_bridge, chan, NULL, &chan_features, NULL, 1);
+
+ ast_bridge_features_cleanup(&chan_features);
return 0;
}
Modified: team/jrose/bridge_projects/res/parking/parking_bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_bridge.c?view=diff&rev=385267&r1=385266&r2=385267
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_bridge.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_bridge.c Wed Apr 10 14:34:56 2013
@@ -27,6 +27,7 @@
#include "asterisk/logger.h"
#include "res_parking.h"
#include "asterisk/astobj2.h"
+#include "asterisk/features.h"
struct ast_bridge_parking
{
@@ -124,10 +125,8 @@
}
/* Apply parking duration limits */
- if (bridge_channel->features) {
- reset_parked_time(pu);
- parking_set_duration(bridge_channel->features, pu);
- }
+ reset_parked_time(pu);
+ parking_set_duration(bridge_channel->features, pu);
/* Set this to the bridge pvt so that we don't have to refind the parked user associated with this bridge channel again. */
bridge_channel->bridge_pvt = pu;
@@ -154,6 +153,7 @@
static void bridge_parking_pull(struct ast_bridge_parking *self, struct ast_bridge_channel *bridge_channel)
{
struct parked_user *pu = bridge_channel->bridge_pvt;
+ struct ast_bridge_features *features = bridge_channel->features;
ast_bridge_base_v_table.pull(&self->base, bridge_channel);
/* This should only happen if the exiting channel was swapped out */
@@ -186,8 +186,14 @@
return;
case PARK_ANSWERED:
/* If answered or forced, the channel should be pulled from the bridge as part of that process and unlinked from
- * the parking lot afterwards. */
+ * the parking lot afterwards. We do need to apply bridge features though and play the courtesy tone if set. */
publish_parked_call(pu, PARKED_CALL_UNPARKED);
+ parked_call_retrieve_enable_features(features, pu->lot_state, AST_FEATURE_FLAG_BYCALLEE);
+
+ if (pu->lot_state->parkedplay & AST_FEATURE_FLAG_BYCALLEE) {
+ ast_bridge_channel_queue_playfile(bridge_channel, NULL, pu->lot_state->courtesytone, NULL);
+ }
+
return;
case PARK_TIMEOUT:
/* Timeout is similar to abandon because it simply sets the bridge state to end and doesn't
Modified: team/jrose/bridge_projects/res/parking/parking_controller.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/parking_controller.c?view=diff&rev=385267&r1=385266&r2=385267
==============================================================================
--- team/jrose/bridge_projects/res/parking/parking_controller.c (original)
+++ team/jrose/bridge_projects/res/parking/parking_controller.c Wed Apr 10 14:34:56 2013
@@ -30,6 +30,7 @@
#include "asterisk/utils.h"
#include "asterisk/manager.h"
#include "asterisk/test.h"
+#include "asterisk/features.h"
struct ast_bridge *parking_lot_state_get_bridge(struct parking_lot_state *state)
{
@@ -187,6 +188,37 @@
/* Bump the ref count by 1 since the RAII_VAR will eat the reference otherwise */
ao2_ref(user, +1);
return user;
+}
+
+void parked_call_retrieve_enable_features(struct ast_bridge_features *features, struct parking_lot_state *lot_state, int recipient_mode)
+{
+ struct ast_flags feature_flags = { 0 };
+
+ if (lot_state->parkedcalltransfers & recipient_mode) {
+ ast_set_flag(&feature_flags, AST_FEATURE_REDIRECT);
+ ast_set_flag(&feature_flags, AST_FEATURE_ATXFER);
+ }
+
+ if (lot_state->parkedcallreparking & recipient_mode) {
+ ast_set_flag(&feature_flags, AST_FEATURE_PARKCALL);
+ }
+
+ if (lot_state->parkedcallhangup & recipient_mode) {
+ ast_set_flag(&feature_flags, AST_FEATURE_DISCONNECT);
+ }
+
+ if (lot_state->parkedcallrecording & recipient_mode) {
+ ast_set_flag(&feature_flags, AST_FEATURE_AUTOMON);
+ ast_set_flag(&feature_flags, AST_FEATURE_AUTOMIXMON);
+ }
+
+ if (ast_setup_bridge_channel_features(features, &feature_flags)) {
+ /* Some features were applied that weren't explicitly mapped. We can safely ignore this. */
+ ast_debug(10, "One or more features could not be applied because they weren't mapped. "
+ "Check debug output for ast_bridge_features_enable in bridging.c to see which ones.\n");
+ }
+
+ return;
}
static void destroy_parked_user(void *obj)
Modified: team/jrose/bridge_projects/res/parking/res_parking.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/res/parking/res_parking.h?view=diff&rev=385267&r1=385266&r2=385267
==============================================================================
--- team/jrose/bridge_projects/res/parking/res_parking.h (original)
+++ team/jrose/bridge_projects/res/parking/res_parking.h Wed Apr 10 14:34:56 2013
@@ -209,6 +209,17 @@
/*!
* \since 12
+ * \brief Apply features based on the parking lot feature options
+ *
+ * \param features Which feature set is being modified
+ * \param lot_state parking lot state which establishes the features used
+ * \param recipient_mode AST_FEATURE_FLAG_BYCALLER if the user is the retriever
+ * AST_FEATURE_FLAG_BYCALLEE if the user is the parkee
+ */
+void parked_call_retrieve_enable_features(struct ast_bridge_features *features, struct parking_lot_state *lot_state, int recipient_mode);
+
+/*!
+ * \since 12
* \brief Set necessary bridge roles on a channel that is about to enter a parking lot
*
* \param chan Entering channel
More information about the asterisk-commits
mailing list