QT开发pjsip的VOIP,A8平台运行

QT开发pjsip的VOIP

开发环境

平台:A8

环境:Linux-3.0.8

实现功能:使用QT开发VOIP进行初始化、拨号、挂起

测试工具:minisipserver服务器

效果

界面:

minisipserver显示:

封装SIP操作接口:

#include "qt_sip.h"

qt_sip::qt_sip()

{

}

初始化

bool qt_sip::init_sip(void)

{

    pj_status_t status;

    /* Create pjsua first! */

    status = pjsua_create();

    if (status != PJ_SUCCESS)

        return -1;

    /* Init pjsua */

    {

    pjsua_config cfg;

    pjsua_logging_config log_cfg;

    pjsua_config_default(&cfg);

    cfg.cb.on_incoming_call = &on_incoming_call;

    cfg.cb.on_call_media_state = &on_call_media_state;

    cfg.cb.on_call_state = &on_call_state;

    pjsua_logging_config_default(&log_cfg);

    log_cfg.console_level = 4;

    status = pjsua_init(&cfg, &log_cfg, NULL);

    if (status != PJ_SUCCESS)

        return -3;

    }

    /* Add UDP transport. */

    {

    pjsua_transport_config cfg;

    pjsua_transport_config_default(&cfg);

    cfg.port = 5060;

    status = pjsua_transport_create(PJSIP_TRANSPORT_UDP, &cfg, NULL);

    if (status != PJ_SUCCESS)

        return -4;

    }

    /* Initialization is done, now start pjsua */

    status = pjsua_start();

    if (status != PJ_SUCCESS)

        return -5;

}

void qt_sip::on_incoming_call(pjsua_acc_id acc_id, pjsua_call_id call_id,pjsip_rx_data *rdata)

 {

  pjsua_call_info ci;

  PJ_UNUSED_ARG(acc_id);

  PJ_UNUSED_ARG(rdata);

  pjsua_call_get_info(call_id, &ci);

  PJ_LOG(3,(THIS_FILE, "Incoming call from %.*s!!",

  (int)ci.remote_info.slen,

  ci.remote_info.ptr));

  /* Automatically answer incoming calls with 200/OK */

  pjsua_call_answer(call_id, 200, NULL, NULL);

 }

/* Callback called by the library when call's state has changed */

 void qt_sip::on_call_state(pjsua_call_id call_id, pjsip_event *e)

 {

  pjsua_call_info ci;

  PJ_UNUSED_ARG(e);

  pjsua_call_get_info(call_id, &ci);

  PJ_LOG(3,(THIS_FILE, "Call %d state=%.*s", call_id,

  (int)ci.state_text.slen,

  ci.state_text.ptr));

 }

 /* Callback called by the library when call's media state has changed */

 void qt_sip::on_call_media_state(pjsua_call_id call_id)

 {

  pjsua_call_info ci;

  pjsua_call_get_info(call_id, &ci);

  if (ci.media_status == PJSUA_CALL_MEDIA_ACTIVE) {

  // When media is active, connect call to sound device.

  pjsua_conf_connect(ci.conf_slot, 0);

  pjsua_conf_connect(0, ci.conf_slot);

  }

 }

 /* Display error and exit application */

void qt_sip::error_exit(const char *title, pj_status_t status)

 {

  pjsua_perror(THIS_FILE, title, status);

  pjsua_destroy();

  exit(1);

 }

注册

说明:

在封装sip协议栈的操作接口时,最好是使用SIP协议栈提供的接口,比如:

使用pj_ansi_snprintf这个函数,而不直接使用C的snprintf或是sprintf函数。

int qt_sip::sip_register(char *cname,char *cpasswd,char *sdomain)

