跳到主要内容

拨号计划配置与呼叫路由

📖 返回主文档

XML 拨号计划配置、呼叫路由逻辑和拨号计划变量的综合指南。

相关文档

核心文档

呼叫处理流程

  • 🔢 号码转换 - E.164 规范化(发生在拨号计划之前)
  • 👥 Sh 接口 - 为拨号计划变量检索的用户数据
  • 📡 SS7 MAP - 拨号计划变量中的 MSRN/HLR 数据
  • 💳 在线计费 - 呼叫流程中的 OCS 授权

服务实现

  • ⚙️ 补充服务 - 在拨号计划中实现呼叫转移、CLI 阻止
  • 📞 语音邮件 - 拨号计划中的语音邮件路由和存储/检索
  • 🔊 TTS 提示 - 在拨号计划中使用播放提示

监控


拨号计划配置 / 呼叫路由

TAS 使用与标准电信 XML 拨号计划格式兼容的 XML 拨号计划,变量由 TAS 填充。 这意味着您可以根据需要定义自己的拨号计划,包含运营商的业务逻辑,但拥有所有所需的数据,如存储库数据、SS7 路由信息、IMPI / IMPU 身份、拨号计划规范化等。

拨号计划写入 priv/templates,形式如下:

  • mo_dialplan.xml - 移动发起呼叫拨号计划
  • mo_emergency_dialplan.xml - 移动发起紧急呼叫拨号计划
  • mt_dialplan.xml - 移动终止呼叫拨号计划

您可以从 Web UI 内部查看拨号计划。

路由视图

在 XML 被解析之前,TAS 设置了各种变量,这些变量在呼叫开始时以其当前值打印到日志中,在定义自己的呼叫逻辑时非常有帮助。

FreeSWITCH XML 拨号计划基础

OmniTAS 使用与 FreeSWITCH 项目相同的 XML 呼叫路由系统,允许灵活的呼叫路由以满足您的需求。

本节解释核心概念并提供实际示例。

基本结构

拨号计划由 扩展 组成,包含 条件操作

<extension name="description-of-what-this-does">
<condition field="${variable}" expression="regex-pattern">
<action application="app_name" data="parameters"/>
<anti-action application="app_name" data="parameters"/>
</condition>
</extension>

扩展 按顺序从上到下进行评估。当条件匹配时,其操作执行。

条件和正则匹配

条件测试变量与正则表达式。如果正则匹配,则执行操作;如果不匹配,则执行反操作。

基本精确匹配:

<condition field="${tas_destination_number}" expression="2222">
<action application="log" data="INFO Calling voicemail access number"/>
</condition>

多个号码匹配:

<condition field="${tas_destination_number}" expression="^(2222|3444|3445)$">
<action application="log" data="INFO Calling special service"/>
</condition>

带捕获组的模式匹配:

<condition field="${tas_destination_number}" expression="^1(8[0-9]{9})$">
<!-- 匹配 1 后跟 8 和 9 个数字 -->
<action application="log" data="INFO Matched toll-free: $1"/>
<action application="bridge" data="sofia/gateway/trunk/${tas_destination_number}"/>
</condition>

前缀匹配:

<condition field="${tas_destination_number}" expression="^00">
<!-- 匹配以 00 开头的任何号码(国际) -->
<action application="log" data="INFO International call detected"/>
</condition>

范围匹配:

<condition field="${msisdn}" expression="^5551241[0-9]{4}$">
<!-- 匹配 55512410000 到 55512419999 -->
<action application="log" data="INFO Subscriber in range"/>
</condition>

操作与反操作

操作 在条件匹配时执行。反操作 在条件不匹配时执行。

<condition field="${cli_withheld}" expression="true">
<!-- 如果 CLI 被隐藏则执行 -->
<action application="set" data="effective_caller_id_number=anonymous"/>
<action application="set" data="origination_privacy=hide_number"/>

<!-- 如果 CLI 未被隐藏则执行 -->
<anti-action application="log" data="DEBUG CLI is normal"/>
<anti-action application="set" data="effective_caller_id_number=${msisdn}"/>
</condition>

continue="true" 属性

默认情况下,当扩展的条件匹配时,拨号计划停止处理后续扩展。continue="true" 属性允许处理继续到下一个扩展。

没有 continue(默认行为):

<extension name="First-Check">
<condition field="${tas_destination_number}" expression="^(.*)$">
<action application="log" data="INFO Processing call"/>
</condition>
</extension>

<extension name="Never-Reached">
<!-- 这永远不会执行,因为上一个扩展匹配 -->
<condition field="${tas_destination_number}" expression="^(.*)$">
<action application="log" data="INFO This won't print"/>
</condition>
</extension>

使用 continue="true":

<extension name="Print-Vars" continue="true">
<condition field="${tas_destination_number}" expression="^(.*)$">
<action application="info" data=""/>
</condition>
</extension>

<extension name="Check-Balance" continue="true">
<condition field="${hangup_case}" expression="OUTGOING_CALL_BARRED">
<action application="log" data="ERROR Insufficient balance"/>
<action application="hangup" data="${hangup_case}"/>
</condition>
</extension>

<extension name="Route-Call">
<!-- 这个扩展仍然会被评估 -->
<condition field="${tas_destination_number}" expression="^(.*)$">
<action application="bridge" data="sofia/gateway/trunk/${tas_destination_number}"/>
</condition>
</extension>

使用 continue="true" 用于:

  • 日志/调试扩展
  • 设置适用于多种场景的变量
  • 不路由呼叫的验证检查

常见应用

呼叫控制

answer - 接听呼叫(发送 200 OK)

<action application="answer" data=""/>

hangup - 以特定原因终止呼叫

<action application="hangup" data="NORMAL_CLEARING"/>
<action application="hangup" data="USER_BUSY"/>
<action application="hangup" data="NO_ANSWER"/>

bridge - 将呼叫连接到另一个目的地

<!-- 桥接到外部网关 -->
<action application="bridge" data="sofia/gateway/trunk/+12125551234"/>

<!-- 桥接到具有编解码器优先级的内部分机 -->
<action application="bridge" data="{absolute_codec_string=AMR-WB,AMR,PCMA}sofia/internal/sip:user@domain.com"/>

<!-- 带超时的桥接 -->
<action application="bridge" data="{originate_timeout=30}sofia/gateway/trunk/${tas_destination_number}"/>
变量和通道数据

set - 设置通道变量

<action application="set" data="my_variable=my_value"/>
<action application="set" data="sip_h_X-Custom-Header=CustomValue"/>
<action application="set" data="effective_caller_id_number=anonymous"/>

unset - 移除通道变量

<action application="unset" data="sip_h_P-Asserted-Identity"/>

export - 设置变量并导出到 B-leg(桥接呼叫)

