Fax as a Service (FaaS)

Lower end customers are looking to get away from having a dedicated phone line for their fax server.  The TR1034 board also requires a physical server.  These customers are looking to move to a service base deployment for the following benefits.

Software Only Solution

The benefits of a software only fax solution removes the requirement to have a dedicated physical server for the fax server.  By having a software only solution, the fax server could be deployed in a virtual environment either locally or cloud based. 

No Dedicated Phone Line

By removing the physical phone line provided by the telco for the fax server, remove the monthly fee cost for a phone line that may or may not be used.  The fax server is also not tied down to a physical location.  

Pay for Usage

Customer would like to move from paying for a up front fax server with a defined number of channels to a service that can scale as needed.  

Customers would like to keep their existing fax server application and would like to be able to use a fax service with their current setup. These customers are also willing to use a store and forward solution that the current FasS providers provide. The FaaS providers would like to deploy to the current Bfv based market. They have approached the application vendors to use their FaaS API. 

Fax Service Layer

To direct traffic to a FaaS provider, the Bfv API would need to be aware of these FaaS API's.   Would need to know what one it is to connect to. Customer Credentials to use the service.  Know it is in FaaS mode and perform store and forward faxing.   

 

Issues with FaaS

It is a store and forward solution.

Fax media processing is performed at the service location and is out of the control of Dialogic.  Debugging issues would require the service provider to provide details back to the application on the error.  Items like headers and fonts are no longer performed by the SR140 or TR1034 board.  Bfv API functions that allow the application to make real-time decisions or provide protocol information may not be available. (T.30 Holdup)

Sample Service

FaxSIPit is an example of a FaaS vendor. They provide a REST based API that allows sending and receiving of faxes. The applciation will make a HTTPs request to the API and parse the responses. Their current format is JSON. It uses standard HTTP methods like GET And POST to access the service.

Send

This function is used to send a fax. The method used by this request is post and has the URL http://65.39.245.253/rest/1.0/api/send. It follows the Rest API calling conventions:

POST  http://65.39.245.253/rest/1.0/api/send

Input Parameters
InputDescription
dialnumber Destination number in the format 1+areacode+number
callernumber Specify the caller id
csid Calling station id
faxfile This field contains the document to send. Accepted format is tiff

Output Parameter Description

OutputDescription
RefCode Unique code for the sent fax
Status Status of the sent fax
Created Time Shows the time the fax was created

Example: Sending a fax to 17274568620

 curl -X POST \

  http://65.39.245.253/rest/1.0/api/send \

  -H 'cache-control: no-cache' \

  -H 'content-type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW' \

  -F dialnumber=17274568620 \

  -F callernumber=7274568620 \

  -F 'csid=my fax' \

  -F 'faxfile=@\\rsdbs3\Home\vijur\Desktop\test pages few\1p - CCITTTest.tif'

If successful response will include a file object as follows.   

{"RefCode":"a4ba2090-8360-11e7-8717-513b01d011ef","DialNumber":"17274568620","CallerNumber":"727","CSID":"Viju Fax","Status":"Created","PagesDelivered":0,"ConnectTime":0,"ConnectSpeed":0,"RemoteId":null,"CreatedTime":"8/17/2017, 8:27:56 AM","CompletedTime":null}

Only TIFF documents can be uploaded. Sending any other format will generate the following response object:

{"Response”: “Failed to upload the file. You can upload tif or tiff file only."}


Outbox

This is used to check faxes that are in the process of being sent. The method used by this request is GET and has the URL http://65.39.245.253/rest/1.0/api/outbox

OutputDescription
RefCodeUnique code for the sent fax
DialnumberShows the destination number
CallernumberSpecify the caller id
CSIDCalling station id
StatusShows the status of a fax 

 

Fax sent to 7274568620 is in sending status. Here is the response from the outbox command:

curl -X GET \

  http://65.39.245.253/rest/1.0/api/outbox \

  -H 'authorization: Basic dGVzdDp0ZXN0' \

  -H 'cache-control: no-cache' \

