|
|
## PUSHER ROLE
|
|
|
|
|
|
#!trydef KZ_PUSHER_LOG_CONTACT 0
|
|
|
kazoo.pusher_log_contacts = KZ_PUSHER_LOG_CONTACT descr "logs contacts after registration"
|
|
|
|
|
|
######## Generic Hash Table container in shared memory ########
|
|
|
modparam("htable", "htable", "push_cache=>autoexpire=60;")
|
|
|
|
|
|
route[PUSHER_ROUTE]
|
|
|
{
|
|
|
if ( (!is_method("INVITE")) || (!isflagset(FLAG_INTERNALLY_SOURCED)) || $hdr(X-KAZOO-PUSHER-Token-ID) == $null)
|
|
|
return;
|
|
|
|
|
|
xlog("L_INFO", "$ci|pusher|start deliver call to $hdr(X-KAZOO-PUSHER-Token-ID)\n");
|
|
|
if(route(PUSHER_PREPARE_PUSH)) {
|
|
|
if(reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee")) {
|
|
|
$du = $(ulc(callee=>received));
|
|
|
$fs = $(ulc(callee=>socket));
|
|
|
xlog("L_INFO", "$ci|pusher|routing $hdr(X-KAZOO-AOR) to contact $du\n");
|
|
|
send_reply(100, "calling a push device");
|
|
|
t_set_fr(0, 2000);
|
|
|
route(PUSHER_TO_EXTERNAL_RELAY);
|
|
|
} else {
|
|
|
send_reply(100, "waking the push device");
|
|
|
route(PUSHER_SEND_PUSH_NOTIFICATION);
|
|
|
}
|
|
|
}
|
|
|
exit();
|
|
|
}
|
|
|
|
|
|
route[PUSHER_TO_EXTERNAL_RELAY]
|
|
|
{
|
|
|
remove_hf_re("^X-.*");
|
|
|
set_forward_no_connect();
|
|
|
t_on_branch("MANAGE_BRANCH");
|
|
|
t_on_reply("EXTERNAL_REPLY");
|
|
|
t_on_failure("PUSHER_EXTERNAL_FAULT");
|
|
|
t_relay();
|
|
|
}
|
|
|
|
|
|
failure_route[PUSHER_EXTERNAL_FAULT]
|
|
|
{
|
|
|
if (!t_check_status("486|487|603") && $avp(push_sent) != 1) {
|
|
|
send_reply(182, "sending push notification");
|
|
|
route(PUSHER_SEND_PUSH_NOTIFICATION);
|
|
|
} else if (t_check_status("487")) {
|
|
|
xlog("L_INFO", "$ci|pusher|push transaction canceled\n");
|
|
|
t_reply("$T_reply_code", "pusher canceled");
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|pusher|push transaction result - $T_reply_code\n");
|
|
|
t_reply("$T_reply_code", "pusher failed");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[PUSHER_PREPARE_PUSH]
|
|
|
{
|
|
|
if (t_newtran()) {
|
|
|
route(PUSHER_PREPARE_PUSH_PAYLOAD);
|
|
|
remove_hf_re("^X-.*");
|
|
|
t_save_lumps();
|
|
|
t_set_auto_inv_100(0);
|
|
|
return 1;
|
|
|
} else {
|
|
|
sl_send_reply(500, "error creating transaction for waking the dead guy");
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[PUSHER_PREPARE_PUSH_PAYLOAD]
|
|
|
{
|
|
|
|
|
|
$var(TokenID) = $hdr(X-KAZOO-PUSHER-Token-ID);
|
|
|
$var(TokenType) = $hdr(X-KAZOO-PUSHER-Token-Type);
|
|
|
$var(TokenApp) = $hdr(X-KAZOO-PUSHER-Token-App);
|
|
|
|
|
|
$var(TokenProxy) = $hdr(X-KAZOO-PUSHER-Token-Proxy);
|
|
|
#!ifdef PUSHER_TOKEN_PROXY
|
|
|
$var(TokenProxy) = $_s(PUSHER_TOKEN_PROXY);
|
|
|
#!endif
|
|
|
|
|
|
### token for fast reg ###
|
|
|
$var(TokenReg) = $uuid(g);
|
|
|
$sht(push_cache=>$var(TokenReg)) = 1;
|
|
|
|
|
|
### caller-id ###
|
|
|
if($hdr(Remote-Party-ID) != $null) {
|
|
|
$var(from_user) = $(hdr(Remote-Party-ID){tobody.user});
|
|
|
$var(from_name) = $(hdr(Remote-Party-ID){tobody.display}{re.subst,/"//g});
|
|
|
} else if($hdr(P-Asserted-Identity) != $null) {
|
|
|
$var(from_user) = $(hdr(P-Asserted-Identity){tobody.user});
|
|
|
$var(from_name) = $(hdr(P-Asserted-Identity){tobody.display}{re.subst,/"//g});
|
|
|
} else if($hdr(P-Preferred-Identity) != $null) {
|
|
|
$var(from_user) = $(hdr(P-Preferred-Identity){tobody.user});
|
|
|
$var(from_name) = $(hdr(P-Preferred-Identity){tobody.display}{re.subst,/"//g});
|
|
|
} else {
|
|
|
$var(from_user) = $(hdr(From){tobody.user});
|
|
|
$var(from_name) = $(hdr(From){tobody.display}{re.subst,/"//g});
|
|
|
}
|
|
|
|
|
|
$var(from) = $_s($var(from_user) - $var(from_name));
|
|
|
|
|
|
|
|
|
$var(PushPayload) = $_s({"call-id" : "$ci", "proxy" : "$var(TokenProxy)", "caller-id-number" : "$var(from_user)", "caller-id-name" : "$var(from_name)", "registration-token" : "$var(TokenReg)"});
|
|
|
$var(Payload) = $_s({ "Event-Category" : "notification", "Event-Name" : "push_req", "Call-ID" : "$ci", "Token-ID" : "$var(TokenID)", "Token-Type" : "$var(TokenType)", "Token-App" : "$var(TokenApp)", "Alert-Key" : "IC_SIL", "Alert-Params" : ["$var(from)"], "Sound" : "ring.caf", "Payload" : $var(PushPayload) });
|
|
|
|
|
|
$avp(push_routing_key) = "notification.push." + $var(TokenType) + "." + $var(TokenID);
|
|
|
$avp(push_payload) = $var(Payload);
|
|
|
}
|
|
|
|
|
|
route[PUSHER_SEND_PUSH_NOTIFICATION]
|
|
|
{
|
|
|
xlog("L_INFO", "$ci|pusher|sending push notification request\n");
|
|
|
xlog("L_DEBUG", "$ci|pusher|pushing to $avp(push_routing_key) : $avp(push_payload)\n");
|
|
|
t_set_fr(20000, 20000);
|
|
|
$avp(push_sent) = 1;
|
|
|
t_suspend();
|
|
|
$sht(push_cache=>$(tu{s.tolower})) = $_s(a=0;index=$T(id_index);label=$T(id_label));
|
|
|
kazoo_publish("pushes", $avp(push_routing_key), $avp(push_payload));
|
|
|
}
|
|
|
|
|
|
route[PUSHER_ATTEMPT_REGISTRATION]
|
|
|
{
|
|
|
if (!is_method("REGISTER")) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if($hdr(X-Token-Reg) != $null) {
|
|
|
if($sht(push_cache=>$hdr(X-Token-Reg)) != $null) {
|
|
|
$var(password) = $null;
|
|
|
$sht(push_cache=>$hdr(X-Token-Reg)) = $null;
|
|
|
xlog("L_INFO", "$ci|pusher|registration with x-token-reg $hdr(X-Token-Reg)\n");
|
|
|
$xavp(ulattrs=>custom_channel_vars) = "{}";
|
|
|
$xavp(ulattrs[0]=>x_token_reg) = $hdr(X-Token-Reg);
|
|
|
route(SAVE_LOCATION);
|
|
|
exit;
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|pusher|registration x-token-reg '$hdr(X-Token-Reg)' from header was not found\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if($(sel(contact.uri){uri.param,x-token-reg}) != "") {
|
|
|
if($sht(push_cache=>$(sel(contact.uri){uri.param,x-token-reg})) != $null) {
|
|
|
$var(password) = $null;
|
|
|
$sht(push_cache=>$(sel(contact.uri){uri.param,x-token-reg})) = $null;
|
|
|
xlog("L_INFO", "$ci|pusher|registration with x-token-reg $(sel(contact.uri){uri.param,x-token-reg})\n");
|
|
|
$xavp(ulattrs=>custom_channel_vars) = "{}";
|
|
|
$xavp(ulattrs[0]=>x_token_reg) = $(sel(contact.uri){uri.param,x-token-reg});
|
|
|
route(SAVE_LOCATION);
|
|
|
exit;
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|pusher|registration x-token-reg from contact uri param '$(sel(contact.uri){uri.param,x-token-reg})' was not found\n");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if($(sel(contact){tobody.params}{param.value,x-token-reg}) != "") {
|
|
|
if($sht(push_cache=>$(sel(contact){tobody.params}{param.value,x-token-reg})) != $null) {
|
|
|
$var(password) = $null;
|
|
|
$sht(push_cache=>$(sel(contact){tobody.params}{param.value,x-token-reg})) = $null;
|
|
|
xlog("L_INFO", "$ci|pusher|registration with x-token-reg $(sel(contact){tobody.params}{param.value,x-token-reg})\n");
|
|
|
$xavp(ulattrs=>custom_channel_vars) = "{}";
|
|
|
$xavp(ulattrs[0]=>x_token_reg) = $(sel(contact){tobody.params}{param.value,x-token-reg});
|
|
|
route(SAVE_LOCATION);
|
|
|
exit;
|
|
|
} else {
|
|
|
xlog("L_INFO", "$ci|pusher|registration x-token-reg from contact param '$(sel(contact){tobody.params}{param.value,x-token-reg})' was not found\n");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[PUSHER_ON_REGISTRATION]
|
|
|
{
|
|
|
if( ( $(xavp(ulattrs=>x_token_reg){s.len}) > 0 ||
|
|
|
$(xavp(ulattrs=>custom_channel_vars){kz.json,Pusher-Application}{s.len}) > 0) &&
|
|
|
$var(Status) == "Registered") {
|
|
|
if($sht(push_cache=>$(tu{s.tolower})) != $null) {
|
|
|
xlog("L_INFO", "$ci|pusher|device registered, delivering the call\n");
|
|
|
$var(ref) = $sht(push_cache=>$(tu{s.tolower}));
|
|
|
$sht(push_cache=>$(tu{s.tolower})) = $null;
|
|
|
$var(t_index) = $(var(ref){param.value,index}{s.int});
|
|
|
$var(t_label) = $(var(ref){param.value,label}{s.int});
|
|
|
t_continue("$var(t_index)", "$var(t_label)", "PUSHER_DELIVER_CALL");
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
route[PUSHER_DELIVER_CALL]
|
|
|
{
|
|
|
if(reg_fetch_contacts("location", "$hdr(X-KAZOO-AOR)", "callee")) {
|
|
|
if($sel(cfg_get.kazoo.pusher_log_contacts) == 1) {
|
|
|
xlog("L_NOTICE", "callee=>aor: $(ulc(callee=>aor))\n");
|
|
|
xlog("L_NOTICE", "callee=>count: $(ulc(callee=>count))\n");
|
|
|
xlog("L_NOTICE", "callee=>domain: $(ulc(callee=>domain))\n");
|
|
|
xlog("L_NOTICE", "callee=>aorhash $(ulc(callee=>aorhash))\n");
|
|
|
$var(i) = 0;
|
|
|
while($var(i) < $(ulc(callee=>count))) {
|
|
|
xlog("L_NOTICE", "--- contact [$var(i)]\n");
|
|
|
xlog("L_NOTICE", "callee=>addr: $(ulc(callee=>addr)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>path: $(ulc(callee=>path)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>received: $(ulc(callee=>received)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>expires: $(ulc(callee=>expires)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>callid: $(ulc(callee=>callid)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>regid: $(ulc(callee=>regid)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>q: $(ulc(callee=>q)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>cseq: $(ulc(callee=>cseq)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>flags: $(ulc(callee=>flags)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>cflags: $(ulc(callee=>cflags)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>user_agent: $(ulc(callee=>user_agent)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>socket: $(ulc(callee=>socket)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>modified: $(ulc(callee=>modified)[$var(i)])\n");
|
|
|
xlog("L_NOTICE", "callee=>methods: $(ulc(callee=>methods)[$var(i)])\n");
|
|
|
$var(i) = $var(i) + 1;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
$var(idx) = $ulc(callee=>count) - 1;
|
|
|
$du = $(ulc(callee=>received)[$var(idx)]);
|
|
|
$fs = $(ulc(callee=>socket)[$var(idx)]);
|
|
|
t_set_fr(30000, 30000);
|
|
|
route(PUSHER_TO_EXTERNAL_RELAY);
|
|
|
} else {
|
|
|
t_reply(486, "Failed to lookup after resume");
|
|
|
}
|
|
|
}
|