Hi there,
I solved this by recompiling Asterisk with a small fix applied to apps/app_mixmonitor.c. Here are the steps I took in identifying and solving this, for everyone that might be interested.
-
I identified the version of Asterisk used in the FreePBX distro in question typing “core show version” at the CLI. The output showed me it was Asterisk 10.10.0
-
I downloaded the sources package of this version of Asterisk from http://downloads.asterisk.org/pub/telephony/asterisk/releases/ ; namely asterisk-10.10.0.tar.gz
-
I started a new project in my IDE of choice and loaded the Asterisk sources as a project. I then used “Find in files” to locate all references to the ast_writefile function, defined in main/file.c. The problem was evidently in MixMonitor (the module taking care of call recording) so I easily identified the following:
/usr/src/asterisk-10.10.0/apps/app_mixmonitor.c:
359 }
360
361: if (!(*fs = ast_writefile(filename, ext, NULL, *oflags, 0, 0666))) {
362 ast_log(LOG_ERROR, “Cannot open %s.%s\n”, filename, ext);
363 *errflag = 1;
- The above is a fragment of the mixmonitor_save_prep function, declared in apps/app_mixmonitor.c. This is how the whole function looked like:
static void mixmonitor_save_prep(struct mixmonitor *mixmonitor, char *filename, struct ast_filestream **fs, unsigned int *oflags, int errflag)
{
/ Initialize the file if not already done so */
char *ext = NULL;
char *last_slash = NULL;
if (!ast_strlen_zero(filename)) {
if (!*fs && !*errflag && !mixmonitor->mixmonitor_ds->fs_quit) {
*oflags = O_CREAT | O_WRONLY;
*oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
last_slash = strrchr(filename, '/');
if ((ext = strrchr(filename, '.')) && (ext > last_slash)) {
*(ext++) = '\0';
} else {
ext = "raw";
}
if (!(*fs = ast_writefile(filename, ext, NULL, *oflags, 0, 0666))) {
ast_log(LOG_ERROR, "Cannot open %s.%s\n", filename, ext);
*errflag = 1;
} else {
struct ast_filestream *tmp = *fs;
mixmonitor->mixmonitor_ds->samp_rate = MAX(mixmonitor->mixmonitor_ds->samp_rate, ast_format_rate(&tmp->fmt->format));
}
}
}
}
- Because of the funny characters I got in the logs my initial hunch was that this was some erroneous use of the pointer operator in C. I thought this resulted in the ast_writefile function getting passed an address rather than the value found at that address (you know how strings in C are).
The function is determining the recording type based on the file extension, doing some string manipulation with the recording filename on rows 355-356. I don’t have much experience with debugging under linux and didn’t want to delve too deep in this, so I decided I will first try a quick and dirty fix. I hardcoded the value of the ext variable after the string manipulation part like this:
if ((ext = strrchr(filename, '.')) && (ext > last_slash)) {
*(ext++) = '\0';
} else {
ext = "raw";
}
/* UGLY FIX START: CALL RECORDING - FORCE THE RECORDING FORMAT */
ext = "wav";
/* UGLY FIX END */
- I now had to recompile Asterisk and see if my suggested fix will work.
I pulled the Asterisk sources on the freepbx box:
[root@localhost ~]# cd /usr/src/
[root@localhost src]# wget http://downloads.asterisk.org/pub/telephony/asterisk/releases/asterisk-10.10.0.tar.gz
[root@localhost src]# tar xvfz asterisk-10.10.0.tar.gz
[root@localhost src]# cd asterisk-10.10.0/
I then used my text editor of choice to amend the app_mixmonitor.c file and apply the fix:
[root@localhost asterisk-10.10.0]# vim apps/app_mixmonitor.c
After saving the file it was then time to recompile:
[root@localhost asterisk-10.10.0]# ./configure
The configure script will complain that there are certain packages missing. These are the ones that did the trick for me:
[root@localhost asterisk-10.10.0]# yum install make
[root@localhost asterisk-10.10.0]# yum install ncurses-devel
[root@localhost asterisk-10.10.0]# yum install libxml2-devel
[root@localhost asterisk-10.10.0]# yum install sqlite-devel.i686
Finally you do make and make install:
[root@localhost asterisk-10.10.0]# make
[root@localhost asterisk-10.10.0]# make install
Upon installation completion make complained about some of the asterisk modules (it gave me the list but I did not save it) in the modules folder were not part of this installation (or something similar). I ignored this message and did a reboot on the PBX.
Miraculously call recording was working after the reboot. I had my PBX completely set up beforehand (the call recording was the final issue I had to address) so I managed to do some functional testing right after the recompile and everything seemed to be working as expeced.
I will now be deploying the newly setup PBX into production to replace an old trixbox CE install and I will update this thread if I notice any side effects.
I hope this helps!
DISCLAIMER Reproducing this solution may break or impair your FreePBX install so use at your own risk.