|
|
|
|
|
|
|
Fax-Empfang mit AsteriskSeit der Verfügbarkeit einer CAPI unter Linux kann man auch mit passiven ISDN Karten, wie z.B. der AVM Fritz!Card PCI, Faxe empfangen. Hierfür brauchen wir weder mgetty noch hylafax, sondern nur unsere Asterisk und das Asterisk app "receivefax". Anschließend zeige ich Euch dann, wie der Faxversand funktioniert.
UPDATE: 12.03.2007Ich habe mir sagen lassen, dass diese Anleitung ebenso mit asterisk-bristuff und Zaptel Karten statt Fritz mit Capi funktioniert. Ihr könnt also auch die günstigen Karten mit dem "Kölner Dom" in eurem Fax Server installieren.
Asterisk-App-FaxFür Debian/etch (stable) bekommt Ihr das Paket mit "apt-get update; apt-get install asterisk-app-fax libtiff-tools libfile-sync-perl libmime-lite-perl libconfig-tiny-perl liblocale-gettext-perl libpaper-utils psutils gs-common". Das installiert automatisch auch alle Abhängigkeiten wie z.B. spandsp (libspandsp1).
Eine Konfigurationsdatei wird im Verzeichnis: "/etc/asterisk/asterisk_faxreceive.conf/faxreceive.conf" angelegt, ich habe jedoch lieber alle Configs in "/etc/asterisk". Um das mitgelieferte AGI Skript ("/usr/share/asterisk/agi-bin/receive_fax") nicht ändern zu müssen, legen wir einen symbolic link an: "ln -s /etc/asterisk/asterisk_faxreceive.conf/faxreceive.conf /etc/asterisk/faxreceive.conf".
E-Mail KonfigurationDamit E-Mails versand werden können, muss SMTP eingerichtet sein. Unter debian nimmt man dafür in der Regel exim. Falls Ihr dies bei der Installation noch nicht konfiguriert habt, könnt Ihr dies mit "dpkg-reconfigure exim4-config" nachholen.
Ich verwende die Einstellung "mail sent by smarthost; no local mail".
/etc/asterisk/asterisk_faxreceive.conf/faxreceive.conf
#
# See /usr/share/doc/asterisk-faxreceive/README for documentation.
#
# $Id: asterisk_faxreceive.conf 75 2005-09-04 10:52:23Z florz $
#
# hier muss die Absendeadresse hin, Ihr könnt auch Eure "normale" E-Mail Adresse nehmen
# stellt aber sicher, dass dieser Absender von dieser Maschine aus Mails versenden darf (relaying)
# Mailversand geht in Debian üblicherweise mit exim
email_from="Asterisk-Faxsystem" <asterisk@example.com>
# Papierformat DIN A4
paper_name=a4
# Wo sollen temporäre Dateien hin?
# Vorsicht! Hier kann unter Umständen jeder mitlesen!
temp_dir=/tmp
[recipient foobar]
# Hier muss die Adresse des Empängers hin, also Eure normale E-Mail.
email_to=fax@example.com
#locale=de_DE
AGIDas Original AGI hat bei mir wegen Problemen mit den psutils nicht funktioniert. Um den in der Regel unnötigen Konvertierungen aus dem Weg zu gehen, ersetzen wir kurzerhand die 25 Zeilen von system("tiff2ps ...") bis system("ps2pdf ..."), also Zeilen 145-170, durch eine einzige Zeile:
system("ps2pdf $recv_filename.resized.ps $recv_filename.pdf 1>&2")&&die();
Dafür braucht Ihr das Paket "libtiff-tools".
Der Rest des Skripts kann bleiben wie er ist, trotzdem hier nochmal die angepasste Version:
/usr/share/asterisk/agi-bin/receive_fax#!/usr/bin/perl
#
# asterisk-faxreceive - handles reception of faxes using app_rxfax and
# dispatches the received faxes via email
#
# Copyright (C) 2005 Florian Zumbiehl <florz@gmx.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# $Id: receive_fax 77 2005-09-05 19:16:10Z florz $
#
use strict;
use Fcntl ':flock';
use File::Sync 'fsync';
use File::Temp qw(tempdir);
use File::Path;
use MIME::Lite;
use Config::Tiny;
use Storable qw(nstore retrieve);
use POSIX qw(setlocale);
use Locale::gettext;
my $fax_counter_dir='/var/lib/asterisk/faxreceive/counters';
my $config_file='/etc/asterisk/asterisk_faxreceive.conf/faxreceive.conf';
$|=1;
textdomain('asterisk-faxreceive')||die();
my $config=Config::Tiny->read($config_file)||die(Config::Tiny::errstr());
my $email_from;
my $email_to;
my $deadx;
my $deady;
my $dmw;
my $dmh;
my $email_locale;
while(1){
defined($_=<stdin>)||die();
chomp();
length($_)||last;
};
#"Uses LOCALSTATIONID to identify itself to the remote end\n"
#"Sets REMOTESTATIONID to the sender CSID\n"
#" FAXPAGES to the number of pages received\n"
#" FAXBITRATE to the transmition rate\n"
#" FAXRESOLUTION to the resolution\n"
if($ARGV[0] eq 'receive'){
my $recipient=agi_get_var('FAXRECIPIENT');
$recipient eq 'new'&&die();
$recipient eq 'lock'&&die();
my $temp_dir;
my $config_defaults={
'paper_name'=>'',
'margin_vertical'=>0.25,
'margin_horizontal'=>0.25
};
defined(my $recipient_config=$config->{"recipient $recipient"})||die();
for my $c($config_defaults,$config->{_},$recipient_config){
config_get($email_from,'email_from',$c);
config_get($email_to,'email_to',$c);
($dmw,$dmh)=resolve_papername($c->{paper_name})if(defined($c->{paper_name}));
config_get($dmw,'paper_width',$c);
config_get($dmh,'paper_height',$c);
config_get($deadx,'margin_vertical',$c);
config_get($deady,'margin_horizontal',$c);
config_get($temp_dir,'temp_dir',$c);
config_get($email_locale,'locale',$c);
}
my($recv_counter,$fax_counter)=inc_fetch_counters($recipient,'recv');
my $recv_dirname=tempdir("asterisk_faxreceive.$recipient.".sprintf('%05d.%05d',$recv_counter,$fax_counter+1).'.XXXXXX',
$temp_dir ne ''?(DIR=>$temp_dir):(TMPDIR=>1))||die();
{
no strict 'refs';
nstore({
'version'=>1,
map({$_=>eval("\$$_")} (
'recipient',
'email_from',
'email_to',
'dmw',
'dmh',
'deadx',
'deady',
'email_locale'
))
},"$recv_dirname/info")||die();
}
agi_cmd("SET VARIABLE FAXRECVFILE \"$recv_dirname/fax.tiff\"",1);
agi_cmd("EXEC RxFAX \"$recv_dirname/fax.tiff\"",0);
agi_cmd("HANGUP",1);
}elsif($ARGV[0] eq 'deliver'){
my $remotecallerid=agi_get_var('MY_CALLERIDNUM');
my $recv_filename=agi_get_var('FAXRECVFILE');
my $remotestationid=agi_get_var('REMOTESTATIONID');
my $faxpages=agi_get_var('FAXPAGES');
$recv_filename=~s/\.tiff$//||die();
my $recv_dirname=$recv_filename;
$recv_dirname=~m,.*/,||die();
$recv_dirname=$&;
my $recipient;
(my %info_data=%{retrieve("$recv_dirname/info")})||die();
$info_data{version}==1||die();
{
no strict 'refs';
for(
'recipient',
'email_from',
'email_to',
'dmw',
'dmh',
'deadx',
'deady',
'email_locale'
){
my $x=$info_data{$_};
eval("\$$_=\$x");
}
}
system("tiff2ps -2az $recv_filename.tiff > $recv_filename.ps")&&die();
$dmw-=2*$deadx;
$dmh-=2*$deady;
open(my $ps_file,'<',"$recv_filename.ps")||die();
my $count;
while(defined($_=<$ps_file>)){
m/^(\d+\.\d+) (\d+\.\d+) scale$/||next;
my $sw=$1/72*2.54;
my $sh=$2/72*2.54;
my $scale;
if($dmw/$dmh>$sw/$sh){
$scale=$dmh/$sh;
}else{
$scale=$dmw/$sw;
}
my $dw=$sw*$scale;
my $dh=$sh*$scale;
my $xoff=($dmw-$dw)/2+$deadx;
my $yoff=$dmh-$dh+$deady;
$count++;
system("psselect -p$count $recv_filename.ps | pstops -w${sw}cm -h${sh}cm '0\@$scale(${xoff}cm,${yoff}cm)' >> $recv_filename.resized.ps")&&die();
}
close($ps_file)||die();
system("ps2pdf $recv_filename.resized.ps $recv_filename.pdf 1>&2")&&die();
my($fax_counter)=(inc_fetch_counters($recipient,'fax'))[1];
$email_to||die();
if($email_locale ne ''){
defined(setlocale(LC_MESSAGES,$email_locale))||die();
defined(setlocale(LC_CTYPE,$email_locale))||die();
}
my $mail=new MIME::Lite(
From => $email_from,
To => $email_to,
Type => 'text/plain; charset=iso-8859-1',
Subject => sprintf(gettext('Fax from %s (%s)'),$remotestationid,$faxpages==1?gettext('one page'):sprintf(gettext('%d pages'),$faxpages)),
Data => sprintf(gettext(<<EOD),$remotestationid,$remotecallerid eq 'CID withheld'?gettext('CID withheld'):$remotecallerid,$faxpages)
Fax station ID of the sender..: %s
Caller-ID of the sender.......: %s
Number of pages...............: %d
EOD
);
$mail->attach(
Type => 'application/pdf',
Filename => $recipient."-".sprintf(sprintf(gettext('fax%s.pdf'),'%05d'),$fax_counter),
Path => "$recv_filename.pdf"
);
defined(setlocale(LC_MESSAGES,'C'))||die();
defined(setlocale(LC_CTYPE,'C'))||die();
$mail->send()||die();
rmtree($recv_dirname,0,1);
}else{
die();
}
exit(0);
sub config_get{
my($x,$name,$config)=@_;
$_[0]=$config->{$name}if(defined($config->{$name}));
}
sub resolve_papername{
my $name=shift();
open(my $paperconf,'-|',"paperconf -csz $name")||die();
defined(my $paperdims=<$paperconf>)||die();
close($paperconf)||die();
($paperdims=~/^\s*(\d+(?:\.\d+)?|\.\d+)\s*cm\s*(\d+(?:\.\d+)?|\.\d+)\s*cm\s*$/)||die();
my $width=$1;
my $height=$2;
return($width,$height);
}
sub agi_get_var{
my $var=shift();
print("GET VARIABLE $var\n")||die();
defined(my $r=<stdin>)||die();
$r=~/^200 result=1 \((.*)\)$/||die();
return($1);
}
sub agi_cmd{
my($cmd,$correct_result)=@_;
print("$cmd\n")||die();
defined(my $r=<stdin>)||die();
$r=~/^200 result=$correct_result$/||die();
}
sub inc_fetch_counters{
my($recipient,$which)=@_;
open(my $fax_cnt_lock,'>',"$fax_counter_dir/lock")||die();
flock($fax_cnt_lock,LOCK_EX)||die();
unlink("$fax_counter_dir/$recipient.new"); # just in case an old version of this script left one of those lying around ...
if(stat("$fax_counter_dir/$recipient.new2")){
commit_counters($recipient);
}elsif(!$!{ENOENT}){
die();
}
my $recv_counter=0;
my $fax_counter=0;
if(open(my $fax_cnt,'<',"$fax_counter_dir/$recipient.cnt")){
defined(my $cnt_file_version=<$fax_cnt>)||die();
$cnt_file_version==1||die();
defined($recv_counter=<$fax_cnt>)||die();
defined($fax_counter=<$fax_cnt>)||die();
$recv_counter+=0;
$fax_counter+=0;
close($fax_cnt)||die();
}elsif(!$!{ENOENT}){
die();
}
if($which eq 'recv'){
++$recv_counter;
}elsif($which eq 'fax'){
++$fax_counter;
}else{
die();
}
open(my $fax_cnt,'>',"$fax_counter_dir/$recipient.new1")||die();
print($fax_cnt "1\n")||die();
print($fax_cnt "$recv_counter\n")||die();
print($fax_cnt "$fax_counter\n")||die();
close($fax_cnt)||die();
open($fax_cnt,'<',"$fax_counter_dir/$recipient.new1")||die();
fsync($fax_cnt)||die();
close($fax_cnt)||die();
rename("$fax_counter_dir/$recipient.new1","$fax_counter_dir/$recipient.new2")||die();
commit_counters($recipient);
flock($fax_cnt_lock,LOCK_UN)||die();
close($fax_cnt_lock)||die();
return($recv_counter,$fax_counter);
}
sub commit_counters{
my($recipient)=@_;
open(my $fax_cnt_dir,'<',$fax_counter_dir)||die();
fsync($fax_cnt_dir)||die();
unlink("$fax_counter_dir/$recipient.cnt")||$!{ENOENT}||die();
link("$fax_counter_dir/$recipient.new2","$fax_counter_dir/$recipient.cnt")||die();
fsync($fax_cnt_dir)||die();
unlink("$fax_counter_dir/$recipient.new2")||die();
close($fax_cnt_dir)||die();
}
Asterisk-Chan-CAPIFür Debian/etch (stable) bekommt Ihr das Paket mit "apt-get update; apt-get install asterisk-chan-capi".
Die Original capi.conf muss nicht geändert werden und kann eins zu eins übernommen werden:
/etc/asterisk/capi.conf;
; CAPI config
;
;
; general section
[general]
nationalprefix=0
internationalprefix=00
rxgain=0.8
txgain=0.8
language=de ;set default language
;ulaw=yes ;set this, if you live in u-law world instead of a-law
; interface sections ...
[ISDN1] ;this example interface gets name 'ISDN1' and may be any
;name not starting with 'g' or 'contr'.
;ntmode=yes ;if isdn card operates in nt mode, set this to yes
isdnmode=msn ;'MSN' (point-to-multipoint) or 'DID' (direct inward dial)
;when using NT-mode, 'DID' should be set in any case
incomingmsn=* ;allow incoming calls to this list of MSNs/DIDs, * = any
;defaultcid=123 ;set a default caller id to that interface for dial-out,
;this caller id will be used when dial option 'd' is set.
;controller=0 ;ISDN4BSD default
;controller=7 ;ISDN4BSD USB default
controller=1 ;capi controller number to use
group=1 ;dialout group
;prefix=0 ;set a prefix to calling number on incoming calls
softdtmf=on ;enable/disable software dtmf detection, recommended for AVM cards
relaxdtmf=on ;in addition to softdtmf, you can use relaxed dtmf detection
accountcode= ;Asterisk accountcode to use in CDRs
context=capi-in ;context for incoming calls
;holdtype=hold ;when Asterisk puts the call on hold, ISDN HOLD will be used. If
;set to 'local' (default value), no hold is done and Asterisk may
;play MOH.
;immediate=yes ;DID: immediate start of pbx with extension 's' if no digits were
; received on incoming call (no destination number yet)
;MSN: start pbx on CONNECT_IND and don't wait for SETUP/SENDING-COMPLETE.
; info like REDIRECTINGNUMBER may be lost, but this is necessary for
; drivers/pbx/telco which does not send SETUP or SENDING-COMPLETE.
;echosquelch=1 ;_VERY_PRIMITIVE_ echo suppression
;echocancel=yes ;EICON DIVA SERVER (CAPI) echo cancelation
;(possible values: 'no', 'yes', 'force', 'g164', 'g165')
echocancelold=yes;use facility selector 6 instead of correct 8 (necessary for older eicon drivers)
;echotail=64 ;echo cancel tail setting
;bridge=yes ;native bridging (CAPI line interconnect) if available
;callgroup=1 ;Asterisk call group
;language=de ;set language for this device (overwrites default language)
devices=2 ;number of concurrent calls on this controller
;(2 makes sense for single BRI, 30 for PRI)
/etc/asterisk/extensions.conf (relevanter Teil)[globals]
;...
TRUNK=CAPI
;...
; Die Schnittstelle zum CAPI-Fax
[faxrecv]
exten => s,1,AGI(receive_fax,receive)
exten => h,1,Set(MY_CALLERIDNUM=${CALLERIDNUM})
exten => h,2,DeadAGI(receive_fax,deliver)
; Fax Empfang für Benutzer foobar, bei mehreren Benutzern bekommt jeder seinen eigenen Kontext
[foobar-fax]
exten => fax,1,Set(LOCALSTATIONID=+49-12-345678) ; Hier Eure Faxnummer, wie sie normalerweise auf Faxen erscheint
exten => fax,2,Set(FAXRECIPIENT=foobar) ; Das ist der entsprechende Context in der faxreceive.conf
exten => fax,3,Goto(faxrecv,s,1) ; Zur Schnittstelle
; Alle ISDN Anrufe landen hier (Kontext konfigurierbar in "/etc/asterisk/capi.conf")
[capi-in]
exten => 345678,1,Goto(foobar-fax,fax,1) ; Eure Faxnummer hier eintragen
|
|
|
|
|
|
Wenn Euch diese Seite weitergeholfen hat, dann verlinkt sie bitte. Ihr habt ein Problem? Fragen, Anregungen und Kritik bitte an feedback@lilalinux.net
Ihr könnt mich auch per ICQ erreichen: 1028730, sowie mit Jabber/GoogleTalk/XMPP: lilalinux@jabber.net-lab.net
|
|
|
|