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;