[general] ; Global module settings that are read only at first initialization ; expires: int: Will execute the engine.timer query only every that many seconds ;expires=30 ; stoperror: regexp: Regular expression matching errors that will stop fallback ;stoperror=busy ; The following parameters enable handling of individual messages ; Each must be enabled manually in this config file ; user.auth: bool: Activate handler on the "user.auth" message ;user.auth=no ; user.register: bool: Activate handler on the "user.register" message ;user.register=no ; user.unregister: bool: Activate handler on the "user.unregister" message ;user.unregister=no ; engine.timer: bool: Activate handler on the "engine.timer" message ;engine.timer=no ; call.preroute: bool: Activate handler on the "call.preroute" message ;call.preroute=no ; call.route: bool: Activate handler on the "call.route" message ;call.route=no ; call.cdr: bool: Activate handler on the "call.cdr" message ;call.cdr=no ; linetracker: bool: Activate line status tracking on "call.cdr" ;linetracker=no ; fallback: bool: Activate fallback routing handlers on the "chan.disconnected", ; "call.answered" and "chan.hangup" messages ;fallback=no ; accounts: bool: Activate client registrations on "user.notify" and "engine.timer" ;accounts=no ; subscriptions: bool: Activate resource subscriptions support ; You will also need to activate the handlers for the following messages: ; "resource.subscribe", "user.notify", "call.cdr", "engine.timer" ;subscriptions=no ; resource.subscribe: bool: Activate handler on the "resource.subscribe" message ;resource.subscribe=no [default] ; This section holds default settings for each of the following message handlers ; All these settings can be overriden in individual handler sections ; priority: int: Priority in Yate's handlers chain ;priority=50 ; account: string: Name of the database connection to use ;account= ; In each of the following sections you have to specify the following: ; - initial query to execute when module is initialized ; - query to execute for each received message ; - result field to copy in message's textual return value (only for some) ; You can also override the settings from section [default] ; Sample queries below are for PostgreSQL ; Timestamps and intervals are unfortunately non-portable [user.auth] ; Query and result name for the user.auth message ; The result must not be empty for password authentication to work ; The designated result field is mandatory in the columns to prevent a ; configuration error from authorizing everybody. Use something ; like "SELECT NULL AS password" if you really don't need it ever ;query=SELECT password FROM users WHERE username='${username}' AND password IS NOT NULL AND password<>'' ;result=password [user.register] ; Query for the user.register message ;query=UPDATE users SET location='${data}',expires=CURRENT_TIMESTAMP + INTERVAL '${expires} s' WHERE username='${username}' [user.unregister] ; Query for the user.unregister message ;query=UPDATE users SET location=NULL,expires=NULL WHERE expires IS NOT NULL AND username='${username}' [engine.timer] ; Query for the timer message that expires registrations ; Also look at the expires setting in section [general] ;query=UPDATE users SET location=NULL,expires=NULL WHERE expires IS NOT NULL AND expires<=CURRENT_TIMESTAMP [call.preroute] ; Query and result name for the prerouting message ;query= ;priority=120 [call.route] ; Query and result name for the routing message ; offlineauto: boolean: Set the "offline" error for queries that return records but no route ;offlineauto=yes ;query=SELECT location,(CASE WHEN location IS NULL THEN 'offline' ELSE NULL END) AS error FROM users WHERE username='${called}' ;result=location ;priority=120 [call.cdr] ; Queries for the CDR updating message ; critical: boolean: Reject all registrations and routing if query fails ;critical=yes ;initquery=UPDATE cdr SET ended=true WHERE ended IS NULL OR NOT ended ;cdr_initialize=INSERT INTO cdr VALUES(TIMESTAMP 'EPOCH' + INTERVAL '${time} s','${chan}',\ ; '${address}','${direction}','${billid}','${caller}','${called}',INTERVAL '${duration} s',\ ; INTERVAL '${billtime} s',INTERVAL '${ringtime} s','${status}','${reason}',false) ;cdr_update=UPDATE cdr SET address='${address}',direction='${direction}',billid='${billid}',\ ; caller='${caller}',called='${called}',duration=INTERVAL '${duration} s',\ ; billtime=INTERVAL '${billtime} s',ringtime=INTERVAL '${ringtime} s',status='${status}',\ ; reason='${reason}' WHERE chan='${chan}' AND time=TIMESTAMP 'EPOCH' + INTERVAL '${time} s' ;cdr_status=UPDATE cdr SET duration=INTERVAL '${duration} s',billtime=INTERVAL '${billtime} s',\ ; ringtime=INTERVAL '${ringtime} s' WHERE chan='${chan}' AND time=TIMESTAMP 'EPOCH' + INTERVAL '${time} s' ;cdr_finalize=UPDATE cdr SET address='${address}',direction='${direction}',\ ; billid='${billid}',caller='${caller}',called='${called}',duration=INTERVAL '${duration} s',\ ; billtime=INTERVAL '${billtime} s',ringtime=INTERVAL '${ringtime} s',status='${status}',\ ; reason='${reason}',ended=true WHERE chan='${chan}' AND time=TIMESTAMP 'EPOCH' + INTERVAL '${time} s' ;cdr_combined=INSERT INTO cdr VALUES(TIMESTAMP 'EPOCH' + INTERVAL '${time} s','${chan}',\ ; '${address}','${caller}','${called}',INTERVAL '${duration} s',INTERVAL '${billtime} s',\ ; INTERVAL '${ringtime} s','${status}','${reason}','${out_leg.chan}','${out_leg.address}',\ ; INTERVAL '${out_leg.billtime} s',INTERVAL '${out_leg.ringtime} s',\ ; INTERVAL '${out_leg.duration} s','${out_leg.reason}' [linetracker] ; Queries for the line usage tracker ; critical: boolean: Reject all registrations and routing if query fails ;critical=no ;initquery=UPDATE users SET inuse=0 ;cdr_initialize=UPDATE users SET inuse=inuse+1 WHERE username='${external}' ;cdr_finalize=UPDATE users SET inuse=(CASE WHEN inuse>0 THEN inuse-1 ELSE 0 END) WHERE username='${external}' [accounts] ; Queries for registering as client to other servers ; query executed only once to create client registrations at startup ;initquery=SELECT account,protocol,username,password,server FROM accounts WHERE enabled IS TRUE ; poll on timer to update registrations if database was changed externally ;timerquery=BEGIN; \ ; SELECT (CASE WHEN enabled IS FALSE THEN 'logout' ELSE 'login' END) AS operation,\ ; account,protocol,username,password,server FROM accounts WHERE modified IS TRUE; \ ; UPDATE accounts SET modified=FALSE; \ ; COMMIT ; update account status after receiving an user.notify ;statusquery=UPDATE accounts SET status='${status}' WHERE account='${internalaccount}' [resource.subscribe] ; Queries used for event subscribe and event state changes notification ; query executed on subscribe requests to check authorisation and refresh a subscription ;subscribe_subscribe=SELECT * FROM subscriptions_subscribe('${notifier}','${event}','${subscriber}','${data}','${notifyto}',INTERVAL '${expires} s') as t(notifier text,data text,subscriber text,event text,notifyto text,notifyseq int8) ; query executed on unsubscribe requests to check authorisation and remove a subscription ;subscribe_unsubscribe=SELECT * FROM subscriptions_unsubscribe('${notifier}','${event}','${subscriber}') ; query executed when nedded to get all subscribers for a specified notifier's event ;subscribe_notify=SELECT * FROM subscriptions_notify('${notifier}','${event}') as t(notifier text,data text,subscriber text,event text,notifyto text,notifyseq int8) ; query used to expire subscriptions ;subscribe_expire=SELECT * FROM subscriptions_expires() AS t(notifier text,data text,subscriber text,event text,notifyto text,notifyseq int8)