<action application="export" data="sip_h_X-Account-Code=ABC123"/>
媒体和提示

playback - 播放音频文件

<action application="playback" data="/sounds/en/us/callie/misc/8000/out_of_credit.wav"/>
<action application="playback" data="$${base_dir}/sounds/custom_prompt.wav"/>

sleep - 暂停指定毫秒

<action application="sleep" data="1000"/>  <!-- 暂停 1 秒 -->

echo - 将音频回显给呼叫者(测试)

<action application="echo" data=""/>

conference - 将呼叫放入会议

<action application="conference" data="room-${destination_number}@wideband"/>
语音邮件

voicemail - 访问语音邮件系统

<!-- 为邮箱留语音邮件 -->
<action application="voicemail" data="default default ${msisdn}"/>

<!-- 使用授权检查语音邮件 -->
<action application="voicemail" data="check auth default default ${msisdn}"/>
日志和调试

log - 写入日志文件

<action application="log" data="INFO Processing call from ${msisdn}"/>
<action application="log" data="DEBUG Destination: ${tas_destination_number}"/>
<action application="log" data="ERROR Call failed with cause: ${hangup_cause}"/>

info - 将所有通道变量转储到日志

<action application="info" data=""/>
杂项应用

say - 文本转语音号码读取

<action application="say" data="en number iterated ${tas_destination_number}"/>

send_dtmf - 发送 DTMF 音调

<action application="send_dtmf" data="1234#"/>

实际示例

紧急服务路由:

<extension name="Emergency-911">
<condition field="${tas_destination_number}" expression="^(911|112)$">
<action application="log" data="ALERT Emergency call from ${msisdn}"/>
<action application="answer" data=""/>
<action application="playback" data="/sounds/emergency_services_transfer.wav"/>
<action application="bridge" data="sofia/gateway/emergency_gw/${tas_destination_number}"/>
</condition>
</extension>

基于余额的条件路由:

<extension name="Check-Credit">
<condition field="${hangup_case}" expression="OUTGOING_CALL_BARRED">
<action application="answer" data=""/>
<action application="playback" data="/sounds/out_of_credit.wav"/>
<action application="hangup" data="CALL_REJECTED"/>
</condition>
</extension>

On-Net 与 Off-Net 路由:

<extension name="Route-Decision">
<condition field="${on_net_status}" expression="true">
<!-- On-net: 通过 TAS 路由 -->
<action application="log" data="INFO Routing to on-net subscriber"/>
<action application="bridge" data="sofia/internal/+${tas_destination_number}@10.179.3.60"/>
<anti-action application="log" data="INFO Routing off-net"/>
<anti-action application="bridge" data="sofia/gateway/trunk/+${tas_destination_number}"/>
</condition>
</extension>

匿名来电 ID 处理:

<extension name="CLI-Privacy" continue="true">
<condition field="${cli_withheld}" expression="true">
<action application="set" data="effective_caller_id_name=anonymous"/>
<action application="set" data="effective_caller_id_number=anonymous"/>
<action application="set" data="origination_privacy=hide_number"/>
</condition>
</extension>

无人接听时的语音邮件:

<extension name="Try-Bridge-Then-VM">
<condition field="${tas_destination_number}" expression="^(555124115\d{2})$">
<action application="set" data="call_timeout=30"/>
<action application="bridge" data="sofia/internal/${tas_destination_number}@domain.com"/>

<!-- 如果桥接失败,转到语音邮件 -->
<action application="log" data="INFO Bridge failed, routing to voicemail"/>
<action application="answer" data=""/>
<action application="voicemail" data="default default ${tas_destination_number}"/>
</condition>
</extension>

号码范围路由:

<extension name="Local-Numbers">
<condition field="${tas_destination_number}" expression="^([2-9]\d{2})$">
<!-- 3 位本地分机 200-999 -->
<action application="log" data="INFO Local extension: $1"/>
<action application="bridge" data="sofia/internal/$1@pbx.local"/>
</condition>
</extension>

<extension name="National-Numbers">
<condition field="${tas_destination_number}" expression="^555\d{7}$">
<!-- 国家移动号码 -->
<action application="log" data="INFO National mobile call"/>
<action application="bridge" data="sofia/gateway/national_trunk/${tas_destination_number}"/>
</condition>
</extension>

<extension name="International">
<condition field="${tas_destination_number}" expression="^00\d+$">
<!-- 以 00 开头的国际呼叫 -->
<action application="log" data="INFO International call"/>
<action application="bridge" data="sofia/gateway/intl_trunk/${tas_destination_number}"/>
</condition>
</extension>

进一步文档

有关每个应用程序的完整详细信息:

FreeSWITCH 维基包含每个拨号计划应用程序的详细文档,包括所有参数和用例。

拨号计划变量

TAS 在 XML 拨号计划逻辑中设置的变量:

常见变量(所有呼叫类型)

初始设置:

  • destination_number - 转换后的目的号码
  • tas_destination_number - 转换后的目的号码
  • effective_caller_id_number - 转换后的源号码

紧急呼叫

  • hangup_case - "none"
  • ims_private_identity - 私有用户身份
  • ims_public_identity - 公共用户身份
  • msisdn - 订阅者号码(去掉 +)
  • imsi - 来自私有身份的 IMSI
  • ims_domain - 来自私有身份的域

MT 呼叫(移动终止)

  • ims_private_identity - 私有用户身份
  • ims_public_identity - 公共用户身份
  • msisdn - 订阅者号码(去掉 +)
  • imsi - 来自私有身份的 IMSI
  • ims_domain - 来自私有身份的域
  • call_forward_all_destination - CFA 目的地或 "none"
  • call_forward_not_reachable_destination - CFNRc 目的地
  • scscf_address - S-CSCF 地址或 "none"
  • scscf_domain - S-CSCF 域或 "none"
  • no_reply_timer - 无回复超时
  • hangup_case - "none" 或 "UNALLOCATED_NUMBER"
  • msrn - 来自 PRN 的 MSRN(如果漫游)或来自 SRI 的转发号码(如果呼叫转移处于活动状态)
  • tas_destination_number - 路由目的地覆盖(设置为 MSRN 或转发号码)

MO 呼叫(移动发起)

  • hangup_case - "none"、"OUTGOING_CALL_BARRED" 或 "UNALLOCATED_NUMBER"
  • ims_private_identity - 私有用户身份
  • ims_public_identity - 公共用户身份
  • msisdn - 订阅者号码(去掉 +)
  • imsi - ���自私有身份的 IMSI
  • ims_domain - 来自私有身份的域
  • allocated_time - OCS 分配的时间(如果启用在线计费)
  • cli_withheld - "true" 或 "false" 字符串
  • on_net_status - "true" 或 "false" 字符串(目的地是否在网内)
  • msrn - 漫游订阅者的 MSRN(如果适用)
  • tas_destination_number - MSRN 覆盖(如果漫游)

