|
|
######## Presence server module ########
|
|
|
#!trydef PRESENCE_MIN_EXPIRES 300
|
|
|
#!trydef PRESENCE_MIN_EXPIRES_ACTION 1
|
|
|
#!trydef PRESENCE_MAX_EXPIRES 3600
|
|
|
|
|
|
#!trydef KZ_PRESENCE_IGNORE_STATUS_PROBE_RESP 1
|
|
|
|
|
|
#!trydef KZ_PRESENCE_CSEQ_OFFSET 2
|
|
|
|
|
|
#!trydef KZ_PRESENCE_MAX_CALL_PER_PRESENTITY 20
|
|
|
|
|
|
#!trydef BLF_USE_SINGLE_DIALOG 1
|
|
|
|
|
|
#!trydef KZ_PRESENCE_AMQP_PUBLISH 0
|
|
|
|
|
|
#!trydef KZ_PRESENCE_REQUEST_RESUBSCRIBE_PROBE 0
|
|
|
#!trydef KZ_PRESENCE_REQUEST_PROBE 1
|
|
|
|
|
|
#!trydef KZ_PRESENCE_NO_TARGETS_LOG_LEVEL L_DBG
|
|
|
|
|
|
modparam("htable", "htable", "p=>size=32;autoexpire=3600;")
|
|
|
modparam("htable", "htable", "first=>size=32;autoexpire=3600;initval =0;updateexpire=1;")
|
|
|
|
|
|
loadmodule "presence.so"
|
|
|
loadmodule "presence_dialoginfo.so"
|
|
|
loadmodule "presence_mwi.so"
|
|
|
loadmodule "presence_xml.so"
|
|
|
|
|
|
modparam("presence_dialoginfo", "force_dummy_dialog", 1)
|
|
|
modparam("presence_dialoginfo", "force_single_dialog", BLF_USE_SINGLE_DIALOG)
|
|
|
|
|
|
modparam("presence_xml", "force_dummy_presence", 1)
|
|
|
modparam("presence_xml", "force_active", 1)
|
|
|
modparam("presence_xml", "disable_winfo", 1)
|
|
|
modparam("presence_xml", "disable_bla", 1)
|
|
|
|
|
|
modparam("presence", "subs_db_mode", 3)
|
|
|
modparam("presence", "expires_offset", 0)
|
|
|
modparam("presence", "send_fast_notify", 1)
|
|
|
|
|
|
modparam("presence", "clean_period", 0)
|
|
|
modparam("presence", "db_update_period", 0)
|
|
|
|
|
|
modparam("presence", "publ_cache", 0)
|
|
|
modparam("presence", "min_expires_action", PRESENCE_MIN_EXPIRES_ACTION)
|
|
|
modparam("presence", "min_expires", PRESENCE_MIN_EXPIRES)
|
|
|
modparam("presence", "max_expires", PRESENCE_MAX_EXPIRES)
|
|
|
modparam("presence", "sip_uri_match", 1)
|
|
|
modparam("presence", "waitn_time", 1)
|
|
|
modparam("presence", "notifier_processes", 0)
|
|
|
modparam("presence", "db_url", "KAZOO_DB_URL")
|
|
|
modparam("presence", "xavp_cfg", "pres")
|
|
|
modparam("presence", "local_log_level", 6)
|
|
|
modparam("presence", "startup_mode", 0)
|
|
|
modparam("presence", "force_delete", 1)
|
|
|
modparam("presence", "timeout_rm_subs", 0)
|
|
|
modparam("presence", "cseq_offset", KZ_PRESENCE_CSEQ_OFFSET)
|
|
|
|
|
|
modparam("kazoo", "db_url", "KAZOO_DB_URL")
|
|
|
modparam("kazoo", "pua_mode", 1)
|
|
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
|
#!ifndef NAT_TRAVERSAL_LOADED
|
|
|
#!trydef NAT_TRAVERSAL_LOADED
|
|
|
loadmodule "nat_traversal.so"
|
|
|
#!endif
|
|
|
modparam("nat_traversal", "keepalive_method", "OPTIONS")
|
|
|
modparam("nat_traversal", "keepalive_from", "sip:sipcheck@MY_HOSTNAME")
|
|
|
modparam("nat_traversal", "keepalive_state_file", "KAZOO_DATA_DIR/keep_alive_state")
|
|
|
modparam("nat_traversal", "keepalive_interval", 45)
|
|
|
#!endif
|
|
|
|
|
|
kazoo.presence_sync_amqp = KZ_PRESENCE_AMQP_PUBLISH descr "sync subscriptions to amqp"
|
|
|
kazoo.presence_request_probe = KZ_PRESENCE_REQUEST_PROBE descr "request probe for new subscriptions"
|
|
|
kazoo.presence_request_resubscribe_probe = KZ_PRESENCE_REQUEST_RESUBSCRIBE_PROBE descr "request probe for resubscriptions"
|
|
|
kazoo.presence_ignore_status_probe_resp = KZ_PRESENCE_IGNORE_STATUS_PROBE_RESP descr "ignore online/offline probe replies"
|
|
|
kazoo.presence_max_call_per_presentity = KZ_PRESENCE_MAX_CALL_PER_PRESENTITY descr "max number of calls per presentity"
|
|
|
kazoo.presence_no_targets_log_level = KZ_PRESENCE_NO_TARGETS_LOG_LEVEL descr "when a presence event is received and there no targets we can log at another level"
|
|
|
|
|
|
#!include_file "presence-query.cfg"
|
|
|
#!include_file "presence-notify.cfg"
|
|
|
#!include_file "presence-reset.cfg"
|
|
|
#!include_file "presence-fast-pickup.cfg"
|
|
|
|
|
|
####### Presence Logic ########
|
|
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
|
route[PRESENCE_NAT]
|
|
|
{
|
|
|
if (isflagset(FLT_NATS)) {
|
|
|
nat_keepalive();
|
|
|
}
|
|
|
}
|
|
|
#!endif
|
|
|
|
|
|
route[HANDLE_SUBSCRIBE]
|
|
|
{
|
|
|
if (!is_method("SUBSCRIBE")) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if ($hdr(Event) != "dialog"
|
|
|
&& $hdr(Event) != "presence"
|
|
|
&& $hdr(Event) != "message-summary") {
|
|
|
xlog("L_INFO", "$ci|presence|subscribe event $hdr(Event) not supported\n");
|
|
|
send_reply(489, "Bad Event");
|
|
|
exit();
|
|
|
}
|
|
|
|
|
|
if (!t_newtran()) {
|
|
|
sl_reply_error();
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
#!ifdef NAT_TRAVERSAL_ROLE
|
|
|
route(PRESENCE_NAT);
|
|
|
#!endif
|
|
|
|
|
|
if(has_totag()) {
|
|
|
loose_route();
|
|
|
}
|
|
|
|
|
|
record_route();
|
|
|
|
|
|
if(has_totag()) {
|
|
|
route(HANDLE_RESUBSCRIBE);
|
|
|
} else {
|
|
|
route(HANDLE_NEW_SUBSCRIBE);
|
|
|
}
|
|
|
|
|
|
t_release();
|
|
|
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
route[DELETE_DUPLICATED_SUBSCRIPTIONS]
|
|
|
{
|
|
|
sql_query("exec", '$_s(DELETE FROM ACTIVE_WATCHERS WHERE FROM_USER = "$subs(from_user)" AND FROM_DOMAIN="$subs(from_domain)" AND EVENT="$subs(event)" AND PRESENTITY_URI="$subs(uri)" AND CALLID <> "$subs(callid)")');
|
|
|
}
|
|
|
|
|
|
route[HANDLE_RESUBSCRIBE]
|
|
|
{
|
|
|
|
|
|
if(handle_subscribe()) {
|
|
|
if($subs(remote_cseq) < 5) {
|
|
|
$sht(first=>$subs(callid)) = $null;
|
|
|
$sht(first=>$subs(from_user)::$subs(pres_uri)::$subs(from_domain)::$subs(event)) = $null;
|
|
|
}
|
|
|
route(DELETE_DUPLICATED_SUBSCRIPTIONS);
|
|
|
route(SUBSCRIBE_AMQP);
|
|
|
route(REQUEST_PROBE);
|
|
|
};
|
|
|
}
|
|
|
|
|
|
|
|
|
route[HANDLE_NEW_SUBSCRIBE]
|
|
|
{
|
|
|
if ($hdr(Event) == "dialog"
|
|
|
|| $hdr(Event) == "presence"
|
|
|
|| $hdr(Event) == "message-summary") {
|
|
|
|
|
|
|
|
|
if ($tU == $null) {
|
|
|
xlog("L_INFO", "$ci|stop|ignoring subscribe with empty TO username from a $ua\n");
|
|
|
send_reply(400, "Missing TO username");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if ($fU == $null) {
|
|
|
xlog("L_INFO", "$ci|stop|ignoring subscribe with empty FROM username from a $ua\n");
|
|
|
send_reply(400, "Missing FROM username");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if($shtinc(first=>$ci) > 1) {
|
|
|
sql_query("exec", 'KZQ_HANDLE_NEW_SUBSCRIBE_DELETE1');
|
|
|
xlog("L_INFO", "$ci|subscribe|resetting $hdr(Event) subscription from $fU to $tU in realm $fd : $sqlrows(exec)\n");
|
|
|
} else {
|
|
|
$var(presentity_uri) = $ru;
|
|
|
if($(var(presentity_uri){uri.user}) == "") {
|
|
|
$var(presentity_uri) = $tu;
|
|
|
}
|
|
|
if($shtinc(first=>$fU::$var(presentity_uri)::$fd::$hdr(Event)) > 1) {
|
|
|
sql_query("exec", 'KZQ_HANDLE_NEW_SUBSCRIBE_DELETE2');
|
|
|
xlog("L_INFO", "$ci|subscribe|resetting $hdr(Event) subscription from $fU to $var(presentity_uri) in realm $fd : $sqlrows(exec)\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (handle_subscribe()) {
|
|
|
xlog("L_INFO","$ci|end|new $hdr(Event) subscription from $fU to $tU in realm $fd : $sht(first=>$ci) : $sht(first=>$fU::$tU::$fd::$hdr(Event))\n");
|
|
|
route(DELETE_DUPLICATED_SUBSCRIPTIONS);
|
|
|
route(SUBSCRIBE_AMQP);
|
|
|
route(REQUEST_PROBE);
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|stop|error $T_reply_code for new $hdr(Event) subscription from $fU to $tU in realm $fd\n");
|
|
|
}
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|stop|unsupported subscription package $hdr(Event) from $fU to $tU in realm $fd\n");
|
|
|
send_reply(489, "Bad Event");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[SUBSCRIBE_AMQP]
|
|
|
{
|
|
|
if($sel(cfg_get.kazoo.presence_sync_amqp) == 1) {
|
|
|
$var(rk) = "subscribe." + $(subs(to_domain){kz.encode}) + "." + $(subs(to_user){kz.encode});
|
|
|
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "subscription", "Event-Package" : "$hdr(event)", "Expires" : $subs(expires), "Queue" : "BLF-MY_HOSTNAME", "Server-ID" : "BLF-MY_HOSTNAME" , "Contact" : "$(ct{s.escape.common}{s.replace,\','}{s.replace,$$,})", "Call-ID" : "$ci", "From" : "$fu", "User" : "$subs(uri)", "User-Agent" : "$(ua{s.escape.common}{s.replace,\','}{s.replace,$$,})" });
|
|
|
kazoo_publish("omnipresence", "$var(rk)", $var(amqp_payload_request));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[REQUEST_PROBE]
|
|
|
{
|
|
|
if( ($sel(cfg_get.kazoo.presence_request_probe) == 1 && (!has_totag()))
|
|
|
|| ($sel(cfg_get.kazoo.presence_request_resubscribe_probe) == 1 && has_totag()) ) {
|
|
|
if( route(HAS_PRESENTITY) == 0) {
|
|
|
if($hdr(event) == "message-summary") {
|
|
|
$var(mwi) = $tU;
|
|
|
route(REQUEST_MWI);
|
|
|
} else {
|
|
|
if($tU =~ "\*98") {
|
|
|
$var(mwi) = $(tU{s.substr,3,0});
|
|
|
route(REQUEST_MWI);
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|sub|requesting $hdr(Event) probe for $subs(to_user) in realm $subs(to_domain)\n");
|
|
|
$var(rk) = "probes." + $hdr(Event);
|
|
|
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "probe", "Event-Package" : "$hdr(event)", "Username" : "$tU", "Realm" : "$fd", "Call-ID" : "$ci"});
|
|
|
kazoo_publish("presence", "$var(rk)", $var(amqp_payload_request));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[REQUEST_MWI]
|
|
|
{
|
|
|
xlog("L_INFO", "$ci|sub|requesting mwi probe for $var(mwi) in realm $subs(to_domain)\n");
|
|
|
$var(rk) = "mwi_queries." + $(subs(to_domain){kz.encode});
|
|
|
$var(amqp_payload_request) = $_s({"Event-Category" : "presence", "Event-Name" : "mwi_query", "Username" : "$var(mwi)", "Realm" : "$fd", "Call-ID" : "$ci"});
|
|
|
kazoo_publish("presence", "$var(rk)", $var(amqp_payload_request));
|
|
|
}
|
|
|
|
|
|
route[HANDLE_PUBLISH]
|
|
|
{
|
|
|
if(!is_method("PUBLISH")) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if ($hdr(Event) != "dialog"
|
|
|
&& $hdr(Event) != "presence"
|
|
|
&& $hdr(Event) != "message-summary") {
|
|
|
xlog("L_INFO", "$ci|presence|publish event $hdr(Event) not supported\n");
|
|
|
send_reply(489, "Bad Event");
|
|
|
exit();
|
|
|
}
|
|
|
|
|
|
if (!t_newtran()) {
|
|
|
sl_reply_error();
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
if($hdr(Sender)!= $null) {
|
|
|
handle_publish("$hdr(Sender)");
|
|
|
} else {
|
|
|
handle_publish();
|
|
|
}
|
|
|
t_release();
|
|
|
exit;
|
|
|
}
|
|
|
|
|
|
route[HAS_PRESENTITY]
|
|
|
{
|
|
|
$var(Query) = $_s(KZQ_HAS_PRESENTITY);
|
|
|
$var(res) = 0;
|
|
|
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
|
|
|
{
|
|
|
if($xavp(subs) != $null) {
|
|
|
$var(res) = $xavp(subs=>count);
|
|
|
pv_unset("$xavp(subs)");
|
|
|
}
|
|
|
}
|
|
|
return $var(res);
|
|
|
}
|
|
|
|
|
|
route[COUNT_PRESENTITIES]
|
|
|
{
|
|
|
$var(Query) = $_s(KZQ_COUNT_PRESENTITIES);
|
|
|
$var(p) = $_s(presence_id='$var(presentity)');
|
|
|
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
|
|
|
{
|
|
|
while($xavp(subs) != $null) {
|
|
|
$var(p) = $var(p) + ";" + $xavp(subs=>event) + "=" + $xavp(subs=>count);
|
|
|
pv_unset("$xavp(subs)");
|
|
|
}
|
|
|
}
|
|
|
xavp_params_explode($var(p), "watchers");
|
|
|
}
|
|
|
|
|
|
route[COUNT_ALL_PRESENTITIES]
|
|
|
{
|
|
|
$var(Query) = $_s(select event, (select count(*) from presentity b where b.event = a.event) count from event_list a);
|
|
|
$var(p) = "presence_id=none";
|
|
|
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
|
|
|
{
|
|
|
while($xavp(subs) != $null) {
|
|
|
$var(p) = $var(p) + ";" + $xavp(subs=>event) + "=" + $xavp(subs=>count);
|
|
|
pv_unset("$xavp(subs)");
|
|
|
}
|
|
|
}
|
|
|
xavp_params_explode($var(p), "watchers");
|
|
|
}
|
|
|
|
|
|
route[COUNT_ALL_SUBSCRIBERS]
|
|
|
{
|
|
|
$var(Query) = $_s(KZQ_COUNT_ALL_SUBSCRIBERS);
|
|
|
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
|
|
|
{
|
|
|
$var(sep) = "";
|
|
|
$var(Subscribers) = "";
|
|
|
$var(Subscriptions) = "";
|
|
|
while($xavp(subs) != $null) {
|
|
|
$var(Subscribers) = $var(Subscribers) + $var(sep) + $_s("$xavp(subs=>event)" : $xavp(subs=>count_unique));
|
|
|
$var(Subscriptions) = $var(Subscriptions) + $var(sep) + $_s("$xavp(subs=>event)" : $xavp(subs=>count));
|
|
|
$var(sep) = " , ";
|
|
|
pv_unset("$xavp(subs)");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[COUNT_SUBSCRIBERS]
|
|
|
{
|
|
|
$var(Query) = $_s(KZQ_COUNT_SUBSCRIBERS);
|
|
|
$var(p) = $_s(presence_id='$var(presentity)');
|
|
|
if (sql_xquery("cb", "$var(Query)", "subs") == 1)
|
|
|
{
|
|
|
while($xavp(subs) != $null) {
|
|
|
$var(p) = $var(p) + ";" + $xavp(subs=>event) + "=" + $xavp(subs=>count);
|
|
|
pv_unset("$xavp(subs)");
|
|
|
}
|
|
|
}
|
|
|
xavp_params_explode($var(p), "watchers");
|
|
|
}
|
|
|
|
|
|
event_route[kazoo:consumer-event-presence-dialog-update]
|
|
|
{
|
|
|
$var(presence_log_level) = $sel(cfg_get.kazoo.presence_no_targets_log_level);
|
|
|
$var(StartRoute) = $(TV(Sn){s.replace,.,});
|
|
|
$var(delta_to_start) = $var(StartRoute) - $(kzE{kz.json,AMQP-Received});
|
|
|
xlog("L_DEBUG", "$(kzE{kz.json,Call-ID})|log|received $(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From}) state $(kzE{kz.json,State}) from $(kzE{kz.json,AMQP-Broker-Zone}) => $(kzE{kz.json,Switch-URI}) (Δ1 $(kzE{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs)\n");
|
|
|
|
|
|
$var(JObj) = $kzE;
|
|
|
route(PRESENCE_FAST_PICKUP_INIT);
|
|
|
|
|
|
$var(presentity) = $(kzE{kz.json,From});
|
|
|
$var(payload) = $kzE;
|
|
|
|
|
|
route(PRESENCE_UPDATE);
|
|
|
|
|
|
$var(EndRoute) = $(TV(Sn){s.replace,.,});
|
|
|
$var(delta_to_finish) = $var(EndRoute) - $var(StartRoute);
|
|
|
|
|
|
xlog("$var(presence_log_level)", "$(kzE{kz.json,Call-ID})|log|$(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From}) state $(kzE{kz.json,State}) from $(kzE{kz.json,AMQP-Broker-Zone}) => $(kzE{kz.json,Switch-URI}) (Δ1 $(kzE{kz.json,AMQP-Elapsed-Micro}) μs , Δ2 $var(delta_to_start) μs, Δ3 $var(delta_to_finish) μs)\n");
|
|
|
}
|
|
|
|
|
|
event_route[kazoo:consumer-event-presence-mwi-update]
|
|
|
{
|
|
|
$var(presence_log_level) = $sel(cfg_get.kazoo.presence_no_targets_log_level);
|
|
|
xlog("L_DBG", "$(kzE{kz.json,Call-ID})|log|received message-summary update for $(kzE{kz.json,From}) ($(kzE{kz.json,AMQP-Broker-Zone}))\n");
|
|
|
$var(presentity) = $(kzE{kz.json,From});
|
|
|
$var(payload) = $kzE;
|
|
|
route(COUNT_SUBSCRIBERS);
|
|
|
if($xavp(watchers=>message-summary) > 0) {
|
|
|
$var(presence_log_level) = L_INFO;
|
|
|
xlog("L_INFO", "$(kzE{kz.json,Call-ID})|log|publishing $(kzE{kz.json,From}) message-summary update for $xavp(watchers=>message-summary) watchers\n");
|
|
|
kazoo_pua_publish_mwi($kzE);
|
|
|
pres_refresh_watchers("$(kzE{kz.json,From})", "message-summary", 1);
|
|
|
} else {
|
|
|
#!ifdef PRESENCE_TRACK_ALL_PKG_MWI
|
|
|
if($(kzE{kz.json,Event-Package}) == "message-summary") {
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|saving $var(presentity) from mwi update => $var(payload)\n");
|
|
|
if(kazoo_pua_publish_mwi($kzE) != 1) {
|
|
|
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) mwi update => $var(payload)\n");
|
|
|
}
|
|
|
}
|
|
|
#!else
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|skip mwi update for $var(presentity)\n");
|
|
|
#!endif
|
|
|
}
|
|
|
|
|
|
route(MWI_AS_PRESENCE);
|
|
|
xlog("$var(presence_log_level)", "$(kzE{kz.json,Call-ID})|log|message-summary update for $(kzE{kz.json,From}) light should be on ? $(kzE{kz.json,Messages-Waiting}) at $(kzE{kz.json,AMQP-Received})/$var(Now)/$TS\n");
|
|
|
|
|
|
}
|
|
|
|
|
|
event_route[kazoo:consumer-event-presence-update]
|
|
|
{
|
|
|
$var(presence_log_level) = $sel(cfg_get.kazoo.presence_no_targets_log_level);
|
|
|
if($sel(cfg_get.kazoo.presence_ignore_status_probe_resp) == 1) {
|
|
|
if($(kzE{kz.json,State}) == "offline" || $(kzE{kz.json,State}) == "online") {
|
|
|
xlog("L_DEBUG", "$(kzE{kz.json,Call-ID})|log|ignoring $(kzE{kz.json,State}) state $(kzE{kz.json,Presence-ID})\n");
|
|
|
return;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
xlog("L_DEBUG", "$(kzE{kz.json,Call-ID})|log|received presence update for $(kzE{kz.json,Presence-ID})");
|
|
|
$var(JObj) = $kzE;
|
|
|
$var(presentity) = $_s(sip:$(kzE{kz.json,Presence-ID}));
|
|
|
$var(payload) = $kzE;
|
|
|
route(PRESENCE_UPDATE);
|
|
|
|
|
|
xlog("$var(presence_log_level)", "$(kzE{kz.json,Call-ID})|log|$(kzE{kz.json,Event-Package}) update for $(kzE{kz.json,From}) state $(kzE{kz.json,State}) from $(kzE{kz.json,Switch-URI}) Δ at $(kzE{kz.json,AMQP-Received})/$var(Now)/$TS\n");
|
|
|
}
|
|
|
|
|
|
route[PRESENCE_UPDATE]
|
|
|
{
|
|
|
if($(var(payload){kz.json,State}) == "terminated") {
|
|
|
route(COUNT_PRESENTITIES);
|
|
|
} else {
|
|
|
route(COUNT_SUBSCRIBERS);
|
|
|
}
|
|
|
|
|
|
if($xavp(watchers=>self) > $sel(cfg_get.kazoo.presence_max_call_per_presentity) &&
|
|
|
( $(var(payload){kz.json,State}) == "early" ||
|
|
|
($(var(payload){kz.json,State}) == "confirmed" && $(var(payload){kz.json,State}) == "initiator")
|
|
|
)) {
|
|
|
xlog("L_WARN", "$(var(payload){kz.json,Call-ID})|log|not publishing state $(var(payload){kz.json,State}) for presentity $var(presentity) with $xavp(watchers=>self) calls, policy limit of $sel(cfg_get.kazoo.presence_max_call_per_presentity) calls per presentity \n");
|
|
|
} else {
|
|
|
if($xavp(watchers=>dialog) > 0) {
|
|
|
$var(presence_log_level) = L_INFO;
|
|
|
if($(var(payload){kz.json,State}) == "terminated") {
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) dialog update for terminated dialog\n");
|
|
|
} else {
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) dialog update for $xavp(watchers=>dialog) watchers\n");
|
|
|
}
|
|
|
if(kazoo_pua_publish_dialoginfo($var(JObj)) == 1) {
|
|
|
pres_refresh_watchers("$var(presentity)", "dialog", 1);
|
|
|
} else {
|
|
|
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) dialog update\n");
|
|
|
};
|
|
|
} else {
|
|
|
#!ifdef PRESENCE_TRACK_ALL_PKG_DIALOG
|
|
|
if($(kzE{kz.json,Event-Package}) == "dialog") {
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|saving $var(presentity) from dialog update => $var(payload)\n");
|
|
|
if(kazoo_pua_publish_dialoginfo($var(JObj)) != 1) {
|
|
|
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) dialog update => $var(payload)\n");
|
|
|
}
|
|
|
}
|
|
|
#!else
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|skip dialog update for $var(presentity)\n");
|
|
|
#!endif
|
|
|
}
|
|
|
|
|
|
if($xavp(watchers=>presence) > 0) {
|
|
|
$var(presence_log_level) = L_INFO;
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|publishing $var(presentity) presence update for $xavp(watchers=>presence) watchers\n");
|
|
|
kazoo_pua_publish_presence($var(payload));
|
|
|
pres_refresh_watchers("$var(presentity)", "presence", 1);
|
|
|
} else {
|
|
|
#!ifdef PRESENCE_TRACK_ALL_PKG_PRESENCE
|
|
|
if($(kzE{kz.json,Event-Package}) == "presence") {
|
|
|
$var(presence_log_level) = L_INFO;
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|saving $var(presentity) from dialog update => $var(payload)\n");
|
|
|
if(kazoo_pua_publish_dialoginfo($var(JObj)) != 1) {
|
|
|
xlog("L_ERR", "$(var(payload){kz.json,Call-ID})|log|error publishing $var(presentity) dialog update => $var(payload)\n");
|
|
|
}
|
|
|
}
|
|
|
#!else
|
|
|
xlog("L_DEBUG", "$(var(payload){kz.json,Call-ID})|log|skip presence update for $var(presentity)\n");
|
|
|
#!endif
|
|
|
}
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
#!define MWI_PRESENCE_BODY $(kzE{re.subst,/"Messages-Waiting"\s*\:\s*"[^"]*"/"State" : "$var(State)"/} \
|
|
|
{re.subst,/"From"\s*\:\s*"[^"]*"/"From" : "$var(presentity)"/} \
|
|
|
{re.subst,/"From-User"\s*\:\s*"[^"]*"/"From-User" : "$var(user)"/} \
|
|
|
{re.subst,/"To"\s*\:\s*"[^"]*"/"To" : "$var(presentity)"/} \
|
|
|
{re.subst,/"To-User"\s*\:\s*"[^"]*"/"To-User" : "$var(user)"/} \
|
|
|
{re.subst,/"Messages-New"\s*\:\s*[^,]*/"Direction" : "initiator"/} \
|
|
|
{re.subst,/"Event-Name"\s*\:\s*"[^"]*"/"Event-Name" : "presence"/});
|
|
|
|
|
|
|
|
|
route[MWI_AS_PRESENCE]
|
|
|
{
|
|
|
if( $(kzE{kz.json,Extended-Presence-ID}) == "" ) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
$var(realm) = $(kzE{kz.json,From-Realm});
|
|
|
$var(user) = $(kzE{kz.json,Extended-Presence-ID});
|
|
|
$var(presentity) = $_s(sip:$var(user)@$var(realm));
|
|
|
if( $(kzE{kz.json,Messages-Waiting}) == "yes" ) {
|
|
|
$var(State) = "confirmed";
|
|
|
} else {
|
|
|
$var(State) = "terminated";
|
|
|
}
|
|
|
|
|
|
$var(payload) = MWI_PRESENCE_BODY
|
|
|
$var(JObj) = $var(payload);
|
|
|
route(PRESENCE_UPDATE);
|
|
|
|
|
|
}
|
|
|
|
|
|
route[PRESENCE_BINDINGS]
|
|
|
{
|
|
|
#!import_file "presence-custom-bindings.cfg"
|
|
|
|
|
|
#!ifndef PRESENCE_CUSTOM_BINDINGS
|
|
|
$var(payload) = $_s({ "name" : "presence", "exchange" : "presence", "type" : "topic", "queue" : "presence-dialog-MY_HOSTNAME", "routing" : ["dialog.*.*", "update.*.*", "mwi_updates.*.*"], "exclusive" : 0, "federate" : 1 });
|
|
|
kazoo_subscribe("$var(payload)");
|
|
|
#!endif
|
|
|
|
|
|
route(PRESENCE_API_BINDINGS);
|
|
|
|
|
|
route(PRESENCE_FAST_PICKUP_START);
|
|
|
|
|
|
}
|
|
|
|
|
|
route[PRESENCE_API_BINDINGS]
|
|
|
{
|
|
|
#!import_file "presence-api-custom-bindings.cfg"
|
|
|
|
|
|
#!ifndef PRESENCE_API_CUSTOM_BINDINGS
|
|
|
$var(payload) = $_s({"name": "presence-api", "exchange": "presence", "type": "topic", "queue": "presence-api-MY_HOSTNAME", "routing": ["presence.search_req.*", "presence.reset.*.*"], "exclusive": 0, "federate": 1 });
|
|
|
kazoo_subscribe("$var(payload)");
|
|
|
#!endif
|
|
|
|
|
|
}
|
|
|
|
|
|
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
|