{

    pj_status_t status;

     /* Register to SIP server by creating SIP account. */

     {

     pjsua_acc_config cfg;

     pjsua_acc_config_default(&cfg);

     char uri[PJSIP_MAX_URL_SIZE];

    //local地址

   //minisipserver的ip地址:100.100.100.199

   //在minisipserver服务器上添加SIP账号,名称:100,密码:100

   //形式:"sip:账号名称@服务器地址"

     pj_ansi_snprintf(uri, PJSIP_MAX_URL_SIZE,

                  "sip:%s@%s",

                  cname,sdomain);

      cfg.id = pj_str(uri);

    //服务器地址

   / /形式:“sip:地址”

   //“sip:100.100.100.199”

     char reg_uri[PJSIP_MAX_URL_SIZE];

     pj_ansi_snprintf(reg_uri, PJSIP_MAX_URL_SIZE,"sip:%s",sdomain);

     PJ_LOG(3,(THIS_FILE, "***%s***",reg_uri));

     cfg.reg_uri = pj_str(reg_uri);

     cfg.cred_count = 1;

        char realm_uri[PJSIP_MAX_URL_SIZE];

     pj_ansi_snprintf(realm_uri,100,"%s",sdomain);

     PJ_LOG(3,(THIS_FILE, "***%s***",realm_uri));

     cfg.cred_info[0].realm = pj_str("*");

     //cfg.cred_info[0].scheme = pj_str("digest");

     cfg.cred_info[0].username = pj_str(cname);

     cfg.cred_info[0].data_type = PJSIP_CRED_DATA_PLAIN_PASSWD;

     cfg.cred_info[0].data = pj_str(cpasswd);

     status = pjsua_acc_add(&cfg, PJ_TRUE, &g_acc_id);

     if (status != PJ_SUCCESS)

         return -6;

     }

     return 0;

}

拨号

   //在minisipserver服务器上添加SIP账号,名称:101

   //使用另外的客户端注册

   //拨打101,命令格式:“sip:101@100.100.100.199”

int qt_sip::sip_dial(char *phonenum)

{

    pj_status_t status;

    char tmp_uri[PJSIP_MAX_URL_SIZE];

    pj_ansi_snprintf(tmp_uri, PJSIP_MAX_URL_SIZE,

                 "sip:%s@%s",

                 phonenum,g_server_name);

    /* If argument is specified, it's got to be a valid SIP URL */

    status = pjsua_verify_url(tmp_uri);

    if (status != PJ_SUCCESS)

        return -1;

    pj_str_t uri = pj_str(tmp_uri);

    status = pjsua_call_make_call(g_acc_id, &uri, 0, NULL, NULL, NULL);

    if (status != PJ_SUCCESS)

        return -2;

    return 0;

}

挂断

void qt_sip::sip_hangup()

{

pjsua_call_hangup_all();

}

打印日志:

1)初始化

[root@FriendlyARM QT_PJSIP_VOIP-build-desktop-Qt_4_7_0__QtEmbedded-4_7_0-arm____]# ./QTVOIP -qws

11:56:48.281 os_core_unix.c !pjlib 2.1 for POSIX initialized

11:56:58.294 sip_endpoint.c  .Creating endpoint instance...

11:56:58.295          pjlib  .select() I/O Queue created (0x1b16d8)

11:56:58.295 sip_endpoint.c  .Module "mod-msg-print" registered

11:56:58.295 sip_transport.  .Transport manager created.

11:56:58.295   pjsua_core.c  .PJSUA state changed: NULL --> CREATED

11:56:58.295 sip_endpoint.c  .Module "mod-pjsua-log" registered

11:56:58.295 sip_endpoint.c  .Module "mod-tsx-layer" registered

11:56:58.295 sip_endpoint.c  .Module "mod-stateful-util" registered

11:56:58.295 sip_endpoint.c  .Module "mod-ua" registered

11:56:58.295 sip_endpoint.c  .Module "mod-100rel" registered

11:56:58.295 sip_endpoint.c  .Module "mod-pjsua" registered

11:56:58.296 sip_endpoint.c  .Mo[19531.501318] EPLL Rate changes from 49152000 to 67738000

[19531.503760] EPLL Rate changes from 67738000 to 49152000

dule "mod-invite" registered

11:56:58.364       pa_dev.c  ..PortAudio sound library initialized, status=0

11:56:58.364       pa_dev.c  ..PortAudio host api count=2

11:56:58.364       pa_dev.c  ..Sound device count=4

11:56:58.364          pjlib  ..select() I/O Queue created (0x1c947c)

11:56:58.396 sip_endpoint.c  .Module "mod-evsub" registered

11:56:58.396 sip_endpoint.c  .Module "mod-presence" registered

11:56:58.397 sip_endpoint.c  .Module "mod-mwi" registered

11:56:58.397 sip_endpoint.c  .Module "mod-refer" registered

11:56:58.397 sip_endpoint.c  .Module "mod-pjsua-pres" registered

