FreeSWITCH 1.8
上QQ阅读APP看书,第一时间看更新

Extensions, Contexts and Profiles

This is another source of great confusion. If you are new to FreeSWITCH, forget about the meaning you used to associate to the word "extension". In FreeSWITCH "extension" is an immaterial concept. It can be understood as "a group of instructions into a context". OK, this leave us with the problem of what a context is. A context is a named collection of extensions. So, in a way, we have a circular definition here, in which contexts and extensions define each others.

Bear with me and in a couple of paragraph we'll be over all this.

FreeSWITCH has "profiles". A profile is a collection of configurations that is related to a specific IP address and port couple. For example 192.168.1.12:5060 is a profile, 192.168.1.13:5060 is another profile, 192.168.1.12:5061 is a third profile. Each one profile can contains configurations that are completely different from that of other profiles. One very important such configuration contained in a profile is to which context the incoming call will go. A call is always incoming to a profile, eg, to an address:port couple. So, let's say the address:port couple is the enter gate to a specific profile. Once the call has entered the profile, first thing FreeSWITCH do is to look up in that profile the configuration that defines which context the call must go into.

Let's say the call is incoming at 192.168.1.12:5060. We called this profile "myprofile", and in the XML configuration of that profile is defined that the context to be used is "mycontext". This means that the incoming call will only be processed by the extensions (instructions sets) contained in the "mycontext" extensions collection (context). That is, the incoming call will go in the context defined in the profile, and it has no way to access anything that is outside that context.

Context is the jail of the call. This has obvious security, logical, and practical advantages: for example the calls that are incoming to a profile that is accessible by our coworkers from the internal LAN will be directed to a context that gives the feature of internal office calls, and allows also for reaching the PSTN, because we want our coworkers to be authorized to place national and international calls. On the other hand, the calls that are incoming to a profiles with a public Internet address, that is the calls that are reaching us passing through the router from the outside of our internal LAN, those calls are directed to a context that only allows for the call to be connected to one of our coworkers' phone. This specific profile will have only the feature to allow for external incoming calls to reach an internal phone, without any possibility to originate PSTN calls. That is, strangers cannot use our paid gateway to reach the PSTN.

So, different address:port couple, different profile, different context. It is actually so simple!

Now is time to see what are those "extensions". We know from above each extension is a set of instructions. When a call is incoming into a context (a context is a collection of extensions) the most important thing in each extension is: do this extension apply to the incoming call? Or, from the point of view of the call: do I enter this extension? Do this extension apply to me?

Each extension has one property, the "condition", that defines if that extension applies or not to the call. Eg, if the call will enter that extension, and pass through the steps defined by the instructions contained into the extension. An extension can be viewed as an instructions container, and the call must satisfy the extension "condition" to enter it and pass through the instructions inside it.

So, extension==list of instructions. To enter an extension, a call must satisfy a "condition".

And a "condition", what is a condition? A condition is a regular expression (regex) to be applied to one attribute of the call. If that regular expression matches (eg if it successfully describes the attribute of the call) the call will enter the extension and will execute the instructions.

Let's see an example. A call is incoming on the 192.168.1.12:5060, "myprofile". In "myprofile" XML configuration is defined "mycontext" context. In "mycontext" are specified many extensions, each one of them with its own "condition".

The first one of those extensions has a very simple condition: regex "^1010$" to be checked upon the "destination_number". So, this regex will be successful, it will matches, if the "destination_number" attribute of the call is the exact string "1010" (caret means string beginning, dollar sign means string end. So, "1010" is exactly what must be between begin and end of the string).

If the incoming call was meant to be directed to the destination number 1010, then the call will enter this extension and execute the instructions therein.

Those instructions are called "actions" in FreeSWITCH lingo, and can be whatever. For example: create a variable and assign a value to it. Read another variable, apply a regex to it so it convert to all capitals, create another variable and assign that value to it. Answer the incoming call, eg go off hook. Play a prerecorded message to the caller. Originate another, new, outbound call, and then join it (eg: bridge it) with the incoming call, so caller from incoming call and callee from outbound call can talk to each other. Hangup the call. Query a database. Access a web server. Read or write a file. etc etc.
The actions (that are always contained inside an extension, "loose" actions do not exist) can truly do anything.

All the rest, profiles, contexts, extensions, conditions, regular expressions, are neat ways to have your actions pretty well organized, and to build logics and flows of executions.
Also, a call can matches many extensions (eg, can satisfy the condition of more than one extension) and in many cases will be allowed to enter many or all of the matched extensions, and to execute the actions contained by each one of those extensions. We'll see much more about that.