pjsua_lib示例之简单UA

本文介绍了如何利用pjsip2.5.5库中的samples工程,特别是`simpleua.c`文件,来创建一个无需注册到SIP服务器的基本UA。该UA支持基本呼叫、UDP在5060端口传输、RTP在4000端口传输、仅使用PCMA和PCMU编码器的语音媒体。通过调用`simpleua sip地址`命令,程序会进行SDP协商并启动RTP媒体传输。呼入呼叫会自动应答并挂断。代码示例展示了如何处理SIP请求和响应,以及媒体流的创建和管理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是pjsip2.5.5的samples工程内提供包括媒体及完整UA功能的简单应用,文件位置:pjproject-2.5.5\pjsip-apps\src\samples\simpleua.c,用户代理(UA)在SDK协商成功后启动RTP媒体传输。

此程序不需要注册到SIP服务器,它能够完成:基本呼叫、在5060端口传输UDP、在4000端口传输RTP、SDP协商、语音编解码器只支持PCMA和PCMU、声卡的语音媒体。

Samples工程编译完成后,在命令行输入:

       simpleua 要呼叫的sip地址

要呼叫的sip地址格式: sip:用户名@对端IP

 

*呼入的呼叫先以180自动应答,再以200自动应答,此程序单次呼叫后即退出。

 

 

#include <pjsip.h>

#include <pjmedia.h>

#include <pjmedia-codec.h>

#include <pjsip_ua.h>

#include <pjsip_simple.h>

#include <pjlib-util.h>

#include <pjlib.h>

 

#define THIS_FILE  "simpleua.c"

 

#include "util.h"

 

 

//设置

#define AF      pj_AF_INET()// 如果使用IPV6,将此行改为pj_AF_INET6()

                             //必须设置PJ_HAS_IPV6

                             //并且操作系统也需要支持 IPv6.  */

#if 0

#define SIP_PORT    5080             //侦听的SIP端口

#define RTP_PORT    5000             // RTP端口

#else

#define SIP_PORT    5060            //侦听的SIP端口

#define RTP_PORT    4000            // RTP端口

#endif

 

#define MAX_MEDIA_CNT   2       //媒体数量,设置为1将支持音频,

                              //设置为2,即支持音频,又支持视频

 

//全局静态变量

 

static pj_bool_t        g_complete;    //退出状态

static pjsip_endpoint      *g_endpt;        // SIP终端

static pj_caching_pool       cp;          //全局pool factory

 

static pjmedia_endpt       *g_med_endpt;   // 媒体终端

 

staticpjmedia_transport_info g_med_tpinfo[MAX_MEDIA_CNT];

                        //媒体传输用套接字信息

staticpjmedia_transport    *g_med_transport[MAX_MEDIA_CNT];

                        //媒体流传输端口

staticpjmedia_sock_info     g_sock_info[MAX_MEDIA_CNT]; 

                        //套接字信息组

 

//呼叫部分变量

staticpjsip_inv_session    *g_inv;      //当前invite传话

static pjmedia_stream       *g_med_stream;  //语音流

static pjmedia_snd_port     *g_snd_port;   //声卡设备

 

#if defined(PJMEDIA_HAS_VIDEO)&& (PJMEDIA_HAS_VIDEO != 0)

staticpjmedia_vid_stream   *g_med_vstream; //视频流

static pjmedia_vid_port    *g_vid_capturer;//视频捕获设备

static pjmedia_vid_port    *g_vid_renderer;//视频播放设备

#endif  //PJMEDIA_HAS_VIDEO

 

//函数声明

 

 

//呼叫过程上,当SDP协商完成后,回调此函数

static void  call_on_media_update( pjsip_inv_session *inv,

                 pj_status_t status);

 

//invite会话状态变化后,回调此函数

static void  call_on_state_changed( pjsip_inv_session *inv,

                   pjsip_event *e);

 

//当新对话建立后,回调此函数

static void  call_on_forked(pjsip_inv_session *inv, pjsip_event *e);

 

//对话之外,当收到请求时,回调此函数

static pj_bool_t  on_rx_request( pjsip_rx_data *rdata );

 

 

 

 

//PJSIP模块注册到应用用于处理对话或事务之外的请求,主要目的是处理INVITE请求消息,在那里将为它创建新的对话和INVITE会话

 

static pjsip_module  mod_simpleua =

{

    NULL, NULL,             /*prev, next.       */

    { "mod-simpleua", 12 },      /* Name.         */

    -1,                  /* Id            */

    PJSIP_MOD_PRIORITY_APPLICATION, /* Priority          */

    NULL,                /* load()            */

    NULL,                /* start()           */

    NULL,                /* stop()            */

    NULL,                /* unload()          */

    &on_rx_request,          /* on_rx_request()       */

    NULL,                /* on_rx_response()      */

    NULL,                /* on_tx_request.        */

    NULL,                /* on_tx_response()      */

    NULL,                /* on_tsx_state()        */

};

 

 

//呼入消息通知

static pj_bool_t  logging_on_rx_msg(pjsip_rx_data *rdata)

{

    PJ_LOG(4,(THIS_FILE, "RX %d bytes%s from %s %s:%d:\n"

             "%.*s\n"

             "--end msg--",

             rdata->msg_info.len,

             pjsip_rx_data_get_info(rdata),

             rdata->tp_info.transport->type_name,

             rdata->pkt_info.src_name,

             rdata->pkt_info.src_port,

             (int)rdata->msg_info.len,

             rdata->msg_info.msg_buf));

   

    //此处必须返回false,否则其它消息将不被处理

    return PJ_FALSE;

}

 

//呼出消息通知

static pj_status_t  logging_on_tx_msg(pjsip_tx_data *tdata)

{

    

    /* Important note:

     *   tp_infofield is only valid after outgoing messages has passed

     *   transportlayer. So don't try to access tp_info when the module

     *   haslower priority than transport layer.

     */

 

    PJ_LOG(4,(THIS_FILE, "TX %d bytes%s to %s %s:%d:\n"

             "%.*s\n"

             "--end msg--",

             (tdata->buf.cur - tdata->buf.start),

             pjsip_tx_data_get_info(tdata),

             tdata->tp_info.transport->type_name,

             tdata->tp_info.dst_name,

             tdata->tp_info.dst_port,

             (int)(tdata->buf.cur - tdata->buf.start),

             tdata->buf.start));

 

    /* Always return success, otherwise message w

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值