编译libeXosip以及向代理服务器注册

测试 Linux linux

编译 libeXosip2说明

浏览编译说明 libeXosip2-4.1.0/help/INSTALL.linux

Common Install process for linux/UNIX.

1: compile/install libosip first.

  $> tar -xvzf libosip2-x.x.x.tar.gz
  $> CFLAGS="-I/usr/local/include/" ../configure
  $> make
  $> make install      (as root...)

2: compile/install eXosip

  $> tar -xvzf libeXosip2-x.x.x.tar.gz
  $> CFLAGS="-I/usr/local/include/" ../configure
  $> make
  $> make install      (as root...)

所以编译libeXosip2-4.1.0 ,需要先编译 libosip2-4.1.0 (保持版本的一致)

第一步,编译libosip2

编译libosip2-4.1.0
编译:

$ ./configure --prefix=$PWD/_install & make & make install
$ ./configure --prefix=$PWD/_install --host=arm-none-linux-gnueabi  & make & make install

顺利产生以下文件
libosip2-4.1.0/_install/lib/
|-libosip2.a
|-libosip2.so
|-libosipparser2.a
|-libosipparser2.so

第二步,编译libeXosip2

编译 libeXosip2-4.1.0
但是使用 ./configure –prefix=$PWD/_install & make & make install
编译阶段报错
/usr/local/lib/libosipparser2.so: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [libeXosip2.la] Error 1

显然是configure配置阶段就出现了配置不完整的情况。
网上的资料基本上只讲到把相关的文件拷贝到 /usr/local/ 目录下面;
比如
cp libosip2-3.0.1/src/osip2/.libs/libosip2.a /usr/lib
cp libosip2-3.0.1/src/osipparser2/.libs/libosipparser2.a /usr/lib

但是显然这是需要root权限的,所以希望在不影响其他用户的其他下,在自己的权限目录下进行编译。
则需要配置相关的目录。

./configure --prefix=$PWD/_install LDFLAGS="-L/home/zzy/project/wrtWgServerlib/debug/libosip2-4.1.0/_install/lib" \
LIBS="-losipparser2 -losip2" --host=x84_64-unknown-linux-gnu

配置成这样,虽然configure可以配置通过,但是仍然没有通过make;
报错依旧;
下面需要怎么样的配置呢,但是 configure help 的时候已经说到配置 LIBS 以及 LDFLAGS 了
没有讲到更多的配置方式,网上的资料也是少之又少;
编译动态库的时候仍然无法实现,所以屏蔽编译动态库后:

#
# build.sh
#
echo "BUILD libeXosip2-4.1.0"
./configure --prefix=$PWD/_install \
CC=gcc \
--host=x84_64-unknown-linux-gnu \
--disable-tools \
--disable-debug \
--disable-trace \
--disable-shared \
--enable-openssl \
--enable-static \
CFLAGS='-I/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib/include' \
LDFLAGS='-L/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib' \
LIBS='-losipparser2 -losip2' \
SIP_CFLAGS='-I/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib/include' \
OSIP_LIBS='-L/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib -losipparser2 -losip2'

如果配置嵌入式环境 :
CC=arm-none-linux-gnueabi-gcc
–host=arm-none-linux-gnueabi

配置成功后可以生成:
libeXosip2-4.1.0/_install
|-include
|-lib
|-lib/libeXosip2.a
|-lib/libeXosip2.la
这是在屏蔽生成动态库的时候,如果需要生成动态库,估计依然报错;

生成动态库的方法了:
configure 的时候除了生成Makefile之外,还生成了libtool文件,需要修改libtool文件:

# Compile-time system search path for libraries.
sys_lib_search_path_spec="/home/zzy/project/demo/osip_demo/libosip2-4.1.0/_install/lib \
/usr/lib/gcc/x86_64-linux-gnu/4.4.7 \
/usr/lib/x86_64-linux-gnu \
/usr/lib \
/lib/x86_64-linux-gnu /lib "

