diff options
-rw-r--r-- | include/asterisk/framehook.h | 6 | ||||
-rw-r--r-- | main/framehook.c | 15 | ||||
-rw-r--r-- | res/res_pjsip_t38.c | 13 |
3 files changed, 33 insertions, 1 deletions
diff --git a/include/asterisk/framehook.h b/include/asterisk/framehook.h index 8a58323f2..d388f2e1b 100644 --- a/include/asterisk/framehook.h +++ b/include/asterisk/framehook.h @@ -224,7 +224,7 @@ typedef int (*ast_framehook_consume_callback)(void *data, enum ast_frame_type ty typedef void (*ast_framehook_chan_fixup_callback)(void *data, int framehook_id, struct ast_channel *old_chan, struct ast_channel *new_chan); -#define AST_FRAMEHOOK_INTERFACE_VERSION 3 +#define AST_FRAMEHOOK_INTERFACE_VERSION 4 /*! This interface is required for attaching a framehook to a channel. */ struct ast_framehook_interface { /*! framehook interface version number */ @@ -242,6 +242,10 @@ struct ast_framehook_interface { * on is masqueraded and should be used to move any essential framehook data onto the channel the * old channel was masqueraded to. */ ast_framehook_chan_fixup_callback chan_fixup_cb; + /*! chan_breakdown_cb is optional. This function is called when another channel is masqueraded into + * the channel that a framehook is running on and should be used to evaluate whether the framehook + * should remain on the channel. */ + ast_framehook_chan_fixup_callback chan_breakdown_cb; /*! disable_inheritance is optional. If set to non-zero, when a channel using this framehook is * masqueraded, detach and destroy the framehook instead of moving it to the new channel. */ int disable_inheritance; diff --git a/main/framehook.c b/main/framehook.c index ec4e1695f..8df3a31a4 100644 --- a/main/framehook.c +++ b/main/framehook.c @@ -227,6 +227,21 @@ void ast_framehook_list_fixup(struct ast_channel *old_chan, struct ast_channel * struct ast_framehook *framehook; int moved_framehook_id; + if (ast_channel_framehooks(new_chan)) { + AST_LIST_TRAVERSE_SAFE_BEGIN(&ast_channel_framehooks(new_chan)->list, framehook, list) { + if (framehook->i.disable_inheritance) { + ast_framehook_detach(new_chan, framehook->id); + continue; + } + + if (framehook->i.chan_breakdown_cb) { + framehook->i.chan_breakdown_cb(framehook->i.data, framehook->id, + old_chan, new_chan); + } + } + AST_LIST_TRAVERSE_SAFE_END; + } + if (!ast_channel_framehooks(old_chan)) { return; } diff --git a/res/res_pjsip_t38.c b/res/res_pjsip_t38.c index c5d0412c4..a031716d9 100644 --- a/res/res_pjsip_t38.c +++ b/res/res_pjsip_t38.c @@ -440,12 +440,25 @@ static struct ast_frame *t38_framehook(struct ast_channel *chan, struct ast_fram return f; } +static void t38_masq(void *data, int framehook_id, + struct ast_channel *old_chan, struct ast_channel *new_chan) +{ + if (ast_channel_tech(old_chan) == ast_channel_tech(new_chan)) { + return; + } + + /* This framehook is only applicable to PJSIP channels */ + ast_framehook_detach(new_chan, framehook_id); +} + /*! \brief Function called to attach T.38 framehook to channel when appropriate */ static void t38_attach_framehook(struct ast_sip_session *session) { static struct ast_framehook_interface hook = { .version = AST_FRAMEHOOK_INTERFACE_VERSION, .event_cb = t38_framehook, + .chan_fixup_cb = t38_masq, + .chan_breakdown_cb = t38_masq, }; /* Only attach the framehook on the first outgoing INVITE or the first incoming INVITE */ |