[asterisk-bugs] [JIRA] (ASTERISK-25482) Faxes are randomly not sent using T.38 when faxing over a local channel

Filip Jenicek (JIRA) noreply at issues.asterisk.org
Mon Mar 7 06:52:56 CST 2016


     [ https://issues.asterisk.org/jira/browse/ASTERISK-25482?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Filip Jenicek updated ASTERISK-25482:
-------------------------------------

    Description: 
After upgrading to Asterisk 13.5.0 from the 1.8 branch I discovered, that faxes are randomly not sent using the T.38 codec, but instead fall back to G.711. The remote endpoint is another Asterisk on a local network. There are no differences in SIP signalization. It all happens inside asterisk.

I am sending the fax over a local channel using an AMI command:
{code}
Action: Originate
ActionID: 08ca8820897b702508b256b8d1ec343a
Channel: Local/999 at sip-locals/n
CallerID: "Admin" <10>
Context: faxSend
Exten: faxSend
Priority: 1
Timeout: 180000
Variable: ktsFrom="Admin"<10>,ktsFromName=Admin,ktsFromNum=10,ktsTo=999,ktsFaxFile=/var/spool/operator/fax/prepareFax.p5VrO67F8i.tiff
{code}

Asterisk extensions.conf is simple:
extensions.conf:
{code}
[faxSend]
exten => faxSend,1,NoOp(Send fax ${ktsFaxFile} from ${ktsFrom} to ${ktsTo})
exten => faxSend,n,Set(FAXOPT(headerinfo)=From ${ktsFromName})
exten => faxSend,n,Set(FAXOPT(localstationid)= )
exten => faxSend,n,SendFax(${ktsFaxFile},dfz)
exten => h,1,NoOp(Status: ${FAXSTATUS} (${FAXERROR}) ${FAXMODE} ${REMOTESTATIONID} ${FAXPAGES} ${FAXBITRATE} ${FAXRESOLUTION})

[sip-locals]
exten => 999,1,Dial(SIP/213 at i-borg-outbound)
{code}

I have been able to localize the issue, but I can't come up with a proper fix. The problem first happens in core_unreal.c in function ast_unreal_queryoption. The Local channel is sometimes not bridged yet. As a result, the function returns a zero, and several functions later, asterisk sends a 488 reply and falls back to G.711.

By adding a simple for loop to the ast_unreal_queryoption function, I was able to mitigate the issue. This is not a fix, but rather a proof that there is a race condition.
{code}
int attempt = 0;
for (attempt = 0; attempt < 100; attempt++) {
	peer = ast_channel_bridge_peer(other);
	if (peer) {
		ast_debug(3, "Peer bridged (attempts %d).\n", attempt);
		break;
	}
		ast_debug(3, "Peer not bridged yet, retry (attempts %d).\n", attempt);
	usleep(10000);
}
{code}

Another way to overcome the issue is by using a sleep:
{code}
[faxSend]
exten => faxSend,1,NoOp(Send fax ${ktsFaxFile} from ${ktsFrom} to ${ktsTo})
exten => faxSend,n,Set(FAXOPT(headerinfo)=From ${ktsFromName})
exten => faxSend,n,Set(FAXOPT(localstationid)= )
exten => faxSend,n,Wait(1)                                           ;<-- Deal with the race
exten => faxSend,n,SendFax(${ktsFaxFile},dfz)
{code}


Three log files are attached:
* asterisk_13_5_0_orig_488err.log - Displays the 488 error response and fallback to G.711.
* asterisk_13_5_0_patched_fixed.log - Contains the for loop fix, the fax was successfully transmitted over T.38.
* asterisk_13_5_0_patched_didnt_happen.log - The race didn't happen this time, the fax was successfully transmitted over T.38.

  was:
After upgrading to Asterisk 13.5.0 from the 1.8 branch I discovered, that faxes are randomly not sent using the T.38 codec, but instead fall back to G.711. The remote endpoint is another Asterisk on a local network. There are no differences in SIP signalization. It all happens inside asterisk.

I am sending the fax over a local channel using an AMI command:
{code}
Action: Originate
ActionID: 08ca8820897b702508b256b8d1ec343a
Channel: Local/999 at sip-locals/n
CallerID: "Admin" <10>
Context: faxSend
Exten: faxSend
Priority: 1
Timeout: 180000
Variable: ktsFrom="Admin"<10>,ktsFromName=Admin,ktsFromNum=10,ktsTo=999,ktsFaxFile=/var/spool/operator/fax/prepareFax.p5VrO67F8i.tiff
{code}

Asterisk extensions.conf is simple:
extensions.conf:
{code}
[faxSend]
exten => faxSend,1,NoOp(Send fax ${ktsFaxFile} from ${ktsFrom} to ${ktsTo})
exten => faxSend,n,Set(FAXOPT(headerinfo)=From ${ktsFromName})
exten => faxSend,n,Set(FAXOPT(localstationid)= )
exten => faxSend,n,SendFax(${ktsFaxFile},dfz)
exten => h,1,NoOp(Status: ${FAXSTATUS} (${FAXERROR}) ${FAXMODE} ${REMOTESTATIONID} ${FAXPAGES} ${FAXBITRATE} ${FAXRESOLUTION})

[sip-locals]
exten => 999,1,Dial(SIP/213 at i-borg-outbound)
{code}

I have been able to localize the issue, but I can't come up with a proper fix. The problem first happens in core_unreal.c in function ast_unreal_queryoption. The Local channel is sometimes not bridged yet. As a result, the function returns a zero, and several functions later, asterisk sends a 488 reply and falls back to G.711.

By adding a simple for loop to the ast_unreal_queryoption function, I was able to mitigate the issue. This is not a fix, but rather a proof that there is a race condition.
{code}
int attempt = 0;
for (attempt = 0; attempt < 100; attempt++) {
	peer = ast_channel_bridge_peer(other);
	if (peer) {
		ast_debug(3, "Peer bridged (attempts %d).\n", attempt);
		break;
	}
		ast_debug(3, "Peer not bridged yet, retry (attempts %d).\n", attempt);
	usleep(10000);
}
{code}

Three log files are attached:
* asterisk_13_5_0_orig_488err.log - Displays the 488 error response and fallback to G.711.
* asterisk_13_5_0_patched_fixed.log - Contains the for loop fix, the fax was successfully transmitted over T.38.
* asterisk_13_5_0_patched_didnt_happen.log - The race didn't happen this time, the fax was successfully transmitted over T.38.


> Faxes are randomly not sent using T.38 when faxing over a local channel
> -----------------------------------------------------------------------
>
>                 Key: ASTERISK-25482
>                 URL: https://issues.asterisk.org/jira/browse/ASTERISK-25482
>             Project: Asterisk
>          Issue Type: Bug
>      Security Level: None
>          Components: Applications/app_fax, Channels/chan_local, Channels/chan_sip/T.38
>    Affects Versions: 13.5.0
>         Environment: Debian wheezy, 32bit
>            Reporter: Filip Jenicek
>         Attachments: asterisk_13_5_0_orig_488err.log, asterisk_13_5_0_patched_didnt_happen.log, asterisk_13_5_0_patched_fixed.log
>
>
> After upgrading to Asterisk 13.5.0 from the 1.8 branch I discovered, that faxes are randomly not sent using the T.38 codec, but instead fall back to G.711. The remote endpoint is another Asterisk on a local network. There are no differences in SIP signalization. It all happens inside asterisk.
> I am sending the fax over a local channel using an AMI command:
> {code}
> Action: Originate
> ActionID: 08ca8820897b702508b256b8d1ec343a
> Channel: Local/999 at sip-locals/n
> CallerID: "Admin" <10>
> Context: faxSend
> Exten: faxSend
> Priority: 1
> Timeout: 180000
> Variable: ktsFrom="Admin"<10>,ktsFromName=Admin,ktsFromNum=10,ktsTo=999,ktsFaxFile=/var/spool/operator/fax/prepareFax.p5VrO67F8i.tiff
> {code}
> Asterisk extensions.conf is simple:
> extensions.conf:
> {code}
> [faxSend]
> exten => faxSend,1,NoOp(Send fax ${ktsFaxFile} from ${ktsFrom} to ${ktsTo})
> exten => faxSend,n,Set(FAXOPT(headerinfo)=From ${ktsFromName})
> exten => faxSend,n,Set(FAXOPT(localstationid)= )
> exten => faxSend,n,SendFax(${ktsFaxFile},dfz)
> exten => h,1,NoOp(Status: ${FAXSTATUS} (${FAXERROR}) ${FAXMODE} ${REMOTESTATIONID} ${FAXPAGES} ${FAXBITRATE} ${FAXRESOLUTION})
> [sip-locals]
> exten => 999,1,Dial(SIP/213 at i-borg-outbound)
> {code}
> I have been able to localize the issue, but I can't come up with a proper fix. The problem first happens in core_unreal.c in function ast_unreal_queryoption. The Local channel is sometimes not bridged yet. As a result, the function returns a zero, and several functions later, asterisk sends a 488 reply and falls back to G.711.
> By adding a simple for loop to the ast_unreal_queryoption function, I was able to mitigate the issue. This is not a fix, but rather a proof that there is a race condition.
> {code}
> int attempt = 0;
> for (attempt = 0; attempt < 100; attempt++) {
> 	peer = ast_channel_bridge_peer(other);
> 	if (peer) {
> 		ast_debug(3, "Peer bridged (attempts %d).\n", attempt);
> 		break;
> 	}
> 		ast_debug(3, "Peer not bridged yet, retry (attempts %d).\n", attempt);
> 	usleep(10000);
> }
> {code}
> Another way to overcome the issue is by using a sleep:
> {code}
> [faxSend]
> exten => faxSend,1,NoOp(Send fax ${ktsFaxFile} from ${ktsFrom} to ${ktsTo})
> exten => faxSend,n,Set(FAXOPT(headerinfo)=From ${ktsFromName})
> exten => faxSend,n,Set(FAXOPT(localstationid)= )
> exten => faxSend,n,Wait(1)                                           ;<-- Deal with the race
> exten => faxSend,n,SendFax(${ktsFaxFile},dfz)
> {code}
> Three log files are attached:
> * asterisk_13_5_0_orig_488err.log - Displays the 488 error response and fallback to G.711.
> * asterisk_13_5_0_patched_fixed.log - Contains the for loop fix, the fax was successfully transmitted over T.38.
> * asterisk_13_5_0_patched_didnt_happen.log - The race didn't happen this time, the fax was successfully transmitted over T.38.



--
This message was sent by Atlassian JIRA
(v6.2#6252)



More information about the asterisk-bugs mailing list