紧急呼叫

紧急呼叫通过 emergency_call_codes 配置参数进行控制,并在呼叫授权期间自动检测。

配置

在您的 TAS 配置文件中配置紧急呼叫代码:

配置参数:

  • emergency_call_codes:要检测的紧急服务号码列表
  • 常见代码: "911"(美国)、"112"(欧盟)、"000"(澳大利亚)、"999"(英国)、"sos"
  • 这些代码在 SIP 紧急 URN(例如,<urn:service:sos>)之外进行检查
  • 系统对目的号码执行 精确匹配 比较

示例配置值:

  • 美国部署: ["911", "933"] - 911 用于紧急情况,933 用于测试
  • 欧洲部署: ["112", "999"]
  • 澳大利亚部署: ["000", "106"] - 000 用于紧急情况,106 用于文本中继
  • 多区域: ["911", "112", "000", "sos"]

紧急检测工作原理

系统检查两个条件:

  1. SIP URI 紧急服务 URN:检测 <urn:service:sos> 或任何包含 "service:sos" 的 URI
  2. 目的号码匹配:将 Caller-Destination-Number 与配置的 emergency_call_codes 进行比较

如果 任一条件 为真,则呼叫被分类为紧急。

处理流程

呼叫流程详细信息:

  1. 呼叫到达 TAS
  2. 授权模块检查目的地与紧急模式
  3. 如果检测到紧急情况:
    • 呼叫类型设置为 :emergency
    • 使用 mo_emergency_dialplan.xml 模板
    • OCS 授权通常被绕过
    • 呼叫路由到 PSAP 网关
  4. 指标记录为 call_type: emergency 标签

拨号计划路由

priv/templates/mo_emergency_dialplan.xml 中定义紧急呼叫的路由。此模板确定如何根据您的市场需求将呼叫路由到您的 PSAP(公共安全应答点)网关或 SIP URI。

示例紧急拨号计划:

<extension name="Emergency-SOS">
<condition field="${destination_number}" expression="^(911|912|913|sos)$">
<action application="log" data="ALERT Emergency call from ${msisdn}"/>
<action application="answer" data=""/>
<action application="bridge" data="sofia/gateway/psap_gw/${destination_number}"/>
</condition>
</extension>

最佳实践

  • 始终在紧急代码列表中包含 "sos" 以确保 SIP URN 兼容性
  • 包括您管辖区内的所有本地紧急号码(例如,911、112、000、999)
  • 定期测试紧急路由,使用呼叫模拟器
  • 绕过 OCS 以确保紧急呼叫始终连接(通过 skipped_regex 配置)
  • 配置 PSAP 网关,确保高可用性和冗余
  • 监控紧急呼叫指标 以确保系统可靠性

On-Net 移动发起呼叫到 On-Net 移动终止订阅者

当订阅者呼叫您网络上的另一位订阅者(在网呼叫)时,正确的方法是将 MO 呼叫路由回 TAS 进行 MT 处理。这确保被叫方接收到完整的 MT 呼叫处理,包括呼叫转移、语音邮件、漫游的 MSRN 路由以及所有其他订阅者服务。

为什么将 MO 路由到 MT?

没有 MT 处理(直接路由):

  • 被叫方的呼叫转移设置被忽略
  • 无法在无人接听时转移到语音邮件
  • 无法为漫游订阅者进行 MSRN 路由
  • 缺少订阅者服务逻辑

有 MT 处理(路由回 TAS):

  • 完整的呼叫转移支持(CFU、CFB、CFNRy、CFNRc)
  • 忙/无人接听时的语音邮件
  • 漫游 CS 订阅者的 MSRN 路由
  • 完整的订阅者服务体验
  • 对双方的正确呼叫状态跟踪

实施

MO 拨号计划检查目的地是否在网(由您的 TAS 提供),如果是,则将呼叫路由回 TAS 本身。TAS 将其视为新的 MT 呼叫,并通过 mt_dialplan.xml 模板处理。

示例拨号计划片段:

<extension name="On-Net-Route">
<condition field="${on_net_status}" expression="true">
<action application="log" data="DEBUG On-Net MO call - Routing back into TAS" />

<!-- 清理内部路由的头部 -->
<action application="set" data="sip_copy_multipart=false"/>
<action application="set" data="sip_h_Request-Disposition=no-fork"/>

<!-- 路由回 TAS(变为 MT 呼叫) -->
<action application="bridge"
data="{absolute_codec_string='AMR-WB,AMR,PCMA,PCMU',originate_retries=1,originate_timeout=60,sip_invite_call_id=${sip_call_id}}sofia/internal/${tas_destination_number}@${sip_local_network_addr}" />
<action application="hangup" data="" />
</condition>
</extension>

