summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/asterisk/framehook.h6
-rw-r--r--main/framehook.c15
-rw-r--r--res/res_pjsip_t38.c13
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 */