diff options
author | Richard Mudgett <rmudgett@digium.com> | 2013-07-24 21:13:00 +0000 |
---|---|---|
committer | Richard Mudgett <rmudgett@digium.com> | 2013-07-24 21:13:00 +0000 |
commit | 07d2694f725557854142fb6ae8fafa0e708b389e (patch) | |
tree | d4acf240ded6041d72ea4aedf10a062901c51b3d /main/bridging.c | |
parent | 50d69a9d12c7001f37d011b2860734619b45b2a9 (diff) |
Refactor ast_bridge_features struct.
* Reduced the number of hook containers to just dtmf_hooks,
interval_hooks, and other_hooks. As a result, several functions dealing
with the different hook containers could be combined.
* Extended the generic hook struct for DTMF and interval hooks instead of
using a variant record.
* Merged the special talk detector hook into the other_hooks container.
* Replaced ast_bridge_features_set_talk_detector() with
ast_bridge_talk_detector_hook().
(issue ASTERISK-22107)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395322 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/bridging.c')
-rw-r--r-- | main/bridging.c | 193 |
1 files changed, 75 insertions, 118 deletions
diff --git a/main/bridging.c b/main/bridging.c index 6be48c7ce..bc1d36d83 100644 --- a/main/bridging.c +++ b/main/bridging.c @@ -3509,16 +3509,17 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags) { - struct ast_bridge_hook *hook; + struct ast_bridge_hook_dtmf *hook; int res; /* Allocate new hook and setup it's various variables */ - hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor, - remove_flags); + hook = (struct ast_bridge_hook_dtmf *) bridge_hook_generic(sizeof(*hook), callback, + hook_pvt, destructor, remove_flags); if (!hook) { return -1; } - ast_copy_string(hook->parms.dtmf.code, dtmf, sizeof(hook->parms.dtmf.code)); + hook->generic.type = AST_BRIDGE_HOOK_TYPE_DTMF; + ast_copy_string(hook->dtmf.code, dtmf, sizeof(hook->dtmf.code)); /* Once done we put it in the container. */ res = ao2_link(features->dtmf_hooks, hook) ? 0 : -1; @@ -3529,18 +3530,33 @@ int ast_bridge_dtmf_hook(struct ast_bridge_features *features, * Remove the hook_pvt destructor call from the hook since we * are returning failure to install the hook. */ - hook->destructor = NULL; + hook->generic.destructor = NULL; } ao2_ref(hook, -1); return res; } -int ast_bridge_hangup_hook(struct ast_bridge_features *features, +/*! + * \internal + * \brief Attach an other hook to a bridge features structure + * + * \param features Bridge features structure + * \param callback Function to execute upon activation + * \param hook_pvt Unique data + * \param destructor Optional destructor callback for hook_pvt data + * \param remove_flags Dictates what situations the hook should be removed. + * \param type What type of hook is being attached. + * + * \retval 0 on success + * \retval -1 on failure (The caller must cleanup any hook_pvt resources.) + */ +static int bridge_other_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, - enum ast_bridge_hook_remove_flags remove_flags) + enum ast_bridge_hook_remove_flags remove_flags, + enum ast_bridge_hook_type type) { struct ast_bridge_hook *hook; int res; @@ -3551,9 +3567,10 @@ int ast_bridge_hangup_hook(struct ast_bridge_features *features, if (!hook) { return -1; } + hook->type = type; /* Once done we put it in the container. */ - res = ao2_link(features->hangup_hooks, hook) ? 0 : -1; + res = ao2_link(features->other_hooks, hook) ? 0 : -1; if (res) { /* * Could not link the hook into the container. @@ -3568,36 +3585,24 @@ int ast_bridge_hangup_hook(struct ast_bridge_features *features, return res; } -int ast_bridge_join_hook(struct ast_bridge_features *features, +int ast_bridge_hangup_hook(struct ast_bridge_features *features, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags) { - struct ast_bridge_hook *hook; - int res; - - /* Allocate new hook and setup it's various variables */ - hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor, - remove_flags); - if (!hook) { - return -1; - } - - /* Once done we put it in the container. */ - res = ao2_link(features->join_hooks, hook) ? 0 : -1; - if (res) { - /* - * Could not link the hook into the container. - * - * Remove the hook_pvt destructor call from the hook since we - * are returning failure to install the hook. - */ - hook->destructor = NULL; - } - ao2_ref(hook, -1); + return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags, + AST_BRIDGE_HOOK_TYPE_HANGUP); +} - return res; +int ast_bridge_join_hook(struct ast_bridge_features *features, + ast_bridge_hook_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags) +{ + return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags, + AST_BRIDGE_HOOK_TYPE_JOIN); } int ast_bridge_leave_hook(struct ast_bridge_features *features, @@ -3606,40 +3611,20 @@ int ast_bridge_leave_hook(struct ast_bridge_features *features, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags) { - struct ast_bridge_hook *hook; - int res; - - /* Allocate new hook and setup it's various variables */ - hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor, - remove_flags); - if (!hook) { - return -1; - } - - /* Once done we put it in the container. */ - res = ao2_link(features->leave_hooks, hook) ? 0 : -1; - if (res) { - /* - * Could not link the hook into the container. - * - * Remove the hook_pvt destructor call from the hook since we - * are returning failure to install the hook. - */ - hook->destructor = NULL; - } - ao2_ref(hook, -1); - - return res; + return bridge_other_hook(features, callback, hook_pvt, destructor, remove_flags, + AST_BRIDGE_HOOK_TYPE_LEAVE); } -void ast_bridge_features_set_talk_detector(struct ast_bridge_features *features, - ast_bridge_talking_indicate_callback talker_cb, - ast_bridge_talking_indicate_destructor talker_destructor, - void *pvt_data) +int ast_bridge_talk_detector_hook(struct ast_bridge_features *features, + ast_bridge_talking_indicate_callback callback, + void *hook_pvt, + ast_bridge_hook_pvt_destructor destructor, + enum ast_bridge_hook_remove_flags remove_flags) { - features->talker_cb = talker_cb; - features->talker_destructor_cb = talker_destructor; - features->talker_pvt_data = pvt_data; + ast_bridge_hook_callback hook_cb = (ast_bridge_hook_callback) callback; + + return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags, + AST_BRIDGE_HOOK_TYPE_TALK); } int ast_bridge_interval_hook(struct ast_bridge_features *features, @@ -3649,7 +3634,7 @@ int ast_bridge_interval_hook(struct ast_bridge_features *features, ast_bridge_hook_pvt_destructor destructor, enum ast_bridge_hook_remove_flags remove_flags) { - struct ast_bridge_hook *hook; + struct ast_bridge_hook_timer *hook; int res; if (!features ||!interval || !callback) { @@ -3665,17 +3650,18 @@ int ast_bridge_interval_hook(struct ast_bridge_features *features, } /* Allocate new hook and setup it's various variables */ - hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor, - remove_flags); + hook = (struct ast_bridge_hook_timer *) bridge_hook_generic(sizeof(*hook), callback, + hook_pvt, destructor, remove_flags); if (!hook) { return -1; } - hook->parms.timer.interval = interval; - hook->parms.timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(hook->parms.timer.interval, 1000)); - hook->parms.timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1); + hook->generic.type = AST_BRIDGE_HOOK_TYPE_TIMER; + hook->timer.interval = interval; + hook->timer.trip_time = ast_tvadd(ast_tvnow(), ast_samp2tv(hook->timer.interval, 1000)); + hook->timer.seqno = ast_atomic_fetchadd_int((int *) &features->interval_sequence, +1); ast_debug(1, "Putting interval hook %p with interval %u in the heap on features %p\n", - hook, hook->parms.timer.interval, features); + hook, hook->timer.interval, features); ast_heap_wrlock(features->interval_hooks); res = ast_heap_push(features->interval_hooks, hook); ast_heap_unlock(features->interval_hooks); @@ -3686,7 +3672,7 @@ int ast_bridge_interval_hook(struct ast_bridge_features *features, * Remove the hook_pvt destructor call from the hook since we * are returning failure to install the hook. */ - hook->destructor = NULL; + hook->generic.destructor = NULL; ao2_ref(hook, -1); } @@ -3836,24 +3822,22 @@ static void hooks_remove_heap(struct ast_heap *hooks, enum ast_bridge_hook_remov void ast_bridge_features_remove(struct ast_bridge_features *features, enum ast_bridge_hook_remove_flags remove_flags) { hooks_remove_container(features->dtmf_hooks, remove_flags); - hooks_remove_container(features->hangup_hooks, remove_flags); - hooks_remove_container(features->join_hooks, remove_flags); - hooks_remove_container(features->leave_hooks, remove_flags); + hooks_remove_container(features->other_hooks, remove_flags); hooks_remove_heap(features->interval_hooks, remove_flags); } static int interval_hook_time_cmp(void *a, void *b) { - struct ast_bridge_hook *hook_a = a; - struct ast_bridge_hook *hook_b = b; + struct ast_bridge_hook_timer *hook_a = a; + struct ast_bridge_hook_timer *hook_b = b; int cmp; - cmp = ast_tvcmp(hook_b->parms.timer.trip_time, hook_a->parms.timer.trip_time); + cmp = ast_tvcmp(hook_b->timer.trip_time, hook_a->timer.trip_time); if (cmp) { return cmp; } - cmp = hook_b->parms.timer.seqno - hook_a->parms.timer.seqno; + cmp = hook_b->timer.seqno - hook_a->timer.seqno; return cmp; } @@ -3875,21 +3859,21 @@ static int interval_hook_time_cmp(void *a, void *b) */ static int bridge_dtmf_hook_sort(const void *obj_left, const void *obj_right, int flags) { - const struct ast_bridge_hook *hook_left = obj_left; - const struct ast_bridge_hook *hook_right = obj_right; + const struct ast_bridge_hook_dtmf *hook_left = obj_left; + const struct ast_bridge_hook_dtmf *hook_right = obj_right; const char *right_key = obj_right; int cmp; switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) { default: case OBJ_POINTER: - right_key = hook_right->parms.dtmf.code; + right_key = hook_right->dtmf.code; /* Fall through */ case OBJ_KEY: - cmp = strcasecmp(hook_left->parms.dtmf.code, right_key); + cmp = strcasecmp(hook_left->dtmf.code, right_key); break; case OBJ_PARTIAL_KEY: - cmp = strncasecmp(hook_left->parms.dtmf.code, right_key, strlen(right_key)); + cmp = strncasecmp(hook_left->dtmf.code, right_key, strlen(right_key)); break; } return cmp; @@ -3908,30 +3892,16 @@ int ast_bridge_features_init(struct ast_bridge_features *features) return -1; } - /* Initialize the hangup hooks container */ - features->hangup_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, - NULL); - if (!features->hangup_hooks) { - return -1; - } - - /* Initialize the join hooks container */ - features->join_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, - NULL); - if (!features->join_hooks) { - return -1; - } - - /* Initialize the leave hooks container */ - features->leave_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, + /* Initialize the miscellaneous other hooks container */ + features->other_hooks = ao2_container_alloc_list(AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL); - if (!features->leave_hooks) { + if (!features->other_hooks) { return -1; } /* Initialize the interval hooks heap */ features->interval_hooks = ast_heap_create(8, interval_hook_time_cmp, - offsetof(struct ast_bridge_hook, parms.timer.heap_index)); + offsetof(struct ast_bridge_hook_timer, timer.heap_index)); if (!features->interval_hooks) { return -1; } @@ -3942,7 +3912,7 @@ int ast_bridge_features_init(struct ast_bridge_features *features) /* BUGBUG make ast_bridge_features_cleanup() static when make ast_bridge_join() requires features to be allocated. */ void ast_bridge_features_cleanup(struct ast_bridge_features *features) { - struct ast_bridge_hook *hook; + struct ast_bridge_hook_timer *hook; /* Destroy the interval hooks heap. */ if (features->interval_hooks) { @@ -3964,22 +3934,9 @@ void ast_bridge_features_cleanup(struct ast_bridge_features *features) features->limits = NULL; } - if (features->talker_destructor_cb && features->talker_pvt_data) { - features->talker_destructor_cb(features->talker_pvt_data); - features->talker_pvt_data = NULL; - } - - /* Destroy the leave hooks container. */ - ao2_cleanup(features->leave_hooks); - features->leave_hooks = NULL; - - /* Destroy the join hooks container. */ - ao2_cleanup(features->join_hooks); - features->join_hooks = NULL; - - /* Destroy the hangup hooks container. */ - ao2_cleanup(features->hangup_hooks); - features->hangup_hooks = NULL; + /* Destroy the miscellaneous other hooks container. */ + ao2_cleanup(features->other_hooks); + features->other_hooks = NULL; /* Destroy the DTMF hooks container. */ ao2_cleanup(features->dtmf_hooks); |