Asterisk/FreePBX E.164 FQTN normalizer with configurable country codes
In our previous post FreePBX/Asterisk rule for splitting Telefonica/O2 ‘To:’ header we detailed how to determine the DID for incoming calls from O2 SIP trunks.
However, the resulting DID can still take one of the following formats, depending on which number is being dialled by the caller:
1234567
0891234567
+49891234567
0049891234567
O2/Telefonica SIP trunks will not normalize these numbers in any way, but this causes issues with the FreePBX inbound route matcher.
For example, if you’ve configured an inbound route for 0891234567
, it will only match if the caller is calling exactly 0891234567
. If the caller dials +49891234567
, the inbound route will not match, even though it will map to the same phone number.
To solve this issue, we can use a FreePBX E.164 FQTN normalizer to normalize the incoming number to the E.164 format.
FreePBX 15 only provides the from-pstn-e164-us
normalizer by default, which is hardcoded to only support US numbers and does not include the O2-specific split rule (which should work for many, if not most other SIP trunk providers).
The following dialplan config, which you can add to /etc/asterisk/extensions_custom.conf
, will normalize the incoming number to E.164 format and has configurable country and area codes (att the top of the file).
[from-pstn-toheader-o2]
exten => _.,1,Set(COUNTRY_CODE=49) ; Set the country code
exten => _.,n,Set(AREA_CODE=89) ; Set the area code
; Split "To:" header, e.g. "08912345;telefonica=xyz@..." or "08912345@telefonica"
exten => _.,n,Set(TOHEADERNUM=${CUT(CUT(CUT(PJSIP_HEADER(read,To),\;,1),@,1),:,2)})
; Debug the original number
exten => _.,n,NoOp(Original TOHEADERNUM: ${TOHEADERNUM})
; Handle numbers without a prefix (short numbers) (except for numbers with "+" prefix)
exten => _.,n,ExecIf($["${TOHEADERNUM:0:1}" != "0" & "${TOHEADERNUM:0:1}" != "+"]?Set(TOHEADERNUM=+${COUNTRY_CODE}${AREA_CODE}${TOHEADERNUM}))
; Handle numbers starting with 00 => convert to +
exten => _.,n,ExecIf($["${TOHEADERNUM:0:2}" = "00"]?Set(TOHEADERNUM=+${TOHEADERNUM:2}))
; Handle numbers starting with just ONE zero (local numbers): 0891234 => +49891234
exten => _.,n,ExecIf($["${TOHEADERNUM:0:1}" = "0"]?Set(TOHEADERNUM=+${COUNTRY_CODE}${TOHEADERNUM:1}))
; Note: No need to handle numbers such as +498912345, already in E.164 FQTN format
; Debug the final normalized number
exten => _.,n,NoOp(Final TOHEADERNUM after normalization: ${TOHEADERNUM})
exten => _.,n,Goto(from-pstn,${TOHEADERNUM},1)
Once you’ve enabled this dialplan as context for your SIP trunks, configure your inbound routes to have DIDs in the E.164 format (e.g. +49891234567
) and they will now match the incoming numbers from O2 SIP trunks, regardless of the format the caller used to dial the number.