FreePBX 2.6, NVFax Detection, Asterisk 1.6.1.6 and Digium FAX - Working!

Woo Hoo!

Before you read any further, if you want to try this, you need a free license from Digium for a single port of FAX - the FFA - Free Fax for Asterisk - it’s free, but it took them three days to get the license to me, so do this first!

I don’t know, maybe I am dense, but I have been scouring the web for DAYS trying to get this working because I NEED to get to Asterisk 1.6 for the better CDR’s, SIP-over-TCP and all the other goodness that 1.6 has to offer - but I also NEED to have NVFax Detection working because our customers demand it. I have read everything I can find, to no avail, so I finally started hacking - if someone else has done this and gotten it working, Google and Bing sure can’t find it.

First the Obvious:

You will need the updated source for app_nv_faxdetect.c and app_nv_backgrounddetect.c - get them here if you don’t already have them:

ftp://ftp.bdc-llc.com/sources-1.6

Once you have the files, they will need to go into the apps folder of the Asterisk source files before you compile them.

Now, the Non-Obvious Stuff (Again, maybe it’s me…)

  1. Remove app_fax.c from the apps folder in the Asterisk Source - this conflicts with res_fax and res_fax_digium that you need to download from Digium. This is probably the most counter-intuitive part of the install to me, and after reading over the docs several times, it’s just not there to remove it - if you don’t, Asterisk crashes when you try and load it. If it’s already compiled, just remove the file from the /usr/lib/asterisk/modules folder - app_fax.so

  2. You will need to compile spandsp-0.0.6pre12.tgz for the NVFax to use - it is also on my ftp server if you need it.

  3. Get the FAX files from Digium - or get the files from me if you want the quick route. The have to go into /usr/lib/asterisk/modules also.

Now, for the last step, a comment, and then a question - you need to edit /etc/extensions.conf and search for ‘rxfax’ and replace it with ‘ReceiveFAX’ - case sensitive - this is the only Dialplan Change I made to be able to receive FAXes - in fact, while I have been typing this up and posting the files to my FTP server, I have received an 86 page FAX and a 116 Page FAX - I used my Wife’s laptop and faxed myself two of the books she is working on - they went without a hitch. I also sent several 3-5 page faxes from web pages that were HEAVY with graphics and they worked fine also.

So here’s the question - where is the template for extensions.conf so that as I update my FreePBX, I won’t have to keep going back into that file and fixing it?

Greg

P.S. - I am working on a procedure to install a scratch-load CentOS 5.4/Asterisk 1.6/FreePBX 2.6 machine - including the instructions specific to the FAXing - I will post that also when it is complete.

I have been talking to DarkBasic (Strange Tag, but he seems very helpful) and I think we were having a Language-Barrier problem, but I finally explained it to him where he understood what is was I was trying to do with the Asterisk as the T.38 FAX Gateway and here is his response:

You have to use the FaxGateway() application instead of the Dial() application to make use of the t38 gateway patch!

Cheers,
Darkbasic

YES!!!
Ok, this may be obvious to some, but it was the piece I was missing - So to get things started again, I think I need to call a Custom Context from the internal FAX machines that are connected this way, and then they should FAX out - I will post when I have some results!

Greg

Please post how you use t38gateway in the syntax either within a context, etc.

I’ll patch for my setup and give it a whirl this week. Do you have a phone number I could chat with you on this week?

Thanks

Brock

The application is FaxGateway() and here is what the source code says:
application name=“FaxGateway” language=“en_US”>
synopsis>
T.38 Gateway Handling
synopsis>
syntax>
parameter name=“dialstring” required=“true”>
para>Filename of TIFF file save incoming fax
parameter>
parameter name=“timeout” required=“false”>
para>Makes the application behave as the calling machine
para>(Default behavior is as answering machine)
parameter>
syntax>
description>
para>Receives a FAX from the channel into the given filename
overwriting the file if it already exists.
para>File created will be in TIFF format.