11:56:58.397 sip_endpoint.c  .Module "mod-pjsua-im" registered

11:56:58.397 sip_endpoint.c  .Module "mod-pjsua-options" registered

11:56:58.397   pjsua_core.c  .1 SIP worker threads created

11:56:58.397   pjsua_core.c  .pjsua version 2.1 for Linux-3.0.8/armv7l/glibc-2.11 initialized

11:56:58.397   pjsua_core.c  .PJSUA state changed: CREATED --> INIT

11:57:08.402   pjsua_core.c  SIP UDP socket reachable at 100.100.100.102:5060

11:57:08.402    udp0x1d7e78  SIP UDP transport started, published address is 100.100.100.102:5060

11:57:08.402   pjsua_core.c  PJSUA state changed: INIT --> STARTING

11:57:08.402 sip_endpoint.c  .Module "mod-unsolicited-mwi" registered

11:57:08.402   pjsua_core.c  .PJSUA state changed: STARTING --> RUNNING

2)注册

11:59:02.256            APP  ***sip:100.100.100.199***

11:59:02.256            APP  ***100.100.100.199***

11:59:02.256    pjsua_acc.c  Adding account: id=sip:100@100.100.100.199

11:59:02.256    pjsua_acc.c  .Account sip:100@100.100.100.199 added with id 0

11:59:02.256    pjsua_acc.c  .Acc 0: setting registration..

11:59:02.257   pjsua_core.c  ...TX 506 bytes Request msg REGISTER/cseq=44772 (tdta0x2b89e8) to UDP 100.100.100.199:5060:

REGISTER sip:100.100.100.199 SIP/2.0

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPj82a14091-f95e-44de-b525-fe21626f594b

Max-Forwards: 70

From: <sip:100@100.100.100.199>;tag=b6314bb4-660d-487b-b2f0-8e7099dbd28a

To: <sip:100@100.100.100.199>

Call-ID: c90be808-43c1-498a-9817-1a4c53b06c4a

CSeq: 44772 REGISTER

Contact: <sip:100@100.100.100.102:5060;ob>

Expires: 300

Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS

Content-Length:  0

--end msg--

11:59:02.258    pjsua_acc.c  ..Acc 0: Registration sent

11:59:02.271   pjsua_core.c  .RX 595 bytes Response msg 407/REGISTER/cseq=44772 (rdata0x1d92a4) from UDP 100.100.100.199:5060:

SIP/2.0 407 Proxy Authentication Required

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPj82a14091-f95e-44de-b525-fe21626f594b

From: <sip:100@100.100.100.199>;tag=b6314bb4-660d-487b-b2f0-8e7099dbd28a

To: <sip:100@100.100.100.199>;tag=2db82286

CSeq: 44772 REGISTER

Call-ID: c90be808-43c1-498a-9817-1a4c53b06c4a

Allow: REGISTER,INVITE,OPTIONS,ACK,CANCEL,BYE,REFER,NOTIFY,SUBSCRIBE

User-Agent: miniSipServer V2.3.2 (100) build on Nov  6 2008

Proxy-Authenticate: Digest realm="example.com",algorithm=MD5,nonce="649b3b454ccd12ff21c6509715c2513b",stale=false

Content-Length: 0

--end msg--

11:59:02.272   pjsua_core.c  ....TX 700 bytes Request msg REGISTER/cseq=44773 (tdta0x2b89e8) to UDP 100.100.100.199:5060:

REGISTER sip:100.100.100.199 SIP/2.0

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPj2ac23c60-15b7-475f-abd2-247976b94d3e

Max-Forwards: 70

From: <sip:100@100.100.100.199>;tag=b6314bb4-660d-487b-b2f0-8e7099dbd28a

To: <sip:100@100.100.100.199>

Call-ID: c90be808-43c1-498a-9817-1a4c53b06c4a

CSeq: 44773 REGISTER

Contact: <sip:100@100.100.100.102:5060;ob>

Expires: 300

Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS

Proxy-Authorization: Digest username="100", realm="example.com", nonce="649b3b454ccd12ff21c6509715c2513b", uri="sip:100.100.100.199", response="22b3e8e9d88a2f9ace62c83308c7d741", algorithm=MD5

Content-Length:  0

--end msg--

