AF
Asterisk Forum
обсуждения телефонии, VoIP и IP-PBX
12разделов
5 423тем
34 385сообщений
← К списку тем

fax on asterisk 1.2.12.1

Newbies/FAQ Forum 12 сообщений -
#1

Имеется asterisk 1.2.12.1 доставшийся совместно с FXO картой от Sangoma A200d. Живет через WANPIPE Release: 3.2.7 на CentOS 4 c ядром 2.6.9-67.0.22.ELsmp.
Возникла потребность послать-принять факс через Asterisk (через FXO карту только, без всяческих T.3Cool. Однако, изучение перечня доступных приложений (как и содержимого /usr/lib/asterisk/modules/) показало полное отсутствие каких-либо приложений, связанных с факсом. Я понимаю, что 1.2 это из области некрофилии, но хочется найти наименее геморройное решение, ведь вроде как даже во времена 1.2 факс-приложения существовали. Поэтому вопрос возможно ли добавить к моему старью подобный функционал и если да, то как именно это сделать?

п.с. вопрос обновления на более новую версию тоже рассматривается, но по логике должен быть сопряжен с большим головняком, так как придется обновлять все, включая WANPIPE и эта перспектива слегка пугает.

п.п.с собственно систему отправки факсов через самбу я прикрутил согласно http://asteriskforum.ru/viewtopic.php?t=1677, но при попытке отправки естественно получаю жалобу
Код:
WARNING[24019]: pbx.c:5152 ast_pbx_run_app: No such application 'SendFax '


Added after 1 hours 3 minutes:

Читаю http://www.voip-info.org/wiki/view/app_rxfax+and+app_txfax. По ссылке http://www.soft-switch.org/downloads/snapshots/spandsp/ самый старый файл это spandsp-20070908.tar.gz, то есть никаких директорий test-apps-asterisk-1.2 и test-apps-asterisk-1.4 там нету.

Поставил spandsp-0.0.5, дальше в мане по установке spandsp идет ссылка на http://sourceforge.net/projects/agx-ast-addons как на источник приложений. Там версия agx-ast-addons-1.4.17.5 и в ней имеются исходники app_rxfax.c и app_txfax.c.

На правильном ли я пути и будут ли они совместимы с моим asterisk 1.2.12.1?

Added after 29 minutes:

Собираться agx-ast-addons-1.4.17.5 не захотел, так как в текущих исходниках /usr/src/asterisk/ (asterisk-1.2.12.1.tar.gz) отсутствует файл autoconfig.h (ну и многое чего еще не так в имеющемся asterisk.h). Sad

Вопрос остался, где найти антикварные исходники app_rxfax.c и app_txfax.c, которые бы собрались с asterisk-1.2.12.1?
#2

Можно обновиться до последнего релиза в ветке 1.2.
А там уж и прикрутить txfax & rxfax
#3

посмотрите в ветку http://asteriskforum.ru/viewtopic.php?t=1761
вам подойдет и для просто и для т38(на будущее) Smile

просто там много че для факсов сделано

я работаю вот с этим астериском до сих пор
http://asteriskforum.ru/download.php?id=354
ну если не считать патчи по безопасности))

_________________
нанотехнолигии в области Asterisk
#5

Cache писал(а):
посмотрите в ветку http://asteriskforum.ru/viewtopic.php?t=1761
вам подойдет и для просто и для т38(на будущее)


То есть все же рекомендуете переходить на 1.4? Не подскажете, это обойдется только обновлением asterisk или wanpipe обновлять тоже потребуется? Просто если обновлять, то хотелось бы это сделать минимальной кровью и если что-то пойдет не так то легко откатиться назад, система то рабочая сейчас.
#6