para>This application sets the following channel variables:
variablelist>
variable name=“LOCALSTATIONID”>
para>To identify itself to the remote end
variable>
variable name=“LOCALHEADERINFO”>
para>To generate a header line on each page
variable>
variable name=“FAXSTATUS”>
value name=“SUCCESS”/>
value name=“FAILED”/>
variable>
variable name=“FAXERROR”>
para>Cause of failure
variable>
variable name=“REMOTESTATIONID”>
para>The CSID of the remote side
variable>
variable name=“FAXPAGES”>
para>Number of pages sent
variable>
variable name=“FAXBITRATE”>
para>Transmission rate
variable>
variable name=“FAXRESOLUTION”>
para>Resolution of sent fax
variable>
variablelist>
description>
application>

So, unless I am misreading the code here, it says that it takes only two parameters - the dialstring (number to be dialed) and a File Name (What for?)

I tried executing this from a custom context as follows:

[custom-faxgateway]
exten => _X.,1,FaxGateway(SIP/Paetec/${EXTEN})

and it tries to route the traffic in that direction, but of course fails because the dial is not populated correctly with calling party ID and such, so here are the questions:

  1. Even though it appears not to take the parameters I need such as Calling Party ID, can I append them in some order in the FaxGateway() such that Asterisk is pre-conditioned to accept, or is there no such thing?

  2. It seems to me that the code needs to be modified to accept and pass through to the called channel this necessary information - POTS lines don’t care, and some PRI’s don’t either, but my SIP trunks sure do - they fail the call, and I think they would pass it if I could populate the fields.

Any thoughts?

Greg

And this setup works great. I had some busies and I probably had 30 successful faxes, with no faxes failing. Asterisk version 1.6.0.10-FONCORE (Trixbox 2.8)

I’m using my built-in laptop modem for the faxing via the SPA 2102 ATA. The laptop modem most likely does not have an ECM mode.

Brock

That’s what I told my wife I wanted to be when I don’t have to work for a living someday.

Anyways, I found out my problem was with the sip carrier tonight. YEAH. After 2-3 weeks of work it was a SIP carrier termination problem. So now I can send 8-9 page faxes all day long. I’m wondering how many fax problems over IP are directly related to 3rd party carriers. (Pacwest)

We have used some grandstream devices. These things are so buggy in terms of saving new settings; we have to sometimes reflash the entire boards before they will work again once changes are made. The SPA2012 works incredibly well, and now i know my fax problems are not related to the SPA, but the frigging carrier and not asterisk!

I’m curious to see if the 1.6.2 actually has true gateway support on the fly. My understanding is that the gateway needs to recognize the call as a fax and then send the re-invite back to the sip trunk - > then ATA and re-negotiate T.38. BTW, I should mention I was able to send 9-10 pages twice w/o problems now too. So this is fairly reliable,and the SPA2012 shows T.38 in the log.

Those of us here on this board should setup a conference bridge and exchange numbers so we can all chat about this. There is very few people really into this stuff from my research.

530-571-7520 - work

Email - brock (@) digitalpath.net

Brock

themselves - I have just gotten back with all of my ATA’s - haven’t done anything with T.38 yet - just getting started.

I wonder if I am going to need to put the ATA’s in a Custom Context to make Asterisk negotiate the T.38 with them - I am still very fuzzy on the mechanics of how this will work - the concept seems fairly clear to me, but I am stumbling along blind as to what needs to be tweaked and where - since your SIP provider is acting as a T.38 gateway for you, did you have to change anything on the Extension definition for the ATA other than turning on re-invites?

I will post more as I test.

Greg

I just noticed above that I was talking about applying the patch to 1.6.1.9 - this actually doesn’t work at all - the patch complains loudly about this and that - the way I tested was to patch against 1.6.2.0.rc4 and then move the three files it patches into 1.6.1.9 before I tried to compile - Since the patch wasn’t written for 1.6.1.9, I don’t know if it is the patch or the difference in app_fax.c between 1.6.1.9 and 1.6.2.0.rc4 that is the problem - just don’t want anyone trying to duplicate what I am doing to not be able to repeat my steps.

Greg

In searching for the SPA2012, the only things I see for sale are SPA2102 - Was that a Typo, or are these different - it that’s the right ATA, I am going to order a couple of them for testing.

Greg

That was a typo. It’s the SPA 2102. What did you disable in terms of error correction? I’m currently using t38redudancy.

