【问题标题】:How to get value of SIP header in Freeswitch?如何在 Freeswitch 中获取 SIP 标头的值?
【发布时间】:2019-03-07 08:14:12
【问题描述】:

我需要获取CALLED_DID 标头的值并在拨号方案中执行一些操作,但我不知道如何。

我尝试使用 ${sip_h_CALLED_DID} 但它是空的,因为标题名称前没有 X- 前缀。

还有其他方法可以从 SIP 标头中提取值吗?

请帮助我,我已经阅读了整个互联网但找不到答案。

INVITE sip:gw+zadarma-rbcrm@185.70.135.33: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:+79630495339@sip.zadarma.com>;tag=as6a38207b
To: <sip:346127@185.45.152.161>
Contact: <sip:+79630495339@185.45.152.148:5060>
Call-ID: 401671d34e8247a9694c3da87c97fbbb@185.45.152.148: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

【问题讨论】:

    标签: sip freeswitch dialplan


    【解决方案1】:

    可以通过设置 &lt;param name="parse-all-invite-headers" value="true"/&gt;Sofia SIP 配置文件中。然后将来自 Invite 的所有标头设置为 sip_i_Header-Name 通道变量。

    对任何其他 SIP 消息中的特定 Headears 做出反应:

    如果您想对其他消息的特定标头做出反应,可以通过设置变量 sip_watch_headers 来实现(如果需要,需要导出并以 nolocal 为前缀它仅适用于 B 腿)

    如果检测到标头,您将收到子类“sofia::notify_watched_header”的 CUSTOM 事件。

    检测B-Leg Reason标头的示例:

    &lt;action application="export" data="_nolocal_sip_watch_headers=Reason"/&gt;

    这是一个在 B-Leg 上寻找 Reason 标头的 Event 示例,查看标头“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",
    

    可以通过在 Lua 配置中设置挂钩脚本或通过 AMQP / EventSocket 对 Lua 做出反应。

    如何使用 Lua 对这些事件做出反应

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

    示例: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>
    

    Lua 脚本示例

    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
    

    在拨号方案中启用它:

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

    【讨论】:

    • 这是正确答案 - 我不确定为什么另一个被标记为正确答案!我在随机谷歌上找到参数名称后来到这里!它自 2014 年以来一直存在,所以我不确定为什么 5 年后的这些答案会如此错误。 github.com/signalwire/freeswitch/commit/…
    【解决方案2】:

    Sip 值不容易提取。 以 X- 为标题添加前缀。其他的都是无效的。

    您可以重新编译 mod_sofia - 添加额外的标头阅读器:

    https://freeswitch.org/stash/projects/FS/repos/freeswitch/browse/src/mod/endpoints/mod_sofia/sofia.c 示例第 11297 行。

    添加这个:

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

    之间:

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

    还有:

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

    并像这样在拨号方案中检索此标头:

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

    【讨论】:

    • 感谢参与。这是一个可能的,但不是理想的解决方案。因为它需要在 FreeSwitch 的每个新版本中完成。
    【解决方案3】:

    看了一大堆资料,我得出结论:

    如果不修改源代码,则无法读取没有X- 前缀的自定义标头。

    但这在我的情况下是不可接受的。

    【讨论】:

    • 请注意这是不正确的。请参阅 Marcel Haldemann 将“parse-all-header-invites”添加到 Sofia Profile 的回答
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    • 2016-07-25
    • 2015-11-26
    相关资源
    最近更新 更多