freeswitch修改mod_sofia模組並上報自定義頭域

求真得真發表於2022-01-26

 

 

 

概述

在之前的文章中,我們介紹瞭如何使用fs的event事件機制來獲取呼叫的各種資訊。

這些event事件一般都是底層模組定義好的,其中的各種資訊已經很完備了,日常的開發需求都可以滿足。

但是,總有一些場景是無法完全滿足的,例如,在fs的註冊事件中,就沒有X-自定義頭域的資訊。

在定製化的sip互動過程中,freeswitch是支援自定義頭域的,頭域格式要滿足“X-***”的模式。而當我們訂閱了"sofia::register"事件,在事件中是無法獲得自定義頭域的資訊的。

本文從fs的核心模組mod_sofia的程式碼出發,分析如何增加對自定義頭域的資訊的獲取和事件上報。

 

環境

centos:CentOS  release 7.0 (Final)或以上版本

freeswitch:v1.8.7

GCC:4.8.5

 

mod_sofia模組

mod_sofia模組是fs在sofia-sip庫的基礎上實現的SIP終端模組,fs中所有的sip訊息處理和上報都要通過mod_sofia模組來對接。

我們可以在 src\mod\endpoints\mod_sofia\sofia_reg.c 檔案中,找到註冊訊息的處理函式“sofia_reg_handle_register_token”,並在函式中找到“MY_EVENT_REGISTER "sofia::register"”事件的建立和上報流程。

if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "profile-name", profile->name);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-user", to_user);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "from-host", reg_host);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "presence-hosts", profile->presence_hosts ? profile->presence_hosts : "n/a");

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "contact", contact_str);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "call-id", call_id);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "rpid", rpid);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "status", reg_desc);

       switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long) exptime);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-user", from_user);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "to-host", from_host);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-ip", network_ip);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "network-port", network_port_c);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "username", username);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "realm", realm);

       switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "user-agent", agent);

       if (update_registration) {

              switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "update-reg", "true");

       }

       if (v_event && *v_event) {

              switch_event_merge(s_event, *v_event);

       }

      

       //add by zr 20220121

       for (sip_unknown_t *un = sip->sip_unknown; un; un = un->un_next) {

           switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, un->un_name, un->un_value);

    }

 

       switch_event_fire(&s_event);

}

 

從上面的程式碼中,我們可以看到“sofia::register”事件中包含的所有頭域內容。

sofia sip協議棧會解析所有的頭域,並把非標準的頭域都放到“sip->sip_unknown”中。

在紅色新增的程式碼中,我們把所有unknown的頭域都放到register上報事件中。

 

編譯

cd freeswitch-1.8.7/src/mod/endpoints/mod_sofia

make

make install

 

測試

啟動freeswitch,使用sip終端註冊1002賬戶。

使用api命令“/event plain ALL”開啟fs的事件列印,可以在屏顯中看到如下資訊:

RECV EVENT

Event-Subclass: sofia::register

Event-Name: CUSTOM

Core-UUID: b95d5721-38f1-406d-b6f1-8c056394d63e

FreeSWITCH-Hostname: localhost.localdomain

FreeSWITCH-Switchname: localhost.localdomain

FreeSWITCH-IPv4: 192.168.0.152

FreeSWITCH-IPv6: ::1

Event-Date-Local: 2022-01-21 17:15:14

Event-Date-GMT: Fri, 21 Jan 2022 09:15:14 GMT

Event-Date-Timestamp: 1642756514420767

Event-Calling-File: sofia_reg.c

Event-Calling-Function: sofia_reg_handle_register_token

Event-Calling-Line-Number: 2011

Event-Sequence: 902

profile-name: internal

from-user: 1002

from-host: 192.168.0.152

presence-hosts: 192.168.0.152,192.168.0.152

contact: "1002" <sip:1002@10.9.136.138:1666;fs_nat=yes;fs_path=sip:1002@10.9.136.138:1666>

call-id: 1378235421@10.9.136.138

rpid: unknown

status: Registered(UDP-NAT)

expires: 3600

to-user: 1002

to-host: 192.168.0.152

network-ip: 10.9.136.138

network-port: 1666

username: 1002

realm: 192.168.0.152

user-agent: FaramAndroid/1.5.9

sip_number_alias: 1002

sip_auth_username: 1002

sip_auth_realm: 192.168.0.152

number_alias: 1002

user_name: 1002

domain_name: 192.168.0.152

record_stereo: true

default_gateway: example.com

default_areacode: 918

transfer_fallback_extension: operator

toll_allow: domestic,international,local

accountcode: 1002

user_context: default

effective_caller_id_name: Extension 1002

effective_caller_id_number: 1002

outbound_caller_id_name: FreeSWITCH

outbound_caller_id_number: 0000000000

callgroup: techsupport

X-Packet: com.sipp

X-Brand: huawei

X-Osver: 29

X-Token: IQAAAACy0eGUAAAWdHyqUVfb0b

X-Jgtoken: 190e35f7e0

X-Olduser: 12345678

 

我們可以在事件資訊的最後看到“X-”開頭的自定義頭域資訊列印。

 

總結

本文從fs的sip協議棧出發,修改了mod_sofia模組程式碼,增加自定義訊息頭域的事件上報,對sip訊息的定製有一定參考意義。

但是,在日常的VOIP中,我們應該儘量避免自定義頭域的使用,以避免相容性的問題。

  


 

空空如常

求真得真

 

相關文章