Asterisk 1.8-15 CentOS5 FreePBX настройка факса.

Метки: Asterisk, FreePBX

чтобы настроить прием факса на email в Астериске надо многое сделать:

начать надо с проверки версии установленных в системе пакетов, выглядеть это должно примерно так:

[root]# yum list installed |grep aster
asterisk.i386                              1.8.15-0.cert1.1_centos5    installed
asterisk-addons-core.i386                  1.8.15-0.cert1.1_centos5    installed
asterisk-addons-mysql.i386                 1.8.15-0.cert1.1_centos5    installed
asterisk-core.i386                         1.8.15-0.cert1.1_centos5    installed
asterisk-dahdi.i386                        1.8.15-0.cert1.1_centos5    installed
asterisk-devel.i386                        1.8.15-0.cert1.1_centos5    installed
asterisk-doc.i386                          1.8.15-0.cert1.1_centos5    installed
asterisk-sounds-core-en-gsm.noarch         1.4.21-1_centos5            installed
asterisk-sounds-core-en-ulaw.noarch        1.4.21-1_centos5            installed
asterisk-sounds-extra-en-gsm.noarch        1.4.11-1_centos5            installed
asterisk-sounds-moh-opsound-ulaw.noarch    0.0-4_centos5               installed
asterisk-voicemail.i386                    1.8.15-0.cert1.1_centos5    installed
asterisknow-version.noarch                 2.0.0-4_centos5             installed
[root]# yum list installed |grep tiff
libtiff.i386                               3.8.2-18.el5_8              installed
libtiff-devel.i386                         3.8.2-18.el5_8              installed
[root]#

обязательно asterisk-devel libtiff.

сделать прохождение t38 кодека (t38pt_udptl = yes)
и убрать факсдетект (faxdetect=no) в конфигурации sip.

теперь нужно проверить установлен ли модуль spandsp.so в системе:

*CLI> module show like fax
Module                         Description                              Use Count
res_fax.so                     Generic FAX Applications                 1        
res_fax_spandsp.so             Spandsp G.711 and T.38 FAX Technologies  2        
2 modules loaded

если показывает что Spadsp не загружен, значит скорее всего его нет.
Выйти из этой ситуации можно двумя путями:
1. Пересобрать из исходников Астериск с поддержкой факса (ставится в меню конфигуре).
2. Собрать динамическую библиотеку libspandsp.so из исходников.

остановлюсь на втором варианте, так как его я и реализовывал на своей системе:

1. идем сюда http://soft-switch.org/ и читаем как собрать и установить сие чудо,
устанавливается просто, понадобится

gcc.i386                                   4.1.2-54.el5                installed
libgcc.i386                                4.1.2-54.el5                installed

а дальше все как обычно, проверяем whereis spandsp.so или libspandsp.so.

2. далее надо сделать из библиотеки модуль для астериска, берем res/res_fax_spandsp.c
из подходящих нам исходников, у меня был
res_fax_spandsp.c?revision=370667 и выполняем для него такие операции...
3.

gcc -g -Wall -D_REENTRANT -D_GNU_SOURCE -fPIC -DAST_MODULE=\"res_fax_spandsp\"
   -c -o res_fax_spandsp.o res_fax_spandsp.c

4.

gcc -shared -Xlinker -x /usr/lib/libspandsp.so -o res_fax_spandsp.so  
res_fax_spandsp.o

5. кладем получившийся модуль res_fax_spandsp.so в каталог модулей астериска -
у меня он /usr/lib/asterisk/modules
6. убеждаемся что

[modules]
autoload=yes

7. делаем amportal restart
8. проверяем подключился ли модуль.

далее переходим к dial plan.

1. правим extensions_custom.conf
у меня он выглядит следующим образом брал отсюда
http://asterisk-system.ru/asterisk/nastraivaem-asterisk-1-8-na-priem-i-o...

чтобы изнутри звонить было не на 666, любой можете указать вместо 5000

exten => 5000,1,NoOp(-------------------Call from ${CALLERID(number)} to ${EXTEN}------------------)
exten => 5000,n,Goto(fax-rx,receive,1)

контекст для custom dectination

[fax001]
exten => fax,1,NoOp(-------------------Call from ${CALLERID(number)} to ${EXTEN}------------------)
exten => fax,n,Goto(fax-rx,receive,1)

контекст принимающий факс

