Regular expressions
(→Handling authentication) |
|||
Line 93: | Line 93: | ||
{| | {| | ||
− | ; reject unauthenticated calls, give challenge-response protocols a second chance: | + | |; reject unauthenticated calls, give challenge-response protocols a second chance: |
${username}^$=-;error=noauth | ${username}^$=-;error=noauth | ||
|} | |} | ||
− | |||
=== Changing codec priorities === | === Changing codec priorities === |
Revision as of 09:51, 3 October 2012
Contents |
About regexroute module
The regexroute module provides a simple way of routing telephony calls inside Yate. This module describes the routes using a configuration file in which each number is matched using regular expressions.
For more informations about how regular expressions in Yate are working use "man grep" or you may use a graphical interface like http://laurent.riesterer.free.fr/regexp/
There are two messages handled by the regexroute module:
- the "preroute" message that tries to classify the caller in a context
- the "route" message that tries to map a called number to a string describing the target channel or module
In the preroute stage the caller is matched with regular expressions in the [contexts] section and the result is stored in a message parameter named "context". Note that the preroute stage is skipped if the message already has a "context" parameter.
In the route stage the called number is matched against regular expressions from the section with the same name as the value of the "context" parameter. If this parameter is missing the "default" section is used.
In both prerouting and routing the result of the match (right-hand size of the line, after the equal sign) can include parts of the matched string. For this to work the matching expression should include the \( and \) subexpression capture markers. In the result you can use \digit markers which are replaced with the entire matched string (\0), first captured subexpression (\1), second matched subexpression (\2) and so on. You can include each of the the \digit placeholders as many times as you need
Expressions are checked sequentially in their section. As soon as one matches and specifies a result, its result is returned and no further matches are attempted. If an expression matches, but its result is empty, parameters will be changed according to the string after ";", but further matches will be attempted (see the gsm codec example which doesn't return).
You can act on non-matching regular expressions by adding a caret character ^ at the end of them. Note that in this case the matched string (\0) and all captured subexpressions will be empty.
If no expression matched the corresponding message handler will not consider the message handled, giving an opportunity to route the call in another module. The priority of each handler is controlled by the [priorities] section.
First word of a matched target has a special meaning:
- if - makes a new match using the rest of the line up to the = character
- return - returns immediately from the context without routing
- include - calls another context, returns at the next entry if the other context did not return successfully
- jump - jumps to another context, does not return to this context
- match - modifies the matched string instead of specifying a target
- rename - changes the name of the message
- enqueue - puts a new message in the engine, parameters are taken from the old message but placed in the new one
- dispatch - dispatches a new message in the engine waiting for it to return, parameters are taken from the old message but placed in the new one
- echo - just displays that line after making substitutions
It is possible to set message parameters by appending them as name=value while separating them with semicolons (;)
The module also supports global variables that are not tied to a specific message. These can be used in the right hand expressions for building call targets and setting message parameters. Global variables are accessed as $(variable) or as $variable in function parameters.
Order of processing
For each line that matches the following operations are applied:
- line is broken at semicolon ; characters
- matches of the form \N are replaced
- parameters of the form ${name} are replaced
- functions of the form $(name,etc.) are evaluated
For the echo target the line is not broken at semicolons. For the if target the line is processed only after matching the last if - that is on the first target that is not if.
Examples
1) For the matching rule: ^00\(.*\)$=iax/\1@internat.ion.al/\0 (match strings starting with 00 and capture everything else to the end of string)
And the called number: 0099123456
The routing will return: iax/99123456@internat.ion.al/0099123456
2) For the matching rule: ^123456$=return;called=johndoe
And the called number: 123456
The routing will dial the registered user johndoe.
Just remember to have the route priority numerically lower (which gives it a higher actual priority) than the regfile (that routes the call to johndoe)!
More in-depth explanation of the sentence above (as I had a hard time understanding it myself :-) ):
- regexroute.conf: i.e. preroute=10 route=10
- regfile.conf: i.e. preroute=50 route=50
YATE will start routing with regexroute.conf (highest priority!). There the number 123456 matches, changes the called parameter to johndoe and returns. As the number has not been routed yet, YATE tries the files with the lower routing priority, now trying to route johndoe. johndoe is found in regfile.conf, and the originally called number 123456 is routed to the user johndoe.
Naturally, instead of regfile.conf you can use the database module (register.conf), with the priorities set accordingly. Note, if you have a catch-all in regexroute, and give it a higher numeric priority, then it will route all your internal lines - meaning, you need to define rules in regexroute so these numbers get routed by your register or regfile modules.
Testing and debug routing
An easy way to debug routing is to use the function echo
^.*$=echo called is ${called}
The first part - ^.*$ matches every call and the second part prints in the Yate Debug called is called_value
Handling authentication
In many cases you need to authorize only authenticated calls. The authentication is performed by the module that handles the incoming call which sets the "username" parameter. This is valid only for the SIP protocol.
; reject unauthenticated calls, give challenge-response protocols a second chance:
${username}^$=-;error=noauth |
Changing codec priorities
The incoming call's codecs are hold in a parameter "formats" that can be manipulated to favor some codecs. An example of bringing the GSM codec to front is this:
; move the GSM codec to front if not already there
${formats}^\(.*\),gsm\(.*\)$=;formats=gsm,\1\2 |
There is no need to match gsm with no comma in front of it because it would already be first!
See more info about using regexroute for transcoding on a separate page.
Request inband DTMF detection
If inband DTMF tones are used and the hardware does not support detecting them Yate can provide detection using the [tonedetect] module. Please check the module documentation for applicability and resource format.
The request for attaching a DTMF detector can be specified from routing, where a boolean true value stands equivalent to tone/* :
; request DTMF detection on inbound calls from PSTN
${id}^sig/=;tonedetect_in=yes ; request DTMF detection on all outbound calls - CPU consuming! .*=;tonedetect_out=yes |
Handling extra messages
It is possible to use this module to install handlers for arbitrary messages. This is done by listing the messages and their priority in the [extra] section of the config file. You can only install one handler for any given message name.
Each such message will be handled in a section with the same name as the message. The default match sting is the message name so make sure you set a new match or name the parameters explicitely:
[extra]
user.auth=50 [user.auth]
${ip_host}^10\.0\.=-;error=forbidden;reason=Your IP range is blacklisted
${username}^$=;auth_register=false |
Using global variables
The module supports arbitrary variables that are preserved between calls.
These variables can be initialized when Yate starts by listing them in the [$once] section or they can be reinitialized each time by placing them in the [$init] section. The variables can also be created by assigning them a value.
To access a global variable use $(varname) or, if in a function, $(funcname,...,$varname,...)
To set a global variable use: ...;$varname=expression
To delete a global variable use: ...;$varname
The following recipe allows retrieving and setting global variables from the [rmanager] command line:
[extra] engine.command=150 [engine.command] .*=newmatch ${line} ^get \([^ ]\+\)$=\1=$(\1)$(chr,13)$(chr,10) ^set \([^ ]\+\) \+\(.*\)$=\1=\2$(chr,13)$(chr,10);$\1=\2 |
The regexroute configuration file
Parameters
This is a list of usual parameters found in the call.route message. Arbitrary parameters can be added by any module.
- ${address} - "address" (e.g. analog/pstn/1 or IP address) from which current incoming call was received.
- ${callsource} - e.g. fxs/fxo for analog lines
- ${formats} - list of codecs that the incoming call will accept
- ${id} - channel ID (e.g. 'sip/1')
- ${peerid} - peer's channel ID, usually empty during initial routing
- ${ip_host} - ip address of the transport connection or message
- ${ip_port} - port of the transport connection or message
- ${overlapped} - set by overlapped.php to indicated overlapped dialling is happening.
- ${rtp_forward} - do rtp forwarding, can be no, possible, or yes
- ${type} - call type (e.g. record)
- ${username} - username for incoming call, only if authenticated
- ${caller} - caller ID (e.g. 'user' for a call from 'sip:user@example.com')
- ${callername} - caller ID name field
- ${called} - called party