Собрал 1.4.21.1 c указанным патчем, предварительно установив libpri-1.4.10 и zaptel-1.4.12.1 (без этого не собирался chan_zap.so), обновил wanpipe до 3.4.1, теперь все пускается нормально.
Важный момент: при инсталяции wanpipe необходи указать правильный путь к zaptel, по умолчанию он ищет его в /usr/src/zaptel/. Я сделал символические ссылки их /usr/src на дистрибутивы zaptel, wanpipe и *. Из-за того, что вчера я оставил исходники старого zaptel (1.2.9.1) в /usr/src * не мог загрузить chan_zap.so с сообщением:
Код:
[May 31 17:19:37] ERROR[28813] chan_zap.c: Unable to get parameters
[May 31 17:19:37] ERROR[28813] chan_zap.c: Unable to register channel '1'


При этом никакие конфиги не правил (ну почти, посмотрел на что есть warning в /var/log/asterisk/message) и еще убрал автолоад модулей согласно http://asteriskforum.ru/viewtopic.php?t=1270

Сейчас буду разбираться с факсом. Wink
#7

что-то не выходит каменный цветок Sad. уже и libspandsp.so.1 прописал линком в /lib (без этого не грузился app_fax.so), но отправляться факс (просто на обычный аппарат) не желает:
Код:
[Jun 1 11:55:38] WARNING[17492]: app_fax.c:170 phase_e_handler: Error transmitting fax. result=49: The call dropped prematurely.
[Jun 1 11:55:38] WARNING[17492]: app_fax.c:612 transmit: Transmission error
-- Hungup 'Zap/2-1'


поборол. засада было в том, что при установке wanpipe прописал аппаратные определения DTMF & FAX. как убрал, так сразу факс прошел.

Added after 1 hours 46 minutes:

Про определение входящего факса. Установил в zapata.conf faxdetect=incoming (подсмотрел тут). Слегка помучавшись таки заставил запускаться макрос из extension fax (он, как оказалось, должен быть в том контексте, который будет текущим на момент определения входящего факса, то есть через 2-5 секунд после Answer). Отлаживать макрос буду уже завтра.
#8

По отправке факса. Все отлично работает согласно этим рекомендациям.
Правда, то, как отправляется факс скриптом Cache-а не позволяет обработать результат отправки. Поэтому я его немного подправил пользуясь http://www.voip-info.org/tiki-index.php? ... o-dial+out.
Во-первых отправку запускаю из контекста faxsend, а не вызовом application на прямую, что позволит обработать результаты. Во-вторых опция Archive сохранит обработанный звонок с результатами в /var/spool/asterisk/outgoing/outgoing_done, причем, что самое приятное, добавит туда статус звонка Completed, Expired or Failed, что интереснее чем просто голый call файл.

create_call_fax:
Код:
#!/bin/sh
DATE=`date +%d.%m.%Y-%H:%M:%S`
OUTGOINGDIR=/var/spool/asterisk/outgoing
OUTDIR=/opt/fax/out
TIFFDIR=/opt/fax/tiff
LOGFILE=/opt/fax/fax_logs
NUMBER=$6
FROM=$5
FAXNAME="fax-$DATE-from-$FROM-to-$NUMBER"
cat $OUTDIR/$7 | gs -q -sDEVICE=tiffg3 -sPAPERSIZE=a4 -r204x196 -dNOPAUSE -sOutputFile=$TIFFDIR/$FAXNAME.tif -

cat s,1,SendFax(${faxfile})
exten => s,2,NoOp(Fax Send completed)
exten => s,n,NoOp(Send status is ${FAXSTATUS})
exten => s,n,NoOp(Fax sent to ${REMOTESTATIONID})


Кстати, при SendFax стоит использовать контекст fail? Возможна ли тут ситуация "If the call is not answered". Мне проверить этот момент трудно потому, что все телефонные операторы всем автоматом предоставляют голосовую почту, так что какой-то да ответ будет всегда. А при неудаче именно отправки факса мы просто получим FAXSTATUS.
#10

Наваял скрипт для обработки результатов отправки. Вроде все хорошо, но если передача обрывается, то имеем:
Код:

-- Executing [s@faxsend:1] SendFAX("Zap/2-1", "/opt/fax/tiff/fax-04.06.2009-08:49:48-from-re
ceptionist-to-4362201.tif") in new stack
[Jun 4 08:51:12] WARNING[591]: app_fax.c:170 phase_e_handler: Error transmitting fax. result=49: The call dropped prematurely.
[Jun 4 08:51:12] WARNING[591]: app_fax.c:612 transmit: Transmission error
== Spawn extension (faxsend, s, 1) exited non-zero on 'Zap/2-1'
-- Hungup 'Zap/2-1'


В extensions.conf контекст отправки исправлен таким образом:
Цитата:
[faxsend]
exten => s,1,SendFax(${faxfile})
exten => s,2,NoOp(Fax Send completed)
exten => s,n,NoOp(Send status is ${FAXSTATUS})
exten => s,n,NoOp(Fax sent to ${REMOTESTATIONID})
exten => s,n,Macro(faxresult,${FAXSTATUS},${FAXERROR},${REMOTESTATIONID},${FAXPAGES},${FAXBITRATE},${FAXRESOLUTION},${faxfile})
exten => failed,1,Macro(faxresult,${FAXSTATUS},${FAXERROR},${REMOTESTATIONID},${FAXPAGES},${FAXBITRATE},${FAXRESOLUTION},${faxfile})


Что интересно, если дозвона не произошло (time out), то SendFax корректно завершается, все отрабатывается в контексте s, но кроме того имеем в логе
Код:
[Jun 3 20:09:53] WARNING[31082]: pbx.c:2538 __ast_pbx_run: Timeout, but no rule 't' in context
'faxsend'
-- Hungup 'Zap/2-1'

То есть идет поиск екстеншина t, но он тут и не нужен, так как s к этому моменту отработал и макрос faxresult выполнился. А вот при обрыве передачи исполнение контекста прерывается совсем. Почему так и как отловить результат отправки в таком случае?

п.с. макрос faxresult и bash скрипт, который формирует письмо выложу после того, как разберусь с этим вопросом.
#11

Заменить
exten => failed,1,Macro(faxresult,${FAXSTATUS},${FAXERROR},${REMOTESTATIONID},${FAXPAGES},${FAXBITRATE},${FAXRESOLUTION},${faxfile})
на
exten => h,1,Macro(faxresult,${FAXSTATUS},${FAXERROR},${REMOTESTATIONID},${FAXPAGES},${FAXBITRATE},${FAXRESOLUTION},${faxfile})

_________________
Человек мира. RHCE + clustering.
#12

Romik, спасибо. Теперь получился законченный продукт:

В принципе, все как и у Cache тут, но кое-какие изменения и дополнения:
- добавлена запись в лог (кстати, не придумал ничего умнее, чем считать кол-во строк в логе, чтобы делать ID факса, может кто лучше придумает?);
- подразумевается что у виндового юзера (вставляется Respond-ом как Sender User), который отправляет факс есть мыло на корпоративном почтовике, чтобы слать ему репорт об отправке. Так как у меня мыло не совпадало с виндовым логином, то были сделаны алиасы;
- про остальные изменения я рассказал раньше.
create_call_fax:
Код:

#!/bin/bash
# Author: Cache from asteriskforum.ru
# Modified: Dmytro Golovchenko dimagolov at yahoo.com

DATE=`date +%d.%m.%Y-%H:%M:%S`
OUTGOINGDIR=/var/spool/asterisk/outgoing
OUTDIR=/opt/fax/out
TIFFDIR=/opt/fax/tiff
LOGFILE=/opt/fax/fax_logs
NUMBER=$6
FROM=${5%@*}
FAXNAME="fax-$DATE-from-$FROM-to-$NUMBER"
if [ -e $LOGFILE ]
then
FAXID=`wc -l $LOGFILE`
FAXID=$(( $FAXID+1 ))
else
FAXID=1
fi
cat $OUTDIR/$7 | gs -q -sDEVICE=tiffg3 -sPAPERSIZE=letter -r204x196 -dNOPAUSE -sOutputFile=$TIFFDIR/$FAXNAME.tif -
cat $LOGFILE
$FAXID $DATE To: $NUMBER From: $FROM
EOF
cat s,1,SendFax(${faxfile})
exten => h,1,NoOp(Fax Send completed)
exten => h,n,NoOp(Send status is ${FAXSTATUS})
exten => h,n,NoOp(Fax sent to ${REMOTESTATIONID})
exten => h,n,Macro(faxresult,${FAXSTATUS},${FAXERROR},${REMOTESTATIONID},${FAXPAGES},${FAXBITRATE},${FAXRESOLUTION},${faxfile},${senderemail})


Макрос в extensions.ael, просто готовит параметры. добавляется к адресу отправителя алиас fax@mydomain который у меня пересылается администраторам в конторе. Обратите внимание на слеширование запятой между адресами, без него она превращается в |, я так и не понял почему Shocked
Код:
macro faxresult (status, error, remoteid, pages, bitrate, resolution, FAXFILE, senderemail) {
System(/opt/fax/sendresult2mail -s '${status}' -se '${error}' -c '${remoteid}' -p '${pages}' -b '${bitrate}' -r '${resolution}' -f '${FAXFILE}' -e 'fax@mydomain\,${senderemail}');
}


Ну и самое вкусное, подготовка страницы отчета и конвертация факса в pdf, отправка этого на мыло скриптом sendresult2mail. У меня была задача максимально эмулировать отчет, который печатает наш DELL 1815n, с уменьшенной копией первой страницы отправленного факса.
Для отправки мыла используется sendEmail, для манипуляций с картинками ImageMagic, с TIF-ам LIBTIFF, Version 3.6.1 (из дистрибутива CentOS 4), пришлось править парсинг результатов именно под мою версию, может и Вам придется.
Объясню зачем приседание с линком во временной директории на исходящий документ. ImageMagic классная тулза, но для выкусывания первой страницы из файла у нее очень специфический синтаксис:
Код:
convert file'[0]'

Вот именно так, со строчкой в одинарных кавычках БЕЗ пробела после имени файла. Все хорошо, пока нету символов в имени файла, которые надо экранировать. Причем поведение у меня различалось когда я вызывал скрипт из консоли (при этом : в имени файла экранировались) и когда я вызывал из * через System (там все пропихивалось параметром без экранирования. В общем, для исключения такого решил формировать временные файлы и линк на оригинальный файл так, чтобы ничего гарантированно не надо было экранировать.
sendresult2mail:
Код:
#!/bin/bash
# Author: Dmytro Golovchenko dimagolov at yahoo.com

DATETIME=$(date +"%A, %B %d %Y, %H:%M")
TIMESTAMP=$(date +%s)
LOGFILE=/opt/fax/fax_logs
while [ ${#} -gt 0 ]; do
case "${1}" in
"--to-email" | "-e" )
TO_EMAIL=${2}
shift
;;
"--file" | "-f" )
SOURCEFILE=${2}
shift
;;
"--status" | "-s" )
FAXSTATUS=${2}
shift
;;
"--error" | "-se" )
FAXERROR=${2}
shift
;;
"--csid" | "-c" )
REMOTESTATIONID=${2}
shift
;;
"--pages" | "-p" )
FAXPAGES=${2}
shift
;;
"--bitrate" | "-b" )
FAXBITRATE=${2}
shift
;;
"--resolution" | "-r" )
FAXRESOLUTION=${2}
shift
;;

