На мой взгляд это не однозначный вопрос. Hylafax мы пробовали. Работает через раз, тяжело получать обратную связь. В связке был iaxmodem, но это просто ужас. t38modem нет в портейжах нашей генты и это печально. А здесь повилось вот такое решение. Согласен, не фонтан, но работает и удовлетворяет все наши потребности.
Вот описание для тех, кто возможно столкнется в будущем (у нас таки завелось):
1. Формируем call-файлы
Код: Выделить всё
Channel:Local/send@fax_with_threads
Callerid:"FaxSender"<1111>
Maxretries:{maxRetries}
Waittime:300
RetryTime:60
Context:faxsend-t38
Extension:faxout
Priority:1
SetVar: T38CALL=1
Set:RETURNURL={returnUrl}
Set:TAGLINE=company
Set:LOCALSTATIONID=phone
Set:RECEIVER={fax}
Set:FAX_ID={faxId}
Set:TIFF_2_SEND={faxId}.tif
2. помещаем в спул, далее два контекста:
Код: Выделить всё
[fax_with_threads]
; здесь наш канал (или несколько, при необходимости)
exten => send,1,Dial(SIP/канал/${RECEIVER},30)
exten => send,n,Goto(send-${DIALSTATUS},1)
exten => send-CANCEL,1,Hangup()
exten => send-ANSWER,1,Hangup()
exten => send-NOANSWER,1,Hangup()
exten => send-BUSY,1,Hangup()
exten => send-CONGESTION,1,Wait(10)
exten => send-CONGESTION,n,GoTo(send,1)
exten => send-CHANUNAVAIL,1,Wait(10)
exten => send-CHANUNAVAIL,n,GoTo(send,1)
[faxsend-t38]
exten => faxout,1,Set(STARTTIME=${SHELL(date +%s)} )
exten => faxout,n,Wait(2)
exten => faxout,n,Playback(/mnt/asterisk_call_records/fax,skip)
exten => faxout,n,Hangup()
exten => faxout,n,NoOp(**** SENDING FAX ****)
; Set FAXOPTs
exten => faxout,n,NoOp(**** SETTING FAXOPT ****)
exten => faxout,n,Set(FAXFILE=${TIFF_2_SEND})
exten => faxout,n,Set(FAXOPT(ecm)=yes)
exten => faxout,n,Set(FAXOPT(headerinfo)=${TAGLINE})
exten => faxout,n,Set(FAXOPT(maxrate)=14400)
exten => faxout,n,Set(FAXOPT(minrate)=4800)
exten => faxout,n,Set(FAXOPT(localstationid)=${LOCALSTATIONID})
; Send the fax
exten => faxout,n,NoOp(**** SENDING FAX : ${FAXFILE} ****)
exten => faxout,n,SendFAX(/mnt/asterisk_call_records/faxes/${FAXFILE},dfzs)
;Calculating Time of Sending
exten => faxout,n,Set(ENDTIME=${SHELL(date +%s)} )
exten => faxout,n,Set(TRANSFERTIME=${MATH(${ENDTIME}-${STARTTIME},int)})
;Actions after sending fax
exten => faxout,n,Set(NORMURL=${FAXOPT(error)})
exten => faxout,n,Set(STATUSMESSAGE=${REPLACE(NORMURL, ,+)})
exten => faxout,n,Set(FAXOPTRATE=${FAXOPT(rate)})
exten => faxout,n,Hangup
;Actions if no answer or busy
exten => failed,1,Set(FAXSTATUS=FAILED)
exten => failed,2,Set(STATUSMESSAGE=number+no+answer+or+busy)
exten => failed,3,Set(FAXOPTRATE=none)
;
exten => h,1,NoOP(------------------- FAX to ${EXTEN} with ${FAXSTATUS} -----------------)
exten => h,2,Set(CURLRESULT=${CURL(${RETURNURL}?fax=${RECEIVER}&faxId=${FAX_ID}&status=${FAXSTATUS}&message=${STATUSMESSAGE})})
exten => h,4,Set(LOGFAXOUT=${SHELL(echo "${STRFTIME(${EPOCH},,%d%m%Y-%H:%M:%S)} : ${FAX_ID} : ${RECEIVER} : ${FAXSTATUS} : ${STATUSMESSAGE} : ${TRANSFERTIME}$
exten => h,3,NoOp(${RECEIVER}:${FAX_ID}:${FAXSTATUS}:${STATUSMESSAGE}:${FAXOPTRATE})
3. в настройках наших каналов надо выставить лимит по ним call-limit=1
И все успешно работает.
N call файлов помещается в spool, далее астериск их забирает и начинает работу по тем которые можно (исходя из возможностей своих каналов). Если все каналы заняты - таймаут 10 секунд и повторная попытка. Если на удаленной стороне не отвечают/занято - hangup и повторно через RetryTime в количестве Maxretries. Результат убегает скрипту по адресу RETURNURL.
------------------
и теперь оффтоп: предыдущая проблема имеет интересный характер.
при звонке с любого телефона на наш sip номер провайдер кидает такое сообщение
Код: Выделить всё
INVITE sip:s@192.168.0.65:5060 SIP/2.0
Via: SIP/2.0/UDP 188.187.253.3:5060;rport;branch=z9hG4bK-109865469-3792765912-4082920356-10123420121
Via: SIP/2.0/UDP 188.187.253.1:5161;rport=5161;branch=z9hG4bK-109865469-3792765912-4082920356-1012342012;received=188.187.253.1
From: "79370822551" <sip:79370822551@188.187.253.1:5161;user=phone>;tag=3565251069-3792765912-4082920356-1012342012
To: <sip:78442526660@188.187.253.1;user=phone>
Call-ID: fd6981fcd80311e2a46b5cf3fc1c573c@188.187.253.1
CSeq: 1 INVITE
Contact: <sip:79370822551@188.187.253.3:5060>
Content-Type: application/sdp
Allow: ACK, BYE, CANCEL, INFO, INVITE, OPTIONS, REFER, REGISTER, SUBSCRIBE, UPDATE
Max-Forwards: 70
User-Agent: MERA MVTS3G v.4.3.0-38t
Cisco-Guid: 4236016284-3624079842-2758499571-4229715772
Content-Length: 415
Все бы ничего, но в поле From в качестве идентификатора сервера есть только IP.
И опять же все бы ничего, но на данного провайдера и на этот сервер есть несколько разных записей разных телефонов в sip.conf.
Соответственно получалась такая ситуация: т.к. тестировали мы на своем собственном факсе, то при попытке вызова с первого канала приходил входящий на первый канал, который по лимиту отклонялся - и собственно эпик фейл.
Вопрос в следующем:
в документации на sip.conf сказано что для friend определение сервера происходит по полю From любым возможным методом.
Каким образом указать asterisk'у на то, что ему надо идентифицировать канал другим способом, например с помощью поля To?