## PUSHER ROLE ######## Generic Hash Table container in shared memory ######## modparam("htable", "htable", "push_cache=>autoexpire=60;") modparam("tm", "failure_exec_mode", 1) 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"); 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-.*"); t_set_fr(0, 2000); t_relay(); } failure_route[PUSHER_EXTERNAL_FAULT] { if (!t_check_status("486|487|603") && $avp(push_sent) != 1) { send_reply(182, "waking the dead guy"); 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()) { t_set_fr(20000, 20000); route(PUSHER_PREPARE_PUSH_PAYLOAD); remove_hf_re("^X-.*"); t_on_reply("EXTERNAL_REPLY"); t_on_failure("PUSHER_EXTERNAL_FAULT"); 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); ### 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); } 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); } 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); } 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")) { $du = $(ulc(callee=>received)); $fs = $(ulc(callee=>socket)); route(PUSHER_TO_EXTERNAL_RELAY); } else { t_reply(486, "Failed to lookup after resume"); } }