Retrieving PJSIP_Header from a PJSIP registered trunk

Hello everybody ,

Since a few weeks , I have set up a FreePBX ( Asterisk based ) and I have registered a trunk with Chan_PJSIP trunk.

All is working fine for outbound calls , but for incoming calls , it works only if I don’t specify “DID inbound route”. After a lot of troubleshooting and time to research , I came to the conclusion that my provider is sending those DID Numbers in the SIP or PJSIP Headers. So I set up the context to “from-pstn-toheader” that contains :
[from-pstn-toheader]exten => .,1,Goto(from-pstn,${CUT(CUT(PJSIPHEADER(To),@,1),:,2)},1)
to recover the PJSIPHEADER , but I have the following error and I can’t figure it out :

ERROR[11578][C-00000000]: res_pjsip_header_funcs.c:465 func_read_header: This function requires a header name

Thanks for reading and have a nice day !

What is the complete console output and the actual dialplan logic? The dialplan function would be used as ${PJSIP_HEADER(To)} not what is above.

Hi , this is the complete output console when I use this function to retrieve the DID number in a dynamic way
This is the function :
exten => s,1,Goto(from-trunk,${CUT(CUT(PJSIP_HEADER(To),@,1),:,2)},1)

This is the output :

[2016-06-27 09:46:21] ERROR[25793][C-00000001]: res_pjsip_header_funcs.c:465 func_read_header: This function requires a header name.
– Executing [s@from-pstn-toheader:1] Goto(“PJSIP/PJSIP Trunk-00000001”, “from-trunk,1”) in new stack
– Goto (from-trunk,s,1)
– Executing [s@from-trunk:1] NoOp(“PJSIP/PJSIP Trunk-00000001”, “No DID or CID Match”) in new stack
– Executing [s@from-trunk:2] Answer(“PJSIP/PJSIP Trunk-00000001”, “”) in new stack
[2016-06-27 09:46:22] WARNING[25793][C-00000001]: chan_sip.c:22377 func_header_read: This function can only be used on SIP channels.
– Executing [s@from-trunk:3] Log(“PJSIP/PJSIP Trunk-00000001”, "WARNING,Friendly Scanner from ") in new stack
[2016-06-27 09:46:22] WARNING[25793][C-00000001]: Ext. s:3 @ from-trunk: Friendly Scanner from
– Executing [s@from-trunk:4] Wait(“PJSIP/PJSIP Trunk-00000001”, “2”) in new stack
> 0x2cf9de0 – Probation passed - setting RTP source address to X.X.X.X:30202
– Executing [s@from-trunk:5] Playback(“PJSIP/PJSIP Trunk-00000001”, “ss-noservice”) in new stack
– <PJSIP/PJSIP Trunk-00000001> Playing ‘ss-noservice.ulaw’ (language ‘en’)
– Executing [h@from-trunk:1] Macro(“PJSIP/PJSIP Trunk-00000001”, “hangupcall,”) in new stack
– Executing [s@macro-hangupcall:1] GotoIf(“PJSIP/PJSIP Trunk-00000001”, “1?theend”) in new stack
– Goto (macro-hangupcall,s,3)
– Executing [s@macro-hangupcall:3] ExecIf(“PJSIP/PJSIP Trunk-00000001”, “0?Set(CDR(recordingfile)=)”) in new stack
– Executing [s@macro-hangupcall:4] Hangup(“PJSIP/PJSIP Trunk-00000001”, “”) in new stack
== Spawn extension (macro-hangupcall, s, 4) exited non-zero on ‘PJSIP/PJSIP Trunk-00000001’ in macro ‘hangupcall’
== Spawn extension (from-trunk, h, 1) exited non-zero on ‘PJSIP/PJSIP Trunk-00000001’

However , I can make things work if I set up the extensions.conf file in a “hard way” :

exten => s,1,Goto(from-trunk,00334XXXXXXXX,1) --> where the X respresents my num

But ! Next problem , I have 4 nums , that when they are dialed , redirect to my trunk line so I set up :