esac
shift
done

if [ "$SOURCEFILE" = "" ]; then
echo "Error: A file is required (-f or --file)"
cat $LOGFILE
ResultProcess $DATETIME Error: File name is missing
EOF
exit 1;
fi
if [ "$TO_EMAIL" = "" ]; then
echo "Error: A destantion email is required (-e or --to-email)"
cat $LOGFILE
ResultProcess $DATETIME Error: destantion email is missing
EOF
exit 1;
fi
if [ "$FAXSTATUS" = "" ]; then
echo "Error: A fax send status is required (-s or --status)"
cat $LOGFILE
ResultProcess $DATETIME Error: fax send status is missing
EOF
exit 1;
fi

SOURCEPATH=${SOURCEFILE%/*}
FILE=${SOURCEFILE##*/}
NAME=${FILE%.*}
EXT=${FILE##*.}

FORMAT="pdf"
TMPDIR=/tmp

ln -s "$SOURCEFILE" $TMPDIR/$TIMESTAMP.$EXT
SOURCEFILE=$TMPDIR/$TIMESTAMP.$EXT
DESTFILE=$TMPDIR/report${NAME#fax}.$FORMAT
COPYFILE=$TMPDIR/$NAME.$FORMAT
REPORTFILE=$TMPDIR/report$TIMESTAMP.gif
TMPFILE=$TMPDIR/tmp$TIMESTAMP.gif
INFOFILE=$TMPDIR/$TIMESTAMP.txt

FROM_EMAIL="faxserver@mydomain.lan"
SRV_NAME="smtp.mydomain.lan"
PATH=$PATH:/usr/local/bin:/usr/local/sbin

if [ -e $SOURCEFILE ]
then
# Read data from TIFF file
FAXDATE=$(tiffinfo $SOURCEFILE | grep "Date" | tail -n 1 | cut -d "\"" -f 2)
if [ "$FAXPAGES" = "" ]
then
PAGES=$(tiffinfo $SOURCEFILE | grep "Page" | tail -n 1 | cut -d " " -f 5 | cut -d "-" -f 1)
FAXPAGES=$(( $PAGES + 1 ))
if [ -z $FAXPAGES ]
then
# If didn't find a page count, use the number of occurrences of "spandsp"
FAXPAGES=$(grep -c "spandsp" $SOURCEFILE)
if [ -z $FAXPAGES ]
then
FAXPAGES=""
fi
fi
fi
BODY="Hello,\n
Fax with $FAXPAGES pages was sent at $DATETIME with status $FAXSTATUS\n
See attachments for sent fax and for confirmation pase.\n
\n
Your fax service\n
"
LEN=${#REMOTESTATIONID}
SPACE=' '
while [ $LEN -le 30 ]
do
REMOTESTATIONID=$REMOTESTATIONID$SPACE
LEN=${#REMOTESTATIONID}
done
REMOTESTATIONID=${REMOTESTATIONID:0:28}
FAXDATE=`printf '%10s %8s ' $FAXDATE`
FAXBITRATE=`printf '%-8s' $FAXBITRATE`
FAXPAGES=`printf '%-6s' $FAXPAGES`

LREMOTESTATIONID=`printf '%-30s' 'Name/Number'`
LFAXDATE=`printf '%-20s' 'StartTime'`
LFAXBITRATE=`printf '%-8s' 'Bitrate'`
LFAXPAGES=`printf '%-6s' 'Pages'`
LFAXSTATUS='Result'

cat $COPYFILE

sendEmail -f $FROM_EMAIL -t $TO_EMAIL -u "Fax at $DATETIME" -m "$BODY" -a "$DESTFILE" \
-a "$COPYFILE" -s $SRV_NAME -o message-charset=UTF-8 -q
rm $SOURCEFILE
rm $DESTFILE
rm $COPYFILE

else
echo "Error: File is missing"
cat $LOGFILE
ResultProcess $DATETIME Error: File is missing
EOF
exit 1;
fi


п.с. если кто-то знает, как оптимальнее построить pdf отчета, буду признателен за советы, потому что изучал ImageMagic в процессе написания скрипта.