freeswitch修改mod_sofia模块并上报自定义头域

概述
在之前的文章中,我们介绍了如何使用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中,我们应该尽量避免自定义头域的使用,以避免兼容性的问题。
空空如常
求真得真
freeswitch修改mod_sofia模块并上报自定义头域的更多相关文章
- Joomla - 自定义(自定义模块、修改原有模块样式、添加全局JS)
一.自定义模块 自定义模块 参考 Joomla - 模块系统(新建模块.模块类别.自定义模块)第三点 自定义模块部分 自定义模块布局 参考 Joomla - T3模板(非常好用的4屏响应式模板) 的第 ...
- APM飞控修改数传模块方法
APM飞控修改数传模块方法 硬件 ARDUCOPTER第二代 数传模块(USB接口) 数传模块(telem接口) usb-ttl模块 修改方法 注意:APM固件版本和数传模块估计版本是分开的,但有一定 ...
- 21、手把手教你Extjs5(二十一)模块Form的自定义的设计
前面几节完成了模块Grid的自定义,模块Form自定义的过程和Grid的过程类似,但是要更复杂一些.先来设计一下要完成的总体目标. 1、可以有多个Form方案,对应于显示.新增.修改.审核.审批等功能 ...
- Django实现自定义template页面并在admin site的app模块中加入自定义跳转链接
在文章 Django实现自定义template页面并在admin site的app模块中加入自定义跳转链接(一) 中我们成功的为/feedback/feedback_stats/路径自定义了使用tem ...
- laravel修改用户模块的密码验证
做项目的时候,用户认证几乎是必不可少的,如果我们的项目由于一些原因不得不使用 users 之外的用户表进行认证,那么就需要多做一点工作来完成这个功能. 现在假设我们只需要修改登录用户的表,表名和表结构 ...
- freeswitch的话单模块
概述 最近因为业务需要,在看freeswitch中话单相关的一些模块. 在voip的使用过程中,话单是重要的基础模块,涉及到计费和问题查找. 呼叫话单最重要的一点是稳定,不能有错误或遗漏. 本章对fs ...
- C#综合揭秘——通过修改注册表建立Windows自定义协议
引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对 ...
- 【转】C#综合揭秘——通过修改注册表建立Windows自定义协议
引言 本文主要介绍注册表的概念与其相关根项的功能,以及浏览器如何通过连接调用自定义协议并与客户端进行数据通信.文中讲及如何通过C#程序.手动修改.安装项目等不同方式对注册表进行修改.其中通过安装项目对 ...
- 修改VCL源码实现自定义输入对话框
来自:https://yq.aliyun.com/wenji/88428 通过修改VCL源码实现自定义输入对话框 在BCB中有两个函数可以实现输入对话框:InputBox和InputQuery,其实I ...
- Swift自定义头视图和尾视图
var data: [[String]]! override func viewDidLoad() { super.viewDidLoad() // Do any additional setup a ...
随机推荐
- [ARC169E] Avoid Boring Matches
题解链接 非常厉害的一道题. 考虑无解是什么情况? R 的个数超过 \(2^{n-1}\) 先考虑如何判定.从前往后考虑,如果遇到一个 B,那么如果后面有 R,就选最靠前的 R,否则选最靠后的一个 B ...
- [USACO2007NOVG] Telephone Wire G
题目描述 Farmer John's cows are getting restless about their poor telephone service; they want FJ to rep ...
- C++学习笔记八:极限和数学运算<limits><cmath>
1) <limits>库: 1.1 源文档: https://en.cppreference.com/w/cpp/types/numeric_limits #include <lim ...
- 使用create-vue创建vue3项目
create-vue是vue3新的脚手架搭建项目工具,底层构建工具使用vite,而不是vue-cli的webpack. 但不是说你不能用以前的vue create命令来创建vue3项目,你完全可以用v ...
- ElasticSearch-Mapping类型映射-增删改查
https://www.elastic.co/guide/en/elasticsearch/reference/6.8/mapping.html 7.x版本后默认都是_doc类型 增加Mapping映 ...
- bash shell笔记整理——ls命令
语法: ls [选项] [文件 或 目录] 选项 使用说明 –a 显示指定目录下的所有文件,包括隐藏文件. -A 显示除了.和..的外的所有文件. -l 显示详细的文件信息. -d 如果是目录,只显示 ...
- Asp.net core Webapi 如何执行定时任务?
前言 在计算机系统中,定时执行一些后台任务是很常见的场景,比如定时发送邮件.备份数据等等. 那么,.NET 技术如何通过编程灵活地实现项目里复杂的自定义任务呢? 如果是 Windows 生态,通常来说 ...
- iMessage群发,iMessage群发功能,iMessage群发功能设计,iMessage群发系统
在数字通讯时代,群发消息已经成为我们日常生活中不可或缺的一部分,无论是商务.社交还是日常沟通,群发功能都大大提高了消息传递的效率和便利性. 而在众多的通讯软件中,iMessage无疑是其中的佼佼者,今 ...
- ChatGPT的中转站 oupuapi,不扶墙也能上楼
我们在建类似 chatgpt 聊天站点的时候,只需对服务器进行扶墙代理,便可实现访问. 那么我们只需要往深里想一下,不要让整个服务器去访问 VPN,而是基于 API 的代理,或者说 API 的中转站也 ...
- 鸿蒙轻内核M核源码分析:中断Hwi
摘要:本文带领大家一起剖析了鸿蒙轻内核的中断模块的源代码,掌握中断相关的概念,中断初始化操作,中断创建.删除,开关中断操作等. 本文分享自华为云社区<鸿蒙轻内核M核源码分析系列五 中断Hwi&g ...