[asterisk-dev] I want to make my first patch but have run into a problem and don't know how to progress.

Mark Michelson mmichelson at digium.com
Mon Oct 10 13:12:04 CDT 2016


On 10/06/2016 12:52 PM, John Kiniston wrote:
> I got all fired up on getting up to date with the current LTS version 
> of Asterisk while at Astricon and I'd like to make my first patch.

Awesome! Hopefully this will be the first of many to come.

> I want to modify bridge_builtin_features.c to honor the"MONITOR_EXEC" 
> and "MONITOR_EXEC_ARGS" variables like Monitor() does so that my one 
> touch recordings using automon get post processed.
>
> I'm no C programmer but I took a class at the local community college 
> uh I guess it's been two decades ago now so forgive me.
>
> I found the code in res/res_monitor.c that handles setting the execute 
> application and running it and I've copied what looked like the part I 
> needed into bridges/bridge_builtin_
> features.c and with a few minor changes it almost works.
>
> The part where it's breaking down is getting the format of the 
> recorded file which I think should be touch_format I'm getting (null) 
> so I reckon set_touch_variables doesn't do what I hoped it did.
>
> Would someone please help me get the file-name extension or point me 
> in a better direction if this doesn't look like a good idea?

I'm going to answer your question in two ways here: first, from the 
perspective of helping to understand the code you've written, and second 
addressing the "if this doesn't look like a good idea" angle.

Let's examine what set_touch_variables does. set_touch_variables first 
determines which channel variables it needs to be looking at. Assuming 
you're using monitor and not mixmonitor, that means that it will look up 
the TOUCH_MONITOR_FORMAT, TOUCH_MONITOR, and TOUCH_MONITOR_PREFIX 
channel variables. It will place the values of each into the 
touch_monitor_format, touch_monitor, and touch_monitor_prefix local 
variables, respectively. In your case, it appears that 
touch_mointor_format ends up NULL, which most likely stems from the fact 
that the TOUCH_MONITOR_FORMAT variable is not set on the channel which 
was passed into set_touch_variables. So later when you start outputting 
your debug, since touch_monitor_format is NULL, the glibc print routines 
turn that into "(null)".

Why don't you see the same thing happen in the res_monitor.c code? In 
that code, the ast_monitor_start() function requires a file format to be 
passed to it, and that format ends up getting set on the ast_monitor 
structure that gets created. That structure then gets set on the 
channel, and it can be later accessed by calling 
ast_channel_monitor(chan). When ast_monitor_stop() is called, it is able 
to get that saved format off the channel and use that for its 
post-processing. You could potentially do the same thing to get the file 
format by getting the value of ast_channel_monitor(chan)->format in your 
code.

So now let's talk about whether your approach is the right one to take. 
One thing you may have noticed when doing your experimental coding is 
that the code that you copy/pasted comes from ast_monitor_stop(). 
ast_monitor_stop() is a C-level API call that is called by several 
places in the code, including in bridge_builtin_features.c when 
one-touch monitoring is stopped. This means, at least the way I see it, 
that the use of MONITOR_EXEC and MONITOR_EXEC_ARGS should already be in 
a position where they could "just work" with builtin automon. We can 
take a closer look at ast_monitor_stop() and see that the guard for 
determining if MONITOR_EXEC and MONITOR_EXEC_ARGS is used is:

     if (ast_channel_monitor(chan)->joinfiles && 
!ast_strlen_zero(ast_channel_monitor(chan)->filename_base))

If MONITOR_EXEC and MONITOR_EXEC_ARGS is currently not working, it is 
likely because one or both of these conditions are not met. Let's 
examine them one by one.

ast_channel_monitor(chan)->joinfiles is a boolean that indicates if 
files should be joined together once recording is done. With the 
Monitor() application, this gets set true by setting the 'm' option (see 
start_monitor_exec() if you want to follow how that is done, 
specifically looking at MON_FLAG_MIX). Otherwise, though, this value is 
false. When ast_monitor_start() is called, it does not automatically set 
joinfiles to true. There is a function, though, called 
ast_monitor_setjoinfiles() you can use to set this value to true.

ast_channel_monitor(chan)->filename_base is the base filename being used 
for monitor recordings. "base filename" means the filename minus the 
extra bits indicating the audio direction. The only reason this would 
not be set is if there were some catastrophic error. ast_strlen_zero() 
is a utility function that returns true if the input string is either 
NULL or zero-length. So since filename_base is almost certainly more 
than zero characters long, it's likely that ast_strlen_zero() of that is 
false, and negating that makes it true.

Summary:
This probably means that you could get the functionality you desire by 
calling ast_monitor_setjoinfiles(chan, 1) after ast_monitor_start() in 
start_automonitor() of bridge_builtin_features.c. This approach would be 
better than copying/pasting because it keeps the code in one spot and 
makes use of already tested code.

Hope this was helpful,
Mark Michelson
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-dev/attachments/20161010/c7c4fb09/attachment.html>


More information about the asterisk-dev mailing list