# Run-time system search path for libraries.
sys_lib_dlsearch_path_spec="/home/zzy/project/demo/osip_demo/libosip2-4.1.0/_install/lib \
/lib \
/usr/lib \
/usr/lib/i386-linux-gnu/mesa \
/lib/i386-linux-gnu /usr/lib/i386-linux-gnu \
/lib/i686-linux-gnu /usr/lib/i686-linux-gnu \
/usr/local/lib /lib/x86_64-linux-gnu \
/usr/lib/x86_64-linux-gnu /usr/lib/x86_64-linux-gnu/mesa \
/lib32 \
/usr/lib32 "

在sys_lib_search_path_spec和sys_lib_dlsearch_path_spec中添加lib的搜索路径;
运行编译脚本

# build.sh
echo "BUILD libeXosip2-4.1.0"

./configure --prefix=$PWD/_install \
CC=gcc \
--host=x84_64-unknown-linux-gnu \
--disable-tools \
--disable-debug \
--disable-trace \
--enable-openssl \
--enable-static \
CFLAGS='-I/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib/include' \
LDFLAGS='-L/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib' \
LIBS='-losipparser2 -losip2' \
SIP_CFLAGS='-I/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib/include' \
OSIP_LIBS='-L/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib -losipparser2 -losip2' 

_install/lib/目录下终于生成:
|-libeXosip2.a
|-libeXosip2.la
|-libeXosip2.so
|-libeXosip2.so.11
|-libeXosip2.so.11.0.0

使用libeXosip2自带的样例测试注册流程

libeXosip2-4.1.0/tools/sip_reg.c
编译:

# build.sh
gcc -O2 -I/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/include \
    -L/home/admin/project/demo/osip_demo/libosip2-4.1.0/_install/lib \
    -I/home/admin/project/demo/osip_demo/libeXosip2-4.1.0/_install/include \
    -L/home/admin/project/demo/osip_demo/libeXosip2-4.1.0/_install/lib \
    sip_reg.c \
    -o sipreg \
    -leXosip2 -losip2 -losipparser2 -lpthread

运行:

# reg.sh 
./sipreg  \
-r sip:192.168.1.22:5060 \
-u sip:01001010101@192.168.1.22 \
-c sip:01001010101@192.168.1.22:5060 \
-U 01001010101 \
-P 01001010101  \
-p 5061 \
-e 1800 \
-d

启动服务器(192.168.1.22)后,运行客户端测试样例:

$ sh build.sh
$ sh reg.sh   
username: 01001010101
password: [removed]01001010101
eXosip_add_authentication_info success
(143)eXosip_register_build_initial_register 2*expiry=3600
---------------
fromuser = sip:01001010101@192.168.1.22
   proxy = sip:192.168.1.22:5060
 contact = sip:01001010101@192.168.1.22:5060
---------------
(169)type=0
registrered successfully

修改注册服务器地址为192.168.1.66 则会注册失败(无代理服务器)

$ sh build.sh
$ sh reg.sh   
username: 01001010101
password: [removed]01001010101
eXosip_add_authentication_info success
(143)eXosip_register_build_initial_register 2*expiry=3600
---------------
fromuser = sip:01001010101@192.168.1.66
   proxy = sip:192.168.1.66:5060
 contact = sip:01001010101@192.168.1.66:5060
---------------
(169)type=1
(175)(nil), Registration failed!


运行程序之后需要添加动态库的搜索路径
分别在libosip2-4.1.0/_install/lib目录,
libeXosip2-4.1.0/_install/lib目录下运行:
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH

以上程序是修改过的sip_reg.c,也仅仅是删除掉一些多余的不影响的宏定义;
修改后的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <syslog.h>
#include <pthread.h>
#include <osip2/osip_mt.h>
#include <eXosip2/eXosip.h>

#define PROG_NAME "sipreg"
#define PROG_VER  "1.0"
#define UA_STRING "SipReg v" PROG_VER
#define SYSLOG_FACILITY LOG_DAEMON

