Is CNAM Lookup/Passing for SIP to IAX2 Forwarded External Calls Possible? [SOLVED]

We use IAX2 Trunks between all of our sites. Internal calls work great. The CNAM information for an extension passes without issue. (Figure 1)

We are now starting to forward external calls (from SIP trunks) to other PBXs in the network. Reasons may be: overflow, night answering etc. When the call is received by the other PBX, the CallerID Number appears but no CNAM information. The CNAM information is populated initially by OpenCNAM lookups on the initial server but does not pass along. (Figure 2)

Is there some way to either pass the CNAM information along from the initial server or do another lookup on the destination server?

Example: PBX A and PBX B

Figure 1 (Internal… Working)

  1. Extension 100101 on PBX A calls Extension 101101 on PBX B.
  2. Name and Number appear on extension 101101.

*This call routes over an IAX2 trunk to PBX B

Figure 2 (External to Internal then Forwarded… Not Working)

  1. External Caller +1-555-212-0505 calls PBX A
  2. CNAM Resolves to “Fake Test Number” on PBX A
  3. Destination for inbound SIP route is set to ring Extension 101101 on PBX B. ( “After Hours” (Time Conditions))
  4. External Call is ringing on 101101 on PBX B
  5. Extension 101101 Phone shows +1-555-212-0505 as CallerID but CNAM is no longer on the record

*This call routes from external SIP trunk to internal IAX2 trunk

I’m not sure if this is a proper fix, so asking as a reply. This old “bug” report describes what is happening. The report was closed and marked “Not an Issue” so maybe this isn’t a proper fix. I would also rather this be “custom” so it persists from upgrade to upgrade.

https://issues.freepbx.org/browse/FREEPBX-5688

I have applied this modification and it works exactly as desired. The line that is stripping the CNAM is:

exten => s,n(usercid),ExecIf($[${LEN(${USEROUTCID})} != 0]?Set(CALLERID(all)=${USEROUTCID}))

It suggests editing “/etc/asterisk/extensions_additional.conf” (/etc/asterisk/extensions_overide_freepbx) as follows:

Original

/etc/asterisk/extensions_additional.conf

[macro-outbound-callerid]
    include => macro-outbound-callerid-custom
    exten => s,1,ExecIf($["${CALLINGNAMEPRES_SV}" != ""]?Set(CALLERPRES(name-pres)=${CALLINGNAMEPRES_SV}))
    exten => s,n,ExecIf($["${CALLINGNUMPRES_SV}" != ""]?Set(CALLERPRES(num-pres)=${CALLINGNUMPRES_SV}))
    exten => s,n,ExecIf($["${REALCALLERIDNUM:1:2}" = ""]?Set(REALCALLERIDNUM=${CALLERID(number)}))
    exten => s,n(start),GotoIf($[ $["${REALCALLERIDNUM}" = ""] | $["${KEEPCID}" != "TRUE"] | $["${OUTKEEPCID_${ARG1}}" = "on"] ]?normcid)
    exten => s,n,Set(USEROUTCID=${REALCALLERIDNUM})
    exten => s,n,GotoIf($["foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}" = "foo"]?bypass)
    exten => s,n(normcid),Set(USEROUTCID=${DB(AMPUSER/${AMPUSER}/outboundcid)})
    exten => s,n(bypass),Set(EMERGENCYCID=${DB(DEVICE/${REALCALLERIDNUM}/emergency_cid)})
    exten => s,n,Set(TRUNKOUTCID=${OUTCID_${ARG1}})
    exten => s,n,GotoIf($["${EMERGENCYROUTE:1:2}" = "" | "${EMERGENCYCID:1:2}" = ""]?trunkcid)
    exten => s,n,Set(CALLERID(all)=${EMERGENCYCID})
    exten => s,n,Set(CDR(outbound_cnum)=${CALLERID(num)})
    exten => s,n,Set(CDR(outbound_cnam)=${CALLERID(name)})
    exten => s,n(exit),MacroExit()
    exten => s,n(trunkcid),ExecIf($[${LEN(${TRUNKOUTCID})} != 0]?Set(CALLERID(all)=${TRUNKOUTCID}))
    exten => s,n(usercid),ExecIf($[${LEN(${USEROUTCID})} != 0]?Set(CALLERID(all)=${USEROUTCID}))
    exten => s,n,ExecIf($[${LEN(${TRUNKCIDOVERRIDE})} != 0 | ${LEN(${FORCEDOUTCID_${ARG1}})} != 0]?Set(CALLERID(all)=${IF($[${LEN(${FORCEDOUTCID_${ARG1}})}=0]?${TRUNKCIDOVERRIDE}:${FORCEDOUTCID_${ARG1}})}))
    exten => s,n(hidecid),ExecIf($["${CALLERID(name)}"="hidden"]?Set(CALLERPRES(name-pres)=prohib_passed_screen))
    exten => s,n,ExecIf($["${CALLERID(name)}"="hidden"]?Set(CALLERPRES(num-pres)=prohib_passed_screen))
    exten => s,n,Set(CDR(outbound_cnum)=${CALLERID(num)})
    exten => s,n,Set(CDR(outbound_cnam)=${CALLERID(name)})

Updated with 2 additional Lines (marked with **)

/etc/asterisk/extensions_overide_freepbx