[fax-rx]
 exten => receive,1,NoOP(------------------- FAX from ${CALLERID(number)} ------------------)
 exten => receive,n,Answer()
 exten => receive,n,Wait(2)
 exten => receive,n,Set(FILENAME=fax-${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)}-${CALLERID(number)})
 exten => receive,n,Set(FAXFILE=/var/spool/asterisk/fax/receive/${FILENAME}.tif)
 exten => receive,n,Set(FAXOPT(headerinfo)=Received by ${CALLERID(number)} ${STRFTIME(${EPOCH},,%Y-%m-%d %H:%M)})
 exten => receive,n,Set(FAXOPT(localstationid)=OFFICE)
 exten => receive,n,Set(FAXOPT(maxrate)=14400)
 exten => receive,n,Set(FAXOPT(minrate)=2400)
 exten => receive,n,NoOp(FAXOPT(ecm) : ${FAXOPT(ecm)})
 exten => receive,n,NoOp(FAXOPT(headerinfo) : ${FAXOPT(headerinfo)})
 exten => receive,n,NoOp(FAXOPT(localstationid) : ${FAXOPT(localstationid)})
 exten => receive,n,NoOp(FAXOPT(maxrate) : ${FAXOPT(maxrate)})
 exten => receive,n,NoOp(FAXOPT(minrate) : ${FAXOPT(minrate)})
 exten => receive,n,NoOp(**** RECEIVING FAX : ${FAXFILE} ****)
 exten => receive,n,ReceiveFAX(${FAXFILE})
 exten => receive,n,Hangup()
 exten => h,1,NoOP(------------------- FAX from ${CALLERID(number)} ------------------)
 exten => h,n,NoOP(------------------- STATUS ${FAXSTATUS} ${FAXERROR} ------------------)
 exten => h,n,system(path-to-/fax-process.pl --to mail@addr --from mail@addr --subject "Fax prineat s ${URIENCODE(${CALLERID(number)})} ${URIENCODE(${CALLERID(name)})}" --attachment ${FILENAME}.pdf --type application/pdf --file ${FAXFILE});

скачать скрипт fax-process.pl:

#!/usr/bin/perl -w

# Small program to process a tiff file into a PDF and email it.
#
# Distributed under the terms of the GNU General Public License (GPL) Version 2
# Copyright 2005 by Rob Thomas (xrobau@gmail.com)

use MIME::Base64;
use Net::SMTP;

# Default paramaters
my $to = "fax\@asterisk.org";
my $from = "fax\@";
my $subject = "Fax received";
my $ct = "application/x-pdf";
my $file = undef;
my $attachment = undef;

# Care about the hostname.
my $hostname = `/bin/hostname`;
chomp ($hostname);
if ($hostname =~ /localhost/) {
        $hostname = "asterisk.org";
}
$from .= $hostname;

