Repository navigation
NethVoice: preserve forwarded-call identity without replacing the upstream loop check #8216
Description
Parent: #7570
Preserve this NethVoice behavior while using the unmodified upstream FreePBX Core module. The upgrade checkout installs Core 17.0.18.54. The old nethesis_nv8 fork is based on Core 16.0.68.40; comparing it with the matching upstream 16 release isolates the Nethesis changes from unrelated upstream updates. The obsolete Flexisip transport change is excluded from this migration.
Problem and original purpose
When an extension forwards a call to an external destination, the fork sets inherited REALCALLERIDNUM to the forwarding extension if the destination is not a PBX user. This supplies that extension's identity to subsequent outbound caller-ID processing; it does not directly set the final presented caller ID. NethVoice later excludes voicemail destinations beginning with vm.
Original change: 77ac604b in nethesis/freepbx-core, with a PHP namespace correction in b8902cfd.
Upstream assessment
Core 17.0.18.54 has no equivalent identity instruction in macro-dial-one,cf. The local nethcti3_get_config_late() currently replaces priority 2. In the fork, that priority held the added identity instruction; in upstream, it holds the forwarding-loop check. The current replacement therefore removes upstream's loop check. This replacement was reproduced with FreePBX's PHP dialplan builder; live call validation remains required.
Implementation plan
- Change the late NethVoice hook to insert the identity instruction after
CFAMPUSERis set, rather than replacing upstream priority 2. - Preserve upstream's forwarding-loop check and subsequent forwarding instructions.
- Explicitly resolve the forwarding destination instead of relying on the implicit
DB_RESULTvalue. - Retain the NethVoice exclusion for voicemail destinations and preserve existing trunk caller-ID policies.
- Guard the insertion against unexpected upstream dialplan changes and verify the generated instruction order.
- Leave Core source files unchanged.
Acceptance criteria
- Generated
cfdialplan contains both the NethVoice identity instruction and upstream's forwarding-loop check in the intended order. - Internal and external callers can be forwarded externally with the expected trunk caller-ID policy.
- Forwarding to PBX users and CTI voicemail destinations retains the intended behavior.
- Self-forwarding and forwarding loops do not produce repeated outbound dialing.
- Blind and attended transfers retain the intended caller identity.
- Behavior survives repeated reloads, restart and backup/restore with unmodified upstream Core.
References
- nethesis/freepbx-core@77ac604
- nethesis/freepbx-core@b8902cf
- nethesis/ns8-nethvoice@0e3e6f3
- https://github.com/FreePBX/core/blob/release/17.0.18.54/Dialplan/macroDialone.php#L148
Affected integration: freepbx/var/www/html/freepbx/admin/modules/nethcti3/functions.inc.php, in nethcti3_get_config_late().
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTesting
Activity
Stell0 commentedon Oct 9, 2026
Test
Test Case 1
forward_identity_test.php: preserve the Core loop check, identity exclusions and fallback Answer/Ringing; reject unexpected layouts.Test Case 2
REALCALLERIDNUMis the forwarding extension; an internal forward keeps the original caller.Test Case 3
REALCALLERIDNUMidentifies the forwarding extension and the callee receives its configured outbound caller ID.REALCALLERIDNUMkeeps the original caller identity.Completed checks passed on
nethvoice58withpr-1034.1097-1.b734d58: simulated external forwardREALCALLERIDNUM=8102, internalREALCALLERIDNUM=8101; both loop cases connected normally.Draft PR: nethesis/ns8-nethvoice#1034.
fix(forward): Preserve the Core loop check