关键参数:

  • ${sip_local_network_addr} - TAS IP 地址(例如,10.179.3.60
  • ${tas_destination_number} - ���叫方的 MSISDN
  • sip_invite_call_id=${sip_call_id} - 保留呼叫 ID 以便跟踪
  • sip_copy_multipart=false - 防止多部分消息复制
  • sip_h_Request-Disposition=no-fork - 确保顺序处理

呼叫流程:

重要配置:

  • TAS IP(例如,10.179.3.60)必须在您的 allowed_sbc_source_ips 配置列表中
  • 这允许 TAS 从自身接收呼叫以进行 MT 处理
  • 如果没有此项,TAS 将拒绝来自未授权源的呼叫

MSRN 用于 2G/3G 漫游订阅者的使用

��订阅者在 2G/3G 电路交换(CS)网络中漫游时,TAS 必须获取 MSRN(移动台漫游号码)以将来电路由到订阅者的当前位置。本节解释 MSRN 检索和路由的工作原理。

什么是 MSRN?

MSRN(移动台漫游号码) 是由访问网络的 VLR(访客位置寄存器)分配的临时路由号码,用于将呼叫路由到漫游订阅者。它充当指向订阅者在 CS 网络中当前位置的临时目的号码。

MSRN 检索流程

TAS 通过 SS7 MAP(移动应用部分)协议使用两步流程检索 MSRN 数据:

实施细节

第一步:发送路由信息(SRI)

TAS 通过 SS7 MAP 查询 HLR 以获取被叫订阅者的路由信息。

SRI 响应场景:

  1. SRI 中直接包含 MSRN - 漫游订阅者的 MSRN 已可用

    • 响应包括:MSISDN、GMSC、IMSI 和 MSRN
    • 示例 MSRN: 61412345678(澳大利亚移动号码格式)
  2. IMSI + VLR 号码 - 订阅者在 CS 网络中注册(需要 PRN)

    • 响应包括:MSISDN、GMSC、IMSI 和 MSC/VLR 号码
    • 表明订阅者在 CS 网络中,但必须请求 MSRN
  3. 仅 IMSI(无 VLR) - 订阅者不在 CS 网络中(仅 IMS/PS)

    • 响应包括:MSISDN、GMSC、IMSI
    • 表明订阅者注册在 IMS/4G 中,而不在 CS 网络中
  4. 呼叫转发处于活动状态 - SRI 返回转发信息

    • 响应包括转发原因(无条件、忙、无人接听、不可达)
    • 响应包括转发到的号码

第二步:提供漫游号码(PRN)- 如果需要

如果 SRI 返回 IMSI + VLR,但没有 MSRN,TAS 将向 VLR 发送 PRN 请求以获取 MSRN。

VLR 从其池中���配一个临时 MSRN,并将其返回给 TAS。此 MSRN 仅在此特定呼叫设置期间有效。

示例 PRN 响应: MSRN 61412345678

拨号计划变量: msrn

一旦通过 SS7 MAP 检索到 MSRN,它将作为拨号计划变量设置,可以在 MT 拨号计划中使用。

变量: ${msrn}

  • 类型: 字符串(不带前导 + 的 E.164 号码)
  • 示例: "61412345678"(澳大利亚移动格式)
  • 用法: 将呼叫路由到 CS 漫游订阅者
  • 由: 在 MT 呼叫处理期间的 HLR 数据检索过程设置

在 mt_dialplan.xml 中路由到 MSRN

MSRN 变量在 MT 拨号计划模板中用于将呼叫路由到漫游订阅者。

拨号计划逻辑:

  1. 检查 MSRN:扩展检查 msrn 变量是否设置(包含数字)
  2. 设置超时参数
    • 进度超时:接收早期媒体的 10 秒
    • 桥接应答超时:使用订阅者配置的无人接听计时器
  3. 桥接到 MSRN:通过 CS 网关将呼叫路由到 MSRN
    • 使用 ignore_early_media=ring_ready 以获得一致的响铃
    • 编解码器优先级:AMR(移动)、PCMA/PCMU(固定线路)
    • 网关: sofia/gateway/CS_Gateway/+${msrn}
  4. 失败时的回退:如果桥接失败,则路由到呼叫转发目的地

示例拨号计划片段:

<extension name="Route-to-CS-MSRN" continue="false">
<condition field="msrn" expression="^(\d+)$">
<!-- 配置超时 -->
<action application="set" data="progress_timeout=10" />
<action application="set" data="bridge_answer_timeout=${no_reply_timer}" />

<!-- 通过 CS 网关桥接到 MSRN -->
<action application="bridge"
data="{ignore_early_media=ring_ready,absolute_codec_string='AMR,PCMA,PCMU',continue_on_fail=true,originate_retries=1,originate_timeout=60}sofia/gateway/CS_Gateway/+${msrn}" />

<!-- 回退到语音邮件/呼叫转发 -->
<action application="bridge"
data="sofia/internal/${call_forward_not_reachable_destination}@${local_ip_v4}" />
</condition>
</extension>

关键点

  1. MSRN 是临时的 - 仅在呼叫设置期间有效
  2. 仅用于 CS 网络 - MSRN 用于 2G/3G 漫游,而不用于 VoLTE/IMS 漫游
  3. 在 MT 流程中的优先级 - MSRN 检查发生在标准 IMS 路由之前
  4. 回退到转发 - 如果 MSRN 桥接失败,则路由到呼叫转发目的地
  5. HLR 优先于 Sh - HLR 中的 MSRN 优先于 Sh 订阅者数据

配置

必须在 TAS 配置中启用 SS7 MAP 集成:

所需设置:

  • enabled:设置为 true 以启用 SS7 MAP 查询
  • http_map_server_url_base:您的 SS7 MAP 网关的 URL(例如,"http://10.1.1.100:5001"
  • gmsc:用于 SRI/PRN 请求的网关 MSC 号码(例如,"61400000000"
  • timeout_ms:查询超时(默认:5000 毫秒)

请参见 SS7 MAP 文档 以获取完整的配置详细信息。


呼叫转发数据使用

呼叫转发设置决定了当主要目的地不可用时呼叫如何路由。TAS 从两个来源检索呼叫转发数据:Sh 接口(HSS)和 SS7 MAP(HLR),HLR 数据优先。

呼叫转发类型

系统支持四种类型的呼叫转发:

转发类型变量活动时
无条件呼叫转发 (CFU)call_forward_all_destination始终立即转发所有呼叫
忙时呼叫转发 (CFB)call_forward_not_reachable_destination订阅者线路忙
无人接听呼叫转发 (CFNRy)call_forward_not_reachable_destination订阅者在超时内未接听
不可达呼叫转发 (CFNRc)call_forward_not_reachable_destination订阅者不可达/离线

数据来源

1. Sh 接口(HSS)

静态配置 存储在 HSS 订阅者配置文件中。

TAS 在呼叫处理期间通过 Sh 接口从 HSS 检索呼叫转发设置。这些是为订阅者配置的默认设置。

示例检索数据:

  • call_forward_all_destination:CFU 目的地(例如,"61412345678"
  • call_forward_not_reachable_destination:CFB/CFNRy/CFNRc 目的地(例如,"61487654321"
  • no_reply_timer:触发 CFNRy 的秒数(例如,"20"

2. SS7 MAP(HLR)

实时数据 来自 HLR,可能与 HSS 不同,如果订阅者通过 USSD/MMI 代码(例如,拨打 *21* 代码)更改了设置。

TAS 在呼叫设置期间通过 SS7 MAP 查询 HLR 以获取当前/活动的转发设置。

HLR 转发响应包括:

  • forwarded_to_number:转发的目的号码(例如,"61412345678"
  • reason:转发类型(无条件、忙、无人接听、不可达)
  • notification flags:是否通知呼叫方、转发方等。

映射到拨号计划变量:

  • 如果原因是 无条件 → 设置 call_forward_all_destination
  • 如果原因是 忙、无人接听或不可达 → 设置 call_forward_not_reachable_destination

变量合并优先级

HLR 数据覆盖 Sh 数据 当两者都存在时。

TAS 在 MT 呼叫处理期间从两个来源检索订阅者数据:

  1. 首先,通过 Sh 接口从 HSS 检索静态配置
  2. 然后,通过 SS7 MAP 查询 HLR 以获取实时设置
  3. 合并数据,HLR 值优先于 Sh 值

这确保了即使 HSS 尚未更新,最近的���阅者更改(通过 USSD 代码)也会被尊重。

拨号计划变量

在 MT 呼叫中可用:

变量类型示例描述
call_forward_all_destination字符串"61412345678"CFU 目的号码
call_forward_not_reachable_destination字符串"61487654321"CFB/CFNRy/CFNRc 目的号码
no_reply_timer字符串"20"CFNRy 的超时时间(秒)

默认值:

  • 如果未配置:"none"(字符串)
  • 检查存在性:使用正则表达式 ^(?!none$).* 匹配任何值,除了 "none"

在 mt_dialplan.xml 中的呼叫转发

示例 1:无条件呼叫转发 (CFU)

立即将所有来电路由到转发目的地。转发目的地通常是一个非网号码,因此使用外部网关。

使用的网关: sofia/gateway/ExternalSIPGateway(您的 PSTN/互联网网关)

模板示例:

<extension name="Check-Call-Forward-All">
<condition field="${call_forward_all_destination}" expression="^(?!none$).*">
<action application="log" data="INFO Call Forward All Set to redirect to ${call_forward_all_destination}" />

<!-- 设置历史信息头以进行呼叫转发 -->
<action application="set" data="sip_h_History-Info=<sip:${destination_number}@${ims_domain}>;index=1.1" />

<!-- 标记呼叫 ID 以指示呼叫转发类型 -->
<action application="set" data="sip_call_id=${sip_call_id};CALL_FORWARD_UNCONDITIONAL" />

<!-- 桥接到非网转发目的地 -->
<action application="bridge"
data="{absolute_codec_string='AMR-WB,AMR,PCMA,PCMU',originate_retries=1,originate_timeout=60}sofia/gateway/ExternalSIPGateway/+${call_forward_all_destination}" />
</condition>
</extension>

关键点:

  • 使用外部网关,因为转发通常是到非网号码
  • ;CALL_FORWARD_UNCONDITIONAL 标记呼叫 ID 以便跟踪
  • 设置 History-Info 头以识别原始被叫号码
  • 示例:订阅者 61412345678 将 CFU 转发到 61487654321 - 所有呼叫立即转发

示例 2:无人接听/不可达呼叫转发

在桥接到主要目的地失败时作为回退使用(订阅者未接听、忙或不可达)。

示例拨号计划片段:

<!-- 在桥接到 MSRN 或 IMS 失败后... -->
<action application="log" data="INFO Failed to bridge Call - Routing to Call Forward No-Answer Destination" />

<!-- 设置历史信息以指示转发 -->
<action application="set" data="sip_h_History-Info=<sip:${destination_number}@${ims_domain}>;index=1.1" />

<!-- 路由到转发目的地 -->
<action application="bridge"
data="{absolute_codec_string='AMR,PCMU,PCMA',originate_timeout=65}sofia/gateway/ExternalSIPGateway/${call_forward_not_reachable_destination}" />

示例场景:

  • 订阅者 61412345678 将 CFNRy 转发到语音邮件号码 61487654321
  • 来电尝试联系订阅者
  • 20 秒后无人接听(no_reply_timer)
  • 呼叫转发到 61487654321,同时保留原始目的地的 History-Info 头

History-Info 头

History-Info SIP 头跟踪呼叫转发:

<action application="set" data="sip_h_History-Info=<sip:${destination_number}@${ims_domain}>;index=1.1" />

目的:

  • 指示呼叫原本是针对 ${destination_number}
  • 允许下游系统识别转发呼叫
  • 被语音邮件系统用于存储到正确的邮箱

语音邮件路由中的示例:

<extension name="Voicemail Route" continue="false">
<condition field="${tas_destination_number}" expression="^(555121|555122)$">
<!-- 从历史信息中提取电话号码 -->
<action application="set" data="history_info_value=${sip_i_history_info}"/>
<action application="log" data="DEBUG Called Voicemail Deposit Number for ${history_info_value}" />

<!-- 将语音邮件存储到原始被叫方,而不是语音邮件号码 -->
<action application="voicemail" data="default default ${history_info_value}"/>
</condition>
</extension>

工作原理:

  • 语音邮件服务号码: 555121555122(通用短代码)
  • 当呼叫转发到语音邮件时,History-Info 包含原始目的地
  • 语音邮件系统从 History-Info 头中提取原始号码
  • 语音邮件存储到原始被叫方的邮箱,而不是语音邮件服务号码

最佳实践

  1. 始终检查 "none" - 使用正则表达式 ^(?!none$).* 避免路由到字面字符串 "none"
  2. 设置历史信息 - 在转发时始终设置以进行适当的呼叫跟踪
  3. 使用 continue_on_fail - 允许在主要路由失败时回退到转发
  4. 调整 CLI 格式 - 国家与国际前缀格式化(参见来电 ID 部分)
  5. 测试转发循环 - 确保转发目的地不会创建路由循环

来电 ID(CLI)管理

TAS 在整个呼叫流程中管理来电线识别(CLI)的呈现和格式,处理隐私请求、前缀规范化和网络特定格式要求。

CLI 变量

拨号计划中的核心 CLI 变量:

变量用法示例
msisdn订阅者的号码(无 +)"61412345678"
effective_caller_id_number显示的来电号码"+61412345678""anonymous"
effective_caller_id_name显示的来电姓名"+61412345678""anonymous"
origination_caller_id_number外发腿的 CLI"+61412345678"
caller_id_number标准 FreeSWITCH CLI 变量"+61412345678"
sip_from_userSIP From 头部用户部分"0412345678""+61412345678"
cli_withheld隐私标志"true""false"(字符串)
origination_privacy隐私设置"hide_number"

CLI 隐私(隐藏/匿名)

检测方法

TAS 通过三种方法检测 CLI 隐私请求:

1. 拨号号码中的阻止前缀

订阅者在目的号码之前拨打前缀以阻止其来电 ID。

常见前缀:

  • *67 - 北美标准
  • #31# - 欧洲/GSM 标准
  • 1831 - 替代格式

TAS 检查拨号号码是否以任何配置的阻止 CLI 前缀开头。如果检测到,则将 cli_withheld 变量设置为 "true"

示例: 订阅者拨打 *67555 1234 - 检测到 *67 前缀并移除,呼叫继续到 5551234,CLI 被隐藏。

2. From 头中的匿名

用户设备(UE)在 SIP From 头中将来电姓名设置为 "anonymous"。

TAS 检查 Caller-Orig-Caller-ID-Name 字段(不区分大小写)是否包含字符串 "anonymous"。如果找到,则将 cli_withheld 设置为 "true"

3. SIP 隐私头

S-CSCF 可能在 SIP INVITE 中设置 Privacy: id 头,拨号计划会尊重这些设置。

拨号计划实施

拨号计划检查 cli_withheld 变量,并相应地设置所有与 CLI 相关的变量。

示例拨号计划片段:

<extension name="Manage-Caller-ID" continue="true">
<condition field="${cli_withheld}" expression="true">
<!-- CLI 被隐藏 - 设置为匿名 -->
<action application="log" data="DEBUG CLI withheld detected" />
<action application="set" data="effective_caller_id_name=anonymous" />
<action application="set" data="effective_caller_id_number=anonymous" />
<action application="set" data="origination_caller_id_number=anonymous" />
<action application="set" data="origination_privacy=hide_number" />

<!-- CLI 未被隐藏 - 使用正常的 MSISDN -->
<anti-action application="log" data="DEBUG CLI is normal (not withheld)" />
<anti-action application="set" data="effective_caller_id_number=${msisdn}" />
</condition>
</extension>

注意: 此扩展使用 continue="true",因此即使设置了 CLI,呼叫处理仍继续到路由扩展。

CLI 格式:国家与国际

不同的目的地可能根据您的网络要求需要不同的 CLI 格式。

示例:国家格式

对于国内呼叫,您可能需要呈现没有国家代码的 CLI。

示例拨号计划片段(澳大利亚移动网络):

<extension name="Outgoing-Call-CLI-National" continue="true">
<condition field="${msisdn}" expression="^61(.*)$">
<action application="log" data="Setting source CLI to $1 for national" />
<action application="set" data="effective_caller_id_number=$1"/> <!-- 0412345678 -->
<action application="set" data="effective_caller_id_name=$1"/>
<action application="set" data="sip_from_user=$1"/>
<action application="set" data="sip_cid_type=pid"/>
</condition>
</extension>

工作原理:

  • 正则表达式 ^61(.*)$ 捕获国家代码 61 之后的所有内容
  • 输入: msisdn="61412345678" → 输出: $1="412345678""0412345678"
  • 在国内呼叫中以国家格式呈现 CLI

示例:国际格式

对于国际呼叫,以完整的 E.164 格式呈现 CLI,并带有 + 前缀。

示例拨号计划片段:

<extension name="Outgoing-Call-CLI-International" continue="true">
<condition field="${tas_destination_number}" expression="^61(.*)$">
<action application="log" data="Call is to national" />

<!-- 反操作在目的地不是国家时运行 -->
<anti-action application="log" data="Setting source CLI for international" />
<anti-action application="set" data="effective_caller_id_number=+${msisdn}"/> <!-- +61412345678 -->
<anti-action application="set" data="effective_caller_id_name=+${msisdn}"/>
<anti-action application="set" data="sip_from_user=+${msisdn}"/>
<anti-action application="set" data="sip_cid_type=pid"/>
</condition>
</extension>

工作原理:

  • 条件检查目的地是否以国家前缀开头(例如,澳大利亚的 61
  • <anti-action> 在条件不匹配时执行(国际呼叫)
  • 为国际呼叫添加 + 前缀以获得完整的 E.164 格式

呼叫转发时的 CLI 格式

在路由到呼叫转发目的地时,您可能需要根据是转发到网内还是非网号码调整 CLI 格式。

示例:调整转发目的地的 CLI 前缀

<!-- 如果需要,调整 CLI 格式 -->
<action application="set" data="effective_caller_id_number=${effective_caller_id_number:3}"/>
<action application="set" data="effective_caller_id_name=${effective_caller_id_name:3}"/>

字符串切片: ${variable:N} 移除前 N 个字符

  • 输入: effective_caller_id_number="+61412345678":3 → 输出: "412345678"
  • 输入: effective_caller_id_number="+61412345678":1 → 输出: "61412345678"

用例:

  • 删��� + 以进行国家转发:使用 :1
  • 删除国家代码以进行本地格式:使用适当的偏移量(+61:3+1:2 等)

SIP P-Asserted-Identity (PAI)

sip_cid_type=pid 设置控制如何呈现来电 ID:

<action application="set" data="sip_cid_type=pid"/>

效果:

  • 设置 SIP P-Asserted-Identity 头部,包含来电信息
  • 用于 IMS 网络的受信网络来电 ID 断言
  • IMS 网络的标准

移除专有头

为了防止泄露内部网络信息,拨号计划应在将呼叫路由到非网之前移除专有或内部头。

示例:在外部路由之前清理头

<action application="set" data="sip_copy_multipart=false"/>
<action application="set" data="sip_copy_custom_headers=false"/>
<action application="unset" data="sip_h_P-Internal-Correlation-ID"/>
<action application="unset" data="sip_h_P-Access-Network-Info"/>
<!-- 根据需要添加更多供应商特定或内部头 -->

目的:

  • 防止内部路由数据到达外部网络
  • 移除供应商特定的专有头
  • 隐私和安全最佳实践
  • 减少 SIP 消息大小

常见需要移除的头:

  • 内部关联/跟踪 ID
  • 访问网络信息(可能泄露网络拓扑)
  • 供应商特定的 P 头
  • 仅供内部使用的自定义应用头

最佳实践

  1. 在 CLI 扩展中使用 continue="true" - 允许多个 CLI 格式规则
  2. 设置 sip_cid_type=pid - IMS 网络合规所需
  3. 测试 CLI 隐藏 - 验证 *67#31# 前缀是否有效
  4. 根据目的地格式化 - 国家与国际 CLI 格式化
  5. 移除专有头 - 防止内部数据泄露
  6. 优雅处理匿名 - 显示和路由应与匿名 CLI 一起工作

桥接到网关

TAS 使用 FreeSWITCH 的 bridge 应用程序将呼叫桥接到外部网关(IMS 核心、PSTN 等),并仔细配置编解码器协商、超时处理和重试逻辑的参数。

网关配置

网关被配置为 SIP 中继到外部系统。TAS 使用单一 SIP 接口处理所有流量,为不同目的地定义不同的网关。

示例网关配置:

<gateway name="CS_Gateway">
<param name="proxy" value="10.1.1.100:5060"/>
<param name="register" value="false"/>
<param name="caller-id-in-from" value="true"/>
<param name="extension-in-contact" value="true"/>
</gateway>

请参见 配置指南 以获取完整的网关设置。

桥接语法

呼叫通过以下语法桥接到网关:

基本语法:

<action application="bridge" data="sofia/gateway/GATEWAY_NAME/DESTINATION_NUMBER" />

带参数:

<action application="bridge" data="{param1=value1,param2=value2}sofia/gateway/GATEWAY_NAME/DESTINATION_NUMBER" />

其中 GATEWAY_NAME 是您在配置中定义的网关名称(例如,IMS_CorePSTN_PrimaryInternational_Gateway)。

桥接参数

编解码器选择

absolute_codec_string - 优先编解码器列表以进行协商:

<action application="bridge" data="{absolute_codec_string='AMR,PCMA,PCMU'}sofia/gateway/IMS_Gateway/+${msisdn}" />

编解码器优先级顺序:

  1. AMR(自适应多速率) - 移动优化,优先用于蜂窝
  2. PCMA(G.711 a-law) - 欧洲/国际固定线路标准
  3. PCMU(G.711 μ-law) - 北美固定线路标准

模板使用: priv/templates/mt_dialplan.xml:80mo_dialplan.xml:124mo_dialplan.xml:202

超时配置

originate_timeout - 等待应答的最大秒数(包括响铃):

<action application="set" data="originate_timeout=60"/>
<action application="bridge" data="{originate_timeout=60}sofia/gateway/CS_Gateway/+${msisdn}" />

progress_timeout - 等待 180/183(早期媒体/响铃)的秒数:

<action application="set" data="progress_timeout=10" />

bridge_answer_timeout - 在响铃开始后等待 200 OK 的秒数:

<action application="set" data="bridge_answer_timeout=${no_reply_timer}" />

leg_progress_timeout - 每条腿的进度超时:

<action application="set" data="leg_progress_timeout=${no_reply_timer}" />

模板示例: priv/templates/mt_dialplan.xml:73-76

<action application="set" data="progress_timeout=10" />
<!-- 我们在 INVITE 和 200 OK 之间等待多长时间(包括响铃) -->
<action application="set" data="bridge_answer_timeout=${no_reply_timer}" />
<action application="set" data="leg_progress_timeout=${no_reply_timer}" />

变量: ${no_reply_timer} 来自订阅者数据(通常为 20-30 秒)

重试和失败处理

originate_retries - 重试尝试的次数:

<action application="bridge" data="{originate_retries=1}sofia/gateway/CS_Gateway/+${msisdn}" />

continue_on_fail - 在桥接失败后继续拨号计划执行:

<action application="set" data="continue_on_fail=true" />
<action application="bridge" data="{continue_on_fail=true}sofia/gateway/CS_Gateway/+${msisdn}" />
<!-- 如果桥接失败,后续操作执行 -->
<action application="log" data="INFO Bridge failed - routing to voicemail" />

hangup_after_bridge - 当 B-leg 挂断时挂断 A-leg:

<action application="set" data="hangup_after_bridge=true"/>

早期媒体处理

ignore_early_media - 控制早期媒体行为:

<action application="set" data="ignore_early_media=ring_ready" />
<action application="bridge" data="{ignore_early_media=ring_ready}sofia/gateway/CS_Gateway/+${msisdn}" />

选项:

  • ring_ready - 生成本地响铃,忽略远程早期媒体
  • true - 完全忽略早期媒体
  • false(默认) - 通过早期媒体(公告、音调)

为什么使用 ring_ready - 防止呼叫者听到来自远程网络的公告或音调

模板示例: priv/templates/mt_dialplan.xml:78-79

<action application="set" data="ignore_early_media=ring_ready" />
<action application="bridge" data="{ignore_early_media=ring_ready,...}sofia/gateway/CS_Gateway/+${msrn}" />

网内与非网呼叫者处理:

<extension name="Route-to-IMS-Sub-Early-Media" continue="true">
<condition field="${on_net_caller}" expression="true">
<!-- 网内呼叫者 - 使用 ring_ready -->
<action application="log" data="INFO On-net caller ${effective_caller_id_number} - using ignore_early_media=ring_ready"/>
<action application="set" data="ignore_early_media=ring_ready"/>

<!-- 非网呼叫者 - 提供即时响铃 -->
<anti-action application="log" data="INFO Off-net caller ${effective_caller_id_number} - setting instant ringback"/>
<anti-action application="set" data="instant_ringback=true"/>
<anti-action application="set" data="ringback=${fr-ring}"/>
<anti-action application="set" data="transfer_ringback=${fr-ring}"/>
</condition>
</extension>

注意: ${on_net_caller} 变量根据您的网络的订阅者编号计划设置。您还可以使用正则表达式模式来匹配您的特定号码范围。

来电 ID 参数

sip_cid_type=pid - 使用 P-Asserted-Identity 进行来电 ID:

<action application="set" data="sip_cid_type=pid" />
<action application="bridge" data="{sip_cid_type=pid}sofia/gateway/CS_Gateway/+${msisdn}" />

常见桥接模式

模式 1:通过 IMS 域路由到 IMS 订阅者

将 MT 呼叫路由到 IMS 订阅者,通过 IMS 域发送(S-CSCF 将解析并路由)。

模板示例:

<extension name="Route-to-IMS-Sub" continue="false">
<condition field="destination_number" expression="^(.*)$">
<action application="set" data="continue_on_fail=true" />
<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="progress_timeout=10" />

<!-- 我们在 INVITE 和 200 OK 之间等待多长时间(包括响铃) -->
<action application="set" data="bridge_answer_timeout=${no_reply_timer}" />
<action application="set" data="leg_progress_timeout=${no_reply_timer}" />

<!-- 将呼叫发送到 IMS 域(S-CSCF 解析) -->
<action application="set" data="ignore_early_media=ring_ready" />
<action application="set" data="sip_cid_type=pid" />

<action application="bridge"
data="{absolute_codec_string='AMR-WB,AMR,PCMA,PCMU',ignore_early_media=ring_ready,continue_on_fail=true,sip_cid_type=pid,originate_retries=1,originate_timeout=${no_reply_timer},sip_invite_call_id=${sip_call_id}}sofia/internal/${msisdn}@${ims_domain}" />

<!-- 如果桥接失败,提供呼叫转发 -->
<action application="log" data="INFO Failed to bridge Call - Routing to Call Forward No-Answer Destination" />
<action application="set" data="sip_h_History-Info=<sip:${destination_number}@${ims_domain}>;index=1.1" />
<action application="set" data="sip_h_Diversion=<sip:${destination_number:2}@${ims_domain}>;reason=busy" />

<!-- 路由到非网网关进行呼叫转发 -->
<action application="bridge"
data="{absolute_codec_string='AMR-WB,AMR,PCMU,PCMA',originate_timeout=65,originate_retries=0}sofia/gateway/ExternalSIPGateway/${call_forward_not_reachable_destination}" />
</condition>
</extension>

关键点:

  • 路由到 ${msisdn}@${ims_domain}(例如,5551234567@ims.mnc380.mcc313.3gppnetwork.org
  • IMS 核心(S-CSCF/I-CSCF)处理最终路由到订阅者
  • ignore_early_media=ring_ready 提供一致的响铃
  • 失败时使用外部网关进行非网呼叫转发
  • 设置 History-InfoDiversion 头以进行呼叫转发跟踪

模式 2:路由到 MSRN(CS 漫游)

通过 CS 网络路由到漫游订阅者:

模板: priv/templates/mt_dialplan.xml:67-80

<extension name="Route-to-CS-MSRN" continue="false">
<condition field="msrn" expression="^(\d+)$">
<action application="set" data="continue_on_fail=true" />
<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="progress_timeout=10" />
<action application="set" data="bridge_answer_timeout=${no_reply_timer}" />
<action application="set" data="leg_progress_timeout=${no_reply_timer}" />

<!-- 将呼叫发送到 MSRN 通过网关 -->
<action application="set" data="ignore_early_media=ring_ready" />
<action application="set" data="sip_cid_type=pid" />
<action application="bridge"
data="{ignore_early_media=ring_ready,absolute_codec_string='AMR,PCMA,PCMU',continue_on_fail=true,sip_cid_type=pid,originate_retries=1,originate_timeout=60}sofia/gateway/CS_Gateway/+${msrn}" />
</condition>
</extension>

模式 3:网内路由(MO 到 MT 通过 TAS)

当订阅者呼叫另一位网内订阅者时,呼叫必须路由回 TAS 进行完整的 MT 处理。此模式对于确保网内呼叫获得与外部 MT 呼叫相同的服务处理至关重要。

为什么需要此模式:

如果不路由回 TAS,网内呼叫将完全绕过 MT 处理,意味着:

  • 呼叫转移设置将不被尊重
  • 无法在无人接听时转移到语音邮件
  • 漫游订阅者的 MSRN 路由将失败
  • 跳过订阅者服务逻辑
  • 呼叫跟踪和 CDR 将不完整

通过将 MO 呼叫路由回 TAS 作为新的 MT 呼叫,被叫订阅者获得完整的服务处理。

模板示例:

<extension name="On-Net-Route">
<condition field="${on_net_status}" expression="true">
<action application="log" data="DEBUG On-Net MO call - Routing back into TAS" />

<!-- 清理内部路由的头部 -->
<action application="set" data="sip_copy_multipart=false"/>
<action application="set" data="sip_h_Request-Disposition=no-fork"/>

<!-- 路由回 TAS(变为 MT 呼叫) -->
<action application="bridge"
data="{absolute_codec_string='AMR-WB,AMR,PCMA,PCMU',originate_retries=1,originate_timeout=60,sip_invite_call_id=${sip_call_id}}sofia/internal/${tas_destination_number}@${sip_local_network_addr}" />
<action application="hangup" data="" />
</condition>
</extension>

工作原理:

  1. MO 呼叫到达:订阅者 A 呼叫订阅者 B(均在网内)
  2. 检查网内状态:TAS 确定目的地在网内,通过 ${on_net_status} 变量
  3. 路由到 TAS:桥接到 sofia/internal/${tas_destination_number}@${sip_local_network_addr}
    • 使用 TAS 自身的 IP 地址作为目的地
    • 保留原始呼叫 ID 以便跟踪
  4. MT 处理:TAS 将呼叫视为新的 MT 呼叫,并处理 mt_dialplan.xml
    • 检查呼叫转移设置(CFU、CFB、CFNRy、CFNRc)
    • 查询 MSRN 如果订阅者在漫游中
    • 适当的路由到 IMS 域或转发
  5. 完整服务:被叫订阅者获得完整的 MT 处理

关键点:

  • 路由到 ${sip_local_network_addr}(TAS IP 地址,例如 10.179.3.60
  • 呼叫作为新的 MT 呼叫重新处理到目的订阅者
  • 使用 sip_invite_call_id 参数保留呼叫 ID 以便进行端到端跟踪
  • 启用所有 MT 特性:呼叫转移、语音邮件、MSRN 路由、订阅者服务
  • 对双方进行正确的呼叫状态跟踪和 CDR 生成
  • 网内呼叫获得与外部 MT 呼叫相同的服务处理
  • TAS IP 必须在 allowed_sbc_source_ips 配置列表中

变量: ${on_net_status} 在目的号码由您的 TAS 提供时设置为 "true"。这在 MO 呼叫授权期间通过检查目的 MSISDN 是否存在于您的订阅者数据库中确定。

模式 4:非网路由(MO 到 PSTN/外部)

将 MO 呼叫路由到外部 PSTN、互联或其他外部网络通过网关。

使用的网关: sofia/gateway/ExternalSIPGatewaysofia/gateway/PSTN_Gateway

模板示例:

<extension name="Outgoing-Call-Off-Net">
<condition field="${tas_destination_number}" expression="^(.*)$">
<action application="log" data="Sending call off-net" />

<!-- 在外部路由之前清理头 -->
<action application="set" data="sip_copy_multipart=false"/>

<!-- 设置呼叫事件钩子以进行 CDR/计费 -->
<action application="set" data='api_body=caller=${msisdn}&called=${tas_destination_number}&call-id=${sip_i_call_id}&action=answer'/>
<action application="set" data='api_on_answer=curl http://localhost:8080/call_event content-type application/x-www-form-urlencoded post ${api_body}'/>
<action application="set" data='api_body=caller=${msisdn}&called=${tas_destination_number}&call-id=${sip_i_call_id}&action=hangup'/>
<action application="set" data='api_hangup_hook=curl http://localhost:8080/call_event content-type application/x-www-form-urlencoded post ${api_body}'/>

<!-- 为受信网络设置 P-Asserted-Identity -->
<action application="set" data="sip_h_Request-Disposition=no-fork"/>
<action application="set" data="sip_h_P-Asserted-Identity=<sip:${msisdn}@${ims_domain}>"/>

<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="continue_on_fail=true"/>

<!-- 桥接到外部 PSTN/互联网网关 -->
<action application="set" data="used_gateway=ExternalSIPGateway"/>
<action application="bridge"
data="{absolute_codec_string='AMR-WB,AMR,PCMA,PCMU',originate_retries=1,originate_timeout=60,sip_invite_call_id=${sip_call_id}}sofia/gateway/ExternalSIPGateway/${tas_destination_number}" />

<!-- 如果桥接失败,提供错误处理 -->
<action application="answer" data="" />
<action application="log" data="INFO Bridge failed with SIP code ${last_bridge_proto_specific_hangup_cause}"/>
<action application="sleep" data="500"/>
<action application="transfer" data="${last_bridge_proto_specific_hangup_cause}"/>
</condition>
</extension>

关键点:

  • 使用 sofia/gateway/ExternalSIPGateway 进行外部路由
  • 在受信互联网上为来电 ID 设置 P-Asserted-Identity
  • 呼叫事件钩子用于 CDR/计费跟踪
  • continue_on_fail=true 允许错误处理
  • 失败时根据 SIP 代码转移到错误公告

常见的非网网关:

  • ExternalSIPGateway - 主要 PSTN 中继/互联
  • BackupSIPGateway - 备用 PSTN 中继(用于故障转移)
  • International_GW - 国际呼叫网关
  • Emergency_GW - 紧急服务网关

网关路由策略

所有呼叫都通过网关路由。了解在不同呼叫场景中使用哪个网关对于正确的呼叫路由至关重要:

网内与非网决策树