# Usage:
my $usage="Usage: --file filename [--attachment filename] [--to email_address]
[--from email_address] [--type content/type] [--subject \"Subject Of Email\"]"
;

# Parse command line..
while (my $cmd = shift @ARGV) {
  chomp $cmd;
  # My kingdom for a 'switch'
  if ($cmd eq "--to") {
        my $tmp = shift @ARGV;
        $to = $tmp if (defined $tmp);
  } elsif ($cmd eq "--subject") {
        my $tmp = shift @ARGV;
        if ($tmp =~ /\^(\")|^(\')/) {
                # It's a quoted string
                my $delim = $+;   # $+ is 'last match', which is ' or "

                $tmp =~ s/\Q$delim\E//; # Strip out ' or "
                $subject = $tmp;
                while ($tmp = shift @ARGV) {
                        if ($tmp =~ /\Q$delim\E/) {
                                $tmp =~ s/\Q$delim\E//;
                                last;
                        }
                $subject .= $tmp;
                }
        } else {
                # It's a single word
                $subject = $tmp;
        }
  # Convert %2x to proper characters, leave anything else alone.
  $subject =~ s/\%20/ /g;
    $subject =~ s/\%21/\!/g;
    $subject =~ s/\%22/\"/g;
    $subject =~ s/\%23/\#/g;
    $subject =~ s/\%24/\$/g;
    $subject =~ s/\%25/\%/g;
    $subject =~ s/\%26/\&/g;
    $subject =~ s/\%27/\'/g;
    $subject =~ s/\%28/\(/g;
    $subject =~ s/\%29/\)/g;
    $subject =~ s/\%2a/\*/g;
    $subject =~ s/\%2A/\*/g;
    $subject =~ s/\%2b/\+/g;
    $subject =~ s/\%2B/\+/g;
    $subject =~ s/\%2c/\,/g;
    $subject =~ s/\%2C/\,/g;
    $subject =~ s/\%2d/\-/g;
    $subject =~ s/\%2D/\-/g;
    $subject =~ s/\%2e/\./g;
    $subject =~ s/\%2E/\./g;
    $subject =~ s/\%2f/\//g;
    $subject =~ s/\%2F/\//g;
  } elsif ($cmd eq "
--type") {
        my $tmp = shift @ARGV;
        $ct = $tmp if (defined $tmp);
  } elsif ($cmd eq "
--from") {
        my $tmp = shift @ARGV;
        $from = $tmp if (defined $tmp);
  } elsif ($cmd eq "
--file") {
        my $tmp = shift @ARGV;
        $file = $tmp if (defined $tmp);
  } elsif ($cmd eq "
--attachment") {
        my $tmp = shift @ARGV;
        $attachment = $tmp if (defined $tmp);
  } else {
        die "
$cmd not understood\n$usage\n";
  }

}

# OK. All our variables are set up.
# Lets make sure that we know about a file...
die $usage unless $file;
# and that the file exists...
open( FILE, $file ) or die "Error opening $file: $!";
# Oh, did we possibly not specify an attachment name?
$attachment = $file unless ($attachment);

my $encoded="";
my $buf="
";
# First, lets find out if it's a TIFF file
read(FILE, $buf, 4);
if ($buf eq "
MM\x00\x2a" || $buf eq "II\x2a\x00") {
        # Tiff magic - We need to convert it to pdf first
        # Need to do some error testing here - what happens if tiff2pdf
        # doesn't exist?
        open PDF, "
tiff2pdf $file|";
        $buf = "
";
        while (read(PDF, $buf, 60*57))  {
                $encoded .= encode_base64($buf);
        }
        close PDF;
} else {
        # It's a PDF already
        # Go back to the start of the file, and start again
        seek(FILE, 0, 0);
        while (read(FILE, $buf, 60*57)) {
                $encoded .= encode_base64($buf);
        }
}
close FILE;

# Now we have the file, we should ensure that there's no paths on the
# filename..
$attachment =~ s/^.+\///;

# And that's pretty much all the hard work done. Now we just create the
# headers for the MIME encapsulation:
my $boundary = '------FREEPBX_FAX_MAIL:';
my $dtime = `date`;
chomp $dtime;
my @chrs = ('0' .. '9', 'A' .. 'Z', 'a' .. 'z');
foreach (0..16) { $boundary .= $chrs[rand (scalar @chrs)]; }

my $len = length $encoded;
# message body..
my $msg ="Content-Class: urn:content-classes:message
Content-Transfer-Encoding: 7bit
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=\"$boundary\"
From: $from
Date: $dtime
Reply-To: $from
X-Mailer: dofaxmail.pl
To: $to
Subject: $subject

This is a multi-part message in MIME format.

--$boundary
Content-Type: text/plain; charset=\"us-ascii\"
Content-Transfer-Encoding: quoted-printable

A Fax has been recieved by the fax gateway, and is attached to this message.

--$boundary
Content-Type: $ct; name=\"$attachment\"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=\"$attachment\"

$encoded
--$boundary--
";

#print "$msg";
# Now we just send it.
my $smtp = Net::SMTP-> new("127.0.0.1", Debug => 0) or
  die "Net::SMTP::new: $!";
$smtp-> mail($from);
$smtp-> recipient($to);
$smtp-> data();
$smtp-> datasend($msg);
$smtp-> dataend();

2. когда я все это проделал первый раз, тон факса бы слышен, но сам прием не работал.. висел минуту и в результате выдавал что статус failed.
пробовал g711 и t38... без t38 вообще за 2 секунды звонок отваливался.
3. оказалось дело в провайдере, у него был не активен t38 на линии моего транка, так что если не растет кокос, возможно стоит спросить поставщика услуг.

пробуйте, пишите комменты, если что помогу.

Уперся в:

localhost*CLI> module load res_fax_spandsp.so
Unable to load module res_fax_spandsp.so
Command 'module load res_fax_spandsp.so' failed.
[May 10 20:11:29] WARNING[19200]: loader.c:497 load_dynamic_module: Error loading module 'res_fax_spandsp.so': /usr/lib64/asterisk/modules/res_fax_spandsp.so: undefined symbol: ast_fax_tech_register
[May 10 20:11:29] WARNING[19200]: loader.c:910 load_resource: Module 'res_fax_spandsp.so' could not be loaded.<blockcode>

похоже что у вас астериск не подходящей версии..

Tags for Asterisk 1.8-15 CentOS5 FreePBX настройка факса.
Вход в систему
Image CAPTCHA
Enter the characters shown in the image.