简体   繁体   English

使用Qt和pjsip在一个应用程序中的多个端口上侦听SIP

[英]Listening for SIP on multiple ports within one application with Qt and pjsip

I am trying to listen for SIP messages on multiple ports within my Qt console-based application. 我试图在基于Qt控制台的应用程序中的多个端口上侦听SIP消息。 I am simply creating multiple objects of my class proxy . 我只是在创建类代理的多个对象。

Sample example of proxy.cpp: proxy.cpp的示例示例:

proxy* thisProxy;
proxy::proxy(quint16 port, QObject *parent) :
    QObject(parent), portFromConfig(port)
{
    thisProxy = this;
    thread = new QThread(this);
    connect(thread, SIGNAL(started()), this, SLOT(start()));
    connect(thread, SIGNAL(finished()), this, SLOT(deleteLater()));
    this->moveToThread(thread);
    thread->start();
}

void proxy::start()
{
    pj_status_t status;
    pj_caching_pool caching_pool;
    pj_sockaddr_in sockaddr;
    pj_str_t ourAddressFromConfig;

    pj_thread_desc initdec;
    pj_thread_t* thread = 0;

    if (!pj_thread_is_registered() && pj_thread_register("PJ_THREAD", initdec, &thread ) != PJ_SUCCESS)
        return;

    pjsip_module proxy = {
        NULL,
        NULL,
        pj_str("proxy"),
        -1,
        PJSIP_MOD_PRIORITY_UA_PROXY_LAYER,
        NULL,
        NULL,
        NULL,
        NULL,
        &onReceivedRequest,
        &onReceivedResponse,
        NULL,
        NULL,
        NULL
    };

    pj_log_set_level(4);

    //initialize pj
    status = pj_init();
    if (status != PJ_SUCCESS)
    {
        qDebug() << "pj_init failed";
        return;
    }

    //initilaize pjlib_util
    status = pjlib_util_init();
    if (status != PJ_SUCCESS)
    {
        qDebug() << "pjlib_util_init failed";
        return;
    }

    //initialize caching pool
    pj_caching_pool_init(&caching_pool, &pj_pool_factory_default_policy, 0);

    //create the endpoint
    status = pjsip_endpt_create(&caching_pool.factory, NULL, &endpoint);
    if (status != PJ_SUCCESS)
    {
        qDebug() << "pjsip_endpt_create failed";
        return;
    }

    //specify our socket
    ourAddressFromConfig = pj_str(addressFromConfig.toLatin1().data());
    sockaddr.sin_family = pj_AF_INET();

    if (ourAddressFromConfig.slen)
        pj_inet_aton(&ourAddressFromConfig, &sockaddr.sin_addr);
    else
        sockaddr.sin_addr.s_addr = 0;

    sockaddr.sin_port = pj_htons((pj_uint16_t) portFromConfig);

    //start the socket
    status = pjsip_udp_transport_start(endpoint, &sockaddr, NULL, 1, &transport);
    if (status != PJ_SUCCESS)
    {
        qDebug() << "pjsip_udp_transport_start failed";
        return;
    }

    //create the caching pool
    poolt = pj_pool_create(&caching_pool.factory, "UDPproxy", 4000, 4000, NULL);

    //register the proxy module
    status = pjsip_endpt_register_module(endpoint, &proxy);
    if (status != PJ_SUCCESS)
    {
        qDebug() << "pjsip_endpt_register_module failed";
        return;
    }

    pj_time_val delay = {0, 10};

    while(true)
    {
        pjsip_endpt_handle_events(endpoint, &delay);
    }

    qDebug() << "finished";
}

The most interesting thing is that when I create first two instances of proxy its working but when I create the third instance my app terminates with these error: 最有趣的是,当我创建代理的前两个实例时,但在创建第三个实例时,我的应用因以下错误而终止:

server: ../src/pjsip/sip_tel_uri.c:173: pjsip_tel_uri_subsys_init: Assertion `status==0' failed.
Aborted (core dumped)

Backtrace from dumped core: 来自转储核心的回溯:

(gdb) bt
#0  0xb777d424 in __kernel_vsyscall ()
#1  0xb6e881df in raise () from /lib/i386-linux-gnu/libc.so.6
#2  0xb6e8b825 in abort () from /lib/i386-linux-gnu/libc.so.6
#3  0xb6e81085 in ?? () from /lib/i386-linux-gnu/libc.so.6
#4  0xb6e81137 in __assert_fail () from /lib/i386-linux-gnu/libc.so.6
#5  0x08079344 in pjsip_tel_uri_subsys_init ()
#6  0x08069265 in pjsip_endpt_create ()
#7  0x080569a7 in proxy::start (this=0x8905db8) at ../server/proxy.cpp:93
#8  0x0805f0c1 in proxy::qt_static_metacall (_o=0x8905db8, _c=QMetaObject::InvokeMetaMethod, _id=1, _a=0xb3aff270) at moc_proxy.cpp:75
#9  0xb73d4c5d in QMetaObject::activate(QObject*, int, int, void**) () from /home/dev/Qt/5.1.1/gcc/lib/libQt5Core.so.5
#10 0xb73d567b in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /home/dev/Qt/5.1.1/gcc/lib/libQt5Core.so.5
#11 0xb7444ef5 in QThread::started(QThread::QPrivateSignal) () from /home/dev/Qt/5.1.1/gcc/lib/libQt5Core.so.5
#12 0xb71d7388 in ?? () from /home/dev/Qt/5.1.1/gcc/lib/libQt5Core.so.5
#13 0xb713ad4c in start_thread () from /lib/i386-linux-gnu/libpthread.so.0
#14 0xb6f49bae in clone () from /lib/i386-linux-gnu/libc.so.6

I don't know what am I doing wrong. 我不知道我在做什么错。 Could anybody help, please? 有人可以帮忙吗?

Thanks in advance for any help. 在此先感谢您的帮助。

Main problem is that you're creating a new SIP endpoint on every proxy instance and, although current documentation states that "theoretically", multiple instance of SIP endpoint is supported, actually, it is not. 主要问题是您要在每个proxy实例上创建一个新的SIP端点,尽管当前文档指出“理论上”支持SIP端点的多个实例,但实际上不支持。

More specifically, first time you call pjsip_endpt_create three static URI parsers are registered (for sip: , sips: and tel: ), second time tel: is registered again (there's a check to avoid sip: and sips: but not for tel: ) and, when trying to register tel: again, at third time, maximum number of URI parsers (4) is overpassed, registration fails and an assertion dumps. 更具体地说,第一次调用pjsip_endpt_create时,将pjsip_endpt_create三个静态URI解析器(对于sip:sips:tel: pjsip_endpt_create ,第二次再次注册tel:有一项检查可以避免sip:sips:但对于tel:则不这样)并且,当尝试注册tel:时,再次第三次超过URI解析器的最大数量(4),注册失败并断言一个断言。

I suggest you to work with only one SIP endpoint, creating a new UDP socket for every proxy instance and attaching it to the endpoint by using pjsip_udp_transport_attach2 我建议您仅使用一个SIP端点,为每个proxy实例创建一个新的UDP套接字,并通过使用pjsip_udp_transport_attach2将其附加到端点

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

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