DECLARE
callednr_orig ALIAS FOR $1;
rtp_f ALIAS FOR $2;
caller ALIAS FOR $3;
result record;
partial2 record;
iteration int2;
iteration2 int2;
iteration3 int2;
newcalled text;
loc record;
dig text;
flag text;
locat text;
format text;
rtp text;
div text;
div_busy text;
div_noanswer text;
noans_timeout int2;
ips text[];
dim int2;
block text;
i int2;
query text;
div_info record;
leavemail text;
callednr text;
callerresult record;
clir boolean;
forked text;
rtpforward text;
exitloop boolean;
BEGIN
iteration:=0;
forked:='';
callednr := callednr_orig;
newcalled := callednr;
SELECT INTO leavemail value FROM settings WHERE param='vm';
IF NOT FOUND THEN
raise notice 'leavemail is not set';
END IF;
FOR loc IN SELECT * FROM form LIMIT 1 LOOP
SELECT into locat line FROM lines WHERE line=callednr;
loc.rtp_forward := 'no';
loc.location := NULL;
IF FOUND THEN
loc.formats:=NULL;
SELECT into div,div_busy,div_noanswer,noans_timeout MAX(CASE WHEN param='forward' THEN value END),MAX(CASE WHEN param='forward_busy' THEN value END),MAX(CASE WHEN param='forward_noanswer' THEN value END) ,MAX(CASE WHEN param='noanswer_timeout' THEN value END) FROM pbx WHERE line=callednr;
IF FOUND THEN
IF div != callednr AND div IS NOT NULL AND div != '' THEN
newcalled := div;
ELSE
newcalled := callednr;
loc.divert_busy := CASE WHEN (div_busy = 'vm') THEN leavemail ELSE div_busy END;
loc.divert_noanswer := CASE WHEN (div_noanswer = 'vm') THEN leavemail ELSE div_noanswer END;
IF div_noanswer IS NOT NULL AND div_noanswer != '' THEN
loc.maxcall := noans_timeout*1000;
END IF;
END IF;
ELSE
newcalled := callednr;
END IF;
if newcalled != 'vm' THEN
SELECT into locat location FROM lines WHERE line=newcalled;
IF FOUND AND locat IS NOT NULL AND locat != '' THEN
loc.location := locat;
loc.called := newcalled;
iteration := iteration + 1;
RETURN next loc;
RETURN;
END IF;
ELSE
loc.location := leavemail;
loc.called := callednr;
iteration := iteration + 1;
RETURN next loc;
RETURN;
END IF;
END IF;
END LOOP;
IF (substr(callednr_orig, 0, 5)) = '3651' THEN -- CLIR
callednr := to_enum(substr(callednr_orig, 5));
newcalled := callednr;
clir := true;
ELSE
callednr := to_enum(callednr_orig);
newcalled := callednr;
clir := false;
END IF;
SELECT INTO callerresult * FROM lines WHERE line=caller;
IF callerresult.balance <= 0 THEN
loc.location:='';
loc.error:='no credit left';
RETURN next loc;
RETURN;
END IF;
iteration2:=0;
FOR result IN SELECT * FROM form LIMIT 3 LOOP
IF iteration<2 THEN
SELECT INTO dig prefix FROM routes WHERE prefix=substr(newcalled,1,LENGTH(prefix)) ORDER BY length(prefix) DESC LIMIT 1 OFFSET iteration2;
IF NOT FOUND THEN
IF iteration=0 THEN
result.location:='';
END IF;
RETURN;
END IF;
iteration2:=iteration2+1;
iteration3:=0;
exitloop := false;
WHILE exitloop = false LOOP
SELECT INTO partial2 * FROM routes WHERE prefix=dig OR prefix='' ORDER BY priority LIMIT 1 OFFSET iteration3;
IF NOT FOUND THEN
IF iteration=0 and iteration3=0 THEN
result.error:='no route to call ('||callednr||')';
result.called:=newcalled;
RETURN next result;
END IF;
exitloop := true;
END IF;
result.rtp_forward:=NULL;
result.formats:=NULL;
block := 'no';
IF dim > 1 THEN
i := 1;
LOOP
--if the trnk is already in the already found trunks
IF partial2.ip = ips[i] THEN
block := 'yes';
END IF;
i := i+1;
IF i+1 > dim THEN
block := 'yes';
exitloop := true;
END IF;
END LOOP;
END IF;
IF block != 'yes' THEN
newcalled := rewritenr(newcalled,partial2.cutbool,partial2.nrdigcut,partial2.poscut,partial2.replacebool,partial2.posrpl,partial2.digrpl,partial2.nrdigrpl);
iteration:=iteration+1;
IF partial2.account IS NOT NULL AND partial2.account!='' AND partial2.protocol<>'zap' AND partial2.protocol<>'wp' THEN
result.location:= partial2.protocol || '/' || newcalled;
result.line:=partial2.account;
SELECT INTO format formats FROM accounts WHERE account=partial2.account;
IF FOUND AND format IS NOT NULL AND format != '' THEN
result.formats:=format;
END IF;
IF FOUND AND partial2.rtp_forward IS TRUE AND rtp_f='possible' THEN
result.rtp_forward:='yes';
END IF;
ELSEIF partial2.protocol='sip' THEN
IF partial2.port IS NULL OR partial2.port='' THEN
result.location := 'sip/sip:' || newcalled || '@' || partial2.ip;
ELSE
result.location := 'sip/sip:' || newcalled || '@' || partial2.ip || ':' || partial2.port;
END IF;
ELSEIF partial2.protocol='h323' THEN
IF partial2.port IS NULL OR partial2.port='' THEN
result.location := 'h323/' || newcalled || '@' || partial2.ip;
ELSE
result.location := 'h323/' || newcalled || '@' || partial2.ip || ':' || partial2.port;
END IF;
ELSEIF partial2.protocol='wp' OR partial2.protocol='zap' THEN
result.location := partial2.protocol || '/' || partial2.chan_group || '/' || newcalled;
ELSEIF partial2.protocol='iax' THEN
IF partial2.iaxuser IS NULL THEN
partial2.iaxuser:='';
END IF;
IF partial2.iaxcontext IS NULL OR partial2.iaxcontext='' THEN
IF partial2.port IS NULL OR partial2.port='' THEN
result.location := 'iax/' || partial2.iaxuser || '@'|| partial2.ip || '/' || newcalled;
ELSE
result.location := 'iax/' || partial2.iaxuser || '@' || partial2.ip || ':' || partial2.port || '/' || newcalled;
END IF;
ELSE
IF partial2.port IS NULL OR partial2.port='' THEN
result.location := 'iax/' || partial2.iaxuser || '@' || partial2.ip || '/' || newcalled || '@' || partial2.iaxcontext;
ELSE
result.location := 'iax/' || partial2.iaxuser || '@' || partial2.ip || ':' || partial2.port || '/' || newcalled || '@' || partial2.iaxcontext;
END IF;
END IF;
END IF;
IF partial2.formats IS NOT NULL AND partial2.formats != '' AND (partial2.account IS NULL OR partial2.account = '') THEN
result.formats := partial2.formats;
END IF;
IF partial2.rtp_forward IS TRUE AND rtp_f='possible' AND (partial2.account IS NULL OR partial2.account='') THEN
result.rtp_forward := 'yes';
END IF;
result.called:=newcalled;
IF (result.rtp_forward IS NOT NULL) THEN
rtpforward:=result.rtp_forward;
END IF;
ips[dim] := partial2.ip;
dim := dim+1;
forked:= forked || ' | ' || result.location;
END IF;
iteration3 := iteration3+1;
END LOOP;
END IF;
END LOOP;
SELECT * INTO result FROM form LIMIT 1;
IF clir THEN
result.caller:='0000';
ELSEIF callerresult.callerid != '' THEN
result.caller:=callerresult.callerid;
ELSE
result.caller:='0000'||caller;
END IF;
IF iteration = 1 THEN
result.location:= substr(forked, 4);
ELSE
result.location:='fork '||substr(forked, 4) || ';stoperror=busy';
END IF;
result.called := newcalled;
result.rtp_forward := rtpforward;
RETURN next result;
RETURN;
END;