我面临以下情况: 我们必须在本地(注册)用户(iOS应用程序pjSIP)之间启动本地呼叫。 当其中一个用户(假设用户B)在成功注册后几分钟关闭应用程序时,就会出现问题。 现在,当用户A试图呼叫用户B时,我们看到INVITE已发送但我们没有收到来自用户B的回复(例如180响铃)。
注意:当我们向用户B发送邀请时,他会向他的设备发送推送通知他打开应用程序的情况(以及重新注册)
我们的目标是: 1.确定在用户B应用程序关闭且其分机仍在注册的情况下,在我们发送INVITE之前是否可以访问用户B(例如被呼叫者) 2.能够在登记后立即向用户B发送邀请
我们试图从多个方向解决这个问题: 1.Qualify - 试图减少注册期的合格时间,以便用户B尽快无法使用(我们将在拨号之前检查设备状态),但这可能会导致我们网络上的大量OPTIONS,并且它是不会解决目标#2 2.AMI服务 - 它可以捕获以下事件:用户A拨打用户B,用户B振铃(180振铃)并将这些状态保存到ASTDB。在我们启动拨号之前,所有这些逻辑都将被预先确定。 这个解决方案很笨拙,而且还需要另外一项服务
经过一些研究,我得出的结论是,最合适的解决方案是存储每个扩展的最后一个OPTIONS回复的时间(需要在chan_sip.c中有一个补丁)。在用户A拨号之前重新触发sip选项限定对用户B的请求。如果原始值(例如在我们重新触发OPTIONS之前)等于触发OPTIONS后的值,则意味着用户B没有回复OPTIONS。我正在附加我要执行的更改以完成此任务。 我想知道问题的解决方案是否合适和有效,当然还有更好的方法来预先形成它。
这是chan_sip的变化(使用星号11.7) 我只是在以下几行进行了预先修改: 23492至23500
23485 /*! \brief Handle qualification responses (OPTIONS) */
23486 static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
23487 {
23488 struct sip_peer *peer = /* sip_ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
23489 int statechanged, is_reachable, was_reachable;
23490 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
23491
23492 time_t result = time(NULL);
23493 result = (int)result;
这是如何用补丁实现dialplan:
Dial(SIP/${dest},10,Rgb(check_extension,s,1));
I'm sending the call to context before inviting ( with the "b" option)
context check_extension {
s => {
Set(IS_REACHABLE=0);
Verbose(KOLA/LastQualify/${DEST}); // Display User B initial quliafy
Set(INITIAL_QUALIFY=${DB(KOLA/LastQualify/${DEST})}); // Store it
for(loop=0;${loop}<60;dialLoop=${loop}+1) { // Loop untill the qualify will be changes
System(/usr/sbin/asterisk -rx "sip qualify peer ${DEST}");
Wait(2); // we need to wait a while for a response
Set(LAST_QUALIFY=${DB(KOLA/LastQualify/${DEST})}); // set the new qualify
if (${LAST_QUALIFY} > ${INITIAL_QUALIFY}) { // if the new qualify is newer, User B is reachable
Set(IS_REACHABLE=1);
break;
}
}
if (${IS_REACHABLE} = 0) {
Verbose(Peer is not reachable);
Hangup();
}
}
}
答案 0 :(得分:1)
最佳选择是不使用星号。
使用kamailio或opensips项目,它可以处理数千个选项包。
此外,您已经重写了应用程序,因此当它关闭 UNREGISTER 时,就像在RFC中描述的那样。
总结一下:你正在使用有缺陷的应用程序,并且对未设计的星号事件进行分类(大量用户有选项)。所以正确的答案 - 使用正确的工具来完成这项任务。