Response:

{

        "RefCode": "a4ba2090-8360-11e7-8717-513b01d011ef",

        "DialNumber": "17274568620",

        "CallerNumber": "727",

        "CSID": "Viju Fax",

        "Status": "Sending",

        "PagesDelivered": 0,

        "ConnectTime": 0,

        "ConnectSpeed": 0,

        "RemoteId": "",

        "CompletedTime": null

    }

 

The current FaxSIPit API document:

Etherfax also has a REST API for faxing (and secure doc transport) that focuses on encryption:    https://docs.etherfax.net/  

 

Information from :

From: Eli Mann [mailto:emann@faxsipit.com]
Sent: Thursday, March 15, 2018 8:24 PM
I have dug some information that I think might be indicative for usage. There is no end to the data mining we can do (sector, volume, other profiles) but at the high level these are strong enough statistics based on few thousands of end users.  So Inbound (IO) and Outbound (OB) split traffic SD and revenues for the higher volume accounts (lower minute rate).

  

 

 

IB

OB

Percent

 

32%

68%

1 standard deviation minutes/month per 8 ports

 

1000

2000

1 standard deviation minutes/month per 8 ports

 

10000

7000

Port Count minimum

 

2

2

Port Count maximum

 

24

48

Monthly traffic charges @ high volume (under 100K minutes/month)

 

$  200.00

 $  140.00

 

I found that mid-size (8 ports) shows very consistent results while some of the larger users are specific application driven and shows skewed results.

 

Nathan Research

Non-realtime 3rd party fax support Version 0.2


 

There are at least 4 ways to approach supporting other third-party fax API libraries within the Bfv API.

  1. Create a new library that implements all Bfv API functions using the third party API in some fashion. This would mean having a different library that exports all the same functions as the regular Bfv API library. It would then be independent of the regular Bfv API library, and would suffer from maintenance issues. Applications would have to include a different header file and link with a different library. The two libraries could not be used together.
  2. Create a library as in #1, but with functions which have distinct names from from those of the regular Bfv API library. Create a series of macros which map from Bfv API function names to the names used in the other library. Applications would have to include a different header file and link with a different library. This would be similar to how the Centennial and Millennial Bfv API libraries both use the same interface and can even be used together in the same program. It would also suffer from maintenance issues.
  3. Extend the Bfv API library to support additional "fake" channel types which are implemented in terms of an external third party library. Depending upon how a channel attach is performed, it could either attach a channel in the standard fashion or it could create a "fake" channel, and have all Bfv API calls that use such a channel call different functions at low levels. It should not suffer from most maintenance issues, since whenever a new feature is added, if channels are not involved, then no extra work should needed, and if they are, the fake channel types would be required to to be handled, too, ifapplicable, at that time.
  4. Make a modified SR140 which accepts firmware commands and performs appropriate actions using the third party library, and create appropriate firmware responses. Almost all changes would be hidden from the API level, but would probably be very complex to implement. I will be assuming that #3 will be the way we will choose to implement the third-party fax API library support.

 


To further expand on #3, we need BfvLineAttach to be able to determine whether it is attaching to a standard Brooktrout channel or a fake channel.

While it is possible that a single config file keyword could be used to turn all channels into fake channels, that would not be conducive to having the channel types coexist.

More flexible would be a variation of this that allows specification of what channels should be attached as fake channels. E.g.

third_party_nonrt <third party shared lib> <lower channel> <upper channel>

This is still somewhat limiting, since it may require knowing something about how many Brooktrout channels there are in advance.

If <upper channel> is not specified, then there would be no upper limit. If <lower channel> is not specified, then it would default to 0, and all attaches would be fake channel attaches.

The channels would seem to have a new module number (0x90?) that is not currently assigned for any purpose and machine 1. Such module and machine numbers are really meaningless, since there would be no communication with the Brooktrout driver for these channels. There would be a limit of approximately 250 channels of this type due to the addressing format.


