Repository navigation
NethVoice: preserve profile-based forwarding routes with upstream FreePBX Core #8219
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
A forwarded external call should follow the outbound routes and permissions assigned to the extension doing the forwarding. The fork resolves the original extension's context and uses it for the forwarded Local-channel destination instead of always using from-internal.
Original change: e39cc045 in nethesis/freepbx-core. Existing bug #7742 documents the user-visible routing problem: forwarded calls can choose an outbound line according to general route order instead of the user's profile. This sub-issue covers the upstream-Core migration implementation and is related to that existing bug.
Upstream assessment
Core 17.0.18.54 still hard-codes from-internal in macro-dial-one,dlocal, while NethVoice still uses cti-profile-* contexts. The fork's behavior therefore needs a module-owned replacement. Source inspection also shows that the fork leaves the no-timer usegoto path using from-internal; that path needs explicit review rather than assuming the fork covers every forwarding case.
Implementation plan
- Share a module-owned context resolver with the pickup migration sub-issue, using the FreePBX device API instead of copying the direct SQL lookup.
- Add a late NethVoice dialplan hook to resolve
${EXTTOCALL}and change thedlocalLocal-channel destination to the appropriate extension context. - Preserve
/n, timers, caller identity and upstream forwarding logic. - Review the no-timer
usegotopath and ensure it follows the same intended profile routing and permissions. - Handle deleted or invalid extensions explicitly; do not fall back to unrestricted routing for an invalid device.
- Check interactions with forwarding chains, ring groups, queues, voicemail and transfers. Leave Core source files unchanged.
Acceptance criteria
- External calls forwarded externally use the forwarding extension's configured outbound routes.
- Destinations allowed by the profile succeed and destinations denied by the profile remain denied.
- Timed and untimed forwarding both follow the intended profile context.
- Forwarding chains, voicemail and blind/attended transfers retain the intended behavior.
- Invalid/deleted extensions do not cause unrestricted outbound routing.
- Profile changes take effect after Apply Config and behavior survives restart and backup/restore with unmodified upstream Core.
References
- External call forwarding uses from-internal context instead of the user’s profile context #7742
- nethesis/freepbx-core@e39cc04
- https://github.com/FreePBX/core/blob/release/17.0.18.54/Dialplan/macroDialone.php#L215
Affected integrations: freepbx/var/www/html/freepbx/admin/modules/nethcti3/functions.inc.php and profile-context assignment in freepbx/var/www/html/freepbx/rest/lib/libExtensions.php.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsTesting
Activity
Stell0 commentedon Oct 9, 2026
Test
Test Case 1
forward_context_test.php: direct, conditional, untimed, group and confirmation paths; missing owner context never falls back to unrestricted routing.Test Case 2
Test Case 3
DIALPARTIESDIALPLANand verify group forwarding uses the correct owner profile, including members sharing a forwarding destination; restore the setting.Completed checks passed on
nethvoice58withpr-1037.1101-1.d0d8f7e: 13 SIP checks, including allowed/denied routes for all three modes, untimed conditional forwards, a group member and simple-dial. Allowed calls reachedcti-profile-8102; denied calls never reached the unrestricted route.Draft PR: nethesis/ns8-nethvoice#1037.
fix(forward): Respect extension profile routes