[2009-11-07 13:10:56] VERBOSE[21201] app_dial.c: – SIP/Paetec-00000001 is making progress passing it to SIP/5480-00000000
[2009-11-07 13:10:57] VERBOSE[21201] app_dial.c: – SIP/Paetec-00000001 answered SIP/5480-00000000
[2009-11-07 13:11:03] WARNING[21088] chan_sip.c: Autodestruct on dialog ‘[email protected]’ with owner in place (Method: INVITE)
[2009-11-07 13:11:03] VERBOSE[21201] pbx.c: – Executing [h@macro-dialout-trunk:1] ^[[1;36mMacro^[[0m("^[[1;35mSIP/5480-00000000^[[0m", “^[[1;35mhangupcall,^[[0m”) in new st$

I was only testing inbound (which was working fine) but I sat down this morning to test outbound calls and they wouldn’t work - my SIP trunk with Paetec hangs up right away - anyone seen this message before with SIP trunks? I think this is the line that is killing the call:

[2009-11-07 13:11:03] WARNING[21088] chan_sip.c: Autodestruct on dialog ‘[email protected]’ with owner in place (Method: INVITE)

Can’t test if I can’t make outbound calls - I am going to troubleshoot this and post if I find anything.

Greg

removed disallow=all and allow=ulaw and then resubmitted the SIP trunk and I was fine - weird - back to testing.

Greg

Ok - got outbound calling working, but then inbound was being seen as Anonymous - looked at this post:

http://www.freepbx.org/forum/freepbx/users/allow-anonymous-inbound-sip-calls

And tried appending the IP address on to the Host line - then Inbound works but outbound fails.

I ended up copying the trunk definition but leaving the registration string off, and duplicating the peer details in the incoming settings - now both inbound and outbound work, but it seems like a kludge to me…

Back to FAXing…

Greg

You have given me a lot to think about. When you say no ECM, you are saying Error Correction Mode. What options do we have for T38FaxUdpEC?

I’ve only seen two: t38UDPRedudancy and t38UDPFEC. I guess I could take out the entire section for T38FaxUdpEC, but I don’t know what would happen then. I’m using bleeding edge 1.6.2-rc code about a week old.

Please let me know how you accomplished this. For the time being, I’m using strictly a SPA2012. Have you seen better results w/ T.38 on grandstream & asterisk?

There should be an entire section of the support forum just dedicated to discussing T.38 faxing in my opinion.

Thanks

Brock

Ok, a couple of things right away - In reference to an earlier post, someone suggested that I could get FAX reception (G.711 - more on T.38 in a minute) working with the built-in app_fax.c - the one that I say to remove and since I wanted to upgrade to Asterisk 1.6.1.9, I figured it was as good a time as any - so I complied 1.6.1.9 with app_nv_faxdetect and app_nv_backgrounddetect.c, and with spandsp-0.0.6pre12.tgz already installed, and guess what - they were right - you don’t need FAX-For-Asterisk - the built-in FAX (app_fax.c in apps) with the FreePBX dialplan mod application works great - I just sent two 115-Page FAXes, and 3 5-Page Graphics-Heavy faxes and they were received fine - if anything, it seems slightly faster (although I don’t know why that would be?).

I am going to modify the original post to include this finding and update the instructions so you can go either way.

Here is a post from Russell Bryant that explains T.38 Origination, Termination, and Gateway:

http://lists.digium.com/pipermail/asterisk-users/2008-August/216517.html

So that clears it up as far as our predicament with T.38 FAXing on Asterisk 1.6 with FAX-For-Asterisk - we would either have to have a SIP Trunking provider that provided T.38 Gateway Services (they do the Packet-2-TDM conversion I was talking about before) or you would need your own T.38 Gateway - several threads say CallWeaver already does this, and it looks like some people are already doing it. So that’s one possible route for successful T.38…

But, while researching that, I found this:

http://www.mail-archive.com/[email protected]/msg39318.html

This is someone that has ported a T.38 Gateway into the code of app_fax.c - it is a Patch, so I am going to apply it to my code and see how it works - If this code actually works, then the Public version of app_fax seems like a FAR superior version to FAX-For-Asterisk because in reading the app_fax.c, it seems to support T.38. If this code turns Asterisk into a T.38 Gateway, then we are home free!

I will post results as soon as I can test and verify.

Wow, I wish this were laid out somewhere in a straightforward manner - this is like solving a mystery blindfolded.

Greg

Wow, this seems really bleeding-edge, but here it is:

To patch the code, download the patch and then go into the Asterisk source directory and apply it as follows (I put this here for those who don’t know how to apply a patch - like me 15 minutes ago!):

assuming the patch is /usr/src/t38-gw-r222535.patch
cd /usr/src/asterisk-1.6.1.9
patch -p0 -i /usr/src/t38-gw-r222535.patch

This cleanly updates threee files:

app/app_fax.c
main/ast_expr2.c
main/ast_expr2.h

The patch referenced above will not compile cleanly against Astersk 1.6.1.9 - It throws the following errors during compilation:

app_fax.c: In function ât38gateway_execâ:
app_fax.c:1238: warning: passing argument 1 of âast_copy_stringâ discards qualifiers from pointer target type
app_fax.c: In function âload_moduleâ:
app_fax.c:1352: warning: implicit declaration of function âast_register_application_xmlâ

And then when you try and start Asterisk, looking at /var/log/asterisk/full, it says that it can’t load app_fax.so because of the function ast_register_application - Maybe someone that is better with app_fax.c can shed some light on how to fix that against 1.6.1.x - but for now, that won’t work.

Ok - It was written for Asterisk 1.6.2.0,rc4, so let’s compile that:

app_fax.c: In function ât38gateway_execâ:
app_fax.c:1238: warning: passing argument 1 of âast_copy_stringâ discards qualifiers from pointer target type

Ok - well, it compiles and more importantly, it loads and as far as I can test so far, it still works for G.711 FAXes - I have sent 5 test faxes so far and they all seem to work perfectly.

I can’t say I am happy to be running Release Candidate software on my test box (I am not that bleeding edge) but from what I read, 1.6.2.0 is VERY close to release - here’s hoping that it is stable!

I am going to bed now (it’s 10:15 pm and I am fried) and in the morning I am going to the office and get a couple of Grandstreams and do TONS of T.38 Gateway Tests tomorrow - I will post results (and probably ask questions) as soon as I know anything, but this is looking REALLY good!

Man I love Open Source Software!

Greg

P.S. - I think if I get this working completely with TDM and T.38, I will post a fresh thread with instructions and reference this thread as to how we got there - wish I had thought to grab the HandyTones before I left the office!

LazyTT - Please say it’s true - that NVFax code is getting a little old - it works, but a solution that was part of the actual FreePBX code would be EVEN better.

Richard - Thanks, I know about putting custom contexts, but since it’s just a single substitution in one place in the code, I would rather edit the FreePBX template so that whatever was changed, it would keep coming back when changes were applied - We had to modify the template for sip_general_additional.conf to be able to use Bandwidth.com trunks since the traffic comes at the box as anonymous traffic - the context=from-sip-external has to be instead context=from-bandwidth, otherwise you can’t get traffic in.

I believe you can edit
/etc/asterisk/extensions_override_freepbx.conf
to override any built-in function
or
/etc/asterisk/extensions_custom.conf
to add your own custom dialplan rules…

so for your situation, try:
in /etc/asterisk/extensions_override_freepbx.conf replacing the built-in function [macro-faxreceive] with your updated one…

[macro-faxreceive]
exten => s,1,Set(FAXFILE=${ASTSPOOLDIR}/fax/${UNIQUEID}.tif)
exten => s,2,Set(EMAILADDR=${FAX_RX_EMAIL})
exten => s,3,RecieveFAX(${FAXFILE})
exten => s,103,Set(EMAILADDR=${FAX_RX_EMAIL})
exten => s,104,Goto(3)

and that should “override” the built-in function in the dialplan, and work for you with reloads.

Someone please correct me if I’m wrong.

note: I am doing a few other overrides like this in my 1.4 installation, and don’t have a 1.6 to test it on atm, but I suspect the overriding works the same.

Let us know if that works for you. :slight_smile:

Greg, what function is NVfaxdetect playing in your setup? Arent you using FFA?

hmm…
Keep your eyes peel for an easier ‘built-in’ solution