Various remarks:

In caps.h, where Bfv API capabilities are defined, we would add two new capabilities, CAP_CHANNEL_BRKT, and CAP_CHANNEL_3RDPARTY_NONRT. CAP_CHANNEL_BRKT would be set for all standard attaches. CAP_CHANNEL_3RDPARTY_NONRT would be set for channels in the range specified by third_party_nonrt. In case we ever have some other third party library of a different type, this could give us some flexibility. Additional other capabilities may be added to help differentiation. These may be based on contacting the remote server and receiving information on its capabilities.

At its lowest level, the Bfv API fax transmission and reception ultimately operate on buffers of fax data. Because of this, the easiest format to use with a third party non-realtime API would either be one big buffer of fax data or a file containing fax data. Most non-realtime APIs operate on files in some pre-specified other format, such as TIFF. Whatever is the case, we would need to convert to/from this file type, and it would need to be done even if the original fax data being sent is already in a file of that type.

The file format used by some of the non-realtime third party APIs has been described as "TIFF", but it is unclear what type of TIFF file this actually is - is it TIFF Class F, which contains MH, MR, or MMR fax data within it? Or some other type?

Because there is no true "number of channels" for utilizing a non-realtime API, the number is what we say it is, which should be no more than approximately 250 channels.

When doing an operation (like the modinfo program) that queries the driver about modules in use and their channels, the fake modules would not be seen since the driver knows nothing about them. (This might be doable differently,if we implement some shared memory region within bostsrv which is created when bostsrv is run based on config keywords which can be queried, but likely this is a needless complication.)

Phone calls, of course, don't actually happen. For inbound calls, we would periodically poll the third party server until either a fax has arrived or an indication of a failed incoming call has arrived. At this point we would report an incoming call, and the fax data would be ready to return immediately, with fake T.30 negotations, etc.

For outgoing calls, since fax data is normally not supplied to the Bfv API until after a call is successfully placed, we would have to pretend that all calls are successful, supply fake T.30 negotations, and accept the data for send. Only then could we initiate the non-realtime send. If there is a call failure or fax transmission failure, we'd have to give an error of some sort, though it is no longer possible to report call placement errors at that point. Before indicating the call placement has been successful, we could possibly verify that we can still contact the remote server first.

Line types for the fake channels would probably be reported as analog.

We will define a Fake API Interface Layer to interface to the third party non-realtime APIs, similar to the CIPI layer used to interface to internet stacks. This is an abstraction layer that the Bfv API will call which hides the low level details of the actual third party software in use. A library will be written that implements the FAIL layer, including any necessary internet communication to talk to the third party non-realtime server. This is the library that will ultimately be loaded by the Bfv API.

Bfv API Functions called by tfax sample application

All

--------------------

BfvLineAttach

    BfvSessionAttach

        ThirdPartyEstablishAccess

BfvLineReset

        ThirdPartyAbortFax

    BfvClearInput

    BfvClearOutput

    BfvModuleInfo

    BfvIntLineConfig

BfvFaxGetRemoteInfo

        [nothing of consequence]

BfvFaxWaitForTraining

        [nothing of consequence]

BfvLineTerminateCall

    BfvCallDisconnect

        ThirdPartyAbortFax

    BfvCallWaitForRelease

        [nothing of consequence]

BfvLineDetach

        ThirdPartyAbortFax

        ThirdPartyReleaseAccess

 

Send only

--------------------

BfvLineOriginateCall

    BfvCallSetup

        ThirdPartySetCallPlacementInfo

    BfvCallWaitForComplete

        [nothing of consequence]

BfvFaxBeginSendTiff

    BfvFaxBeginSendRaw

        ThirdPartyFaxPageParams

BfvFaxNextPageTiff

    BfvFaxNextPageRaw

        ThirdPartyFaxPageParams

    BfvFaxStripParams

        ThirdPartyFaxStripParams

