diff options
Diffstat (limited to 'res')
-rw-r--r-- | res/res_fax.c | 39 | ||||
-rw-r--r-- | res/res_pjsip_refer.c | 1 |
2 files changed, 40 insertions, 0 deletions
diff --git a/res/res_fax.c b/res/res_fax.c index b9a3b2ec4..758309822 100644 --- a/res/res_fax.c +++ b/res/res_fax.c @@ -607,11 +607,47 @@ static void destroy_callback(void *data) } } +static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan); + static const struct ast_datastore_info fax_datastore = { .type = "res_fax", .destroy = destroy_callback, + .chan_fixup = fixup_callback, }; +static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_details *details); +static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags); +static struct ast_fax_session_details *find_or_create_details(struct ast_channel *chan); + +/*! \brief Copies fax detection and gateway framehooks during masquerades + * + * \note must be called with both old_chan and new_chan locked. Since this + * is only called by do_masquerade, that shouldn't be an issue. + */ +static void fixup_callback(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan) +{ + struct ast_fax_session_details *old_details = data; + struct ast_datastore *datastore = ast_channel_datastore_find(old_chan, &fax_datastore, NULL); + + if (old_details->gateway_id >= 0) { + struct ast_fax_session_details *new_details = find_or_create_details(new_chan); + + ast_framehook_detach(old_chan, old_details->gateway_id); + fax_gateway_attach(new_chan, new_details); + ao2_cleanup(new_details); + } + + if (old_details->faxdetect_id >= 0) { + ast_framehook_detach(old_chan, old_details->faxdetect_id); + fax_detect_attach(new_chan, old_details->faxdetect_timeout, old_details->faxdetect_flags); + } + + if (datastore) { + ast_channel_datastore_remove(old_chan, datastore); + ast_datastore_free(datastore); + } +} + /*! \brief returns a reference counted pointer to a fax datastore, if it exists */ static struct ast_fax_session_details *find_details(struct ast_channel *chan) { @@ -3431,6 +3467,7 @@ static int fax_gateway_attach(struct ast_channel *chan, struct ast_fax_session_d .version = AST_FRAMEHOOK_INTERFACE_VERSION, .event_cb = fax_gateway_framehook, .destroy_cb = fax_gateway_framehook_destroy, + .disable_inheritance = 1, /* Masquerade inheritance is handled through the datastore fixup */ }; ast_string_field_set(details, result, "SUCCESS"); @@ -3700,6 +3737,8 @@ static int fax_detect_attach(struct ast_channel *chan, int timeout, int flags) faxdetect->details = details; ast_channel_lock(chan); details->faxdetect_id = ast_framehook_attach(chan, &fr_hook); + details->faxdetect_timeout = timeout; + details->faxdetect_flags = flags; ast_channel_unlock(chan); if (details->faxdetect_id < 0) { diff --git a/res/res_pjsip_refer.c b/res/res_pjsip_refer.c index efcee67a2..b88396f7a 100644 --- a/res/res_pjsip_refer.c +++ b/res/res_pjsip_refer.c @@ -508,6 +508,7 @@ static void refer_blind_callback(struct ast_channel *chan, struct transfer_chann .event_cb = refer_progress_framehook, .destroy_cb = refer_progress_framehook_destroy, .data = refer->progress, + .disable_inheritance = 1, }; refer->progress->transferee = ast_strdup(ast_channel_uniqueid(chan)); |