#define syslog_wrapper    syslog
static void usage (void){
    printf ("Usage: " PROG_NAME " [required_options] [optional_options]\n"
        "\n\t[required_options]\n"
        "\t-r --proxy\tsip:proxyhost[:port]\n"
        "\t-u --from\tsip:user@host[:port]\n"
        "\n\t[optional_options]\n"
        "\t-c --contact\tsip:user@host[:port]\n"
        "\t-d --debug (log to stderr and do not fork)\n"
        "\t-e --expiry\tnumber (default 3600)\n"
        "\t-f --firewallip\tN.N.N.N\n" "\t-h --help\n" 
        "\t-l --localip\tN.N.N.N (force local IP address)\n" 
        "\t-p --port\tnumber (default 5060)\n" 
        "\t-U --username\tauthentication username\n" 
        "\t-P --password\tauthentication password\n");
}

typedef struct regparam_t {
    int regid;
    int expiry;
    int auth;
} regparam_t;

struct eXosip_t *context_eXosip;

static void * register_proc (void *arg) {
    struct regparam_t *regparam = arg;
    int reg;
    for (;;) {
        sleep (regparam->expiry / 2);
        eXosip_lock (context_eXosip);
        reg = eXosip_register_send_register (context_eXosip, regparam->regid, NULL);
        printf("(%d)eXosip_register_send_register = %d\n", __LINE__, reg);
        if (0 > reg) {
            perror ("eXosip_register");
            exit (1);
        }
        regparam->auth = 0;
        eXosip_unlock (context_eXosip);
    }
    return NULL;
}

int main (int argc, char *argv[]) {
    int c;
    int port = 5060;
    char *contact = NULL;
    char *fromuser = NULL;
    const char *localip = NULL;
    const char *firewallip = NULL;
    char *proxy = NULL;
    char *username = NULL;
    char *password = NULL;
    struct regparam_t regparam = { 0, 3600, 0 };
    struct osip_thread *register_thread;
    int debug = 0;
    int nofork = 0;
    for (;;) {
        #define short_options "c:de:f:hl:p:r:u:U:P:"
        c = getopt (argc, argv, short_options);
        if (c == -1){
            break;
        }
        switch (c) {
            case 'c':contact = optarg;break;
            case 'd':nofork = 1;break;
            case 'e':regparam.expiry = atoi (optarg);break;
            case 'f':firewallip = optarg;break;
            case 'h':usage ();exit (0);
            case 'l':localip = optarg;break;
            case 'p':port = atoi (optarg);break;
            case 'r':proxy = optarg;break;
            case 'u':fromuser = optarg;break;
            case 'U':username = optarg;break;
            case 'P':password = optarg;break;
            default:break;
        }
    }
    if (!proxy || !fromuser) {
        usage ();
        exit (1);
    }
    if (!nofork) {
        printf("%d\n", daemon (1, 0));
    }

    if (debug > 0){
        TRACE_INITIALIZE (6, NULL);
    }

    context_eXosip = eXosip_malloc ();
    if (eXosip_init (context_eXosip)) {  // 初始化eXosip和osip协议栈  
        syslog_wrapper (LOG_ERR, "eXosip_init failed");
        exit (1);
    }
    if (eXosip_listen_addr (context_eXosip, IPPROTO_UDP, NULL, port, AF_INET, 0)) {
        //  打开信号socket  传输层初始化失败  
        printf("(%d)eXosip_listen_addr failed, port=%d\n", __LINE__, port);
        syslog_wrapper (LOG_ERR, "eXosip_listen_addr failed");
        exit (1);
    }
    if (localip) {
        syslog_wrapper (LOG_INFO, "local address: %s", localip);
        eXosip_masquerade_contact (context_eXosip, localip, port);
    }
    if (firewallip) {
        syslog_wrapper (LOG_INFO, "firewall address: %s:%i", firewallip, port);
        eXosip_masquerade_contact (context_eXosip, firewallip, port);
    }
    eXosip_set_user_agent (context_eXosip, UA_STRING);
    if (username && password) {
        printf("username: %s\n", username);
        printf("password: [removed]%s\n", password);
        if (eXosip_add_authentication_info (context_eXosip, username, username, password, NULL, NULL)) {
            printf ("eXosip_add_authentication_info failed");
            exit (1);
        }else{
            printf("eXosip_add_authentication_info success\n");
        }
    }

    {
        osip_message_t *reg = NULL;
        int i;
        printf("(%d)eXosip_register_build_initial_register 2*expiry=%d\n", 
            __LINE__, regparam.expiry * 2);
        printf("---------------\n");
        printf("%8s = %s\n", "fromuser", fromuser);
        printf("%8s = %s\n", "proxy", proxy);
        printf("%8s = %s\n", "contact", contact);
        printf("---------------\n");
        // 使用参数进行注册初始化
        regparam.regid = eXosip_register_build_initial_register (context_eXosip, 
            fromuser, proxy, contact, regparam.expiry * 2, &reg);
        if (regparam.regid < 1) {
            syslog_wrapper (LOG_ERR, "eXosip_register_build_initial_register failed");
            exit (1);
        }
        // 初始化成功后,发起注册
        i = eXosip_register_send_register (context_eXosip, regparam.regid, reg);
        if (i != 0) {
            syslog_wrapper (LOG_ERR, "eXosip_register_send_register failed");
            exit (1);
        }
    }
    for (;;) {
        eXosip_event_t *event;
        if (!(event = eXosip_event_wait (context_eXosip, 0, 1))) {
            osip_usleep (10000);
            continue;
        }
        eXosip_automatic_action (context_eXosip);
        printf("(%d)type=%d\n", __LINE__, event->type);
        switch (event->type) {
            case EXOSIP_REGISTRATION_SUCCESS:
                printf("registrered successfully\n");
                break;
            case EXOSIP_REGISTRATION_FAILURE:
                printf("(%d)%p, %s\n", __LINE__, event->response, event->textinfo);
                regparam.auth = 1;
                break;
            default:
                break;
        }
        eXosip_event_free (event);
    }
}