BfvFaxSendPageTiff

    BfvFaxStripParams

        ThirdPartyFaxStripParams

    BfvFaxSendData

        ThirdPartyFaxSendData

BfvFaxEndOfDocument

        ThirdPartyFaxSendandWait

 

Rcv only

--------------------

BfvLineWaitForCall

    BfvCallRingDetect

        [nothing of consequence]

    BfvCallWaitForSetup

        ThirdPartyQueryIncomingFax

BfvLineAnswer

    BfvCallAccept

        [nothing of consequence]

    BfvCallWaitForAccept

        [nothing of consequence]

BfvFaxBeginReceive

    BfvNegotiateMedia

        [nothing of consequence]

BfvFaxRcvPageTiff

    BfvFaxSetReceiveFmt

        ThirdPartySetRcvFmt

    BfvFaxReceiveData

        ThirdPartyFaxReceiveData

BfvFaxEndReception

 

Sample service interface functions

NameDescription
ThirdPartyEstablishAccess(BTLINE *lp,??)

Initialize line pointer and establish access for use of the remote third party server. This will probably involve establishing a connection to the remote server and querying information about it.

ThirdPartyAbortFax(BTLINE *lp,??)Abort the fax that is currently in progress, if it is possible to do so.
ThirdPartyReleaseAccess(BTLINE *lp,??)

Release any allocated or reserved resources associated with the remote server access.

ThirdPartySetCallPlacementInfo(BTLINE *lp,??)Supply destination info for future fax send.
ThirdPartyFaxPageParams(BTLINE *lp,??)

Supply format parameters for the first/next page of fax send,creating a page break.

ThirdPartyFaxStripParams(BTLINE *lp,??)Supply format parameters for next strip of fax data.
ThirdPartyFaxSendData(BTLINE *lp,??)Supply fax data for send.
ThirdPartyFaxSendandWait(BTLINE *lp,??)

Indicates the end of fax data. Send the created fax document.  Waits for completion of the fax and retrieves status.

ThirdPartyQueryIncomingFax(BTLINE *lp,??)

Queries the server for an incoming fax or possible status information about interim failures. Retrieves the fax document.

ThirdPartySetRcvFmt(BTLINE *lp,??)Sets the receive fax format type.
ThirdPartyFaxReceiveData(BTLINE *lp,??)Returns a portion of the received fax.

 

 

 

 

 

 

 

 Exploring with JIRA

  BRKT-841 - Getting issue details... STATUS

 

======================================================================
There are at least 4 ways to approach supporting other third-party fax APIlibraries within the Bfv API.
1) Create a new library that implements all Bfv API functions using the thirdparty API in some fashion. This would mean having a different library thatexports all the same functions as the regular Bfv API library. It would thenbe independent of the regular Bfv API library, and would suffer frommaintenance issues. Applications would have to include a different header fileand link with a different library. The two libraries could not be usedtogether.
2) Create a library as in #1, but with functions which have distinct namesfrom from those of the regular Bfv API library. Create a series of macroswhich map from Bfv API function names to the names used in the other library.Applications would have to include a different header file and link with adifferent library. This would be similar to how the Centennial and MillennialBfv API libraries both use the same interface and can even be used together inthe same program. It would also suffer from maintenance issues.
3) Extend the Bfv API library to support additional "fake" channel types whichare implemented in terms of an external third party library.  Depending uponhow a channel attach is performed, it could either attach a channel in thestandard fashion or it could create a "fake" channel, and have all Bfv APIcalls that use such a channel call different functions at low levels. Itshould not suffer from most maintenance issues, since whenever a new featureis added, if channels are not involved, then no extra work should needed, andif they are, the fake channel types would be required to to be handled, too, ifapplicable, at that time.
4) Make a modified SR140 which accepts firmware commands and performsappropriate actions using the third party library, and create appropriatefirmware responses. Almost all changes would be hidden from the API level,but would probably be very complex to implmement.
I will be assuming that #3 will be the way we will choose to implement thethird-party fax API library support.