11:59:02.273   pjsua_core.c  .RX 503 bytes Response msg 200/REGISTER/cseq=44773 (rdata0x1d92a4) from UDP 100.100.100.199:5060:

SIP/2.0 200 OK

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPj2ac23c60-15b7-475f-abd2-247976b94d3e

From: <sip:100@100.100.100.199>;tag=b6314bb4-660d-487b-b2f0-8e7099dbd28a

To: <sip:100@100.100.100.199>;tag=2db82286

CSeq: 44773 REGISTER

Call-ID: c90be808-43c1-498a-9817-1a4c53b06c4a

Allow: REGISTER,INVITE,OPTIONS,ACK,CANCEL,BYE,REFER,NOTIFY,SUBSCRIBE

User-Agent: miniSipServer V2.3.2 (100) build on Nov  6 2008

Contact: <sip:100@100.100.100.102>

Expires: 300

Content-Length: 0

--end msg--

11:59:02.273    pjsua_acc.c  ....SIP outbound status for acc 0 is not active

11:59:02.273    pjsua_acc.c  ....sip:100@100.100.100.199: registration success, status=200 (OK), will re-register in 300 seconds

11:59:02.273    pjsua_acc.c  ....Keep-alive timer started for acc 0, destination:100.100.100.199:5060, interval:15s

3)拨号

12:00:10.864   pjsua_call.c !Making call with acc #0 to sip:101@100.100.100.199

12:00:10.864    pjsua_aud.c  .Set sound device: capture=-1, playback=-2

12:00:10.865    pjsua_aud.c  ..Opening sound device PCM@16000/1/20ms

Expression 'SetApproximateSampleRate( pcm, hwParams, sr )' failed in 'src/../../../portaudio/src/hostapi/alsa/pa_linux_alsa.c', line: 1294

Expression 'PaAlsaStreamComponent_InitialConfigure( &self->playback, outParams, self->primeBuffers, hwParamsPlayback, &realSr )' failed in 'src/../../../portaudio/src/hostapi/alsa/pa_linux_alsa.c', line: 1873

Expression 'PaAlsaStream_Configure( stream, inputParameters, outputParameters, sampleRate, framesPerBuffer, &inputLatency, &outputLatency, &hostBufferSizeMode )' failed in 'src/../../../portaudio/src/hostapi/alsa/pa_linux_alsa.c', line: 1994

12:00:10.876     ec0x2beb68  ...AEC created, clock_rate=16000, channel=1, samples per frame=320, tail length=200 ms, latency=100 ms

12:00:10.877  pjsua_media.c  .Call 0: initializing media..

12:00:15.893   sound_port.c  EC suspended because of inactivity

12:00:20.886  pjsua_media.c !..RTP socket reachable at 100.100.100.102:40000

12:00:20.887  pjsua_media.c  ..RTCP socket reachable at 100.100.100.102:40001

12:00:20.887  pjsua_media.c  ..Media index 0 selected for audio call 0

12:00:20.888   pjsua_core.c  ....TX 1088 bytes Request msg INVITE/cseq=9089 (tdta0x2f2898) to UDP 100.100.100.199:5060:

INVITE sip:101@100.100.100.199 SIP/2.0

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

Max-Forwards: 70

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199

Contact: <sip:100@100.100.100.102:5060;ob>

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

CSeq: 9089 INVITE

Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS

Supported: replaces, 100rel, timer, norefersub

Session-Expires: 1800

Min-SE: 90

Content-Type: application/sdp

Content-Length:   484

v=0

o=- 3541291220 3541291220 IN IP4 100.100.100.102

s=pjmedia

b=AS:84

t=0 0

a=X-nat:0

m=audio 40000 RTP/AVP 98 97 99 104 3 0 8 9 96

c=IN IP4 100.100.100.102

b=TIAS:64000

a=rtcp:40001 IN IP4 100.100.100.102

a=sendrecv

a=rtpmap:98 speex/16000

a=rtpmap:97 speex/8000

a=rtpmap:99 speex/32000

a=rtpmap:104 iLBC/8000

a=fmtp:104 mode=30

a=rtpmap:3 GSM/8000

a=rtpmap:0 PCMU/8000

a=rtpmap:8 PCMA/8000

a=rtpmap:9 G722/8000

a=rtpmap:96 telephone-event/8000

a=fmtp:96 0-15

--end msg--

