The sip:carrier comes with two ways of accomplishing local number porting (LNP). One is populating the integrated LNP database with porting data, and the other is accessing external LNP databases via the Sipwise LNP daemon using the LNP API (PRO/CARRIER only).
The local LNP database provides the possibility to define LNP Carriers (the owners of certain ported numbers or number blocks) and their corresponding LNP Numbers belonging to those carriers. It can be configured on the admin panel in Settings→Number Porting or via the API. The LNP configuration can be populated individually or via CSV import/export both on the panel and the API.
LNP Carriers are defined by an arbitrary Name for proper identification (e.g. British Telecom) and contain a Prefix which can be used as routing prefix in LNP Rewrite Rules and subsequently in Peering Rules to route calls to the proper carriers. The LNP prefix is written to CDRs to identify the selected carrier for post processing and analytics purposes of CDRs. LNP Carrier entries also have an Authoritative flag indicating that the numbers in this block belong to the carrier operating the sip:carrier. This is useful to define your own number blocks, and in case of calls to those numbers reject the calls if the numbers are not assigned to local subscribers (otherwise they would be routed to a peer, which might cause call loops). Finally the Skip Rewrite flag skips executing of LNP Rewrite Rules if no number manipulation is desired for an LNP carrier.
LNP Carriers contain one or more LNP Numbers. Those LNP Numbers are defined by a Number entry in E164 format (<cc><ac><sn>) used to match a number against the LNP database. Number matching is performed on a longest match, so you can define number blocks without specifying the full subscriber number (e.g. a called party number 431999123 is going to match an entry 431999 in the LNP Numbers).
For an LNP Numbers entry, an optional Routing Number can be defined. This is useful to translate e.g. premium 900 or toll-free 800 numbers to actual routing numbers. If a Routing Number is defined, the called party number is implicitly replaced by the Routing Number and the call processing is continued with the latter.
An optional Start Date and End Date allows to schedule porting work-flows up-front by populating the LNP database with certain dates, and the entries are only going to become active with those dates. Empty values for start indicate a start date in the past, while empty values for end indicate an end time in the future during processing of a call, allowing to define infinite date ranges. As intervals can overlap, the LNP number record with a start time closest to the current time is selected.
In order to activate Local LNP during routing, the feature must be activated in config.yml. Set kamailio→proxy→lnp→enabled to yes and kamailio→proxy→lnp→type to local.
When a call arrives at the system, the calling and called party numbers are first normalized using the Inbound Rewrite Rules for Caller and Inbound Rewrite Rules for Callee within the rewrite rule set assigned to the calling party (a local subscriber or a peer).
If the called party number is not assigned to a local subscriber, or if the called party is a local subscriber and has the subscriber/domain preference lnp_for_local_sub set, the LNP lookup logic is engaged, otherwise the call proceeds without LNP lookup. The further steps assume that LNP is engaged.
If the call originated from a peer, and the peer preference caller_lnp_lookup is set for this peer, then an LNP lookup is performed using the normalized calling party number. The purpose for that is solely to find the LNP prefix of the calling peer, which is then stored as source_lnp_prefix in the CDR. If the LNP lookup does not return a result (e.g. the calling party number is not populated in the local LNP database), but the peer preference default_lnp_prefix is set for the originating peer, then the value of this preference is stored in source_lnp_prefix of the CDR.
Next, an LNP lookup is performed using the normalized called party number. If no number is found (using a longest match), no further manipulation is performed.
If an LNP number entry is found, and the Routing Number is set, the called party number is replaced by the routing number. Also, if the Authoritative flag is set in the corresponding LNP Carrier, and the called party number is not assigned to a local subscriber, the call is rejected. This ensures that numbers allocated to the system but not assigned to subscribers are dropped instead of routed to a peer.
If the system is serving a local subscriber with only the routing number assigned (but not e.g. the premium number mapping to this routing number), the subscriber will not be found and the call will either be rejected if the called party premium number is within an authoritative carrier, or the call will be routed to a peer. This is due to the fact that the subscriber lookup is performed with the dialled number, but not the routing number fetched during LNP. So make sure to assign e.g. the premium number to the local subscriber (optionally in addition to the routing number if necessary using alias numbers) and do not use the LNP routing number mechanism for number mapping to local subscribers. |
Next, if the the LNP carrier does not have the Skip Rewriting option set, the LNP Rewrite Rules for Callee are engaged. The rewrite rule set used is the one assigned to the originating peer or subscriber/domain via the rewrite_rule_set preference. The variables available in the match and replace part are, beside the standard variables for rewrite rules:
${callee_lnp_prefix}
: The prefix stored in the LNP Carrier
${callee_lnp_basenumber}
: The actual number entry causing the match (may be shorter than the called party number due to longest match)
Typically, you would create a rewrite rule to prefix the called party number with the callee_lnp_prefix by matching ^([0-9]+)$
and replacing it by ${callee_lnp_prefix}\1
.
Once the LNP processing is completed, the system checks for further preferences to finalize the number manipulation. If the originating
local subscriber or peer has the preference lnp_add_npdi set, the Request URI user-part is suffixed with ;npdi
. Next,
if the preference lnp_to_rn is set, the Request URI user-part is suffixed with ;rn=LNP_ROUTING_NUMBER
, where
LNP_ROUTING_NUMBER is the Routing Number stored for the number entry in the LNP database, and the originally called number is
kept in place. For example, if lnp_to_rn is set and the number 1800123 is called, and this number has a routing number
1555123 in the LNP database, the resulting Request-URI is sip:1800123;rn=1555123@example.org
.
Finally, the destination_lnp_prefix in the CDR table is populated either by the prefix defined in the Carrier of the LNP database if a match was found, or by the default_lnp_prefix prefrence of the destination peer or subscriber/domain.
If a call originated from a peer and the peer preference force_outbound_calls_to_peer is set to force_nonlocal_lnp (the if callee is not local and is ported selection in the panel), the call is routed back to a peer selected via the peering rules.
This ensures that if a number once belonged to your system and is ported out, but other carriers are still sending calls to you (e.g. selecting you as an anchor network), the affected calls can be routed to the carrier the number got ported to.
The LNP database can be exported to CSV, and in the same format imported back to the system. On import, you can decide whether to drop existing data prior to applying the data from the CSV.
The CSV file format contains the fields in the following order:
carrier_name carrier_prefix number routing_number start end authoritative skip_rewrite
Table 11. LNP CSV Format
Name | Description |
Carrier Name | The Name in the LNP Carriers table (string, e.g. My Carrier) |
Carrier Prefix | The Prefix in the LNP Carriers table (string, e.g. DD55) |
Number | The Number in the LNP Numbers table (E164 number, e.g. 1800666) |
Routing Number | The Routing Number in the LNP Numbers table (E164 number or empty, e.g. 1555666) |
Start | The Start in the LNP Numbers table (YYYY-MM-DD or empty, e.g. 2016-01-01) |
End | The End in the LNP Numbers table (YYYY-MM-DD or empty, e.g. 2016-12-30) |
Authoritative | The Authoritative flag in the LNP Carriers table (0 or 1) |
Skip Rewrite | The Skip Rewrite flag in the LNP Carriers table (0 or 1) |
External LNP relies on the Sipwise LNP Daemon (lnpd) which kamailio-proxy is taking to via a defined JSONRPC protocol. The proxy sends the A and B number to lnpd, which in the current release translates it to a SIP Message sent to an external server (typically a Squire SIP-to-INAP gateway. This external gateway is performing an SS7 INAP request to fetch the LNP result, which is passed back as a binary blob in a 3xx response to the lnpd. The lnpd extracts the TCAP body of the response and returns the information back to the proxy.
TODO: describe config, available fields etc.