============================================================
To further expand on #3, we need BfvLineAttach to be able to determinewhether it is attaching to a standard Brooktrout channel or a fake channel.
While it is possible that a single config file keyword could be used to turnall channels into fake channels, that would not be conducive tohaving the channel types coexist.
More flexible would be a variation of this that allows specification of whatchannels should be attached as fake channels. E.g.
third_party_nonrt <third party shared lib> <lower channel> <upper channel>
This is still somewhat limiting, since it may require knowing something abouthow many Brooktrout channels there are in advance.
If <upper channel> is not specified, then there would be no upper limit.  If<lower channel> is not specified, then it would default to 0, and all attacheswould be fake channel attaches.
The channels would seem to have a new module number (0x90?) that is notcurrently assigned for any purpose and machine 1. Such module and machinenumbers are really meaningless, since there would be no communication with theBrooktrout driver for these channels. There would be a limit of approximately250 channels of this type due to the addressing format.
======================================================================
Various remarks:
In caps.h, where Bfv API capabilities are defined, we would add two newcapabilities, CAP_CHANNEL_BRKT, and CAP_CHANNEL_3RDPARTY_NONRT.CAP_CHANNEL_BRKT would be set for all standard attaches.CAP_CHANNEL_3RDPARTY_NONRT would be set for channels in the range specified bythird_party_nonrt.  In case we ever have some other third party library of adifferent type, this could give us some flexibility. Additional othercapabilities may be added to help differentiation. These may be based oncontacting the remote server and receiving information on its capabilities.
At its lowest level, the Bfv API fax transmission and reception ultimatelyoperate on buffers of fax data. Because of this, the easiest format to usewith a third party non-realtime API would either be one big buffer of fax dataor a file containing fax data. Most non-realtime APIs operate on files in somepre-specified other format, such as TIFF. Whatever is the case, we would needto convert to/from this file type, and it would need to be done even if theoriginal fax data being sent is already in a file of that type.
The file format used by some of the non-realtime third party APIs hasbeen described as "TIFF", but it is unclear what type of TIFF file thisactually is - is it TIFF Class F, which contains MH, MR, or MMR fax datawithin it? Or some other type?
Because there is no true "number of channels" for utilizing a non-realtimeAPI, the number is what we say it is, which should be no more thanapproximately 250 channels.
When doing an operation (like the modinfo program) that queries the driverabout modules in use and their channels, the fake modules would not be seensince the driver knows nothing about them. (This might be doable differently,if we implement some shared memory region within bostsrv which is createdwhen bostsrv is run based on config keywords which can bequeried, but likely this is a needless complication.)
Phone calls, of course, don't actually happen. For inbound calls, we wouldperiodically poll the third party server until either a fax has arrived or anindication of a failed incoming call has arrived.  At this point we wouldreport an incoming call, and the fax data would be ready to returnimmediately, with fake T.30 negotations, etc.
For outgoing calls, since fax data is normally not supplied to the Bfv APIuntil after a call is successfully placed, we would have to pretend that allcalls are successful, supply fake T.30 negotations, and accept the data forsend. Only then could we initiate the non-realtime send. If there is a callfailure or fax transmission failure, we'd have to give an error of some sort,though it is no longer possible to report call placement errors at thatpoint. Before indicating the call placement has been successful, we couldpossibly verify that we can still contact the remote server first.
Line types for the fake channels would probably be reported as analog.
We will define a Fake API Interface Layer to interface to the third partynon-realtime APIs, similar to the CIPI layer used to interface to internetstacks. This is an abstraction layer that the Bfv API will call which hidesthe low level details of the actual third party software in use. A librarywill be written that implements the FAIL layer, including any necessaryinternet communication to talk to the third party non-realtime server.This is the library that will ultimately be loaded by the Bfv API.
The FAIL layer has yet to be defined, and will be the subject ofan additional proposal.