参考 http://blog.chinaunix.net/uid-7684977-id-2569711.html

样例中使用的是基于oSIP开源库的SIP代理服务器PartySIP

添加注册成功后进行呼出

switch (event->type) {
    case EXOSIP_REGISTRATION_SUCCESS:
        printf("registrered successfully\n");
        // 初始化成功后发起呼叫
        char strMsg[256];
        // username=本机账号,password=密码
        sprintf(strMsg, "v=0\r\n"\
                   "o=anonymous 0 0 IN IP4 0.0.0.0\r\n"\
                   "t=1 10\r\n"\
                   "a=username:01001010101\r\n"\
                   "a=password:01001010101\r\n");
        char* strSrcCall = "sip:01001010101@192.168.1.66";// 呼出方(本机账号)
            char* strDestCall = "sip:01001010102@192.168.1.66:5060"; // 被叫账号
            osip_message_t *invite = NULL;
        eXosip_call_build_initial_invite (context_eXosip, &invite, 
                                          strDestCall, 
                                          strSrcCall, 
                                          NULL, 
                                          "This is a call for a conversation");
                osip_message_set_body (invite, strMsg, strlen(strMsg));
                osip_message_set_content_type (invite, "application/sdp");

        eXosip_call_build_initial_invite (context_eXosip, &invite, 
                                          strDestCall, 
                                          strSrcCall, 
                                          NULL, 
                                          "This is a call for a conversation");
        eXosip_call_send_initial_invite (context_eXosip, invite);
        break;
    case EXOSIP_REGISTRATION_FAILURE:
        printf("(%d)%p, %s\n", __LINE__, event->response, event->textinfo);
        regparam.auth = 1;
        break;
    case EXOSIP_CALL_PROCEEDING:
        printf("Processing\n"); // 对方(01001010102)正在进行处理
        break;
    case EXOSIP_CALL_RINGING:
        printf("Ringing\n");// 对方(01001010102)振铃
        break;
    default:
        break;
}

嗯,是的,需要两次调用eXosip_call_build_initial_invite

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值