Here's a first pass of the tables we may consider for routes and trunks:
ROUTES:
tblRouteDetails: Details of each route on the system. A route can have a default callerid, and a route can specifiy wether its callerid can be changed at all, or if it can be changed to internally defined callerids but not foreign callerid (ones that may come from external forwarded numbers, followme, etc.). Specific trunk config may overide these.
tblRouteDetails
routeID
routeName
routeDescription
routeTemplateID
inUseCount (remove this)
tblRoutePatterns: Each route is made up of one or more patterns that it will accept. Each route has its set of patterns stored in this table.
tblRoutePatterns
routeID
routePattern
digitsToRemove ((*)from greg: remove this)
prependPattern
(*) I'm still not convinced. Our current routes, and any forseable change, use the notation of: 99|425NXXXXXX as an example where the pattern to match is 99425NXXXXXX and then the 99 is stripped (e.g. first 2 digits). Although it is a good and user friendly pattern to display for the user, it still seems like it makes sense to store this in the database a 99425NXXXXXX,2. I think it is much easier (and more efficient) to manipulate both in the get_config script where it is most often run, and in the re-display to the gui. And the whole thing can be hidden with appropriate apis. (e.g. core_routing_getpatterns() can return a list of formatted patterns with with "|" where as _core_routing_getpatterns() can return a 2 dimensional array more appropriate for dialplan generation code. More discussion is welcome.
tblRouteTrunks: Each route can have one or more trunks that it will attempt to use. These trunks are stored in this table.
tblRouteTrunks
routeID
trunkSeq
trunkID
tblTenantAccess: Each route may be accessible to one or more tenants. Each tenant who has access to a route will have an entry in this table for each tenant/route pair they have access to. There will also be a template providing additional default values or capabilities that this tenant may have with this route. In the common case of a single tenant installation, there is only one tenant and they will have access to all routes.
tblTenantAccess
routeID
tenantID
routeTemplateID(-1 = no template, all defaults)
tblRouteTemplates: This provides a template of capabilities that each tenant/route pair may point to so that the same route used by different tenants may have different characteristics. Alternatively ,the may be a single template that applies to multiple routes or even one template for all routes and all tenants. In the standard case of a single tenant installation, this becomes redundant since all the fields are defined in the route details. Route details will also take precedence over these values where applicable.
tblRouteTemplates
routeTemplateID
routeTemplateDescription
emerRouteCapable (0=no, 1=optional, 2=always)
intraCompanyCapable (0=no, 1=optional, 2=only)
mohClassDefault
callerID
allowCallerIDchanges
allowForeignCallerID (whether or not non-native CIDs can be transmitted (e.g. fwd call)
inUseCount (remove this)
tblTenantRouteContexts: Within each tenant, there can be multiple dialing contexts (previously referred to as custom-contexts. In the past there was only outbound-allroutes. Each context can define one or more routes that are available to the members of that dialing context, and the order of those routes. It is also at this level that timeConditions objects can be applied. In the simple case of a single outbound-allroutes style configuration (the norm), a set of routes will have to be defined and then those routes will have to be included into a defined 'outbound-allroutes' style context. Whether or not there is a GUI that gives the illusion of a single routing page as in todays implementation, the context will have to use this database to create the route sequences and other configurations.
tblTenantRouteContexts
contextID
routeID
routeSeq
tenantContextTemplateID
tblTenantRouteContexts: The attributes to be applied to a route when used in a specific context.
tblTenantRouteContextTemplates
tenantContextTemplateID
timeConditionID (optional time condition(s) for route)
pinCode (optional) REMOVE and move to pincode module
pinCodeSet (optional) REMOVE and move to pincode module
mohClass (optional - overrides default)
emerRoute (influenced by emerRouteCapable settings)
intraCompany (influenced by intraCompanyCapable settings
callerID
allowCallerIDchanges
allowForeignCallerID (whether or not non-native CIDs can be transmitted (e.g. fwd call)
TRUNKS:
NOTE: Some of these probably need to get normalized into the key/value table but for now ...
tblTrunks
trunkID (if there is an inbound trunk it will share the same id)
trunkDirection (in, out, both - e.g. peer, user, friend)
trunkName
trunkDescription (long description)
trunkTechnology
callerID
changeCallerIDAllow
allowForeignCallerID (whether or not non-native CIDs can be transmitted (e.g. fwd call)
maxChannels
cntInboundChannels (if inbound channels should be counted towards max)
disableTrunk
inUseCount (remove this)
tblTrunkDialRules
trunkId
dialRuleSeq
dialRulePattern
tblTrunkSettings
id (needed as part of PK, in case there are repeated key values - not sure if that could be the case?)
trunkID
inOutBoth (1=inbound trunk only, 2=outbound trunk only, 3=applies to both)
seq(used to retain the sequence entered (e.g. deny all, allow specific
key
value
EXTENSION REGISTRY
We need to make a class that can be used to register extensions that should not be shared to be used anywhere in the dialplan. Any module or core creating a dialable extension must check to make sure it is not being used and then register the extension.
Despite the plan to have different contexts, within a single tenant an extension should not be used more than once.
- We will have to think about the upgrade implications and plans for this. There are existing installations where people have purposely create queues and ringgroups with overlapping extensions as mean to do things like simulate followme functionality prior to followme being there, and for other purposes.
- We have had conflicts with features such as *1122 being a direct dial to voicemail and the featurecode _*11. being the user logon (same goes for CF and others). We need to try to detect such conflicts and accomodate the below registry if possible. This one is a bit more difficult but a solution would be nice. See #1873 as an example where this came up.
The table is fairly basic, something like:
tblExtensionRegistry
extValue (any registered extension, not limitted to numeric)
moduleOwner (the module that registered it)
state (inuse, disabled, reserved)
The class should be created and available globally, and have methods like:
extIsAvail(extValue)
returns true if available for use
useExtIfAvailable(extValue, module, state)
returns true if successful, false if it fails for any reason
setExtState(extValue, module, state)
change the state of an extension, must be owner to change state. returns true if successful, false if it fails for any reason
releasehExt(extValue, module)
relinquish the extension, must be module owner. Returns true if successful, false other wise.
queryExtInfo(extValue)
returns array containing: three elements: resultsextValue?, resultsmoduleOwner?, resultsstate? for the extension, or false if not present.
DESTINATION REGISTRY
Today destiantions are are individually saved by each module, as a goto target. This has several drawbacks and must be changed. We need to define a destination registry. It will have the purpose of:
- translate a destination into dialpan code thus abstracting the destination and making it easier to port to new engines.
- find dependencies so that a module can determine if another module is using their destination (in case someone tries to delete it).
Some goals include:
- all modules using a destination must register the use of that destination
- all modules that stop using a destination should un-register its use
- we need a common format to provide destination idnetifiers, probably:
- modulename
- elementID
- today modules simply provide goto targets, e.g. ext-queues,<exten>,1
- modules will need to provide a function that, given the elementID, they can return or somehow generate dialplan code.
- need to think this one through. Today modules have the goto information which can be used in any type of goto statement. This may end up varying by engine. It may make most sense today for the method to return a simple string (in the case of asterisk) that will simply be the goto target. And conventions for other engines may vary.
DESTINATION REGISTRY
Both inbound and outbound routes are starting to use MoH classes in their configurations. We need to come up with a scheme to check for dependencies so that either the MoH module can't delete one that is being used, or so that the routes that use it detect deletions and switch to default.