[macro-outbound-callerid]
    include => macro-outbound-callerid-custom
    exten => s,1,ExecIf($["${CALLINGNAMEPRES_SV}" != ""]?Set(CALLERPRES(name-pres)=${CALLINGNAMEPRES_SV}))
    exten => s,n,ExecIf($["${CALLINGNUMPRES_SV}" != ""]?Set(CALLERPRES(num-pres)=${CALLINGNUMPRES_SV}))
    exten => s,n,ExecIf($["${REALCALLERIDNUM:1:2}" = ""]?Set(REALCALLERIDNUM=${CALLERID(number)}))
    exten => s,n(start),GotoIf($[ $["${REALCALLERIDNUM}" = ""] | $["${KEEPCID}" != "TRUE"] | $["${OUTKEEPCID_${ARG1}}" = "on"] ]?normcid)
    exten => s,n,Set(USEROUTCID=${REALCALLERIDNUM})
    **exten => s,n,set(REALCALLERIDNAME=${CALLERID(name))**
    exten => s,n,GotoIf($["foo${DB(AMPUSER/${REALCALLERIDNUM}/device)}" = "foo"]?bypass)
    exten => s,n(normcid),Set(USEROUTCID=${DB(AMPUSER/${AMPUSER}/outboundcid)})
    exten => s,n(bypass),Set(EMERGENCYCID=${DB(DEVICE/${REALCALLERIDNUM}/emergency_cid)})
    exten => s,n,Set(TRUNKOUTCID=${OUTCID_${ARG1}})
    exten => s,n,GotoIf($["${EMERGENCYROUTE:1:2}" = "" | "${EMERGENCYCID:1:2}" = ""]?trunkcid)
    exten => s,n,Set(CALLERID(all)=${EMERGENCYCID})
    exten => s,n,Set(CDR(outbound_cnum)=${CALLERID(num)})
    exten => s,n,Set(CDR(outbound_cnam)=${CALLERID(name)})
    exten => s,n(exit),MacroExit()
    exten => s,n(trunkcid),ExecIf($[${LEN(${TRUNKOUTCID})} != 0]?Set(CALLERID(all)=${TRUNKOUTCID}))
    exten => s,n(usercid),ExecIf($[${LEN(${USEROUTCID})} != 0]?Set(CALLERID(all)=${USEROUTCID}))
    **exten => s,n,ExecIf($["${KEEPCID}" = "TRUE" & $["${OUTKEEPCID_${ARG1}}" = "on" | "${OUTKEEPCID_${ARG1}}" = "off"] & "${USEROUTCID}" = "${REALCALLERIDNUM}" & "${CALLERID(name)}" = ""]?Set(CALLERID(name)=${REALCALLERIDNAME}))**
    exten => s,n,ExecIf($[${LEN(${TRUNKCIDOVERRIDE})} != 0 | ${LEN(${FORCEDOUTCID_${ARG1}})} != 0]?Set(CALLERID(all)=${IF($[${LEN(${FORCEDOUTCID_${ARG1}})}=0]?${TRUNKCIDOVERRIDE}:${FORCEDOUTCID_${ARG1}})}))
    exten => s,n(hidecid),ExecIf($["${CALLERID(name)}"="hidden"]?Set(CALLERPRES(name-pres)=prohib_passed_screen))
    exten => s,n,ExecIf($["${CALLERID(name)}"="hidden"]?Set(CALLERPRES(num-pres)=prohib_passed_screen))
    exten => s,n,Set(CDR(outbound_cnum)=${CALLERID(num)})
    exten => s,n,Set(CDR(outbound_cnam)=${CALLERID(name)})

You want to use the “extensions-FreePBX-or-whatever-its-called-override.conf” configuration file (I don’t have access to the /etc/asterisk directory of any of my servers from here - search for “*override*”), rather than the “custom”, since you are replacing an active context. The override file is read first and loads up the new context for you so the “standard” one doesn’t get in your way.

@cynjut Thanks so much. The file I have added this to is /etc/asterisk/extensions_overide_freepbx

Is there any reason this override would not be OK?

I have limited it to only happen when “Allow All CID” or “Do Not Allow Foreign CID” is set on a trunk and also allowed at the SIP level. if “Remove CNAM” or “Fixed CID” is set on the trunk, it is set to respect it.

It honestly does seem like this may be something that is missing from Asterisk or FreePBX. the options are there on the Trunk but they do not actually mean what one may think… at least without overriding this macro.

If you are replacing an existing context, adding it to the override file establishes it. The one in the standard config file won’t override a context that already exists, so you need to make sure you are doing everything the original one did.

Adding an existing system-level context to the -custom.conf file doesn’t do anything, since the context is created already and isn’t replaced when the custom file is read.

SO if you are adding a new context to the system, you can use either the -custom or -override context files. If you are replacing an existing context, you need to add it through the override file.

@cynjut Thank you. I understand the various file assignments.

My concern is more about the overall approach to passing CNAM by modifying a “core functionality” .

If it was marked as “not an issue” in the bug report, I have to assume there was a reason. I don’t like modifying “core functionality” unless I know it won’t have side effects.

That is the beauty of this community. So many people like you, @dicko , @dickson and others have had soooo much experience and save us all pain from our own ignorance.

I know there was some discussion about whether or not it was “an issue.” It seems to me that there was some discussion about it not being a common enough problem to make it a permanent change and the override context (like you are using) was a reasonable approach to solving the problem. For the hand full of people that have this problem, the solution is to implement the code you’re implementing.

@cynjut Excellent! Thank you so much! That is great news. I’ll mark this as solved.