修改linphonec

        Linphone是一个开源的SIP客户端,底层协议栈使用osip和eXosip,在linphone的源码包中,包含了一个exosip目录,这里是完整的exosip代码,这个exosip大概是0.9版的,0.9版与最新的2.*版相差很大。所以在使用linphone之前,只要先安装好osip库就行了。
        我在 www.antisip.com 注册了两个SIP用户,准备在我的机器上同时开两个linphone来试试,研究一下linphone的实现。
        Linphone在编译后主要生成两个可执行的程序,一个是linphone,它是有图形界面的UA;另一个是linphonec,没有图形界面,是一个命令行的UA,我喜欢用命令行,所以只用linphonec。
        我在本机注册了两个用户,一个raysan一个raypan,它们分别对应我在antisip服务器上的两个SIP帐户。在本机分别登录两个用户,分别启动linphonec程序,会自动在用户目录下生成.linphonerc文件,里面是一些配置信息,进行适当的修改后,重新启动linphonec,过一会儿提示已顺利注册。
        使用call命令从raysan向raypan发起呼叫,raypan很快收到呼叫,但两边都开始报出很多alsa方面的错误,一定是因为两边都要响铃(一边是ringing,一边是coming call),造成了声卡资源争用,所以出了错。修改代码,从coreapi/exevents.c里的事件响应部分开始,找到在收到RINGING和NEW_CALL消息时所要调用的函数,在其中注掉几个发出声音的函数,就不会再响了,也不会再报错了,收到call的时候只会有一条文本信息打出来。不过要是回复answer命令来接听的话,还是会报错的,因为两边都要争设备嘛。
        先从简单的研究入手。发现linphonec所提供的几种命令中没有用于即时消息的,于是想实现这个功能。Linphonec的代码比较简单,我对代码做了如下的添加和修改:
在linphonecore.c中加入函数:
 
int linphone_core_chat(LinphoneCore *lc, const char *url, const char *message)  {

        
char *route=
NULL;
        
const char *from=
NULL;
        LinphoneProxyConfig 
*proxy=
NULL;
        osip_to_t 
*to_parsed=
NULL;
        
char *to=
NULL;
        
int err=0
;

        linphone_core_get_default_proxy(lc,
&
proxy);
        
if (!linphone_core_interpret_url(lc,url,&to,&to_parsed))
{
                
return -1
;
        }

        
if (proxy!=NULL) {
                route
=
linphone_proxy_config_get_route(proxy);
                from
=
linphone_proxy_config_get_identity(proxy);
        }

        
/* if no proxy or no identity defined for this proxy, default to primary contact*/
        
if (from==NULL) from=linphone_core_get_primary_contact(lc);
        printf(
"## : linphone_core_chat() :  "
);
        printf(
"## : url = %s "
, url);
        printf(
"## : to = %s "
, to);
        printf(
"## : from = %s "
, from);
        printf(
"## : route = %s "
,route);
        printf(
"## : message = %s "
,message);

        eXosip_lock();
        err 
= eXosip_message(to, (char *)from, route, (char *
)message);
        eXosip_unlock();
        printf(
"## : err = %d "
,err);
        
return 0
;
}
在commands.c中修改命令表:
 
/*
 * Commands table.
 
*/

LPC_COMMAND commands[] 
=  {
    
"help", lpc_cmd_help, "Print commands help", NULL }
,
    
"call", lpc_cmd_call, "Call a SIP uri",
        
"'call <sip-url>' or 'c <sip-url>' "

        
": initiate a call to the specified destination."
        }
,
    
"terminate", lpc_cmd_terminate, "Terminate the current call",
        NULL }
,
    
"answer", lpc_cmd_answer, "Answer a call",
        
"Accept an incoming call."

    }
,
    
"proxy", lpc_cmd_proxy, "Manage proxies",
        
"'proxy list' : list all proxy setups. "

        
"'proxy add' : add a new proxy setup. "
        
"'proxy remove <index>' : remove proxy setup with number index. "
        
"'proxy use <index>' : use proxy with number index as default proxy. "
        
"'proxy unuse' : don't use a default proxy."
    }
,
    
"soundcard", lpc_cmd_soundcard, "Manage soundcards",
        
"'soundcard list' : list all sound devices. "

        
"'soundcard use <index>' : select a sound device. "
        
"'soundcard use files' : use .wav files instead of soundcard "
    }
,
    
"ipv6", lpc_cmd_ipv6, "Use IPV6",
        
"'ipv6 status' : show ipv6 usage status. "

        
"'ipv6 enable' : enable the use of the ipv6 network. "
        
"'ipv6 disable' : do not use ipv6 network."
    }
,
    
"refer", lpc_cmd_refer,
        
"Refer the current call to the specified destination."
,
        
"'refer <sip-url>' or 'r <sip-url>' "

        
": refer the current call to the specified destination."
    }
,
    
"nat", lpc_cmd_nat, "Set nat address",
        
