Discussion:
[asterisk-dev] ast_monitor_start has no effect.... sometimes
Steve Murphy
2018-03-23 20:00:13 UTC
Permalink
Hello--

I guess I have a weird situation, in that we use a separate process to turn
on call recording for a channel. It gets bridge join events via AMI and
send a StartMonitor action via AMI back to asterisk.

The trouble is, that depending on the machine, the phase of the moon, and
who knows what else, the request takes longer cometimes, and the
ast_monitor_start has no effect.

On a good day, the channels are both Locally RTP bridged, and the
native_rtp technology is started, the res_monitor start comes in and then
"switching from native_rtp to simple_bridge gets done, I see both channels
put in a dummy bridge, the native_rtp is stopped, the
ast_channel_make_compatible_helper chooses ulaw, and the simple_bridge
technology is started.
I see 3 more messages about "Bridge xxxxx is already using the new
technology (simple_bridge), and I see __ast_read() copying packets into the
recording files.

On a bad day, I see the channels are both Locally RTP bridged, and the
native_rtp technology is started. I see the "Bridge xxxxx is already using
the new technology (native_rtp) twice, then the __ast_monitor_start is run,
and that's it. The packets are forwarded without any __ast_read() calls,
and no packets are copied to the recording files. (They are in WAV format,
with only the 60-byte header in the files)

Is there something I need to do to get the bridge into simple_bridge tech
when we start the monitor?

murf
--
Steve Murphy
✉ murf at parsetree dot com
Richard Mudgett
2018-03-27 19:29:06 UTC
Permalink
Post by Steve Murphy
Hello--
I guess I have a weird situation, in that we use a separate process to
turn on call recording for a channel. It gets bridge join events via AMI
and send a StartMonitor action via AMI back to asterisk.
The trouble is, that depending on the machine, the phase of the moon, and
who knows what else, the request takes longer cometimes, and the
ast_monitor_start has no effect.
On a good day, the channels are both Locally RTP bridged, and the
native_rtp technology is started, the res_monitor start comes in and then
"switching from native_rtp to simple_bridge gets done, I see both channels
put in a dummy bridge, the native_rtp is stopped, the
ast_channel_make_compatible_helper chooses ulaw, and the simple_bridge
technology is started.
I see 3 more messages about "Bridge xxxxx is already using the new
technology (simple_bridge), and I see __ast_read() copying packets into the
recording files.
On a bad day, I see the channels are both Locally RTP bridged, and the
native_rtp technology is started. I see the "Bridge xxxxx is already using
the new technology (native_rtp) twice, then the __ast_monitor_start is run,
and that's it. The packets are forwarded without any __ast_read() calls,
and no packets are copied to the recording files. (They are in WAV format,
with only the 60-byte header in the files)
Is there something I need to do to get the bridge into simple_bridge tech
when we start the monitor?
This is a bug with res_monitor. Please file an issue.

The ast_monitor_start() function needs to check if the channel is in a
bridge after it has set the monitor
structure on the channel and set the unbridged flag to have the bridging
system reevaluate the bridge
technology.

In res_monitor.c:ast_monitor_start():

ast_channel_monitor_set(chan, monitor);
ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
+
+ if (ast_channel_is_bridged(chan)) {
+ ast_channel_set_unbridged_nolock(chan, 1);
+ }
+
/* so we know this call has been monitored in case we need to bill for it
or something */
pbx_builtin_setvar_helper(chan, "__MONITORED","true");

MixMonitor does not have this problem. When MinMonitor attaches its
audiohook
existing code that I've added above for Monitor causes the bridge to
reevaluate.

I think a better place is in channel_internal_api.c instead as it will
happen for starting, stopping,
and masquarading channels with monitor:

void ast_channel_monitor_set(struct ast_channel *chan, struct
ast_channel_monitor *value)
{
chan->monitor = value;
+ if (ast_channel_internal_bridge(chan)) {
+ ast_channel_set_unbridged_nolock(chan, 1);
+ }
}


Richard
Steve Murphy
2018-03-29 03:00:14 UTC
Permalink
Post by Richard Mudgett
Post by Steve Murphy
Hello--
I guess I have a weird situation, in that we use a separate process to
turn on call recording for a channel. It gets bridge join events via AMI
and send a StartMonitor action via AMI back to asterisk.
The trouble is, that depending on the machine, the phase of the moon, and
who knows what else, the request takes longer cometimes, and the
ast_monitor_start has no effect.
On a good day, the channels are both Locally RTP bridged, and the
native_rtp technology is started, the res_monitor start comes in and then
"switching from native_rtp to simple_bridge gets done, I see both channels
put in a dummy bridge, the native_rtp is stopped, the
ast_channel_make_compatible_helper chooses ulaw, and the simple_bridge
technology is started.
I see 3 more messages about "Bridge xxxxx is already using the new
technology (simple_bridge), and I see __ast_read() copying packets into the
recording files.
On a bad day, I see the channels are both Locally RTP bridged, and the
native_rtp technology is started. I see the "Bridge xxxxx is already using
the new technology (native_rtp) twice, then the __ast_monitor_start is run,
and that's it. The packets are forwarded without any __ast_read() calls,
and no packets are copied to the recording files. (They are in WAV format,
with only the 60-byte header in the files)
Is there something I need to do to get the bridge into simple_bridge tech
when we start the monitor?
This is a bug with res_monitor. Please file an issue.
The ast_monitor_start() function needs to check if the channel is in a
bridge after it has set the monitor
structure on the channel and set the unbridged flag to have the bridging
system reevaluate the bridge
technology.
ast_channel_monitor_set(chan, monitor);
ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
+
+ if (ast_channel_is_bridged(chan)) {
+ ast_channel_set_unbridged_nolock(chan, 1);
+ }
+
/* so we know this call has been monitored in case we need to bill for
it or something */
pbx_builtin_setvar_helper(chan, "__MONITORED","true");
MixMonitor does not have this problem. When MinMonitor attaches its
audiohook
existing code that I've added above for Monitor causes the bridge to
reevaluate.
I think a better place is in channel_internal_api.c instead as it will
happen for starting, stopping,
void ast_channel_monitor_set(struct ast_channel *chan, struct
ast_channel_monitor *value)
{
chan->monitor = value;
+ if (ast_channel_internal_bridge(chan)) {
+ ast_channel_set_unbridged_nolock(chan, 1);
+ }
}
Richard
​I added the lines in almost the exact same spot in my res_monitor.c file,
and we ran
it 28 times with perfect recordings. Then we ran a set of 110 tests with
perfect recording
results, where normally we would see about 45% of the recordings would be
empty.

Now, we have put the new code on a few production machines, and we will
test
a couple days more before distributing to all our systems.

As to add this instead to ast_channel_monitor_set, this is an intriguing
idea. I will see if
it still works with the same efficacy on our servers. I need to know more
about the situations
where it will prevent null recordings.

murf
​
--
Steve Murphy
✉ murf at parsetree dot com
Loading...