Merged revisions 166092,166095 via svnmerge from

https://origsvn.digium.com/svn/asterisk/trunk

........
r166092 | mmichelson | 2008-12-19 16:26:16 -0600 (Fri, 19 Dec 2008) | 28 lines

Adding a new dialplan function AUDIOHOOK_INHERIT

This function is being added as a method to allow for
an audiohook to move to a new channel during a channel
masquerade. The most obvious use for such a facility is
for MixMonitor when a transfer is performed. Prior to
the addition of this functionality, if a channel 
running MixMonitor was transferred by another party, then
the recording would stop once the transfer had completed.
By using AUDIOHOOK_INHERIT, you can make MixMonitor 
continue recording the call even after the transfer
has completed.

It has also been determined that since this is seen
by most as a bug fix and is not an invasive change,
this functionality will also be backported to 1.4 and
merged into the 1.6.0 branches, even though they are
feature-frozen.

(closes issue #13538)
Reported by: mbit
Patches:
      13538.patch uploaded by putnopvut (license 60)
	  Tested by: putnopvut

Review: http://reviewboard.digium.com/r/102/


........
r166095 | mmichelson | 2008-12-19 16:40:57 -0600 (Fri, 19 Dec 2008) | 5 lines

Remove the verbatim tag from the author line

I could have sworn I already did that before, though...


........


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.0@166097 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Michelson
2008-12-19 23:04:07 +00:00
parent fccf7383df
commit eec3edde9f
4 changed files with 93 additions and 2 deletions

View File

@@ -92,6 +92,10 @@ Dialplan functions
ID for the call (not the Asterisk call ID or unique ID), provided that the ID for the call (not the Asterisk call ID or unique ID), provided that the
channel driver supports this. For SIP, you get the SIP call-ID for the channel driver supports this. For SIP, you get the SIP call-ID for the
bridged channel which you can store in the CDR with a custom field. bridged channel which you can store in the CDR with a custom field.
* Added the function AUDIOHOOK_INHERIT. This actually is already in Asterisk
1.4, but since it was added late in the release cycle, I felt it was a good
idea to list it here as well. See the CLI output for "core show function
AUDIOHOOK_INHERIT" for more details
CLI Changes CLI Changes
----------- -----------

View File

@@ -150,6 +150,21 @@ int ast_audiohook_detach(struct ast_audiohook *audiohook);
*/ */
int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list); int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list);
/*! \brief Move an audiohook from one channel to a new one
*
* \todo Currently only the first audiohook of a specific source found will be moved.
* We should add the capability to move multiple audiohooks from a single source as well.
*
* \note It is required that both old_chan and new_chan are locked prior to calling
* this function. Besides needing to protect the data within the channels, not locking
* these channels can lead to a potential deadlock
*
* \param old_chan The source of the audiohook to move
* \param new_chan The destination to which we want the audiohook to move
* \param source The source of the audiohook we want to move
*/
void ast_audiohook_move_by_source(struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source);
/*! /*!
* \brief Detach specified source audiohook from channel * \brief Detach specified source audiohook from channel
* *
@@ -162,6 +177,18 @@ int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list);
*/ */
int ast_audiohook_detach_source(struct ast_channel *chan, const char *source); int ast_audiohook_detach_source(struct ast_channel *chan, const char *source);
/*!
* \brief Remove an audiohook from a specified channel
*
* \param chan Channel to remove from
* \param audiohook Audiohook to remove
*
* \return Returns 0 on success, -1 on failure
*
* \note The channel does not need to be locked before calling this function
*/
int ast_audiohook_remove(struct ast_channel *chan, struct ast_audiohook *audiohook);
/*! \brief Pass a frame off to be handled by the audiohook core /*! \brief Pass a frame off to be handled by the audiohook core
* \param chan Channel that the list is coming off of * \param chan Channel that the list is coming off of
* \param audiohook_list List of audiohooks * \param audiohook_list List of audiohooks

View File

@@ -412,6 +412,11 @@ int ast_audiohook_detach_list(struct ast_audiohook_list *audiohook_list)
return 0; return 0;
} }
/*! \brief find an audiohook based on its source
* \param audiohook_list The list of audiohooks to search in
* \param source The source of the audiohook we wish to find
* \return Return the corresponding audiohook or NULL if it cannot be found.
*/
static struct ast_audiohook *find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source) static struct ast_audiohook *find_audiohook_by_source(struct ast_audiohook_list *audiohook_list, const char *source)
{ {
struct ast_audiohook *audiohook = NULL; struct ast_audiohook *audiohook = NULL;
@@ -434,6 +439,25 @@ static struct ast_audiohook *find_audiohook_by_source(struct ast_audiohook_list
return NULL; return NULL;
} }
void ast_audiohook_move_by_source (struct ast_channel *old_chan, struct ast_channel *new_chan, const char *source)
{
struct ast_audiohook *audiohook = find_audiohook_by_source(old_chan->audiohooks, source);
if (!audiohook) {
return;
}
/* By locking both channels and the audiohook, we can assure that
* another thread will not have a chance to read the audiohook's status
* as done, even though ast_audiohook_remove signals the trigger
* condition
*/
ast_audiohook_lock(audiohook);
ast_audiohook_remove(old_chan, audiohook);
ast_audiohook_attach(new_chan, audiohook);
ast_audiohook_unlock(audiohook);
}
/*! \brief Detach specified source audiohook from channel /*! \brief Detach specified source audiohook from channel
* \param chan Channel to detach from * \param chan Channel to detach from
* \param source Name of source to detach * \param source Name of source to detach
@@ -461,6 +485,42 @@ int ast_audiohook_detach_source(struct ast_channel *chan, const char *source)
return (audiohook ? 0 : -1); return (audiohook ? 0 : -1);
} }
/*!
* \brief Remove an audiohook from a specified channel
*
* \param chan Channel to remove from
* \param audiohook Audiohook to remove
*
* \return Returns 0 on success, -1 on failure
*
* \note The channel does not need to be locked before calling this function
*/
int ast_audiohook_remove(struct ast_channel *chan, struct ast_audiohook *audiohook)
{
ast_channel_lock(chan);
if (!chan->audiohooks) {
ast_channel_unlock(chan);
return -1;
}
if (audiohook->type == AST_AUDIOHOOK_TYPE_SPY)
AST_LIST_REMOVE(&chan->audiohooks->spy_list, audiohook, list);
else if (audiohook->type == AST_AUDIOHOOK_TYPE_WHISPER)
AST_LIST_REMOVE(&chan->audiohooks->whisper_list, audiohook, list);
else if (audiohook->type == AST_AUDIOHOOK_TYPE_MANIPULATE)
AST_LIST_REMOVE(&chan->audiohooks->manipulate_list, audiohook, list);
ast_audiohook_lock(audiohook);
audiohook->status = AST_AUDIOHOOK_STATUS_DONE;
ast_cond_signal(&audiohook->trigger);
ast_audiohook_unlock(audiohook);
ast_channel_unlock(chan);
return 0;
}
/*! \brief Pass a DTMF frame off to be handled by the audiohook core /*! \brief Pass a DTMF frame off to be handled by the audiohook core
* \param chan Channel that the list is coming off of * \param chan Channel that the list is coming off of
* \param audiohook_list List of audiohooks * \param audiohook_list List of audiohooks

View File

@@ -4084,11 +4084,11 @@ int ast_do_masquerade(struct ast_channel *original)
/* Move data stores over */ /* Move data stores over */
if (AST_LIST_FIRST(&clone->datastores)) { if (AST_LIST_FIRST(&clone->datastores)) {
struct ast_datastore *ds; struct ast_datastore *ds;
AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry); AST_LIST_TRAVERSE(&clone->datastores, ds, entry) {
AST_LIST_TRAVERSE(&original->datastores, ds, entry) {
if (ds->info->chan_fixup) if (ds->info->chan_fixup)
ds->info->chan_fixup(ds->data, clone, original); ds->info->chan_fixup(ds->data, clone, original);
} }
AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
} }
clone_variables(original, clone); clone_variables(original, clone);