This book is about the PBX's node-tree concept.
Structured numbering plans
When we were talking about the flat numbering plan we used in the
IT Advanced 2 - 05 Master/Slave Operation book of the
IT Advanced 2 course we said that the
PBX also supports structured numbering plans where some extensions (usually those in a certain location) share a common prefix. In such numbering plans, extensions can share the same number (like extension 10 in location A and extension 10 in location B). You would then distinguish a remote extension from a local extension with the same number by prefixing it with the location-specific prefix common to all extensions at the remote location.
There are 2 flavors of such so-called structured numbering plans: simple node tree and node tree with escapes. We will look at the first flavor in more detail in this book. The second type will be covered in the E164 PBX Setups book.
Numbering Plan, Node and Node Tree
Numbering Plan
In a VoIP PBX, all entities have a distinct name that can be used to call them (this is set in the object's
Name property and sometimes also referred to as
H.323-Id or
SIP for historical reasons). However, like in traditional PBX systems, they can also have an (optional) number to call, often referred to as
extension.
In a simple case all extensions are unique, forming a
flat numbering plan.
However, in some cases, a structured numbering plan is desired where extensions share the same number. For example,
a customer with several branch offices may want to have short, overlapping extensions per geographic region. When dialing an extension, it is interpreted in the context of the caller's region. Remote region extensions are called by means of a region dial prefix.
This creates a
structured, multi-level numbering plan.
Node
In innovaphone speak, each scope in the numbering plan (that is, each range where extension numbers must not overlap) is called a
numbering node. Each extension thus lives within exactly one numbering node.
In our
exemplary numbering plan,
Region Italy would be a node (just like
Region Southwest and
Region North).
Node Tree
Numbering nodes are hierarchically forming the
numbering node tree. The root of this tree is always called
root. There is exactly one numbering node tree per system. Of course, if your numbering plan is
flat, the resulting numbering node tree is trivial: it consists of
the root node only.
The processing of a dialed number is controlled by the numbering node tree and depends - amongst others - on the position of the caller extension's node in the numbering node tree. That is, dialing the same digit string may yield different results for different callers. For example, dialing an extension number 11 from within one region may ring at this regions extension 11 whereas dialing 11 from within another region may ring an extension in that region (like in the exemplary numbering plan shown above where you would reach different extensions when dialing 11 in Region Italy or Region North).
Independent Trees
Just like nodes, PBXs are structured as a tree with the master PBX being the root (we discussed that in chapter
Making the slave known to the master of
IT Advanced 2 - 05 Master/Slave Operation where we connected the slave PBX to the master PBX).
It is important to understand that the PBX tree and the node tree are independent. As a result, there can (and often will) be more nodes than PBXs. Also, leafs in the node tree (Extensions) can be registered at any PBX. There is no need that all extensions living in a certain numbering node must register with the same PBX.
In other words, the node tree is a purely logical concept. In particular, nodes may but don't have to be related to physical sites and/or specific PBXs.
The PBX tree however defines the connections between PBXs (as it defines which slave PBX registers where).
Terminal devices (such as phones) register with PBXs and the PBX tree determines how calls are connected between the terminal devices via the PBXs as the call between two parties on different PBXs will be forwarded
along the PBX connections. For example, a call between devices registered on 2 different slave PBXs (registered to the master) will be forwarded from the originating PBX to the master and from the master to the target PBX. It is not sent directly between the 2 slave PBXs.
Independently of this, users are assigned to a node in the node tree and this position influences the interpretation of the numbers they dial.
How to name them best
All objects in the PBX (users, trunk lines, etc.) share a single name space for their Names. The same is true for the objects Long Names and the Hardware Ids defined in the object Devices list. That is, you cannot have 2 objects with the same name. As a result, you cannot have 2 nodes with the same name or a PBX object with the same name as another Node object. This is true throughout the entire PBX system, as opposed to the objects Numbers, which can have duplicates as long as they do not belong to the same node.
When creating (and thus naming) nodes and PBXs you need to be careful. Of course there are no further restrictions regarding the choice of names. However, here are some guidelines which might be useful.
Both nodes and PBXs should not have names that sound like they could be useful for normal extensions.
Nodes (if you have some other than the root node) should be named in a way that they reflect some sort of logical grouping. innovaphone Holding and innovaphone Manufacturing Ltd might be good numbering node name choices if this is how extensions are grouped.
PBXs in contrast to that, should be named to reflect rather physical properties, such as the physical location of the PBX device. Berlin, Tokio or headquarter might be good choices. Or even Berlin, Kudamm 56, 2nd Floor. Some people find it convenient to use names with prefixes consistently, such as eg. PBX-Berlin, PBX-Tokio etc.
The simple node tree
Let us start with the simple node tree. A simple node tree is a node tree that has no escapes. So what is an escape? This is what the simple node tree does not have
Sorry for kidding you, but we will answer this question in the next book
E164 PBX Setups only.
In the last chapter we said: the user's position in the node tree influences the interpretation of the numbers they dial. We will look at that in some more detail in this chapter.
Setting up the Node Tree
The
numbering node tree (short hand
node tree) is set up by creating
Node and
PBX type PBX objects in the
PBX/Objects area.
The root of the numbering node tree is always called
root and there is no way to change this. Because of this, the
root node does not need to be (in fact must not be) created explicitly. It exists implicitly.
Sub-nodes of the root node (and possibly further sub-nodes below these nodes) must be created explicitly. Each nodes Parent Node property must be set to the Name of the next node further up towards the root of the node tree.
In our
numbering node tree example, the required node definitions would look like this:
Objects (e.g. users) are placed into their appropriate node by setting their Node property to the name of this node:
Let's have a little practice and configure a multi-node PBX.
If you have not yet done so, you should now load start configuration files for this book to your device. Afterwards, please upload a new startup configuration for your app services on your application platform as well. This can be done on the your Devices page in Moodle.
You can log in to
myApps on the IP411LEFT (
hq.dvl-ckl2.net) using user
ckl, password
ip411. Remember that you probably will need to trust both the PBX's and the AP's certificate!
On the IP411LEFT PBX we have pre-configured
some nodes:
Region North (80),
Region Southwest (82) and
Region Italy (81). All of them are tied to the
root node.
After loading the start configuration, please assign the users to nodes and give them extension numbers according to the following table:
User | Node | Extension |
Edward Hyde | Region North | 11 |
Henry Jekyll | Region North | 12 |
Jane Doe | Region Southwest | 11 |
John Doe | Region Southwest | 12 |
Richard Roe | Region Italy | 11 |
Christoph Künkel | root | 42 |
The "full number from the root"
When you have set up the user assignments, you can list all users in the PBX by searching for their number (you might recall that the search field both lets you search for the user's
Long Name and their
Number). For example, when you enter
42 in to the search field,
Christoph Künkel is shown.
However, when you type 11 into the search field instead, no object is shown. Wouldn't we expect Edward Hyde, Jane Doe and Richard Roe to be shown (as all three share the Number 11 as extension)?
The search field matches against the object's full number from the root of the numbering tree. For
Christoph Künkel (being in the root node) this is identical to the user's own
Number property. However, for objects in subnodes, this number is the concatenation of all node numbers from the root node down to the user's node, followed by the user's own
Number property. So if you type
8111 in to the search field, you will see
Richard Roe listed (as he is in the
Region Italy node, which has Number 81).
This complete number is sometimes referred to as
full number from the root or
full e164 number. After all, even innovaphone geeks need their gobbledygook to stand out from the crowd
.
Number resolution
When a call is placed (by a phone or just any VoIP endpoint registered to the PBX), the called number is interpreted to determine the target endpoint.
Generally, the idea is quite straight forward: if a number is not found in the callers node, it is searched in the next higher node (higher meaning nearer to the root). Looking at it a little closer, the overall algorithm is as follows
- The caller's position in the node tree is determined (that is, the value of the Node property in the PBX object the caller is registered with) and the evaluation context is set to this node
- If there is a matching non-node object in the evaluation context (i.e. the calling node) (that is, an object which has a Number defined that is equal to the called number or is equal to the beginning of the called number), then this object is the target and the call is delivered to this object
- Else if there is a matching node-object in the evaluation context, then the evaluation context is set to this node and the number defined for this node is stripped from the head of the called number. The algorithm then resumes with step b
- Else if there is no matching object at all, and the evaluation context is not the root node, and the current evaluation context's Parent Node has not been used as evaluation context so far, then the evaluation context is set to the Parent Node of the current evaluation context. The algorithm then resumes with step b
- Else if the evaluation context is already the root node, or its Parent Node has already been used as evaluation context then there is no target
In other words, the number is searched first in your node, and then up the tree to the root.
Sounds complicated? No worries, we'll walk through that in any detail in the next pages
This way, you can have shared objects, e.g. a trunk line, which can be accessed from all nodes
using the same number. The trunk line object would be put into the
root numbering node then (usually with prefix 0). The steps taken from the above list then are the same from all the sub-nodes: a, d, b.
To call a number that is in a sibling of your node, you
prefix the sibling's node number. This works because the sibling's number is unknown in your node, so the prefixed node number will be evaluated in your parent node where it is known. The steps taken are a, d, c, b.
Be careful not to shadow node prefixes
Accessing numbers in the parent node of course implies that there must be no object in the current node that has a number that overlaps with a number in your parent node.
This is true for plain objects. For example you can not call a trunk with number 0 in the root node when you reside in a sub-node where there also is a trunk with number 0 because the 0 in your own node shadows the 0 in the parent node.
But it is also true for sibling node's. Because if there is an object in your own node that shadows another node's number, you would not be able to
call objects in this sibling node. Note that this is even true if the number of the object in your own node only starts with the node's number.
So if you use multi-level node trees you will probably allocate a generic node prefix which is not used otherwise in any of the nodes. In the example tree, this node prefix is 8 (as all node numbers start with 8).
Calling inside a node
We can now have a closer look at the numbering plan imposed by that node tree and user assignments.
Calling inside a node
- call 11 from John Doe's IP111
Jane Doe's IP112 will ring
Why is that so?
- John Doe resides in node Region Southwest
- when he dials a number, this number is evaluated in the Region Southwest context
- in node Region Southwest, there is an object with number 11 (Jane Doe)
- so the destination is found within the same node
Looking back at the evaluation algorithm described in Number resolution above, the target object is found in step b.
Calling an object closer to the root
But what if there is no matching object in the same node?
We can try that by calling the admin user Christoph Künkel which we have configured with Number 42, living in the root node.
Before we can try this, you need to
Now you are set up for the following test.
Calling towards the root node
- call 42 from John Doe's IP111
your softphone will get a call
Why is that so?
- when the PBX determines that there is no object with Number 42 in the current evaluation context (which is Region Southwest), it moves the evaluation context one level towards the root node (which then already is the root node itself, as we have a very simple one-layer node tree here)
- in node root, there is an object with Number 42 (Christoph Künkel)
- so the destination is found within the root node
Looking back at the
evaluation algorithm described in
Number resolution above, step b does not yield a target object. Neither does step c find one. So step d is performed (which is essentially "the evaluation context is set to the Parent Node of the current evaluation context"). The parent node is the
root node.
Calling to a sibling node
As a last example, lets see what happens when the target object is in a sibling node.
We can try that by calling from John Doe's (who is in node Region Southwest) IP111 to Henry Jekyll which we have configured with Number 12, living in the Region North node.
To call towards the sibling node
- call 8012 from John Doe's IP111
Henry Jekyll's analog phone will get a call
Why is that so?
- when the PBX determines that there is no object with Number 8012 in the current evaluation context (which is Region Southwest), it moves the evaluation context one level towards the root node (which then already is the root node itself, as we have a very simple one-layer node tree here)
- in node root,there is also no user with Number 8012, but there is a node (Region North) with Number 80
- so the node's Number is stripped from the called (8012->12) and the evaluation context is set to Region North
- in node Region North there is a callable object with Number 12 (Henry Jekyll), so the destination is found within the Region North node
Looking back at the evaluation algorithm described in Number resolution above, step b does not yield a target object. Neither does step c find one. So step d is performed (which is essentially "the evaluation context is set to the Parent Node of the current evaluation context"). The parent node is the root node. In that root node, step b fails but step c can be performed, so the evaluation context is set to Region North (which has Number 80) and the lookup is now done for 12 instead of 8012 by repeating step b.
Calling to a child node
Our sample numbering node tree is a fairly simple one-level tree (or 2-level if you count the root). It is also possible however to have multi-level node trees with more than one layer of sub-nodes. Practically, this rarely happens though (with one notable exception which we will discuss in a separate book).
As far as number evaluation is concerned (as described as steps a to e in section Number resolution above), you need to understand that when you descend down to a sub-node (which only happens in step c shown there) and the number is not found in the sub-node (or one of its children), then the number won't be found. It will not be searched for in the parent node any more. This is what the mysterious "and the current evaluation context's Parent Node has not been used as evaluation context so far" in step d is all about.
Sharing a trunk throughout all nodes
Let us do something useful with what we learned so far.
How about providing a trunk line with a dial-prefix 0 that is reachable for all users in the system?
Let's assume that all external calls should be routed through a central trunk in Germany. We have prepared an
appropriate PBX Trunk line object already for this. The trunk is in Berlin, so someone has placed it into node
Region North, probably the closest match that could be found.
So how do we need to configure this trunk so it can be used by everyone in the system just dialing 0?
The trunk's "Number" property
As we want to access the trunk line using 0,
it seems straight forward to
Does that help already?
We can try that by
- dialing 0 from Henry Jekyll's analog phone
You will hear a dial-tone first and after typing 0 an announcement saying "this is the German trunk line" (our trunk line is quite a fake, it does nothing but saying this)
Sounds good!
The trunk's node
However, when we do the same (dialing
0) from
John Doe's IP111, we only get a
number unknown message.
To understand what's wrong here, we need a quick look at our
current node tree. As the trunk is in node
Region North, it is reachable to all objects in this node dialing a 0. This is why it works for
Henry Jekyll.
Seen from John Doe however, there is neither an object with Number 0 in his node Region Southwest nor in the root node above. He therefore needs to call the node where the trunk line is in (Region North) explicitly.
To see how that works
- dial 800 from John Doe's IP111
You will hear the trunk's announcement
Fair enough, but that wasn't our goal. To fix that, we need to
move the trunk line to the root node, which is the parent node to all other nodes and is therefore searched from all nodes.
- change the trunk line's Node property to root
- call 0 from John Doe's IP111
You will hear the announcement - call 0 from Richard Roe's IP222
You will also hear the announcement
Eh voilà
Override the trunk in a specific node
You might have guessed it, but the Italian fellows complain about using a German trunk when they call customers. Despite all possible benefits of using a central trunk, they ask for a dedicated Italian trunk. What now?
So the solution seems fairly simple:
- change its Node property to Region Italy
- change trunk-italy's Number property to 0
If you save the trunk line object and receive a
duplicate number error message, the password is removed from the object. As a result, the GW2 interface cannot register with the object. Please make sure that the password of Trunk Italy is
ip411.
We can try it out now
- call 0 from Richard Roe's IP222 (Region Italy)
You hear a slightly different announcement for the Italian trunk - call 0 from John Doe's IP111 (Region Southwest)
You hear the well-known announcement for the German trunk - call 0 from Henry Jekyll's analog phone (Region North)
again, you hear the well-known announcement for the German trunk
So this is what we planned for.
Anything wrong with this?
Do you remember the warning back in chapter Number resolution above: "Be careful not to shadow node prefixes"?
Looking at our
modified numbering node tree we can see that what we did to override the global trunk in
Region Italy is a variation of shadowing node prefixes: the Italian trunk shadows the global trunk.
Because of that, users in the Region Italy node have no way to call to the global trunk (as the Italian trunk shadows it). While this is what we wanted to achieve in a way, it creates an issue.
When an external German subscriber calls through the German trunk to an Italian extension (say
Richard Roe's 8111), the calling party number (CGPN) will start with
trunk-germany's
Number (which is 0). However when
Richard calls back to this number, it will go through the object with
Number 0 from his point of view (that is, the
Region Italy node) which is
trunk-italy.
In other words: when Richard Roe calls back, he will call a German number but from an Italian trunk, which is likely to fail.
You might fix that issue in a way so that calling party numbers presented by a trunk for incoming calls are always in international format. But this might confuse your users (because this would also apply to German callers calling German users such as Edward Hyde).
If you use separate trunks and nodes, then you should consider using one individual trunk per node.
Why do individual trunks help?
When a call is
received through a trunk line in one node and the call is relayed to another
Node, the
Number of the trunk line (0) along with the
Number of its
Node (e.g. 81) is prefixed to the calling party number. This way, when the recipient calls back, the call will be routed back to the original trunk.
Then again, be aware that the calling number as seen by the call recipient (e.g. 8100456701943) may be confusing. This is because first it starts with 81 and second it resembles a national number although in our example it is actually a number from abroad (Italy). However, technically it is correct. This is correct as if you call it back, you end up calling the original subscriber.
More Node properties
Prefixes Intl/Ntl/Subscriber and
Country Code/Area Code/Subscriber look fairly similar to
some properties set in the
PBX / Config / General tab of the PBX.
You might recall that we have discussed these settings in the
IT Advanced course, chapter
Configure number/name resolution in the PBX in
Setting up the Apps. In this course, we did not think about numbering nodes at all and potential multiple trunk lines in multiple locations. You must understand that these values are used to convert a calling number (e.g. 03092258541 in Germany) to its international equivalent (+493092258541) for reverse lookup. In this process, some initial digits (known as
prefixes) are cut off (usually a sequence of 0s, like the first 0 in 030). Then the number is supplemented with the area code and country code (depending on how many 0s were removed).
These values (prefixes and area/country code) are taken from the Node object of the node where the call came in (the trunk line in our case). The reverse lookup process is carried out on the PBX where the called user is registered to (in case of a master/slave PBX system).
As of this writing (firmware build 13.7377), the values are falsely taken from the node object of the user the call is delivered to. Also, the node prefix which is put in front of the calling number (81 in our example in the previous chapter) is not removed. So reverse lookup for calls between nodes won't work for now, at least not if they do not share the same country node properties such as prefixes and country code.
If there are no values configured for a node, the values are taken from those which are configured in PBX/Config/General.
You may also recall that you never create a Node object for root (it implicitly exists). Therefore, you can not configure these prefixes for the root node. So for the root node, the values configured in PBX/Config/General are used.
In our little example using a special trunk line for Region Italy, you would configure differing values in the Node tab of the Region Italy Node object.
To define the prefixes and area/country codes in our sample scenario, we obviously need to set the right values in both
PBX/Config/General (so that they can be used for the root node) and in the
Region Italy node (as they differ from the settings for all other nodes):
- open PBX/Config/General in the advanced UI
- set Prefix for Intl/Ntl/Subscriber to 000, 00, 0
- set Country Code/Area Code/Subscriber to 49, 30, 92258541
These values are then used for the root node as well as for the Region North and Region Southwest nodes.
So why 000, 00 and 0?
These values declare the digit strings which must be dialed to do international, national and local calls. In Germany, the digit string to call abroad is 00. But in our PBX, to reach the trunk line object, we need to dial an additional 0 (as the Number property of all our trunk line objects is set to 0) which makes 000. Likewise, the digit string to initiate national calls in Germany is 0 and again, we need to add our trunk line number 0, so we end up with 00.
And why 49, 30 and 92258541?
49 is Germany's country code and 30 is the Berlin area code (remember, the trunk line is supposed to be located in Berlin). 92258541 finally is the subscriber number.
A quick look at reverse number lookup
So let us have a closer look at how reverse lookup works and how prefixes and country/area code are used for it.
To do so, we will simulate incoming external calls with various forms of calling numbers. To see how the PBX then does the reverse lookup, we will a) look at some PBX traces and b) have Contacts look up the calling number.
For the latter to work, we need some contact entries in the Contacts app. Fortunately, they should be already present.
You can check that by
- opening the Contacts App and
- searching for caller
You should see
Sindelfingen | Germany | +49703154321 |
Ospedaletto | Italy | +3904554321 |
Berlin | Germany | +493054321 |
If these entries are missing for any reason, you can import the prepared
contacts-multinode.utf8 file using the
Contacts Admin App
For the tracing of the reverse lookup, the REVERSE-LOOKUP module in the PBX firmware must have tracing turned on. This should already be the case.
You can check that as follows
- go to Maintenance/Diagnostics/Config-Show on the IP411LEFT's advanced UI
- check the line config change REVERSE-LOOKUP
There must be a /trace on option - if this is not the case, then
- go to Maintenance/Diagnostics/Command
- type !config add REVERSE-LOOKUP /trace on in to the entry field
- click on the Command button
- type !config write in to the entry field
- click on the Command button
- type !config activate in to the entry field
- click on the Command button
To see how the reverse lookup works, we initiate an external call into the PBX through the Berlin trunk. We have prepared some magic so you can do this using John Doe's phone.
In addition, make sure that the option to log PBX calls is also enabled. This should be enabled by default, but you never know, so please double check.
- go to Maintenance/Diagnostics/Logging on the IP411LEFT's advanced UI
- the check mark next to PBX calls must be active
To simulate an incoming external call from a subscriber in the Sindelfingen area in Germany
- go to Maintenance/Diagnostics/Tracing on the IP411LEFT's advanced UI
- click on trace(buffer)
This will clear the PBX's trace buffer (you can verify that by clicking on it again, there should be an empty trace shown then)
- dial 700 from John Doe's IP111
Edward Hyde's IP232 will ring, showing a call from 000493054321 known as Berlin Germany Caller (you can hang up the call) - click on trace(buffer) again
Let's see what happened here (irrelevant lines are removed from the trace):
2:0445:737:3 - LOG PBX0 19 John Doe(8212:john.doe) setup-> (700)
John Doe calls 700
2:0445:742:3 - LOG PBX0 6 trunk-germany(000493054321) setup-> (8011)
a call comes in from 000493054321 though the German Trunk line (this is our little magic: a call to 700 is echoed as call from a Berlin subscriber with a calling party number in international format)
2:0445:742:5 - LOG PBX0 20 Edward Hyde(8011:edward.hyde) <-setup (000493054321)
The incoming call is sent to Edward Hyde
2:0445:745:1 - OUT.20 -> REVERSE-LOOKUP-SESSION.4 0:325 REVERSE_LOOKUP_NUMBER(edward.hyde 000493054321:493054321)
The PBX is doing a reverse lookup on the incoming calling party number for Edward Hyde. The original number is 000493054321 which is converted to 493054321 for the lookup (actually, a + not shown in the trace is also prepended so that the lookup is done for +493054321)
2:0445:771:5 - REVERSE-LOOKUP-SESSION.4 -> OUT.20 0:327 REVERSE_LOOKUP_NUMBER_COMPLETE(000493054321:Berlin Germany Caller)
The number is found to be a contact called Berlin Germany Caller
The conversion (000493054321 -> 493054321) shown above is done based on the prefixes set forth for the
Node object as follows:
- the incoming number 000493054321 is matched against the Prefix for Intl (which we have set to 000 before)
- the international prefix does match and is therefore removed from the number (leaving 49305432)
Now let's see what happens to an incoming subscriber number:
- go to Maintenance/Diagnostics/Tracing on the IP411LEFT's advanced UI
- click on trace(buffer)
- dial 702 from John Doe's IP111
Edward Hyde's IP232 will ring, showing a call from 054321 known as Berlin Germany Caller (you can hang up the call) - click on trace(buffer) again
0:1248:095:6 - LOG PBX0 10 trunk-germany(054321) setup-> (8011)
0:1248:098:4 - OUT.11 -> REVERSE-LOOKUP-SESSION.3 0:84 REVERSE_LOOKUP_NUMBER(edward.hyde 054321:493054321)
0:1248:168:0 - REVERSE-LOOKUP-SESSION.3 -> OUT.11 0:86 REVERSE_LOOKUP_NUMBER_COMPLETE(054321:Berlin Germany Caller)
In order to perform the reverse lookup, the PBX will
- again match the incoming number (054321) against the Prefix for Intl (000)
- as this doesn't match, the Prefix for Ntl is tried (which we have set to 00 before)
- as this also doesn't match , the Prefix for Subscriber is tried (which we have set to 0 before)
- the subscriber prefix does match and therefore the prefix is removed (-> 54321), the area code (30) is prefixed (-> 3054321) and finally the country code (49) is prefixed (-> 493054321)
- so the same number as before is used for the reverse lookup (+493054321) and therefor, the same contact (Berlin Germany Caller) is found
If you like, you can also try it with a national number. Just call
701 from
John Doe's IP111.
Reverse lookup in a different node
But what happens if the call happens in another node, for example through the Italian trunk line in our Region Italy node?
We can also simulate this with our little 7xx magic.
To place a call from a subscriber in Ospedaletto through our Italian trunk line to
Richard Roe (our Italian user) with a subscriber number as calling party
- go to Maintenance/Diagnostics/Tracing on the IP411LEFT's advanced UI
- click on trace(buffer)
- dial 71211 from John Doe's IP111
An incoming call from 004554321 will show up at Richard Roe's IP222 - Notice that no calling name is shown, so the reverse lookup failed
- to see what happened, click on trace(buffer) again
In the trace, you will see
4:2425:859:3 - LOG PBX0 21 John Doe(8212:john.doe) setup-> (71211)
John Doe calls 71211
4:2425:864:4 - LOG PBX0 12 trunk-italy(81004554321) setup-> (11)
An incoming call from 004554321 comes through the Italian trunk line
4:2425:867:3 - OUT.11 -> REVERSE-LOOKUP-SESSION.4 0:512 REVERSE_LOOKUP_NUMBER(richard.roe 004554321:494554321)
A reverse lookup is done for +494554321 which yields no result (no REVERSE_LOOKUP_NUMBER_COMPLETE line in the trace)
Obviously, the number conversion for reverse lookup (004554321 -> 494554321) is wrong. This is because we have still not yet defined the Node object properties for the Region Italy node. Therefore, the PBX uses the values set in the PBX/General/Config area. These however reflect the properties of the German trunk line.
To fix this, we need to edit the
Prefixes Intl/Ntl/Subscriber and
Country Code/Area Code/Subscriber properties in the
Region Italy Node object as follow:
- open the Region Italy Node object
- switch to the Node tab
- set Prefixes Intl/Ntl/Subscriber to 000, 0, 0, respectively
- set Country Code/Area Code/Subscriber to 39, <empty>, 04554321
So why 000, 0 and 0?
As we already know, these values declare the digit strings which must be dialed to do international, national and local calls. In Italy, the digit string to call abroad is 00. But in our
PBX, to reach the trunk line object, we need to dial an additional 0 (as the
Number property of all our trunk line objects is set to 0) which makes 000. This is similar to Germany.
Italy is a bit special, as it surprisingly enough does not have area codes at all. In fact, all Italian numbers are actually subscriber numbers and they follow directly after the country code 39. Therefore, we configure only the trunk access number 0 for both Prefixes Ntl and Prefixes Subscriber.
Italy is in another way, hm, unusual let's say: subscriber numbers often start with 0 (such as in 04554321). What may look like a national dial prefix (0) + an area code (45) followed by a subscriber number (54321) is in fact a subscriber number in its entirety. You can see that when you try to call this number from abroad: you need to dial 00039
04554321, not 000394554321 as you would expect if the 0 would be a national dial prefix.
Local objects
In many cases, there is no need for multiple nodes. Many organizations use a flat numbering scheme, where extension numbers have no prefixes and no relationship to a physical number. One of the advantages of this scheme is that extensions can be moved transparently between different sites without any changes. Of course, you lose the ability to call extensions in your home node with a shorter number. But this is often even perceived as confusing.
In such a scenario, nodes with node prefixes do not make sense at first glance.
The solution is simple: you just use the root node and put all objects in the root node.
So let's convert our setup to a single-node setup (for simplicity, let's keep the full numbers for all extensions, so that, for example,
Edward Hyde would have extension
8011 and
Richard Roe would have extension
8111):
- as we want to get rid of all these nodes, remove Region North, Region Southwest and Region Italy nodes (You really need to delete these objects in order for the Config Checker to detect your progress)
- move the users to the root node and modify their Number property as follows:
Edward Hyde | 8011 |
Henry Jekyll | 8012 |
Richard Roe | 8111 |
Jane Doe | 8211 |
John Doe | 8212 |
You might have noticed that the user objects still had their initial
Node configuration - although the nodes used were already deleted. This can happen easily when reworking a configuration and you should carefully fix all such inconsistencies.
Ok, now we have removed the nodes from the user configuration and assigned distinct extensions in the root node to them, fair enough. But what about the
Trunk line objects?
If we want to place all of them in the root node, we have to assign different extensions. However, we do not want this in any case, since the exchange code number should be 0 everywhere. Strictly speaking, we want a call to 0 to be interpreted depending on the location. In Germany trunk-germany should be used when dialing 0, but in Italy trunk-italy.
To implement this scheme we need what is known as the physical location. The physical location is simply the name of the PBX where an object (User or Trunk line or anything else) is registered with.
You may have observed before that the PBX names are always
part of the Node drop-down in the object configuration. In other words, you can set any PBX not only as a value for the
PBX property but also as a value for the
Node property.
As a result, if we have distinct PBXs for each location where we have a trunk line, then we could put the corresponding Trunk line objects into the node of the respective PBX. This in turn would allow us to use the same Number property (that is, trunk access code, e.g. 0) for all these Trunk line objects.
That fixes the issue of non-unique Number properties per node. However, this does still not mean that users simply could dial 0 to get their appropriate trunk line. For this, we need one other piece of the puzzle: the Local flag in the Trunk line object.
Setting the Local flag slightly changes the rules we discussed in section Number resolution above. It introduces a new step (say, a0) as first step right before step a:
- a-0. The callers physical location is determined and the evaluation context is set to this node. If there is a matching non-node object in the evaluation context that has its Local property set, then this object is the target and the call is delivered to this object. Otherwise...
- a. The caller's position in the node tree is determined (that is, the value of the Node property in the PBX object the caller is registered with) and the evaluation context is set to this node
- b. ...
In other words, if there is a matching local object defined in the numbering node that is the physical location of the caller, then this object will hide any other object that would normally be found in the caller's scope.
So
- set hq (which is the name of our master PBX and therefore also a node name) as Node for trunk-germany and
- also set the Local flag
All users which are registered to
hq (and hence have
hq as their physical location) will use this trunk line when using the trunk access code 0.
You can easily verify this by calling
0 from any of the phones. You will always reach the German trunk line (as all users are registered with
hq).
To implement the use of trunk-italy for the Italian users, we first need a new PBX which we can use as its Node.
Setting up the PBX for the Italian trunk line
As we have discussed, in order to use multiple trunk lines with a flat (that is, root only) numbering plan, we need a separate PBX per location (more precisely, per trunk line).
Fortunately, a kind soul has already prepared our IP811 as a slave to our master PBX hq on the IP411LEFT. The only thing to do to have it working is to create a PBX type object for the new slave PBX.
Let us integrate the new slave PBX:
- the PBX name of the new slave PBX is set to italy on the IP811. So we need to create a PBX type object with the Name property set to italy
- its Long Name property doesn't matter really, but we recommend to set it to Italy
- the Parent Node property should be set to to root. The three Region xyz nodes which are available in the drop-down too are not used anymore in our new scenario, hq is the master PBX and must not be used here (we will discuss later why this is the case) and italy, well, would create a loop of course
- the Parent PBX property is easy. Of course, our slave needs to be connected to the master PBX and hence, hq is the right choice here
- an interesting case is the Number property. It must not be empty for a PBX type entry but the actual value doesn't matter during operation. This is why already the hq PBX has this strange **1 value for it (the best we can say is: it certainly does not conflict with a number you would want to use in real life). So we choose **2 here
- the Password finally, you guessed it, needs to be set to ip411 in our training scenario (and surely you undersign that you will never use this password in a real life scenario)
When this is done, our slave PBX should
be registered with the master PBX.
While we are at that: have you observed that the DNS name of our slave PBX is shown as branch-b.dvl-ckl2.net? Shouldn't it read italy.dvl-ckl2.net?
Well yes, would be nicer. Then again, the DNS name of course does not need to match the PBX name as long as the IP address is correct. And
branch-b.dvl-ckl2.net was already present in the DNS server on the IP411RIGHT. So just blame it on the lesson designer
Now we are ready to fix the Italian location so that their users use the Italian trunk line.
Here is what we need to do:
- change the Node property of trunk-italy to italy
- change the PBX property of trunk-italy to italy
- add the local flag to trunk-italy
- change the PBX property of Richard Roe to italy
Take care not to change the
Node property of the users. They should remain as
root as we want to have all of them in the same flat numbering plan (hence node).
For sure, our expectation when we use Richard Roe's IP222 and dial 0 is that we connect to the Italian trunk line. But not so! We still hear the German trunk announcement. How is that possible?
To understand what happens here, we need to look at the concept of dynamic physical location.
Dynamic physical location
As we have changed Richard Roe's registration PBX, his physical location should have changed from hq to italy. And due to that, we would expect him to reach the Italian trunk line when dialing 0.
So if this doesn't work, perhaps the change of the registration PBX didn't work?
Let us check the registrations on our IP811
- on PBX/Registrations we see Richard Roe registered from 172.31.31.5 which is what we expected
- however, on PBX/Objects we see more information: 172.31.31.5@hq*tls in the rightmost column
The interesting information here is @hq. This indicates that hq is the physical location and that it differs from the actual registration PBX.
So this is why Richard Roe reaches trunk-germany instead of trunk-italy: his physical location is hq and trunk-germany has the Local flag set, so that it shadows the 0 in the root node for Richard Roe.
The reason why
hq still is
Richard Roe's physical location can be seen when we look at the
registration configuration in his IP222: the phone sends its registration request to the master PBX (
hq.dvl-ckl2.net). From there, it is redirected to the slave PBX (
branch-b.dvl-ckl2.net).
The physical location of a user (more precisely: of a registration on behalf of this user) is set to the first PBX that received the registration.
Fixing the Italian site
So
Richard Roe has a physical location different from his registration PBX because his phone
sends the registration to a PBX different from his configured registration PBX initially. Along with the redirect to the correct registration PBX, the name of the initial PBX is sent and remembered as physical location.
In our case, we clearly do not want this. There are two options to fix it.
Sending the registration to the proper PBX
Of course, the issue does not occur if we would configure Richard's phone so that it sends the registration to the correct PBX right away.
This is easily done by using a different Device configuration for Richard's phone.
Fortunately, we have already prepared such a configuration as well as a new
provisioning category so that we can apply it selectively.
There are only
two differences between the new and the original device configuration entries:
- the Category has changed from hq IP phone to italy IP phone
- the Primary gatekeeper is set to branch-b.dvl-ckl2.net instead of hq.dvl-ckl2.net
To apply this new configuration to Richard's phone and thereby fixing its physical location proceed as follows:
- open the Devices App
- switch to the Devices tab
- select the IP222
- select Categories
- remove the hq IP Phone category
- add the italy IP Phone category
You will notice that the new configuration
is applied to the IP222 right away.
If we now call
0 from
Richard Roe's IP222, we will hear the announcement of the Italian trunk line.
Eh voilà
Disabling dynamic physical location
It is certainly a good idea to have separate provisioning categories for different locations (this is why we always
recommend this in our courses). Therefore, using a separate device configuration for phones in another location is easy to do.
Nevertheless, it is also possible to disable dynamic physical locations altogether. This is one of the
options in the Advanced settings section for both an IP phone and an analog phone
device configuration.
The dynamic physical location is a largely obsolete concept used before version 13, so we generally recommend to disable it.
To disable dynamic physical location for both IP and analog phones proceed as follows:
- open the Devices App
- make sure you have the Domains tab selected
- select your dvl-ckl2.net domain
- select Device configuration
- tick the No physical location check-mark in [ Analog phone / fax ] dvl-ckl2.net Analog Phone hq Analog Phone, [ Analog phone / fax ] dvl-ckl2.net.net Fax Device hq Fax Device, [ Phone ] dvl-ckl2.net hq IP Phone and [ Phone ] dvl-ckl2.net italy IP Phone
- you will find the checkmark in the Advanced settings part of these device configurations
Note though that although the check-mark is labeled No physical location it does not disable the physical location entirely. It only disables the modification of the physical location when a registration redirection occurs. The physical location still is relevant as otherwise we would not be able to implement local trunk lines in a flat numbering plan.
Calls from "Local" objects
We have discussed how objects with the Local flag set can be called from foreign nodes. But how does call routing work the other way round?
For example, consider in our new scenario a call towards 8111 (which is Richard Roe's Number property who is located in the root node) comes in through the trunk-germany (which is located in the hq node). How can it be delivered to Richard Roe although both ends are in a different nodes?
In fact, there is no extra magic here. The call to 8111 will first be evaluated in the trunk line's node, which is hq. This fails as there is no object with Number 8111 in the hq node. So the evaluation context is moved one level towards the root of the node-tree, which is root. And here, 8111 exists.
This is exactly according to the mechanism we discussed earlier in section Number resolution.
PBX nodes used as physical location must be located underneath the nodes the users are in.
Obviously, in a simple "all users are in the root node" scenario, this is easily done. However, if you mix multi-node configurations with objects with Local option, you must be careful to adhere to this condition.
"Empty" Node and PBX entries
You may have noticed that both the PBX and the Node property can be set to be empty.
Empty PBX
When the PBX property is left empty, each PBX in a system (that is: the master and all slaves) will treat the object as if it was configured with the respective PBX itself as value. In other words: all PBXs would consider this object as their own whenever a call or a registration for the object comes in.
Empty Node
When the Node property is left empty, each PBX will assume that the object is in the Node of the PBX itself (for example our italy PBX would assume that the Node of such an object is italy whereas our hq PBX would assume the Node to be hq).
Empty Node and PBX with Local flag
An interesting option is the creation of objects with both PBX and Node left empty and the Local flag turned on. Each PBX would consider such an object as their own (and for example accept registrations on it). Also, they would consider it to be in their own numbering node. Finally, due to the Local flag, such an object would shadow all objects with same Number for all users having their physical location on that PBX.
In other words: this creates an object that is universally available but implemented locally (that is, on each users registration PBX).
For example, we could replace our
trunk-italy and
trunk-germany Trunk line objects by a single
trunk-universal object.
However, this also implies that all instances of the object are identical. This might not be appropriate for a trunk line (as you may want to configure different diversion targets such as Loopback, Incomplete, Busy, Rejected and No Answer for example).
Node tree with escapes
This type of numbering plan is discussed in great detail in
E164 PBX Setups (node trees with escapes are also referred to as E.164 because they are structured like the public telephone network and the international standard describing this scheme is known as
ITU E.164).