CREATE OR REPLACE FUNCTION route_auth_function(billid character varying, caller character varying, callee character varying) RETURNS record AS $$ DECLARE result RECORD; client RECORD; dest RECORD; BEGIN ---- Prefix based client authorization SELECT name, prefix, SUBSTR(callee, LENGTH(prefix) + 1) AS dialed, gid INTO client FROM clients WHERE callee LIKE prefix || '%' AND (CASE WHEN type = 'prepaid' AND balance <= 0 THEN false ELSE true END) AND active ORDER BY LENGTH(prefix) DESC LIMIT 1; IF client.prefix IS NULL THEN RAISE NOTICE 'Prefix not found, invalid client'; RETURN NULL; ELSE RAISE NOTICE 'Client: %', client.name; RAISE NOTICE 'Prefix: %', client.prefix; RAISE NOTICE 'Billing ID: %', billid; RAISE NOTICE 'Caller: %', caller; RAISE NOTICE 'Callee: %', client.dialed; END IF; ---- Check banned callers list IF (SELECT CASE WHEN (SELECT caller LIKE number AS valid FROM banned_callers ORDER BY valid DESC LIMIT 1) THEN true ELSE false END) THEN RAISE NOTICE 'Caller is banned'; RETURN NULL; END IF; ---- Check banned callees lisT IF (SELECT CASE WHEN (SELECT client.dialed LIKE number AS valid FROM banned_numbers ORDER BY valid DESC LIMIT 1) THEN true ELSE false END) THEN RAISE NOTICE 'Callee is banned'; RETURN NULL; END IF; ---- Route lookup SELECT route, rid, did, description, country, cinit, cinc, pinit, pinc, rate, cost INTO dest FROM routes WHERE rid = ANY((SELECT routes FROM groups WHERE gid = client.gid AND active)::varchar[]) AND ((route = SUBSTR(client.dialed, 1, 1) AND LENGTH(route) = 1) OR (route = SUBSTR(client.dialed, 1, 2) AND LENGTH(route) = 2) OR (route = SUBSTR(client.dialed, 1, 3) AND LENGTH(route) = 3) OR (LENGTH(route) >= 4 AND SUBSTR(route, 1, 4) = SUBSTR(client.dialed, 1, 4) AND (client.dialed LIKE (route || '%')))) AND active ORDER BY route DESC, cost ASC LIMIT 1; ---- Populate incoming route_cache INSERT INTO route_cache VALUES ('incoming', billid, client.prefix, dest.route, dest.rid, dest.did, dest.description, dest.country, dest.cinit, dest.cinc, dest.pinit, dest.pinc, dest.rate, dest.cost); IF dest.route IS NULL THEN RAISE NOTICE 'No route found'; RETURN NULL; ELSE RAISE NOTICE 'Route: %', dest.route; RAISE NOTICE 'Description: %', dest.description; END IF; ---- Populate outgoing route_cache INSERT INTO route_cache VALUES ('outgoing', billid, client.prefix, dest.route, dest.rid, dest.did, dest.description, dest.country, dest.cinit, dest.cinc, dest.pinit, dest.pinc, dest.rate, dest.cost); ---- Form Yate reply & return SELECT (CASE WHEN LOWER(protocol) = 'wp' THEN LOWER(protocol) || '/' || host || '/' || prefix || client.dialed ELSE LOWER(protocol) || '/' || (CASE WHEN LOWER(protocol) = 'sip' THEN 'sip:' ELSE '' END) || prefix || client.dialed || '@' || host END) AS route, (CASE WHEN LOWER(protocol) = 'wp' THEN 'no'::varchar ELSE (SELECT rtp_forward FROM clients WHERE prefix = client.prefix) END) AS rtp_forward INTO result FROM providers WHERE did = dest.did AND active; RAISE NOTICE 'Destination: %', result.route; RAISE NOTICE 'Forward RTP: %', result.rtp_forward; RETURN result; END; $$ LANGUAGE plpgsql;