简体   繁体   English

如何使用PJSIP库解码SIP字节流?

[英]How to decode SIP byte stream using PJSIP library?

I am trying to use pjsip library to decode the following SIP byte stream but I am getting segmentation fault. 我试图使用pjsip库来解码以下SIP字节流,但我得到分段错误。 What's wrong with my code? 我的代码出了什么问题?

#include <pjsip.h>

int main()
{

    char __MSG[] = {
        0x49, 0x4e, 0x56, 0x49, 0x54, 0x45, 0x20, 0x73, 0x69, 0x70,
        0x3a, 0x40, 0x31, 0x32, 0x37, 0x2e, 0x30, 0x2e, 0x30, 0x2e,
        0x31, 0x20, 0x53, 0x49, 0x50, 0x2f, 0x32, 0x2e, 0x30, 0x0d,
        0x0a, 0x54, 0x6f, 0x3a, 0x20, 0x3c, 0x73, 0x69, 0x70, 0x3a,
        0x31, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2e, 0x34, 0x35, 0x3e,
        0x0d, 0x0a, 0x56, 0x69, 0x61, 0x3a, 0x20, 0x53, 0x49, 0x50,
        0x2f, 0x32, 0x2e, 0x30, 0x2f, 0x55, 0x44, 0x50, 0x20, 0x31,
        0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2e, 0x34, 0x35, 0x0d, 0x0a,
        0x46, 0x72, 0x6f, 0x6d, 0x3a, 0x20, 0x22, 0x74, 0x65, 0x73,
        0x74, 0x74, 0x65, 0x73, 0x74, 0x22, 0x3c, 0x73, 0x69, 0x70,
        0x3a, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x31, 0x2e, 0x31, 0x39,
        0x39, 0x3e, 0x0d, 0x0a, 0x43, 0x61, 0x6c, 0x6c, 0x2d, 0x49,
        0x44, 0x3a, 0x20, 0x31, 0x34, 0x38, 0x31, 0x30, 0x2e, 0x30,
        0x2e, 0x31, 0x2e, 0x34, 0x35, 0x0d, 0x0a, 0x43, 0x53, 0x65,
        0x71, 0x3a, 0x20, 0x31, 0x20, 0x49, 0x4e, 0x56, 0x49, 0x54,
        0x45, 0x0d, 0x0a, 0x4d, 0x61, 0x78, 0x2d, 0x46, 0x6f, 0x72,
        0x77, 0x61, 0x72, 0x64, 0x73, 0x3a, 0x20, 0x32, 0x30, 0x0d,
        0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x63, 0x74, 0x3a, 0x20,
        0x3c, 0x73, 0x69, 0x70, 0x3a, 0x31, 0x32, 0x37, 0x2e, 0x30,
        0x2e, 0x30, 0x2e, 0x31, 0x3e, 0x0d, 0x0a, 0x0d, 0x0a, NULL
    };



    char *testmsg = __MSG;

    pj_size_t msgsize;
    pj_status_t status;


    // INIT
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    status = pjlib_util_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    // PARSING
    pj_caching_pool cp;
    pj_caching_pool_init(&cp, NULL, 1024*1024);
    pj_pool_t *pool = pj_pool_create(&cp.factory, "parser_pool", 4000, 4000, NULL);
    pjsip_parser_err_report err;

    int len = strlen(testmsg);
    pjsip_msg *msg = pjsip_parse_msg(pool, __MSG, len, &err);

    printf("The end...");

    return 0;
}

Program terminated with signal 11, Segmentation fault. 程序以信号11,分段故障结束。
#0 0x0805befb in pj_scan_peek () (gdb) bt pj_scan_peek()(gdb)bt中的#0 0x0805befb
#0 0x0805befb in pj_scan_peek () pj_scan_peek()中的#0 0x0805befb
#1 0x080507f6 in int_parse_msg () int_parse_msg()中的#1 0x080507f6
#2 0x080523a2 in pjsip_parse_msg () pjsip_parse_msg()中的#2 0x080523a2
#3 0x0804fa89 in main () (gdb) #3 0x0804fa89 in main()(gdb)

You need to use a SIP Endpoint instance. 您需要使用SIP端点实例。 From the doc : 来自doc

SIP Endpoint instance (pjsip_endpoint) can be viewed as the master/owner of all SIP objects in an application. 可以将SIP端点实例(pjsip_endpoint)视为应用程序中所有SIP对象的主/所有者。 It performs the following roles: 它执行以下角色:

  • it manages the allocation/deallocation of memory pools for all objects. 它管理所有对象的内存池的分配/释放。
  • it manages listeners and transports, and how they are used by transactions. 它管理侦听器和传输,以及事务如何使用它们。
  • it receives incoming messages from transport layer and automatically dispatches them to the correct transaction (or create a new one). 它从传输层接收传入消息,并自动将它们分派到正确的事务(或创建一个新事务)。
  • it has a single instance of timer management (timer heap). 它有一个定时器管理实例(定时器堆)。
  • it manages modules, which is the primary means of extending the library. 它管理模块,这是扩展库的主要手段。
  • it provides single polling function for all objects and distributes events. 它为所有对象提供单一轮询功能并分发事件。
  • it automatically handles incoming requests which can not be handled by existing modules (such as when incoming request has unsupported method). 它会自动处理现有模块无法处理的传入请求(例如,当传入请求具有不受支持的方法时)。
  • and so on.. 等等..

Application should only instantiate one SIP endpoint instance for every process. 应用程序应该只为每个进程实例化一个SIP端点实例。

You'll need to call pjsip_endpt_create to create an endpoint. 您需要调用pjsip_endpt_create来创建端点。

Take a look at Stateless SIP Endpoint sample to get a feel for the general structure of the library calls that need to be made for initializing and setting up an endpoint. 查看Stateless SIP Endpoint示例,了解初始化和设置端点所需的库调用的一般结构。

Other items of note: 其他注意事项:

  • The pjsip_parse_msg function takes a pjsip_parser_err_report list as the last argument. pjsip_parse_msg函数将pjsip_parser_err_report列表作为最后一个参数。 You have to initialize the list using pj_list_init(&err). 您必须使用pj_list_init(&err)初始化列表。
  • Make sure you are checking that pool is not NULL after the call to pj_pool_create. 调用pj_pool_create后,确保检查池是否为NULL。
  • The doc doesn't indicate if it is okay to not pass in a NULL pool factory policy to pj_caching_pool_init; doc没有说明是否可以将NULL池工厂策略传递给pj_caching_pool_init; probably best to just pass in the default (shown in sample below). 可能最好只传递默认值(如下面的示例所示)。

I believe it should look something like this (but have not tested this): 我相信它应该看起来像这样(但没有测试过):

    // INIT
    status = pj_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    status = pjlib_util_init();
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    // Create pool factory (for memory allocations)
    pj_caching_pool cp;
    pj_caching_pool_init(&cp, &pj_pool_factory_default_policy, 1024*1024);

    // Create global endpoint
    static pjsip_endpoint *sip_endpt;
    status = pjsip_endpt_create(&cp.factory, "uniquesipendpointname", &sip_endpt);
    PJ_ASSERT_RETURN(status == PJ_SUCCESS, 1);

    // PARSING    
    pj_pool_t *pool = pj_pool_create(&cp.factory, "parser_pool", 4000, 4000, NULL);
    pjsip_parser_err_report err;

    int len = strlen(testmsg);
    pj_list_init(&err);
    pjsip_msg *msg = pjsip_parse_msg(pool, __MSG, len, &err);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM