[asterisk-commits] jrose: branch jrose/bridge_projects r381363 - in /team/jrose/bridge_projects:...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Feb 13 15:32:28 CST 2013
Author: jrose
Date: Wed Feb 13 15:32:25 2013
New Revision: 381363
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=381363
Log:
bridginging: interval hooks forever!
Addresses Richard's comments from https://reviewboard.asterisk.org/r/2328/
Also makes limits feature pluggable through bridge_builting_interval_features
Added:
team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c (with props)
Modified:
team/jrose/bridge_projects/apps/app_dial.c
team/jrose/bridge_projects/include/asterisk/bridging_features.h
team/jrose/bridge_projects/main/bridging.c
team/jrose/bridge_projects/main/features.c
Modified: team/jrose/bridge_projects/apps/app_dial.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/apps/app_dial.c?view=diff&rev=381363&r1=381362&r2=381363
==============================================================================
--- team/jrose/bridge_projects/apps/app_dial.c (original)
+++ team/jrose/bridge_projects/apps/app_dial.c Wed Feb 13 15:32:25 2013
@@ -267,7 +267,7 @@
<variable name="LIMIT_CONNECT_FILE">
<value name="filename"/>
<para>If specified, <replaceable>filename</replaceable> specifies the sound prompt to play when the call begins.
- If not set, the time remaining will be announced.</para>
+ If set to 'timeleft', the time remaining will be announced.</para>
</variable>
<variable name="LIMIT_WARNING_FILE">
<value name="filename"/>
Added: team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c?view=auto&rev=381363
==============================================================================
--- team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c (added)
+++ team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c Wed Feb 13 15:32:25 2013
@@ -1,0 +1,227 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2013, Digium, Inc.
+ *
+ * Jonathan Rose <jrose at digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*! \file
+ *
+ * \brief Built in bridging interval features
+ *
+ * \author Jonathan Rose <jrose at digium.com>
+ *
+ * \ingroup bridges
+ */
+
+/*** MODULEINFO
+ <support_level>core</support_level>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$REVISION: 381278 $")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+
+#include "asterisk/module.h"
+#include "asterisk/channel.h"
+#include "asterisk/bridging.h"
+#include "asterisk/file.h"
+#include "asterisk/app.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/test.h"
+
+#include "asterisk/say.h"
+#include "asterisk/stringfields.h"
+#include "asterisk/musiconhold.h"
+
+static int bridge_features_duration_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
+{
+ struct ast_bridge_features_limits *limits = hook_pvt;
+
+ if (!ast_strlen_zero(limits->duration_sound)) {
+ ast_stream_and_wait(bridge_channel->chan, limits->duration_sound, AST_DIGIT_NONE);
+ }
+
+ ao2_lock(bridge_channel);
+ switch (bridge_channel->state) {
+ case AST_BRIDGE_CHANNEL_STATE_WAIT:
+ ao2_unlock(bridge_channel);
+ ast_bridge_change_state(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
+ break;
+ default:
+ ao2_unlock(bridge_channel);
+ break;
+ }
+
+ ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s", ast_channel_name(bridge_channel->chan));
+
+ return -1;
+}
+
+static void limits_interval_playback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_bridge_features_limits *limits, const char *file)
+{
+ if (!strcasecmp(file, "timeleft")) {
+
+ unsigned int remaining = ast_tvdiff_ms(limits->quitting_time, ast_tvnow()) / 1000;
+
+ if (remaining > 0) {
+ unsigned int min;
+ unsigned int sec;
+
+ if ((remaining / 60) > 1) {
+ min = remaining / 60;
+ sec = remaining % 60;
+ } else {
+ min = 0;
+ sec = remaining;
+ }
+
+ ast_stream_and_wait(bridge_channel->chan, "vm-youhave", AST_DIGIT_NONE);
+ if (min) {
+ ast_say_number(bridge_channel->chan, min, AST_DIGIT_NONE,
+ ast_channel_language(bridge_channel->chan), NULL);
+ ast_stream_and_wait(bridge_channel->chan, "queue-minutes", AST_DIGIT_NONE);
+ }
+ if (sec) {
+ ast_say_number(bridge_channel->chan, sec, AST_DIGIT_NONE,
+ ast_channel_language(bridge_channel->chan), NULL);
+ ast_stream_and_wait(bridge_channel->chan, "queue-seconds", AST_DIGIT_NONE);
+ }
+
+ /* It may be necessary to resume music on hold after we finish playing the announcment. */
+ if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
+ ast_moh_start(bridge_channel->chan, NULL, NULL);
+ }
+ }
+ } else {
+ ast_stream_and_wait(bridge_channel->chan, file, AST_DIGIT_NONE);
+
+ /* It may be necessary to resume music on hold after we play the sound file. */
+ if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
+ ast_moh_start(bridge_channel->chan, NULL, NULL);
+ }
+ }
+}
+
+static int bridge_features_connect_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
+{
+ struct ast_bridge_features_limits *limits = hook_pvt;
+
+ if ((bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT)) {
+ return -1;
+ }
+
+ limits_interval_playback(bridge, bridge_channel, limits, limits->connect_sound);
+ return -1;
+}
+
+static int bridge_features_warning_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
+{
+ struct ast_bridge_features_limits *limits = hook_pvt;
+
+ if ((bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT)) {
+ /* If we aren't in the wait state, something more important than this warning is happening and we should skip it. */
+ limits_interval_playback(bridge, bridge_channel, limits, limits->warning_sound);
+ }
+
+ if (limits->frequency) {
+ ast_bridge_features_interval_update(bridge_channel, limits->frequency);
+ }
+
+ return !limits->frequency ? -1 : 0;
+}
+
+static void copy_bridge_features_limits(struct ast_bridge_features_limits *dst, struct ast_bridge_features_limits *src)
+{
+ dst->duration = src->duration;
+ dst->warning = src->warning;
+ dst->frequency = src->frequency;
+ dst->quitting_time = src->quitting_time;
+
+ ast_string_field_set(dst, duration_sound, src->duration_sound);
+ ast_string_field_set(dst, warning_sound, src->warning_sound);
+ ast_string_field_set(dst, connect_sound, src->connect_sound);
+}
+
+static int bridge_builtin_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits)
+{
+ struct ast_bridge_features_limits *feature_limits;
+
+ if (!limits->duration) {
+ return -1;
+ }
+
+ if (features->limits) {
+ ast_log(LOG_ERROR, "Tried to apply limits to a feature set that already has limits.\n");
+ return -1;
+ }
+
+ feature_limits = ast_malloc(sizeof(*feature_limits));
+ if (!feature_limits) {
+ return -1;
+ }
+
+ if (ast_bridge_features_limits_construct(feature_limits)) {
+ return -1;
+ }
+
+ copy_bridge_features_limits(feature_limits, limits);
+ features->limits = feature_limits;
+
+ if (ast_bridge_features_interval_hook(features, feature_limits->duration,
+ bridge_features_duration_callback, feature_limits, NULL)) {
+ ast_log(LOG_ERROR, "Failed to schedule the duration limiter to the bridge channel.\n");
+ return -1;
+ }
+
+ feature_limits->quitting_time = ast_tvadd(ast_tvnow(), ast_samp2tv(feature_limits->duration, 1000));
+
+ if (!ast_strlen_zero(feature_limits->connect_sound)) {
+ if (ast_bridge_features_interval_hook(features, 1, bridge_features_connect_callback, feature_limits, NULL)) {
+ ast_log(LOG_WARNING, "Failed to schedule connect sound to the bridge channel.\n");
+ }
+ }
+
+ if (feature_limits->warning && feature_limits->warning < feature_limits->duration) {
+ if (ast_bridge_features_interval_hook(features, feature_limits->duration - feature_limits->warning,
+ bridge_features_warning_callback,
+ feature_limits, NULL)) {
+ ast_log(LOG_WARNING, "Failed to schedule warning sound playback to the bridge channel.\n");
+ }
+ }
+
+ return 0;
+}
+
+static int unload_module(void)
+{
+ return 0;
+}
+
+static int load_module(void)
+{
+ ast_bridge_interval_register(AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, bridge_builtin_set_limits);
+
+ /* Bump up our reference count so we can't be unloaded. */
+ ast_module_ref(ast_module_info->self);
+
+ return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Builting bridging interval features");
Propchange: team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c
------------------------------------------------------------------------------
svn:keywords = "Author Date Id Rev URL"
Propchange: team/jrose/bridge_projects/bridges/bridge_builtin_interval_features.c
------------------------------------------------------------------------------
svn:mime-type = text/plain
Modified: team/jrose/bridge_projects/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/include/asterisk/bridging_features.h?view=diff&rev=381363&r1=381362&r2=381363
==============================================================================
--- team/jrose/bridge_projects/include/asterisk/bridging_features.h (original)
+++ team/jrose/bridge_projects/include/asterisk/bridging_features.h Wed Feb 13 15:32:25 2013
@@ -79,6 +79,14 @@
AST_BRIDGE_BUILTIN_END
};
+enum ast_bridge_builtin_interval {
+ /*! Apply Call Duration Limits */
+ AST_BRIDGE_BUILTIN_INTERVAL_LIMITS,
+
+ /*! End terminator for list of built in interval features. Must remain last. */
+ AST_BRIDGE_BUILTIN_INTERVAL_END
+};
+
struct ast_bridge;
struct ast_bridge_channel;
@@ -269,6 +277,44 @@
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature);
/*!
+ * \brief Register a handler for a built in interval feature
+ *
+ * \param interval The interval feature that the handler will be responsible for
+ * \param callback the Callback function that will handle it
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * Example usage:
+ *
+ * \code
+ * ast_bridge_interval_register(AST_BRIDGE_BUILTIN_INTERVAL_LIMITS, bridge_builtin_set_limits);
+ * \endcode
+ *
+ * This registers the function bridge_builtin_set_limits as the function responsible for the built in
+ * duration limit feature.
+ */
+int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, void *callback);
+
+/*!
+ * \brief Unregisters a handler for a built in interval feature
+ *
+ * \param interval the interval feature to unregister
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * Example usage:
+ *
+ * \code
+ * ast_bridge_interval_unregister(AST_BRIDGE_BULTIN_INTERVAL_LIMITS)
+ * /endcode
+ *
+ * This unregisters the function that is handling the built in duration limit feature.
+ */
+int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval);
+
+/*!
* \brief Attach a custom hook to a bridge features structure
*
* \param features Bridge features structure
@@ -322,7 +368,6 @@
*/
int ast_bridge_features_interval_hook(struct ast_bridge_features *features,
unsigned int interval,
- unsigned int strict,
ast_bridge_features_hook_callback callback,
void *hook_pvt,
ast_bridge_features_hook_pvt_destructor destructor);
@@ -390,6 +435,26 @@
int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config);
/*!
+ * \brief Constructor function for ast_bridge_features_limits
+ *
+ * \param limits pointer to a ast_bridge_features_limits struct that has been allocted, but not initialized
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits);
+
+/*!
+ * \brief Destructor function for ast_bridge_features_limits
+ *
+ * \param limits pointer to an ast_bridge_features_limits struct that needs to be destroyed
+ *
+ * This function does not free memory allocated to the ast_bridge_features_limits struct, it only frees elements within the struct.
+ * You must still call ast_free on the the struct if you allocated it with malloc.
+ */
+void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits);
+
+/*!
* \brief Limit the amount of time a channel may stay in the bridge and optionally play warning messages as time runs out
*
* \param features Bridge features structure
@@ -402,9 +467,11 @@
*
* \code
* struct ast_bridge_features features;
- * struct ast_bridge_features_limits limits = { .duration = 10000, };
+ * struct ast_bridge_features_limits limits;
* ast_bridge_features_init(&features);
+ * ast_bridge_features_limits_construct(&limits);
* ast_bridge_features_set_limits(&features, &limits);
+ * ast_bridge_features_limits_destroy(&limits);
* \endcode
*
* This sets the maximum time the channel can be in the bridge to 10 seconds and does not play any warnings.
Modified: team/jrose/bridge_projects/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/jrose/bridge_projects/main/bridging.c?view=diff&rev=381363&r1=381362&r2=381363
==============================================================================
--- team/jrose/bridge_projects/main/bridging.c (original)
+++ team/jrose/bridge_projects/main/bridging.c Wed Feb 13 15:32:25 2013
@@ -68,6 +68,9 @@
/*! Function handlers for the built in features */
static void *builtin_features_handlers[AST_BRIDGE_BUILTIN_END];
+
+/*! Function handlers for built in interval features */
+static void *builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END];
int __ast_bridge_technology_register(struct ast_bridge_technology *technology, struct ast_module *module)
{
@@ -1900,6 +1903,31 @@
return 0;
}
+int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, void *callback)
+{
+ if (ARRAY_LEN(builtin_interval_handlers) <= interval
+ || builtin_interval_handlers[interval]) {
+ return -1;
+ }
+
+ builtin_interval_handlers[interval] = callback;
+
+ return 0;
+}
+
+int ast_bridge_interval_unregister(enum ast_bridge_builtin_interval interval)
+{
+ if (ARRAY_LEN(builtin_interval_handlers) <= interval
+ || !builtin_interval_handlers[interval]) {
+ return -1;
+ }
+
+ builtin_interval_handlers[interval] = NULL;
+
+ return 0;
+
+}
+
int ast_bridge_features_hook(struct ast_bridge_features *features,
const char *dtmf,
ast_bridge_features_hook_callback callback,
@@ -1938,7 +1966,6 @@
int ast_bridge_features_interval_hook(struct ast_bridge_features *features,
unsigned int interval,
- unsigned int strict,
ast_bridge_features_hook_callback callback,
void *hook_pvt,
ast_bridge_features_hook_pvt_destructor destructor)
@@ -2014,162 +2041,31 @@
return ast_bridge_features_hook(features, dtmf, builtin_features_handlers[feature], config, NULL);
}
-static int bridge_features_duration_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
-{
- struct ast_bridge_features_limits *limits = hook_pvt;
-
- if (!ast_strlen_zero(limits->duration_sound)) {
- ast_stream_and_wait(bridge_channel->chan, limits->duration_sound, AST_DIGIT_NONE);
- }
-
- ao2_lock(bridge_channel);
- switch (bridge_channel->state) {
- case AST_BRIDGE_CHANNEL_STATE_WAIT:
- ast_bridge_change_state_nolock(bridge_channel, AST_BRIDGE_CHANNEL_STATE_END);
- break;
- default:
- break;
- }
-
- ast_test_suite_event_notify("BRIDGE_TIMELIMIT", "Channel1: %s", ast_channel_name(bridge_channel->chan));
-
- ao2_unlock(bridge_channel);
-
+int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
+{
+ if (ast_string_field_init(limits, 256)) {
+ ast_free(limits);
+ return -1;
+ }
+
+ return 0;
+}
+
+void ast_bridge_features_limits_destroy(struct ast_bridge_features_limits *limits)
+{
+ ast_string_field_free_memory(limits);
+}
+
+int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits)
+{
+ if (builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_LIMITS]) {
+ int (*bridge_features_set_limits_callback)(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits);
+ bridge_features_set_limits_callback = builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_LIMITS];
+ return bridge_features_set_limits_callback(features, limits);
+ }
+
+ ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
return -1;
-}
-
-static void limits_interval_playback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, struct ast_bridge_features_limits *limits, const char *file)
-{
- if (!strcasecmp(file, "timeleft")) {
-
- unsigned int remaining = 0;
- remaining = ast_tvdiff_ms(limits->quitting_time, ast_tvnow()) / 1000;
-
- if (remaining > 0) {
- unsigned int min;
- unsigned int sec;
-
- if ((remaining / 60) > 1) {
- min = remaining / 60;
- sec = remaining % 60;
- } else {
- min = 0;
- sec = remaining;
- }
-
- ast_stream_and_wait(bridge_channel->chan, "vm-youhave", AST_DIGIT_NONE);
- if (min) {
- ast_say_number(bridge_channel->chan, min, AST_DIGIT_NONE,
- ast_channel_language(bridge_channel->chan), NULL);
- ast_stream_and_wait(bridge_channel->chan, "queue-minutes", AST_DIGIT_NONE);
- }
- if (sec) {
- ast_say_number(bridge_channel->chan, sec, AST_DIGIT_NONE,
- ast_channel_language(bridge_channel->chan), NULL);
- ast_stream_and_wait(bridge_channel->chan, "queue-seconds", AST_DIGIT_NONE);
- }
-
- /* It may be necessary to resume music on hold after we finish playing the announcment. */
- if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
- ast_moh_start(bridge_channel->chan, NULL, NULL);
- }
- }
-
- } else {
- if (bridge_channel->state != AST_BRIDGE_CHANNEL_STATE_WAIT) {
- ast_debug(1, "Skipping warning, the channel state is already set to leave bridge.\n");
- return;
- }
-
- ast_stream_and_wait(bridge_channel->chan, file, AST_DIGIT_NONE);
-
- /* It may be necessary to resume music on hold after we play the sound file. */
- if (ast_test_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_MOH)) {
- ast_moh_start(bridge_channel->chan, NULL, NULL);
- }
-
- }
-}
-
-static int bridge_features_connect_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
-{
- struct ast_bridge_features_limits *limits = hook_pvt;
- limits_interval_playback(bridge, bridge_channel, limits, limits->connect_sound);
- return -1;
-}
-
-static int bridge_features_warning_callback(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, void *hook_pvt)
-{
- struct ast_bridge_features_limits *limits = hook_pvt;
-
- if ((bridge_channel->state == AST_BRIDGE_CHANNEL_STATE_WAIT)) {
- /* If we aren't in the wait state, something more important than this warning is happening and we should skip it. */
- limits_interval_playback(bridge, bridge_channel, limits, limits->warning_sound);
- }
-
- if (limits->frequency) {
- ast_bridge_features_interval_update(bridge_channel, limits->frequency);
- }
-
- return !limits->frequency ? -1 : 0;
-}
-
-static void copy_bridge_features_limits(struct ast_bridge_features_limits *dst, struct ast_bridge_features_limits *src)
-{
- dst->duration = src->duration;
- dst->warning = src->warning;
- dst->frequency = src->frequency;
- dst->quitting_time = src->quitting_time;
-
- ast_string_field_set(dst, duration_sound, src->duration_sound);
- ast_string_field_set(dst, warning_sound, src->warning_sound);
- ast_string_field_set(dst, connect_sound, src->connect_sound);
-}
-
-/* XXX This should probably be changed to include failure conditions so that the consumers can know if it failed. */
-int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits)
-{
- struct ast_bridge_features_limits *feature_limits;
-
- if (!limits->duration) {
- return -1;
- }
-
- if (features->limits) {
- ast_log(LOG_ERROR, "Tried to apply limits to a feature set that already has limits.\n");
- return -1;
- }
-
- feature_limits = ast_malloc(sizeof(*feature_limits));
-
- if (!feature_limits) {
- return -1;
- }
-
- if (ast_string_field_init(feature_limits, 256)) {
- ast_free(feature_limits);
- return -1;
- }
-
- copy_bridge_features_limits(feature_limits, limits);
- features->limits = feature_limits;
-
- ast_bridge_features_interval_hook(features, feature_limits->duration, 0,
- bridge_features_duration_callback, feature_limits, NULL);
-
- feature_limits->quitting_time = ast_tvadd(ast_tvnow(), ast_samp2tv(feature_limits->duration, 1000));
-
- if (!ast_strlen_zero(feature_limits->connect_sound)) {
- ast_bridge_features_interval_hook(features, 1, 1, bridge_features_connect_callback, feature_limits, NULL);
- }
-
- if (feature_limits->warning && feature_limits->warning < feature_limits->duration) {
- ast_bridge_features_interval_hook(features, feature_limits->duration - feature_limits->warning, 1,
- bridge_features_warning_callback,
- feature_limits, NULL);
- }
-
- return 0;
}
void ast_bridge_features_set_flag(struct ast_bridge_features *features, enum ast_bridge_feature_flags flag)
@@ -2182,17 +2078,14 @@
{
struct ast_bridge_features_hook *hook_a = a;
struct ast_bridge_features_hook *hook_b = b;
- int tvcmp_res = ast_tvcmp(hook_b->interval_trip_time, hook_a->interval_trip_time);
-
- if (tvcmp_res) {
- return tvcmp_res;
- }
-
- if (hook_b->seqno < hook_a->seqno) {
- return -1;
- }
-
- return 1;
+ int cmp = ast_tvcmp(hook_b->interval_trip_time, hook_a->interval_trip_time);
+
+ if (cmp) {
+ return cmp;
+ }
+
+ cmp = hook_b->seqno - hook_a->seqno;
+ return cmp;
}
int ast_bridge_features_init(struct ast_bridge_features *features)
@@ -2232,7 +2125,7 @@
/* If the features contains a limits pvt, destroy that as well. */
if (features->limits) {
- ast_string_field_free_memory(features->limits);
+ ast_bridge_features_limits_destroy(features->limits);
ast_free(features->limits);
features->limits = NULL;
}
@@ -2249,7 +2142,6 @@
features->talker_destructor_cb(features->talker_pvt_data);
features->talker_pvt_data = NULL;
}
-
}
struct ast_bridge_features *ast_bridge_features_new(void)
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=381363&r1=381362&r2=381363
==============================================================================
--- team/jrose/bridge_projects/main/features.c (original)
+++ team/jrose/bridge_projects/main/features.c Wed Feb 13 15:32:25 2013
@@ -4377,8 +4377,6 @@
if (config->start_sound) {
ast_string_field_set(limits, connect_sound, config->start_sound);
- } else {
- ast_string_field_set(limits, connect_sound, "timeleft");
}
limits->frequency = config->warning_freq;
@@ -4483,10 +4481,6 @@
struct ast_bridge *bridge;
struct ast_bridge_features chan_features;
struct ast_bridge_features *peer_features;
-
- /* These are used for the 'L' option of Dial/Bridge */
- struct ast_bridge_features_limits call_duration_limits_chan = {0};
- struct ast_bridge_features_limits call_duration_limits_peer = {0};
pbx_builtin_setvar_helper(chan, "BRIDGEPEER", ast_channel_name(peer));
pbx_builtin_setvar_helper(peer, "BRIDGEPEER", ast_channel_name(chan));
@@ -4636,7 +4630,6 @@
/* Setup DTMF features. */
ast_bridge_features_init(&chan_features);
-
peer_features = ast_bridge_features_new();
if (!peer_features
|| setup_bridge_channel_features(peer_features, &config->features_callee)
@@ -4651,8 +4644,12 @@
}
if (config->timelimit) {
- if (ast_string_field_init(&call_duration_limits_chan, 256)) {
- ast_log(LOG_ERROR, "Could not allocate caller duration limits string field. Bridge canceled.\n");
+ struct ast_bridge_features_limits call_duration_limits_chan = {0};
+ struct ast_bridge_features_limits call_duration_limits_peer = {0};
+ int abandon_call = 0; /* Flag raised if set limits fails sow e can abandon the call. */
+
+ if (ast_bridge_features_limits_construct(&call_duration_limits_chan)) {
+ ast_log(LOG_ERROR, "Could not construct caller duration limits. Bridge canceled.\n");
ast_bridge_features_destroy(peer_features);
ast_bridge_features_cleanup(&chan_features);
@@ -4662,9 +4659,9 @@
return -1;
}
- if (ast_string_field_init(&call_duration_limits_peer, 256)) {
- ast_log(LOG_ERROR, "Could not allocate callee duration limits string field. Bridge canceled.\n");
- ast_string_field_free_memory(&call_duration_limits_chan);
+ if (ast_bridge_features_limits_construct(&call_duration_limits_peer)) {
+ ast_log(LOG_ERROR, "Could not construct callee duration limits. Bridge canceled.\n");
+ ast_bridge_features_limits_destroy(&call_duration_limits_chan);
ast_bridge_features_destroy(peer_features);
ast_bridge_features_cleanup(&chan_features);
@@ -4675,12 +4672,27 @@
}
bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
- ast_bridge_features_set_limits(&chan_features, &call_duration_limits_chan);
- ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer);
+
+ if (ast_bridge_features_set_limits(&chan_features, &call_duration_limits_chan)) {
+ abandon_call = 1;
+ }
+ if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer)) {
+ abandon_call = 1;
+ }
/* At this point we are done with the limits structs since they have been copied to the individual feature sets. */
- ast_string_field_free_memory(&call_duration_limits_chan);
- ast_string_field_free_memory(&call_duration_limits_peer);
+ ast_bridge_features_limits_destroy(&call_duration_limits_chan);
+ ast_bridge_features_limits_destroy(&call_duration_limits_peer);
+
+ if (abandon_call) {
+ ast_log(LOG_ERROR, "Could not set duration limits on one or more sides of the call. Bridge canceled.\n");
+ ast_bridge_features_destroy(peer_features);
+ ast_bridge_features_cleanup(&chan_features);
+ if (bridge_cdr) {
+ ast_cdr_discard(bridge_cdr);
+ }
+ return -1;
+ }
}
ast_cel_report_event(chan, AST_CEL_BRIDGE_START, NULL, NULL, peer);/* BUGBUG expected to go away. */
More information about the asterisk-commits
mailing list