We have Freepbx with sip trunks configured to providers. Also we have another internal server with pjsip trunk connected to Freepbx.
When users call from this server to outside number call goes through FreePBX and then to sip providers.
We have problem when users call to wrong numbers, sip provider returns code 404, but Freepbx changes the code to 486 when returning response to internal server.
Probably if you fundamentally changed the FreePBX dialplan. Asterisk isn’t a SIP proxy, it doesn’t forward things as-is. Dialplan can and will change the response code.
The other thing you have to consider is that Asterisk is a Back-to-Back User Agent. So when Bob calls Alice’s cellphone there are two channels involved. Bob to Asterisk (A) and Asterisk to Provider (B) so you are getting a 404 back from the Provider, that is on Channel B. Channel B is now going to pass a result back to Channel A. It’s sending a 486 back telling you the channel is busy. It’s either that or if it passes a 404 back to Channel A it will end up playing an out of service or couldn’t be completed as dialed message to the caller.
We would need to see a call trace from /var/log/asterisk/full or direct output from the Asterisk console of this call so we could see how everything was handled. As file said this isn’t a proxy so Channel A (user) will never get the exact SIP code that Channel B gets. It will generate a SIP code based on the internal state of Channel B.
Could you post verbose Asterisk logs as well (not just SIP) ?
By the way, your SIP provider is telling you lies. How can the remote be 180 Ringing and then 404 Not Found? If it’s not found, then what is ringing?
As I have pointed out before you can use HANGUPCAUSE() to get the actual SIP response code. HANGUPCAUSE(channel,type) It will output responses like 200 OK or 486 User Busy Here.
You add a hangup handler to the trunk channel like so:
[pstn-sipcode]
exten => s,1,NoOp(HANGUP DETECTED - CAUSE ${HANGUPCAUSE} SOURCE: ${CHANNEL(hangupsource)} CHECK: ${CHANNEL(checkhangup)})
exten => s,n,Set(SIP_REPLY=${HANGUPCAUSE(${CHANNEL(name)},tech)})
exten => s,n,ExecIf($[${REGEX("(480|486)" ${SIP_REPLY} = 1]?Set(SV_DIALSTATUS=BUSY))
exten => s,n,ExecIf($[${REGEX("(408 User Did Not Answer|404)" ${SIP_REPLY} = 1]?Set(SV_DIALSTATUS=NOANSWER))
exten => s,n,Return()
Now ${SV_DIALSTATUS} will contain the desired dial status you would want to calling channel to use. Of course, you can adjust to needs/taste.
NOTE: Notice that I use 408 User Did Not Answer not just 408. This is due to there being two types of a 408 response. There is a 408 Timeout which happens when no 1XX reply (100 Trying, 180 or 183) is received before timing out. Then there is 408 User Did Not Answer, this is a timeout that happens after a 1XX reply. The former indicates errors/issues while the latter just means no one picked up the phone and it didn’t go to a voicemail.
The issue is that the dialplan is currently returning a sensible dialstatus on the 404 Not Found but then returning 486 Busy to the caller. It’s a dialplan bug. Should not be a need to add handlers or other hacks to work around it.
Well actually it plays a “not in service message” first then it plays busy tones afterwards. So I guess the question is what is that vs using congestion or other indicator of a failure. Even telco’s play a busy/congestion tone after an out of service/not found message.
I guess you could just hangup after the message…