Sergey Khalitov
Sergey Khalitov

Reputation: 1037

How to get value of SIP header in Freeswitch?

I need to get value of CALLED_DID header and do some actions in dialplan, but i don't know how.

I've tried to use ${sip_h_CALLED_DID} but it's empty, because have no X- prefix before header name.

Is there any other method to extract value from SIP header?

Please help me, i've read allover the internet but can't find answer.

INVITE sip:[email protected]:65000;transport=udp;gw=zadarma-rbcrm SIP/2.0
Record-Route: <sip:185.45.152.161;lr=on;ftag=as6a38207b>
Via: SIP/2.0/UDP 185.45.152.161;branch=z9hG4bK26d.6cf33cf5d2cdd6683e8de9503870f397.0
Via: SIP/2.0/UDP 185.45.152.148:5060;rport=5060;branch=z9hG4bK74d97ef6
Max-Forwards: 69
From: "+79630495339" <sip:[email protected]>;tag=as6a38207b
To: <sip:[email protected]>
Contact: <sip:[email protected]:5060>
Call-ID: [email protected]:5060
CSeq: 102 INVITE
User-Agent: Zadarma Voip
Date: Thu, 07 Mar 2019 07:38:22 GMT
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, SUBSCRIBE, NOTIFY, INFO, PUBLISH, MESSAGE
Supported: replaces
CALLED_DID: 73433023519
Content-Type: application/sdp
Content-Length: 415
hostname: sipbalancer-1
cc_num: 346127
cc_counter: 1

Upvotes: 2

Views: 6909

Answers (3)

Marcel Haldemann
Marcel Haldemann

Reputation: 791

It is possible by setting <param name="parse-all-invite-headers" value="true"/> in the Sofia SIP Profile. Then all headers from the Invite are set as sip_i_Header-Name channel variables.

Reacting to specific Headears in any other SIP-Messages:

If you want to react to specific headers on other messages, you can do this via setting the variable sip_watch_headers (needs to be exported and prefixed with nolocal if you want it for B-leg only)

If the header is detected, you will get a CUSTOM event of the Subclass "sofia::notify_watched_header".

example to detect Reason header on B-Leg:

<action application="export" data="_nolocal_sip_watch_headers=Reason"/>

Here is an example of the Event looking for a Reason header on the B-Leg, watching the Header "Reason":

  "Event-Name": "CUSTOM",
...
  "Event-Calling-File": "sofia.c",
  "Event-Calling-Function": "notify_watched_header",
  "Event-Calling-Line-Number": "1443",
  "Event-Sequence": "98672",
  "Event-Subclass": "sofia::notify_watched_header",
  "SIP-Message": "SIP/2.0 183 Session Progress",
  "Header-Name": "Reason",
  "Header-Value": "Q.850;cause=16",
  "Channel-State": "CS_CONSUME_MEDIA",
  "Channel-Call-State": "DOWN",
  "Channel-State-Number": "7",
...
"Call-Direction": "outbound",

This event can be reacted either with Lua by setting a hook script in the Lua configuration or via AMQP / EventSocket.

How to do react to these events with Lua

https://freeswitch.org/confluence/display/FREESWITCH/mod_lua#Event_Hooks

Example: autload_configs/lua.conf.xml:

<configuration name="lua.conf" description="LUA Configuration">
  <settings>
    <param name="module-directory" value="/etc/freeswitch/scripts/?.so"/>
    <param name="script-directory" value="/etc/freeswitch/scripts/?.lua"/>
    <!--<param name="startup-script" value="startup_script_1.lua"/>--> <!-- started at fs startup and maybe lives forever -->
    <hook event="CHANNEL_DESTROY" script="/etc/freeswitch/scripts/on_channel_destroy.lua"/>
    <hook event="CUSTOM" subclass="sofia::notify_watched_header" script="/etc/freeswitch/scripts/on_reason_header.lua"/>
    
  </settings>
</configuration>

Example Lua script

local uuid = event:getHeader("Unique-ID")
local shallHangup = event:getHeader("variable_HangupOnReasonInEarly")
local answerState = event:getHeader("Answer-State")

if (shallHangup ~= nil and shallHangup == "true" and answerState == "ringing") then
    local value = event:getHeader("Header-Value")
    local code = value:match(";cause=(%d*)")
    --local data = event:serialize("json")
    freeswitch.consoleLog("INFO","REASON DETECTED: for: " .. uuid .. "\n")
    api = freeswitch.API()
    api:executeString("uuid_kill " .. uuid .. " " .. code)
end

To enable it in dialplan:

<action application="export" data="_nolocal_sip_watch_headers=Reason"/>
<action application="export" data="_nolocal_HangupOnReasonInEarly=true"/>
<action application="bridge" data="..."/>

Upvotes: 6

Sergey Khalitov
Sergey Khalitov

Reputation: 1037

After reading a ton of material, I came to the conclusion:

Reading of custom header without X- prefix is not possible without modifying of source code.

But this is not acceptable way in my case.

Upvotes: -2

norbeq
norbeq

Reputation: 3076

Sip values can not be easily extracted. Prefix the header with X-. Anything else is invalid.

You can recompile mod_sofia - add an extra header reader:

https://freeswitch.org/stash/projects/FS/repos/freeswitch/browse/src/mod/endpoints/mod_sofia/sofia.c Example line 11297.

Add this:

} else if (!strcasecmp(un->un_name, "CALLED_DID")) {
    switch_channel_set_variable(channel, "called_did", un->un_value);

Between:

} else if (!strcasecmp(un->un_name, "Geolocation")) {
    switch_channel_set_variable(channel, "sip_geolocation", un->un_value);

And:

} else if (!strcasecmp(un->un_name, "Geolocation-Error")) {`
    switch_channel_set_variable(channel, "sip_user_location", un->un_value);

And retrieve this header in dialplan like this:

<action application="log" data="DEBUG Called Did -> ${called_did}"/> 

Upvotes: 0

Related Questions