exten => s,1,Goto(from-trunk,00334XXXXXXX0,1)
exten => s,n,Goto(from-trunk,00334XXXXXXX1,1)
exten => s,n,Goto(from-trunk,00334XXXXXXX2,1)
exten => s,n,Goto(from-trunk,00334XXXXXXX3,1)

It is working well for the first one , but when I dialed for example the second or third one , all the calls are redirected as if I dialed the first in the list ( calls are redirected to the ring group corresponding to the first line in the conf file to be more specific )

So is there a way to make things work in a hard or dynamic way ? No matter wich way lol

You have already bee told that the syntax of your original use of the function is wrong.

The best solution here is to have your provider provide a proper Direct In Dialing service, i.e. they pass routing information in the request URI.

An unconditional Goto, as the first step of a program will always be taken and the subsequent lines not executed. Your new code is behaving exactly as expected.

Yeah , I know :frowning:

Any way to put the same priority and that the inbound routes be considered as equal ?

I tried a pattern because my nums all start the same way so I could have only one line and then redirect to the good route but I didn’t make that work. I tried :

exten => s,1,Goto(from-trunk,_00334XXXXXXXX,1)
exten => s,1,Goto(from-trunk,_00334X.,1)

I think that I have to take this problem “in a dynamical” way to not have priority routes problem , but there is my question , if the function PJSIP_HEADER requires a name as it is told in the error , what I have to put ?
Or do I have to do a PJSIPAddHeader first ?

You are missing $ signs from the original expression and are using the wrong sort of brackets around variables and function calls.

It looks like you need a dialplan designing for you, rather than one debugging. Especially given that you seem to be unfamiliar with programming concepts, you need to pay a consultant to write it for you and to subsequently support it.

A provider won’t change his way for a client ^^

I know some stuff in programming but I have to say that I don’t really understand what this line really return ( this is provide by my sip provider for chan_sip :
exten => s,1,Goto(from-trunk,${CUT(CUT(SIP_HEADER(To),@,1),:,2)},1) --> provide by sip provider
exten => s,1,Goto(from-trunk,${CUT(CUT(PJSIP_HEADER(To),@,1),:,2)},1) --> to match my case

Because when I take my SIP packet :


Retransmitting #3 (NAT) to X.X.X.X:5060:
REGISTER sip:mytrunk SIP/2.0
Via: SIP/2.0/UDP X.X.X.X:5060;branch=z9hG4bK51c03678;rport
Max-Forwards: 70
From: sip:00334XXXXXXXX@mytrunk;tag=as61398322
**To: sip:00334XXXXXXXX@mytrunk **
Call-ID: 6681469103d0b6fc6484e92a5048406c@[::1]
CSeq: 102 REGISTER
Supported: replaces, timer
User-Agent: FPBX-13.0.119(13.7.1)
Expires: 3600
Contact: sip:334XXXXXXXX@X.X.X.X:5060
Content-Length: 0

-I understand that in that way : Take the “To” line
To: sip:00334XXXXXXXX@mytrunk
-Then cut with the “@” as the seperate char and take the first column so you get sip:00334XXXXXXXX , then recut with the “:” as the seperate char and take the 2nd colum so you retrieve the DID number, but the function in Chan_SIP and Chan_PJSIP don’t have the same comportement because Chan_PJSIP needs a name ?

I saw the syntax PJSIP_HEADER(action,name[,number]) and the source code of the error :

if (ast_strlen_zero(args.header_name)) {
ast_log(AST_LOG_ERROR, “This function requires a header name.\n”);
return -1;
}
But I can’t see what I’m missing ( a header name , but what ? …)

I think that the problem is all in the syntax of the extensions.conf line but I don’t still have the knowledge to correct myself.

PJSIP_HEADER(read,To) would be the correct format. PJSIP is different.

As well the wiki[1] has documentation for this sort of stuff[2].

[1] https://wiki.asterisk.org/
[2] https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Function_PJSIP_HEADER

Yep , I tried that and it worked ! Thanks all for your support !