osip2添加多个不同类型body[通俗易懂]

osip2添加多个不同类型body[通俗易懂]最近接到任务,要写一个SIP协议转换的服务器。但个人对SIP了解非常少,幸好学长写有一个类似的东西,于是向学长请教。但是由于个人悟性问题(微笑),我除了知道了用了osip和exosip这个库之外,其他一无所知。于是回实验室开始看源码+网上查资料,发现了一个问题:目前学长的程序还有网上的资料千篇一律全是只添加了一个body(即SDP部分),但是根据实际,我需要添加两个body(SDP和XML),但网

大家好,又见面了,我是你们的朋友全栈君。

        最近接到任务,要写一个SIP协议转换的服务器。但个人对SIP了解非常少,幸好学长写有一个类似的东西,于是向学长请教。但是由于个人悟性问题(微笑),我除了知道了用了osip和exosip这个库之外,其他一无所知。于是回实验室开始看源码+网上查资料,发现了一个问题:目前学长的程序还有网上的资料千篇一律全是只添加了一个body(即SDP部分),但是根据实际,我需要添加两个body(SDP和XML),但网上的资料和手里的程序没有任何地方提到了添加第二个body的方法,并且第二个body还是xml格式的更没人提到了。

        查了两三个小时的资料后,我在网上找到了osip_message_set_content_type(osip_message_t * sip, const char *hvalue)函数的原型,需要用这个函数来设置SIP信令中的content_type头域,但是源码中却说 if (sip->content_type != NULL),就要return,不做任何操作。但我需要两个body啊,word哥。。于是到了昨晚凌晨0点,我甚至认为osip和exosip这个库无法添加两个body,打算看有没有其它好用的库,心灰意冷的回宿舍洗洗睡了。

        但我是个只要有点心事就睡不着的人,凌晨三点醒了,掏出了电脑,想着毕竟osip和exosip项目的那么多人都是国外大神,肯定考虑了这个问题,就换了个思路——硬着头皮开始看osip和exosip的源码。一直到今天中午12点多总算有点头绪了。。

一、构建SIP信令的body

        我看了我需要构建的SIP信令格式,发现了我之前一直忽略了的一个东西,如图:

osip2添加多个不同类型body[通俗易懂]

        这是第一个content_type的内容,填的是multipart/mixed。在exosip的offans.c中,有一个sdp_message_t *eXosip_get_sdp_info(osip_message_t * message)函数,其中有一段代码如下描述:

if (osip_strcasecmp(ctt->type, “multipart”) == 0) {

/* probably within the multipart attachement */

} else if (osip_strcasecmp(ctt->type, “application”) != 0 ||osip_strcasecmp(ctt->subtype, “sdp”) != 0)

return NULL;

        可见,肯定一上来就是要先通过 osip_message_set_content_type函数来将整个message的content_type设置为multipart,这样才能添加多个body。

        那么问题来了,怎样添加第一个body?首先看看osip中osip_message.h关于osip_message_t这个数据结构的定义(图中为其中的一部分):

osip2添加多个不同类型body[通俗易懂]

​        其中,osip_list_t bodies这个元素非常重要,个人感觉有点像个链表一样,存储着所有body的相关内容。再看osip_body.c中的osip_message_set_body(osip_message_t * sip, const char *buf, size_t length)函数: 

osip2添加多个不同类型body[通俗易懂]

​        所以,可以通过 osip_message_set_body向osip_message_t这个数据结构的bodies元素添加字符串,字符串可以是SDP,也可以是其它格式的东西。通过图中所示的osip_list_add,就可以向bodies中添加(存储的数据结构与链表有点像,就不多说了)。

        那么,SDP和XML这两个body总算是塞进去了,那么怎样添加这两个body的content_type呢?网上又没资料(微笑),我在osip.c中,找到了osip_body_set_contenttype(osip_body_t * body, const char *hvalue),函数体如下图所示:

osip2添加多个不同类型body[通俗易懂]

​        其中,osip_body_t的数据结构如下图所示:

osip2添加多个不同类型body[通俗易懂]

       ​那么问题又来了,如何从sip->bodids中,获得osip_body_t类型的body呢?我在忘了哪个.c文件里看到了一种写法:body = (osip_body_t *) osip_list_get(&sip->bodies, pos); (其中,如果只有一个body,pos取0;如果取第二个body,pos取1)。在osip_list.c中, osip_list_get的函数体如下图所示:

osip2添加多个不同类型body[通俗易懂]

        既然得到了body,那就set_content_type吧,可以为啊application/sdp,也可以为application/**xml等。至此,SIP两个body的构建应该就能行了,至于长度之类的,如果原来的库中没计算,用sizeof计算一下,填上去就行了吧。(但是我个人觉得应该是计算了的,没计算的话再议)。

二、解析SIP信令的body

        学长给的程序中,只有一个eXosip_get_sdp_info的使用,因为只有一个body,那就是sdp。exosip库提供了API用来解析sdp,非常方便。 eXosip_get_sdp_info的函数体如下图所示:

osip2添加多个不同类型body[通俗易懂]

       可见,如果有两个body,该函数仍然能够解析出SDP部分的内容,并且返回一个sdp_message_t的结构体。如何通过API得到第二个body(即XML)的内容呢?在osip_body.c中,有一个osip_message_get_body的函数,pos填1就行,函数体如下图所示:

 

osip2添加多个不同类型body[通俗易懂]

​        得到了osip_body_t后,通过dest->body得到字符串,再通过libxml相关库函数即可解析出xml中的数据。

三、写在后面

        以上内容,全是准备工作,没有经过实际验证,但是我在想应该是没有啥问题,毕竟是一个成熟的库,希望不要坑我(破涕为笑)。如果有问题,待我完成服务器后,再写吧。

        其实我写这个主要是为了我在短时间之内不会忘,趁热打铁,毕竟学渣一枚,忘了就又要重来, 毕竟网上这方面的资料不一样的好少。。。。。。。

        不管了,我要回宿舍补觉了,下周和下下周的考试裸考就裸考吧,暂时还不想复习(憨笑)。

​

​

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/147998.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Pytest(2)使用和调用方法

    Pytest(2)使用和调用方法Pytest执行用例规则Pytest在命令行中支持多种方式来运行和选择测试用例1.对某个目录下所有的用例pytest2.对模块中进行测试pytesttest_mod.py3.对文件夹进行

    2022年7月30日
  • 10种不同画法画平行线怎么画_六边形有几种画法

    10种不同画法画平行线怎么画_六边形有几种画法。1.趋势线:趋势线分快速、中速、慢速,趋势的画法为:上升(下降)趋势线是以向上(下)走势中的低点(高点)与低点(高点)的连线。其中时间跨度越长所构成的支撑作用也越强,而趋势线与K线相交的点位越多,趋势线形成的支撑作用也越强。2.水平线:用前期低点画线,构成再度回落的支撑作用,或者前期低点在后期颇为下跌后再度上升将形成阻力作用。水平线有构成阻力和支撑作用。水平线的画法,一般是用K线实体高点或低点画…

    2022年9月20日
  • 7. MyBatisCodeHelperPro 插件[通俗易懂]

    7. MyBatisCodeHelperPro 插件[通俗易懂]MyBatisCodeHelperPro插件       之前介绍了MyBatis的逆向工程生成实体类、自定义接口以及Mapper.xml的操作过程,很显然这样的配置工作非常繁琐且复杂,本文在介绍MyBatis动态SQL之前,先分享一款实用的MyBatisGenerator插件(MyBatisCodeHelperPro),使用这个插件可以简化开发过程,提高开发者的编码效率。第一步:File→Settings

    2022年9月15日
  • 文件管理学习:从百度网盘搬家onedrive测评「建议收藏」

    文件管理学习:从百度网盘搬家onedrive测评「建议收藏」网上已经有很多多家网盘对比的文章了。由于我平时依赖微软系列比较多,常用office,有自己的微软邮箱,科学上网跟吃饭一样(这克服了网页版被qiang的障碍)。所以最后我选择了onedrive,基于上述前提,搬家就是个一蹴而就的事。微软普通账户只有5G免费,要扩容得花钱至少15/月,然后查到了免费扩容的办法,那就是用edu邮箱注册。学校的edu邮箱终于有了用武之处。。用教育邮箱注册office…

    2022年9月4日
  • EasyCVR通过Ehome协议接入部分设备显示离线排查报告

    EasyCVR通过Ehome协议接入部分设备显示离线排查报告对于需要将不同视频协议做融合的项目,我们一般都是建议大家选用EasyCVR视频平台,EasyCVR支持多种协议的视频接入,对于通用的第三方协议,我们支持了海康的Ehome和GB28181的国标协议。EasyCVR视频网关平台接入的部分Ehome设备显示离线,可以从下图中看到,除了通过HIKSDK接入的设备外,通过Ehome接入的设备全部离线:可见离线的部分设备都是Ehome协议接入,Ehome设备为主动注册类型,判断设备是否真实在线的方法一般为抓取对应对端口7660的包,或者是在海康sdk的回调

    2022年10月28日
  • 【C语言的日常实践(十四)】constkeyword详细解释

    【C语言的日常实践(十四)】constkeyword详细解释

    2022年1月2日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号