Linux下编译partysip-2.2.3服务端程序及例程分析

测试
与上一篇《编译libeXosip以及向代理服务器注册》编译基于osip客户端程序有些相同;
编译partysip服务器端程序也是需要首先编译所需的依赖库libosip2, libosipparser2(两个库均来自于libosip2);

这次工程中使用了:
libosip2-4.0.0.tar.gz, partysip-2.2.3.tar.gz

分别下载 libosip和partysip;
http://ftp.gnu.org/gnu/osip/
http://download-mirror.savannah.gnu.org/releases/partysip/

编译libosip2

编译libosip2-4.0.0
./configure –prefix=$PWD/_install
$ make & make install
产生:
|-include
|—-include/osip2 include/osipparser2
|-lib
|—-libosip2.a libosip2.la libosip2.so libosip2.so.3 libosip2.so.3.0.0
|—-libosipparser2.a libosipparser2.la libosipparser2.so libosipparser2.so.3 libosipparser2.so.3.0.0 pkgconfig
|-share/man

编译partysip

编译partysip-2.2.3

./configure LDFLAGS='-L/home/project/demo/osip_demo/libosip2-4.0.0/_install/lib' \
CPPFLAGS='-I/home/project/demo/osip_demo/libosip2-4.0.0/_install/include' \
--prefix=$PWD/_install

问题一 undefined reference to symbol ‘osip_atoi’

/usr/bin/ld: osip_msg.o: undefined reference to symbol 'osip_atoi'
/usr/bin/ld: note: 'osip_atoi' is defined in DSO /home/project/demo/osip_demo/libosip2-4.0.0/_install/lib/libosipparser2.so.3 
so try adding it to the linker command line
/home/project/demo/osip_demo/libosip2-4.0.0/_install/lib/libosipparser2.so.3: could not read symbols: Invalid operation

函数osip_atoi()在libosipparser2库中实现的;
修改文件partysip-2.2.3/src/Makefile添加库的引用
partysip_LDFLAGS = -L$(prefix)/lib -losip2 -losipparser2 -avoid-version -export-dynamic

问题二 undefined reference to ‘__dn_expand’ ‘__res_query’

../ppl/unix/.libs/libppl.so: undefined reference to `__dn_expand'
../ppl/unix/.libs/libppl.so: undefined reference to `__res_query'
collect2: ld returned 1 exit status

两个函数是在glibc下面的libresolv库中实现的。
修改两个文件 1.partysip-2.2.3/src/Makefile,2.partysip-2.2.3/tools/Makefile
所以添加库的引用;
PARTYSIP_LIB = -lnsl -ldl -lresolv
PPL_LIB = -lnsl -ldl -lresolv

问题三 ‘osip_uri_parse’ is defined in DSO

/usr/bin/ld: ../src/psp_utils.o: undefined reference to symbol 'osip_uri_parse'
    /usr/bin/ld: note: 'osip_uri_parse' is defined in DSO 
/home/project/demo/osip_demo/libosip2-4.0.0/_install/lib/libosipparser2.so.3 
so try adding it to the linker command line
could not read symbols: Invalid operation
collect2: ld returned 1 exit status
make[2]: *** [psp_users] Error 1

修改文件 partysip-2.2.3/tools/Makefile添加库的引用
psp_users_LDFLAGS = -O -L$(prefix)/lib -losip2 -losipparser2 -module -avoid-version -export-dynamic

