Skip to content

NethVoice: preserve profile-based forwarding routes with upstream FreePBX Core #8219

Description

@Stell0

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 the dlocal Local-channel destination to the appropriate extension context.
  • Preserve /n, timers, caller identity and upstream forwarding logic.
  • Review the no-timer usegoto path 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

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.

Activity

  1. added
    nethvoiceBug or features releted to the NethVoice project
    on Oct 9, 2026
  2. added theissue type on Oct 9, 2026
  3. Stell0 commented on Oct 9, 2026

    @Stell0
    Author

    Test

    Test Case 1

    • Run forward_context_test.php: direct, conditional, untimed, group and confirmation paths; missing owner context never falls back to unrestricted routing.

    Test Case 2

    • For unconditional, busy and no-answer forwarding, verify an allowed destination uses the forwarding owner's profile and a denied destination stays blocked.
    • Repeat for untimed forwarding, a ring-group member and the simple-dial/Follow Me path.

    Test Case 3

    • Remove a forwarding owner's PJSIP endpoint; verify direct and group forwards cannot fall back to unrestricted routing.
    • With group/Follow Me call confirmation enabled, verify allowed forwards can be accepted and profile-denied destinations remain blocked.
    • Enable DIALPARTIESDIALPLAN and verify group forwarding uses the correct owner profile, including members sharing a forwarding destination; restore the setting.

    Completed checks passed on nethvoice58 with pr-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 reached cti-profile-8102; denied calls never reached the unrestricted route.

    Draft PR: nethesis/ns8-nethvoice#1037.

  4. added
    testingPackages are available from testing repositories
    on Oct 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

nethvoiceBug or features releted to the NethVoice projecttestingPackages are available from testing repositories

Projects

  • Status
    Testing

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions