QueueMember Pausing Recording from Queue

Hi folks,

The Story
My company uses a queue to ring our customer service team and QueueMetrics to monitor them. I was previously tasked with enabling recording for the queue. Simple enough, I turned on recording on the queue and everything worked. The original server is:
FreePBX 2.11.0.43
Call Recording 2.11.0.9
Asterisk 1.8.21.0
I was later tasked with allowing pausing of recordings for PCI compliance to take credit card numbers. My research led me to the fact that the Recording Module was rewritten and upgrading should allow this to work, and luckily enough we have a testbed VM of FreePBX running:
FreePBX 12.0.76.2
Call Recording 12.0.4
Asterisk 11.17.1

If it works correctly we will upgrade our main system to a newer version.

Setup and Issue
Testing on the FreePBX server I created a queue (805) and two extensions (2003, 2004). I set recording on the queue to Yes and placed extension 2004 in it as a static agent. Extension 2004 has Asterisk Dial Options overridden to TtrwWxX and On Demand Recording enabled. All other settings are pretty much default. When calling into the queue I found that:

  1. Recordings were started successfully.
  2. The first time pressing the *1 One Touch Recording feature code it would pause.
  3. Pressing *1 again would resume.
  4. All subsequent *1 presses would fail to pause the recording.

I have 12 text files full of debugging and various things I tested. I am NOT an Asterisk/FreePBX expert by any stretch, but it appeared based on my limited knowledge that:

  1. The queue begins the recording on one channel
  2. When the call is passed to a queue member that answers it and that member pauses and then restarts a recording, the recording is restarted on a different channel.
  3. When again trying to pause subsequently, the One Touch Record feature does not pause the correct channel.

Debugging
FreePBX-SIPCLI>
FreePBX-SIP
CLI>
FIRST PAUSE
– Feature Found: apprecord exten: apprecord
– Executing [s@macro-one-touch-record:1] Set(“SIP/2004-000061b2”, “ONETOUCH_REC_SCRIPT_STATUS=”) in new stack
– Executing [s@macro-one-touch-record:2] System(“SIP/2004-000061b2”, "/var/lib/asterisk/bin/one_touch_record.php “SIP/2004-000061b2"”) in new stack
== MixMonitor close filestream (mixed)
== End MixMonitor Recording SIP/2003-000061b1
– Executing [s@macro-one-touch-record:3] NoOp(“SIP/2004-000061b2”, “ONETOUCH_REC_SCRIPT_STATUS: [RECORDING_STOPPED]”) in new stack
– Executing [s@macro-one-touch-record:4] ExecIf(“SIP/2004-000061b2”, “0?Playback(beep)”) in new stack
– Executing [s@macro-one-touch-record:5] ExecIf(“SIP/2004-000061b2”, “1?Playback(beep&beep)”) in new stack
– <SIP/2004-000061b2> Playing ‘beep.ulaw’ (language ‘en’)
– <SIP/2004-000061b2> Playing ‘beep.ulaw’ (language ‘en’)
– Executing [s@macro-one-touch-record:6] ExecIf(“SIP/2004-000061b2”, “0?Playback(access-denied)”) in new stack
– Executing [s@macro-one-touch-record:7] MacroExit(“SIP/2004-000061b2”, “”) in new stack
FreePBX-SIPCLI>
FreePBX-SIP
CLI>
FIRST UNPAUSE
FreePBX-SIPCLI>
– Feature Found: apprecord exten: apprecord
– Executing [s@macro-one-touch-record:1] Set(“SIP/2004-000061b2”, “ONETOUCH_REC_SCRIPT_STATUS=”) in new stack
– Executing [s@macro-one-touch-record:2] System(“SIP/2004-000061b2”, "/var/lib/asterisk/bin/one_touch_record.php “SIP/2004-000061b2"”) in new stack
== Begin MixMonitor Recording SIP/2003-000061b1
– Executing [s@macro-one-touch-record:3] NoOp(“SIP/2004-000061b2”, “ONETOUCH_REC_SCRIPT_STATUS: [RECORDING_STARTED]”) in new stack
– Executing [s@macro-one-touch-record:4] ExecIf(“SIP/2004-000061b2”, “1?Playback(beep)”) in new stack
– <SIP/2004-000061b2> Playing ‘beep.ulaw’ (language ‘en’)
– Executing [s@macro-one-touch-record:5] ExecIf(“SIP/2004-000061b2”, “0?Playback(beep&beep)”) in new stack
– Executing [s@macro-one-touch-record:6] ExecIf(“SIP/2004-000061b2”, “0?Playback(access-denied)”) in new stack
– Executing [s@macro-one-touch-record:7] MacroExit(“SIP/2004-000061b2”, “”) in new stack
FreePBX-SIP
CLI>
SECOND PAUSE
FreePBX-SIPCLI>
– Feature Found: apprecord exten: apprecord
– Executing [s@macro-one-touch-record:1] Set(“SIP/2004-000061b2”, “ONETOUCH_REC_SCRIPT_STATUS=”) in new stack
– Executing [s@macro-one-touch-record:2] System(“SIP/2004-000061b2”, "/var/lib/asterisk/bin/one_touch_record.php “SIP/2004-000061b2"”) in new stack
----> WHERE IS IT??? <-------
– Executing [s@macro-one-touch-record:3] NoOp(“SIP/2004-000061b2”, “ONETOUCH_REC_SCRIPT_STATUS: [RECORDING_STOPPED]”) in new stack
– Executing [s@macro-one-touch-record:4] ExecIf(“SIP/2004-000061b2”, “0?Playback(beep)”) in new stack
– Executing [s@macro-one-touch-record:5] ExecIf(“SIP/2004-000061b2”, “1?Playback(beep&beep)”) in new stack
– <SIP/2004-000061b2> Playing ‘beep.ulaw’ (language ‘en’)
– <SIP/2004-000061b2> Playing ‘beep.ulaw’ (language ‘en’)
– Executing [s@macro-one-touch-record:6] ExecIf(“SIP/2004-000061b2”, “0?Playback(access-denied)”) in new stack
– Executing [s@macro-one-touch-record:7] MacroExit(“SIP/2004-000061b2”, “”) in new stack
FreePBX-SIP
CLI>
FreePBX-SIP*CLI>

For funsies I hacked the one_touch_record.php file and told ot_debug to also output to my own log file, since I didn’t have a clue where it was putting this information. The RECORDING/STOPPED lines are the ACTUAL results based on listening to the recording.
RECORDING
2016-06-15 08:55:20 - Checking pickup extension
2016-06-15 08:55:20 - Checking this extension
2016-06-15 08:55:20 - Don’t know what this exten is
2016-06-15 08:55:20 - Device is SIP/2004
2016-06-15 08:55:20 - Found SIP/2004 from DIALEDPEERNUMBER as 2004
2016-06-15 08:55:20 - This exten is 2004
2016-06-15 08:55:20 - Checking on demand setting
2016-06-15 08:55:20 - Found Master channel SIP/2003-000061b7
2016-06-15 08:55:20 - Checking if channel SIP/2003-000061b7 is already recording
2016-06-15 08:55:20 - Found SIP/2003-000061b7 as RECORDING
2016-06-15 08:55:20 - RPM is YES in SIP/2004-000061b8
2016-06-15 08:55:20 - Stopping
STOPPED
2016-06-15 08:55:22 - Checking pickup extension
2016-06-15 08:55:22 - Checking this extension
2016-06-15 08:55:22 - This exten is 2004
2016-06-15 08:55:22 - Checking on demand setting
2016-06-15 08:55:22 - Found Master channel SIP/2003-000061b7
2016-06-15 08:55:22 - Checking if channel SIP/2003-000061b7 is already recording
2016-06-15 08:55:22 - Found SIP/2003-000061b7, but it’s not recording
2016-06-15 08:55:22 - Checking recording polcy NO
2016-06-15 08:55:22 - Recording Channel
2016-06-15 08:55:22 - Setting CDR info
RECORDING
2016-06-15 08:55:24 - Checking pickup extension
2016-06-15 08:55:24 - Checking this extension
2016-06-15 08:55:24 - This exten is 2004
2016-06-15 08:55:24 - Checking on demand setting
2016-06-15 08:55:24 - Found Master channel SIP/2004-000061b8
2016-06-15 08:55:24 - Checking if channel SIP/2004-000061b8 is already recording
2016-06-15 08:55:24 - Found SIP/2004-000061b8 as RECORDING
2016-06-15 08:55:24 - RPM is YES in SIP/2004-000061b8
2016-06-15 08:55:24 - Stopping
RECORDING
2016-06-15 08:55:26 - Checking pickup extension
2016-06-15 08:55:26 - Checking this extension
2016-06-15 08:55:26 - This exten is 2004
2016-06-15 08:55:26 - Checking on demand setting
2016-06-15 08:55:26 - Found Master channel SIP/2004-000061b8
2016-06-15 08:55:26 - Checking if channel SIP/2004-000061b8 is already recording
2016-06-15 08:55:26 - Found SIP/2004-000061b8, but it’s not recording
2016-06-15 08:55:26 - Checking recording polcy NO
2016-06-15 08:55:26 - Recording Channel
2016-06-15 08:55:26 - Setting CDR info
RECORDING
2016-06-15 08:55:27 - Checking pickup extension
2016-06-15 08:55:27 - Checking this extension
2016-06-15 08:55:27 - This exten is 2004
2016-06-15 08:55:27 - Checking on demand setting
2016-06-15 08:55:27 - Found Master channel SIP/2004-000061b8
2016-06-15 08:55:27 - Checking if channel SIP/2004-000061b8 is already recording
2016-06-15 08:55:27 - Found SIP/2004-000061b8 as RECORDING
2016-06-15 08:55:27 - RPM is YES in SIP/2004-000061b8
2016-06-15 08:55:27 - Stopping
RECORDING

As you can see, after listing the master channel as SIP/2003-000061b7 and restarting after the first pause, the next time through it sees the master channel as SIP/2004-000061b8 and recording. It says it’s stopping it, however the recording is not stopped. It appears to be noticing when it should be starting/stopping correctly, but not actually stopping. The secret appeared to be that REC_STATUS is updated to STOPPED for multiple channels, but $astman->stopmixmonitor was only being run on one channel.

My Solution
Based upon the following code in
/var/www/html/admin/modules/callrecording/bin/one_touch_record.php
lines 119-122 on mine

foreach (array($channel, $myMaster, $bridgePeer, $theirMaster) as $c) {
$rid = getVariable($c, “RECORD_ID”);
if (!empty($rid)) {
ot_debug(“Found Master channel $rid”);

It appears that it is looking for the recording ID/master channel in a specific order, but not necessarily checking if there could possibly have been two valid recordings? Question mark? Again, I am not an expert and my understanding of ‘channels’ has come from just playing with this.

My line of reasoning was, well, if it doesn’t know which of those channels it should ACTUALLY be pausing, I’ll just tell it to pause all of them just in case. I used the variable names in the foreach(array()) statement to just stop all of those channels via stopmixmonitor.

I changed this section (the bolded is my final result), lines 155 through 195 in my one_touch_record.php.

ot_debug(“Checking if channel $masterChannel is already recording”);
$rid = getVariable($masterChannel, ‘RECORD_ID’);
if (!empty($rid)) {
// This channel, previously, has been recording things.
$recStatus = getVariable($rid, ‘REC_STATUS’);
if ($recStatus == “RECORDING”) {
ot_debug(“Found $rid as RECORDING”);
// We’re recording. Are we allowed to stop it? The CURRENT channel will have the
// latest, correct, policy mode.
$rpm = getVariable($channel, “REC_POLICY_MODE”);
ot_debug(“RPM is $rpm in $channel”);
if ($rpm == “FORCE” && $onDemand != “override”) {
ot_debug(“Denied policymode - $onDemand and $rpm”);
setVariable($channel, “ONETOUCH_REC_SCRIPT_STATUS”, “DENIED-POLICYMODE”);
exit(0);
}

ot_debug("Stopping ".$rid);
$astman->stopmixmonitor($rid, rand());
$astman->stopmixmonitor($channel, rand());
$astman->stopmixmonitor($bridgePeer, rand());
$astman->stopmixmonitor($myMaster, rand());
$astman->stopmixmonitor($theirMaster, rand());
setVariable($rid, “REC_STATUS”, “STOPPED”);
setVariable($channel, “REC_STATUS”, “STOPPED”);
setVariable($bridgePeer, “REC_STATUS”, “STOPPED”);
setVariable($myMaster, “REC_STATUS”, “STOPPED”);
setVariable($theirMaster, “REC_STATUS”, “STOPPED”);
setVariable($channel, “ONETOUCH_REC_SCRIPT_STATUS”, “RECORDING_STOPPED”);
exit(0);

}
// Ah, it’s not recording. So we just want to keep that Recording ID, as we’re
// going to use it later as our master channel. However, we do know what the
// filename should be, so we’ll update that
ot_debug(“Found $rid, but it’s not recording”);
$masterChannel = $rid;
$cfn = getVariable($masterChannel, “CALLFILENAME”);
if (!empty($cfn)) {
$callFileName = $cfn;
}
}

This now works exactly as I want it to, starting a recording on a queue, transferring the call to a queue member, and then allowing the queue member to pause the recording multiple times. Hacky and not elegant at all, but it got the results I wanted without understanding the actual logic behind how the channels are being created and identified. It has a strange side effect that all pauses after the first include the “beep” sound in the final recording, but the first does not.

Could an expert weigh in on this issue? Is this a bug or some sort of intended functionality? Does not seem like expected behavior for a non-technical end-user to have to tangle with.

Thanks for your time.

Edit:
Also, it should be noted I attempted to just change the order it checks the channels from:
foreach (array($channel, $myMaster, $bridgePeer, $theirMaster) as $c) {
to
foreach (array($bridgePeer, $theirMaster, $channel, $myMaster) as $c) {
and that just made the recording bizarre. It wiped out all of the audio after the first pause and instead repeated the last unpaused section a bunch of times. I.E. Instead of ‘a b c d e f g’ it sounded like ‘a g g g g g g’

You need to be on FreePBX 13. That is where we made the changes to Call Recordings and if it still has a bug with pausing the recording that is the only version it would be fixed in.

Hello Tony,

Thank you for your response.
I upgraded our testbed to:
FreePBX 13.0.131
Asterisk 11.17.1
Call Recording 13.0.10
I upgraded all modules and performed a yum update.

I just verified that this issue still exists. When starting a recording with the One Touch Recording feature it works as expected, pausing and recording multiple times.
When the recording is started via a queue, it fails to pause after the first time.

I performed the following:

  • cp /var/www/html/admin/modules/callrecording/bin/one_touch_record.php /var/www/html/admin/modules/callrecording/bin/one_touch_record_custom.php
  • chown asterisk:asterisk /var/www/html/admin/modules/callrecording/bin/one_touch_record_custom.php
  • ln -sf /var/www/html/admin/modules/callrecording/bin/one_touch_record_custom.php /var/lib/asterisk/bin/one_touch_record.php

The above:

  • Copied the file into a custom one I can edit without altering the original
  • Changed the ownership from root root to asterisk asterisk
  • Overwrote the symbolic link that actually gets run to point to my custom file

and then in one_touch_record_custom.php I changed:

170 ot_debug(“Stopping”);
171 $astman->stopmixmonitor($rid, rand());
172 setVariable($rid, “REC_STATUS”, “STOPPED”);
173 setVariable($channel, “REC_STATUS”, “STOPPED”);
174 setVariable($bridgePeer, “REC_STATUS”, “STOPPED”);
175 setVariable($channel, “ONETOUCH_REC_SCRIPT_STATUS”, “RECORDING_STOPPED”);
176 exit(0);

to

170 ot_debug(“Stopping”);
171 $astman->stopmixmonitor($rid, rand());
172 $astman->stopmixmonitor($channel, rand());
173 $astman->stopmixmonitor($myMaster, rand());
174 $astman->stopmixmonitor($bridgePeer, rand());
175 $astman->stopmixmonitor($theirMaster, rand());
176 setVariable($rid, “REC_STATUS”, “STOPPED”);
177 setVariable($channel, “REC_STATUS”, “STOPPED”);
178 setVariable($myMaster, “REC_STATUS”, “STOPPED”);
179 setVariable($bridgePeer, “REC_STATUS”, “STOPPED”);
180 setVariable($theirMaster, “REC_STATUS”, “STOPPED”);
181 setVariable($channel, “ONETOUCH_REC_SCRIPT_STATUS”, “RECORDING_STOPPED”);
182 exit(0);

I tested again and the recording started from the queue now correctly pauses every time.

Just to update this thread:
I had put this project on the backburner and have now revisited it. I have a new VM server setup:
FreePBX 13.0.190.19
Asterisk 13.14.0, Copyright © 1999 - 2014, Digium, Inc. and others.
Call Recording 13.0.11.1 Stable Sangoma Technologies Corporation AGPLv3+ Enabled

I migrated my customer service department’s queue and extensions to our new server on Tuesday night and in the process confirmed this issues still exists.

Again, I copied one_touch_record.php into one_touch_record_custom.php and added several lines to make it work:

168         ot_debug("Stopping");
169         $astman->stopmixmonitor($rid, rand());
170 // added
171 $astman->stopmixmonitor($channel, rand());
172 $astman->stopmixmonitor($bridgePeer, rand());
173 $astman->stopmixmonitor($myMaster, rand());
174 $astman->stopmixmonitor($theirMaster, rand());
175 setVariable($rid, "REC_STATUS", "STOPPED");
176 // end added
177         setVariable($rid, "REC_STATUS", "STOPPED");
178         setVariable($channel, "REC_STATUS", "STOPPED");
179         setVariable($bridgePeer, "REC_STATUS", "STOPPED");
180 // added
181 setVariable($myMaster, "REC_STATUS", "STOPPED");
182 setVariable($theirMaster, "REC_STATUS", "STOPPED");
183 // end added
184         setVariable($channel, "ONETOUCH_REC_SCRIPT_STATUS", "RECORDING_STOPPED");
185         exit(0);
186     }

Then I updated the symlink /var/lib/asterisk/bin/one_touch_record.php -> /var/www/html/admin/modules/callrecording/bin/one_touch_record_custom.php

Now *1 correctly pauses all times after the first on the server my customer service department is currently live on.

Edit:
Also, I’d be willing to bet that I don’t have to stopmixmonitor on every single one of the variables I used, however I decided to kill a fly with a sledgehammer and once I got it working I never bothered to go back and determine exactly which channel needs to be paused. If I get some extra time I’ll see if I can’t comment out some of those lines and run some tests to determine exactly what needs to be paused for this to continue working.

Thanks!

Not to speak for the Sangoma guys, but I know they rely heavily on the ticket system for getting things fixed.

I’m thinking a ticket in Issues with these notes on it would be appreciated by the guy that manages the change list…

Ya without a ticket nobody is going to look at anything. The forums are great to have a converstation but bugs and features must be reported at issues.freepbx.org to get any action.

Hi, thanks for the responses. How about if I make a fork and pull request over on Github after I determine exactly which channel needs to be paused? Should I make the pull request and open a ticket as well, or will just the pull request suffice?

You will need a ticket and this is potentially dangerous change and something that may not go in until 14 as its changing behvaiour.

1 Like

With that said, the clear message is “a ticket is a must”.