问题四 undefined reference to `clock_gettime’

缺少链接库 -lrt, 加到Makefile中即可;
在文件中partysip-2.2.3/src/Makefile追加库引入-lrt
partysip_LDFLAGS = -L$(prefix)/lib -losip2 -losipparser2 -lrt -avoid-version -export-dynamic
以及文件partysip-2.2.3/tools/Makefile:
PARTYSIP_LIB = -lnsl -ldl -lresolv -lrt

问题五 版本兼容性问题普通变量改指针变量
expected ‘const struct osip_list_t *’ but argument is of type ‘osip_list_t’
osip_list_eol(request->routes, i) 改成 osip_list_eol(&request->routes, i);
此类问题大概有10余处左右,根据编译提示修改即可;

编译成功
partysip-2.2.3/_install目录下
|-bin (partysip partysip-config psp_users)
|-etc (partysip)
|-include (partysip ppl)
|-lib (libppl.a libppl.la libppl.so libppl.so.2 libppl.so.2.2.3 partysip)

修改并运行自带的程序例程

添加注释并且简化一下 src/main.c

#include <stdlib.h>
#include <partysip/partysip.h>

#include <partysip/psp_config.h>
#include <psp_utils.h>

#include <ppl/ppl_init.h>
#include <ppl/ppl_getopt.h>
#include <ppl/ppl_uinfo.h>
#include <ppl/ppl_md5.h>

static const char server_built[] = "unknown";

void partysip_exit (int process_exit_value){
    psp_core_free ();
    psp_config_unload ();
    ppl_init_close ();
    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
              "program has terminated.\n"));
}

// 加载所有的配置的插件
static int main_load_plugins (){
    int i;
    psp_plugin_t *psp_plugin;
    char *plugins;
    char *plugins_config;
    char *next;
    char *next_config;
    char *result;
    char *result_config;
    plugins = psp_config_get_element ("plugins"); //获取需要加载的插件
    if (plugins == NULL){
        return -1;
    }
    //输出 plugins=udp syntax auth filter rgstrar ls_localdb ls_sfull
    printf("plugins=%s\n", plugins);
    plugins_config = psp_config_get_element ("plugins_config");
    if (plugins_config == NULL){
        result_config = NULL;
    }

    i = psp_util_get_and_set_next_token (&result, plugins, &next);
    if (i != 0){
        OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
            "failed to load plugin\n"));
        return -1;
    }
    if (plugins_config!=NULL){
        i = psp_util_get_and_set_next_token (&result_config, plugins_config, &next_config);
        if (i != 0){
            OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
            "failed to read plugins_config\n"));
            return -1;
        }
    }
    for (; result != NULL;) {
        if (result_config!=NULL){
            //依次输出 
            //udp (udp),syntax (syntax),auth (auth),filter (filter_internal),
            //rgstrar (rgstrar),ls_localdb (ls_localdb),ls_sfull (ls_sfull)
            OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
            "loading plugin: %s (%s)\n", result, result_config));
        }else{
            OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,
            "loading plugin: %s\n", result));
        }
        i = psp_plugin_load (&psp_plugin, result, result_config);// 加载插件
        if (i != 0){
            OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
            "failed to load plugin %s\n", result));
            return -1;
        }
        if (plugins_config!=NULL){
            osip_free (result_config);
            plugins_config = next_config;
        }
        osip_free (result);
        plugins = next;
        i = psp_util_get_and_set_next_token (&result, plugins, &next);
        if (i != 0){
            break;
        }
        if (plugins_config!=NULL){
            i = psp_util_get_and_set_next_token (&result_config, plugins_config, &next_config);
            if (i != 0) {
                OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,
                "failed to read plugins_config line\n"));
                return -1;
            }
        }
    }

    return 0;
}

int main (int argc, const char *const argv[])
{
    char c;
    int i;
    ppl_getopt_t *opt;
    ppl_status_t rv;
    const char *cf_config_file = CONFIG_DIR "/" PARTYSIP_CONF;
    int interactive_mode = 0;
    int cf_debug_level = 0;
    const char *cf_log_file = NULL;
    const char *optarg;

    ppl_init_open ( ); // 初始化 ppl library.
    ppl_getopt_init (&opt, argc, argv);//通过ppl_getopt初始化部分ppl参数,可删除(147,148行需同时删除)
    cf_debug_level = 6;

    i = psp_config_load ((char *) cf_config_file); //加载配置文件partysip.conf
    // Config name:/project/demo/osip_demo/partysip-2.2.3/_install/etc/partysip/partysip.conf 
    printf ("Config name: %s\n", cf_config_file);
    if (i != 0){
        perror ("ERROR: Could not open config file");
    }
    // 获取配置文件partysip.conf相关的配置
    char *serverip = psp_config_get_element ("serverip");
    char *servername = psp_config_get_element ("servername");
    char *serverrealm = psp_config_get_element ("serverrealm");

    if (serverip == NULL){
        printf ("Bad configuration: \"serverip\" is mandatory\n");
        partysip_exit (1);
    }
    if (servername == NULL) {
        printf ("Bad configuration: \"servername\" is mandatory\n");
        partysip_exit (1);
    }
    // 配置输出日志 OSIP_TRACE (osip_trace...)
    FILE *log_file;
    if (cf_debug_level > 0){
        if (cf_log_file != NULL){
            log_file = fopen (cf_log_file, "w+");
            if (NULL == log_file){
                printf ("Log name:           %s\n", cf_log_file);
                perror ("ERROR: Could not open log file");
                exit (1);
            }
        }else{
            log_file = NULL;
        }
        TRACE_INITIALIZE (cf_debug_level, log_file);//配置日志输出
    }
    osip_free ((void *) (opt->argv));
    osip_free ((void *) opt);

    i = psp_core_init (); //partysip初始化
    i = psp_utils_load_users (); //partysip加载用户,不做验证,所以可以不调用
    i = main_load_plugins (); // 加载插件
    i = psp_core_start (interactive_mode);//partysip启动

    if (interactive_mode == 1)
        while(1);

    if (interactive_mode == 1)
        partysip_exit (0);      /* else, this is done somewhere else */

    return 0;
    main_error:
    partysip_exit (0);
    return -1;
}

修改配置文件
/project/demo/osip_demo/partysip-2.2.3/_install/etc/partysip/partysip.conf
使用属性:
serverip = 192.168.1.123
servername = demo-sip-server
serverport_udp = 5060
authentication = off
magicstring2 = “demo”

其中authentication属性关闭了对用户注册的验证;于是任意用户都可以注册成功;

运行程序
./partysip
如果没有修改直接运行,需要添加参数
./partysip -d 6

使用http://blog.csdn.net/dreamintheworld/article/details/72939454中的例程进行注册;
可以看到注册成功的log输出;
两台注册上来的终端设备已经经过测试,并完成呼叫测试功能,并通过音频传输测试(来自PJSIP的两个客户端,如果使用eXosip媒体协商需要进一步修改)

关于程序中加载插件

编译程序生成

partysip-2.2.3/_install/lib/目录下
libppl.a  libppl.la  libppl.so  libppl.so.2  libppl.so.2.2.3

partysip-2.2.3/_install/lib/partysip/目录下
libpsp_auth.a     libpsp_ls_localdb.a   libpsp_rgstrar.a
libpsp_auth.la    libpsp_ls_localdb.la  libpsp_rgstrar.la
libpsp_auth.so    libpsp_ls_localdb.so  libpsp_rgstrar.so

libpsp_filter.a   libpsp_ls_sfull.a     libpsp_syntax.a
libpsp_filter.la  libpsp_ls_sfull.la    libpsp_syntax.la
libpsp_filter.so  libpsp_ls_sfull.so    libpsp_syntax.so

libpsp_groups.a   libpsp_ls_static.a    libpsp_udp.a
libpsp_groups.la  libpsp_ls_static.la   libpsp_udp.la
libpsp_groups.so  libpsp_ls_static.so   libpsp_udp.so

程序中通过dlopen(const char *filename, int flag)打开动态链接库文件的形式,实现插件加载;

main_load_plugins>>>psp_plugin_load>>>ppl_dso_load>>>dlopen

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值