12:00:20.888            APP  .......Call 0 state=CALLING

12:00:20.897   pjsua_core.c  .RX 486 bytes Response msg 100/INVITE/cseq=9089 (rdata0x1d92a4) from UDP 100.100.100.199:5060:

SIP/2.0 100 Trying

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199;tag=2a46556f

CSeq: 9089 INVITE

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

Allow: REGISTER,INVITE,OPTIONS,ACK,CANCEL,BYE,REFER,NOTIFY,SUBSCRIBE

User-Agent: miniSipServer V2.3.2 (100) build on Nov  6 2008

Contact: <sip:101@100.100.100.199>

Content-Length: 0

--end msg--

12:00:20.907   pjsua_core.c  .RX 487 bytes Response msg 180/INVITE/cseq=9089 (rdata0x1d92a4) from UDP 100.100.100.199:5060:

SIP/2.0 180 Ringing

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199;tag=2a46556f

CSeq: 9089 INVITE

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

Allow: REGISTER,INVITE,OPTIONS,ACK,CANCEL,BYE,REFER,NOTIFY,SUBSCRIBE

User-Agent: miniSipServer V2.3.2 (100) build on Nov  6 2008

Contact: <sip:101@100.100.100.199>

Content-Length: 0

--end msg--

12:00:20.907            APP  .....Call 0 state=EARLY

4)挂断

12:01:03.160   pjsua_call.c !Hangup all calls..

12:01:03.160   pjsua_call.c  .Call 0 hanging up: code=0..

12:01:03.160   pjsua_core.c  .....TX 345 bytes Request msg CANCEL/cseq=9089 (tdta0x2a7e00) to UDP 100.100.100.199:5060:

CANCEL sip:101@100.100.100.199 SIP/2.0

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

Max-Forwards: 70

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

CSeq: 9089 CANCEL

Content-Length:  0

--end msg--

12:01:03.162   pjsua_core.c  .RX 482 bytes Response msg 200/CANCEL/cseq=9089 (rdata0x1d92a4) from UDP 100.100.100.199:5060:

SIP/2.0 200 OK

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199;tag=2a46556f

CSeq: 9089 CANCEL

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

Allow: REGISTER,INVITE,OPTIONS,ACK,CANCEL,BYE,REFER,NOTIFY,SUBSCRIBE

User-Agent: miniSipServer V2.3.2 (100) build on Nov  6 2008

Contact: <sip:101@100.100.100.199>

Content-Length: 0

--end msg--

12:01:03.162   pjsua_core.c  .RX 498 bytes Response msg 487/INVITE/cseq=9089 (rdata0x1d92a4) from UDP 100.100.100.199:5060:

SIP/2.0 487 Request Terminated

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199;tag=2a46556f

CSeq: 9089 INVITE

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

Allow: REGISTER,INVITE,OPTIONS,ACK,CANCEL,BYE,REFER,NOTIFY,SUBSCRIBE

User-Agent: miniSipServer V2.3.2 (100) build on Nov  6 2008

Contact: <sip:101@100.100.100.199>

Content-Length: 0

--end msg--

12:01:03.162   pjsua_core.c  ..TX 352 bytes Request msg ACK/cseq=9089 (tdta0x2f71a0) to UDP 100.100.100.199:5060:

ACK sip:101@100.100.100.199 SIP/2.0

Via: SIP/2.0/UDP 100.100.100.102:5060;rport;branch=z9hG4bKPjb02d3774-83fd-4ff5-8694-26d12697d8d3

Max-Forwards: 70

From: sip:100@100.100.100.199;tag=eb1a9606-dde3-42d8-9253-955509e34509

To: sip:101@100.100.100.199;tag=2a46556f

Call-ID: b30d7a62-82ce-4a1c-8927-fd69d15c8b3b

CSeq: 9089 ACK

Content-Length:  0

--end msg--

12:01:03.163            APP  .....Call 0 state=DISCONNCTD

12:01:03.163  pjsua_media.c  .....Call 0: deinitializing media..

12:01:04.163    pjsua_aud.c  Closing sound device after idle for 1 second(s)

12:01:04.163    pjsua_aud.c  .Closing mini210:  (hw:0,0) sound playback device and mini210:  (hw:0,0) sound capture device

原文地址:https://www.cnblogs.com/dyllove98/p/3230995.html