"'nat'        : show nat settings. "

        
"'nat <addr>' : set nat address (and enable its use). "
        
"'nat use'    : enable nat use (ip must be set). "
        
"'nat unuse'  : disable nat use. "
    }
,
        
"call-logs", lpc_cmd_call_logs, "Calls history",
                NULL }
,
    
"friend", lpc_cmd_friend, "Manage friends",
        
"'friend list [<pattern>]'    : list friends. "

        
"'friend call <index>         : call a friend."
    }
,
    
"play", lpc_cmd_play, "play from a wav file",
        
"This feature is available only in file mode (see 'help soundcard') "

        
"'play <wav file>'    : play a wav file."
    }
,
    
"record", lpc_cmd_record, "record to a wav file",
        
"This feature is available only in file mode (see 'help soundcard') "

        
"'record <wav file>'    : record into wav file."
    }
,
    
"quit", lpc_cmd_quit, "Exit linphonec", NULL }
,
    
//Rayman

    "chat", lpc_cmd_chat, "Chat with someone","'chat <someone> <message>'" },
    
{ (char *)NULL, (lpc_cmd_handler)NULL, (char *)NULL, (char *)NULL }

}
;
并加入函数:
static int
lpc_cmd_chat
(LinphoneCore *lc, char *args)
 {
    char *url
=args;

    char *message
=NULL;
    
    while
(*url && !isspace(*url)) ++url;
    
if (*url)  {
        *url
='0';

        message
=url+1;
        while
(*message && isspace(*message)) ++message;
    }
    linphone_core_chat
(lc,args,message);
    
return 1;
}
        上面程序最核心的目的就是要调用eXosip_message这个函数,这是0.9版exosip里的,在最新版中已面目全非。
        顺利通过编译。运行!在raysan一端键入命令chat raypan hahaha,但遗憾的是在raypan这端并没有显示出有消息到来。用wireshark抓包,以下是其中两个包的截屏:
   
        表明raysan这端的确发出了一个MESSAGE请求,但是从服务器回来了一个unauthored错误信息,有点想不通,试了很多次,结果一样,google一下,未果。
        修改.linphonerc文件,把两个用户都作为本地用户,不向任何公共服务器注册,即本地用户raysan只向同是本地用户的raypan发MESSAGE请问,结果出人意料,MESSAGE消息收到了,但收到消息的不是raypan而是raysan自己,仔细想想,呵呵,也对,注意到上面的截图了吗,MESSAGE消息所在的UDP包的目标端口是5060,它的本意是SIP服务器开5060端口来接收SIP请求,但现在是在本机,raysan用的是5060,而raypan用的是5070,所以这个消息就又发给raysan了。如果是从raypan发给raysan的话,就一定能收到了。
 
        尽管通过公共SIP服务器来发即时消息还没有实现,但经过上面的实验说明使用eXosip_message来发送即时消息是对的,离成功还差一步。
 
<think>好的,用户遇到了Linphone命令行客户端的参数错误问题,具体是关于-C和--media=rtp这两个参数。我需要先确认这两个参数的正确用法。 首先,回想一下Linphone的文档,可能-C用于指定配置文件,而--media用于设置媒体传输协议。用户可能在使用时参数格式有误,比如缺少值或者顺序不对。 然后,检查常见的错误情况。比如,是否在指定参数时漏掉了必要的值,或者使用了错误的参数组合。例如,--media=rtp后面是否需要其他选项,比如地址或端口? 另外,注意到用户提到的引用内容中有disable-rtp-auto-adjust参数设置为true,这可能与媒体传输有关。可能需要检查配置文件中是否有相关设置冲突。 接下来,可能的解决方案包括:检查参数格式是否正确,确保每个参数都有对应的值;尝试不同的参数顺序;查看Linphone的日志或错误输出以获取更详细的提示;或者参考官方文档确认参数的兼容性。 最后,生成相关问题,帮助用户进一步排查问题,比如参数的正确语法、配置文件的位置、其他可能影响媒体传输的设置,以及如何启用调试日志等。</think>关于Linphone命令行客户端参数错误问题,具体解决方案如下: ### 参数错误分析 1. **-C参数特性**:该参数用于指定配置文件路径,格式应为`-C /path/to/config`,若路径包含空格需加引号[^1] 2. **--media参数限制**:rtp传输模式需配合具体编解码器使用,建议补充`--media=rtp,[address]:[port]`格式指定传输地址 ### 分步解决方案 ```bash # 正确参数组合示例 linphonecsh init -C /etc/linphonerc --media=rtp,192.168.1.100:5060 # 禁用RTP自动调节(与错误引用相关) linphonecsh init -C /etc/linphonerc --media=rtp --disable-rtp-auto-adjust=TRUE ``` ### 配置验证方法 1. 使用`linphonecsh status`查看参数加载状态 2. 检查配置文件中的媒体设置项: $$ media_encryption=none $$ $$ rtp_port=5060 $$
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值