######## FAST PICKUP ROLE ########
|
|
modparam("htable", "htable", "park=>size=16;autoexpire=600")
|
|
modparam("htable", "htable", "fp=>size=8");
|
|
|
|
route[FAST_PICKUP_START]
|
|
{
|
|
$sht(fp=>count) = 0;
|
|
}
|
|
|
|
route[FAST_PICKUP_LOAD]
|
|
{
|
|
sht_reset("fp");
|
|
#!ifndef KZ_USE_DISPATCHER_LIST
|
|
xlog("L_INFO", "$ci|log|fast|initializing fastpick hash table from dispatcher\n");
|
|
if (sql_xquery("exec", "select destination from dispatcher", "ra") == 1) {
|
|
while($xavp(ra) != $null) {
|
|
$var(host) = $(xavp(ra=>destination){uri.host});
|
|
$var(port) = $(xavp(ra=>destination){uri.port});
|
|
$var(destination) = $xavp(ra=>destination);
|
|
$var(i) = 0;
|
|
if(!is_ip("$var(host)")) {
|
|
if(dns_query("$var(host)", "xyz")) {
|
|
$var(destination) = $_s(sip:$dns(xyz=>addr[$var(i)]):$var(port));
|
|
}
|
|
}
|
|
xlog("L_INFO", "$ci|log|fast|adding key $(var(destination){s.md5}) for $var(destination)\n");
|
|
$sht(fp=>$(var(destination){s.md5})) = $var(destination);
|
|
pv_unset("$xavp(ra)");
|
|
}
|
|
}
|
|
#!else
|
|
xlog("L_INFO", "$ci|log|fast|cannot initialize hash table from dispatcher. check KZ_USE_DISPATCHER_LIST option in local.cfg\n");
|
|
#!endif
|
|
}
|
|
|
|
route[FAST_PICKUP_ATTEMPT]
|
|
{
|
|
if (!is_method("INVITE")) {
|
|
return;
|
|
}
|
|
|
|
$var(replaced_call_id) = "none";
|
|
|
|
if($hdr(Replaces)!= $null) {
|
|
$var(replaced_call_id) = $(hdr(Replaces){s.select,0,;});
|
|
}
|
|
|
|
if($var(replaced_call_id) =~ "kfp+") {
|
|
if($shtinc(fp=>count) == 1) {
|
|
route(FAST_PICKUP_LOAD);
|
|
}
|
|
remove_hf_re("^Replaces");
|
|
$var(PickupOptions) = $(var(replaced_call_id){re.subst,/^kfp\+(.{2})([^@]*)@(.*)/\1/}{s.decode.hexa});
|
|
$var(md5) = $(var(replaced_call_id){re.subst,/^kfp\+(.{2})([^@]*)@(.*)/\2/});
|
|
$var(replaced_call_id) = $(var(replaced_call_id){re.subst,/^kfp\+(.{2})([^@]*)@(.*)/\3/});
|
|
if( $sht(fp=>$var(md5)) != $null) {
|
|
route(FAST_PICKUP_OPTION);
|
|
$du = $sht(fp=>$var(md5));
|
|
append_hf("Replaces: $var(replaced_call_id)$var(Pickup)\r\n");
|
|
xlog("L_INFO", "$ci|log|fast|found shortcut for call-id $var(replaced_call_id) , redirecting ($(ru{uri.user})) to $du\n");
|
|
route(EXTERNAL_TO_INTERNAL_RELAY);
|
|
exit();
|
|
} else {
|
|
$var(replaced_call_id) = "none";
|
|
xlog("L_INFO", "$ci|log|fast|shortcut $var(md5) invalid in this server, using standard routing\n");
|
|
}
|
|
}
|
|
|
|
if($var(replaced_call_id) != "none") {
|
|
xlog("L_INFO", "$ci|log|request has replaces call-id $var(replaced_call_id)\n");
|
|
$var(amqp_payload_request) = '{"Event-Category" : "call_event" , "Event-Name" : "channel_status_req", "Call-ID" : "' + $var(replaced_call_id) + '", "Active-Only" : true }';
|
|
$var(amqp_routing_key) = "call.status_req." + $(var(replaced_call_id){kz.encode});
|
|
sl_send_reply("100", "locating your call");
|
|
xlog("L_INFO", "$ci|log|querying cluster for the location of call-id $var(replaced_call_id)\n");
|
|
if(kazoo_query("callevt", $var(amqp_routing_key), $var(amqp_payload_request))) {
|
|
$du = $(kzR{kz.json,Switch-URL});
|
|
if($du != $null) {
|
|
if($(ru{uri.user}) =~ "\*") {
|
|
remove_hf_re("^Replaces");
|
|
append_hf("Replaces: $var(replaced_call_id);a-leg=true\r\n");
|
|
}
|
|
xlog("L_INFO", "$ci|log|call-id $var(replaced_call_id) found redirecting call ($(ru{uri.user})) to $du\n");
|
|
route(EXTERNAL_TO_INTERNAL_RELAY);
|
|
exit();
|
|
} else {
|
|
xlog("L_WARN", "$ci|log|call-id $var(replaced_call_id) not found in cluster, proceeding with normal dispatch\n");
|
|
remove_hf_re("^Replaces");
|
|
}
|
|
} else {
|
|
remove_hf_re("^Replaces");
|
|
}
|
|
}
|
|
|
|
##### CALL-PARK ####
|
|
if($(ru{uri.user}) =~ "\*" && $sht(park=>$(ru{uri.user})@$(ru{uri.domain})) != $null) {
|
|
$du = $sht(park=>$(ru{uri.user})@$(ruri{uri.domain}));
|
|
xlog("L_INFO", "$ci|log|redirecting park request to $du\n");
|
|
if ($hdr(Proxy-Authorization) != $null) {
|
|
xlog("L_INFO", "$ci|log|removed park redirect\n");
|
|
$sht(park=>$(ru{uri.user})@$(ruri{uri.domain})) = $null;
|
|
}
|
|
route(EXTERNAL_TO_INTERNAL_RELAY);
|
|
exit();
|
|
}
|
|
}
|
|
|
|
route[FAST_PICKUP_REFER]
|
|
{
|
|
if(!is_method("REFER")) {
|
|
return;
|
|
}
|
|
|
|
$avp(refer_to) = $hdr(Refer-To);
|
|
$avp(referred_by) = $hdr(Referred-By);
|
|
$avp(refer_to_uri) = $rt;
|
|
}
|
|
|
|
route[FAST_PICKUP_REPLY] {
|
|
if (!is_method("REFER") || !t_check_status("(200)|(202)") ) {
|
|
return;
|
|
}
|
|
|
|
$var(contact) = "sip:" + $(ct{tobody.uri}{uri.host}) + ":" + $(ct{tobody.uri}{uri.port});
|
|
xlog("L_INFO", "$ci|log|caching park info $(avp(refer_to_uri){uri.user})@$(avp(refer_to_uri){uri.domain}) = $var(contact)\n");
|
|
|
|
$sht(park=>$(avp(refer_to_uri){uri.user})@$(avp(refer_to_uri){uri.domain})) = $var(contact);
|
|
}
|
|
|
|
route[FAST_PICKUP_OPTION]
|
|
{
|
|
$var(Pickup) = "";
|
|
switch($var(PickupOptions))
|
|
{
|
|
case 1:
|
|
$var(Pickup) = ";a-leg=true";
|
|
break;
|
|
case 2:
|
|
$var(Pickup) = ";early-only=true";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
route[FAST_PICKUP_INIT]
|
|
{
|
|
$var(AppName) = $(kzE{kz.json,App-Name});
|
|
if($var(AppName) == "park") {
|
|
$var(Pickup) = 1; #";a-leg=true";
|
|
} else {
|
|
$var(Pickup) = 2; #";early-only=true";
|
|
}
|
|
$var(Option) = $(var(Pickup){s.encode.hexa});
|
|
$var(Cookie) = $(kzE{kz.json,Switch-URI}{s.md5});
|
|
$var(call_id) = $(kzE{kz.json,Call-ID});
|
|
$var(JObj) = $(kzE{re.subst,/"Call-ID"\s*\:\s*"([^\s"]*)"/"Call-ID" : "kfp+$var(Option)$var(Cookie)@\1"/});
|
|
xlog("L_DEBUG", "$ci|init|fast|created shortcut kfp+$var(Option)$var(Cookie)@ for call-id $var(call_id)\n");
|
|
}
|
|
|
|
# vim: tabstop=4 softtabstop=4 shiftwidth=4 expandtab
|
|
|