При настройке SIP-транка Beeline в 3CX можно столкнуться со следующей ситуацией:
Входящие звонки поступают на АТС и исходящие совершаются, при этом ошибок авторизации нет.
В журнале событий 3CX периодически появляется сообщение:
"Unidentified Incoming Call. Review INVITE and adjust source identification: INVITE sip:XXXXXX@1.1.1.1.:5060;user=phone SIP/2.0 Via: SIP/2.0/UDP 9.9.9.9:5060;branch=z9hG4bKzppu1z3414z0l5p5uf5qsr3rr;Role=3;Hpt=8eb8_16;TRC=ffffffff-ffffffff Max-Forwards: 69 Record-Route: <sip:9.9.9.9:5060;transport=udp;lr;Hpt=8eb8_16;CxtId=4;TRC=ffffffff-ffffffff;X-HwB2bUaCookie=10374> Contact: <sip:12345678@9.9.9.9:5060;transport=udp;Hpt=8eb8_16;CxtId=4;TRC=ffffffff-ffffffff> To: <sip:12345678@1.1.1.1.1;user=phone> From: <sip:12345678@9.9.9.9;user=phone>;tag=ilajpovw-CC-22 Call-ID: isbcmokipouwnnmmowopnojh9vmhxhwlj9ja@SoftX3000 CSeq: 1 INVITE Session-Expires: 300 Min-SE: 90 Allow: INVITE, ACK, OPTIONS, BYE, CANCEL, REGISTER, INFO, PRACK, SUBSCRIBE, NOTIFY, UPDATE, MESSAGE, REFER Content-Type: application/sdp Supported: 100rel, timer User-Agent: Huawei SoftX3000 V300R011 Diversion: <sip:XXXXXXXXXX@2.2.2.2;user=phone>;reason=unknown;counter=1 Content-Length: 326 v=0 o=- 21233080 21233081 IN IP4 9.9.9.9 s=SBC call c=IN IP4 9.9.9.9 t=0 0 m=audio 49096 RTP/AVP 8 0 18 4 2 97 a=rtpmap:8 PCMA/8000 a=rtpmap:0 PCMU/8000 a=rtpmap:18 G729/8000 a=rtpmap:4 G723/8000 a=rtpmap:2 G726-32/8000 a=rtpmap:97 telephone-event/8000 a=ptime:20 a=fmtp:97 0-15 a=fmtp:18 annexb=no
"
3CX не может корректно сопоставить номер вызывающего абонента или номер, на который совершается вызов, и отсылает вызов на первое правило маршрутизации входящих линий (по умолчанию).
Причина в том, что шаблон Beeline, расположенный по умолчанию в каталоге:
/var/lib/3cxpbx/Instance1/Data/Http/Templates/provider/beeline.pv.xml
использует устаревшую переменную $ContactURI и не содержит дополнительной настройки ToUserPart в Source Identification. Из-за этого 3CX неверно интерпретирует поступающие номера или не может их правильно «увидеть», особенно если провайдер передаёт номер в 10-значном формате (без 8 или +7).
1. Оригинальный (старый) фрагмент файла beeline.pv.xml
В стандартном варианте строка с ContactHost выглядит так:
<field name="ParameterOut" custom="" parameter="ContactHost">$ContactURI</field>
а в секции Source Identification нет параметра ToUserPart.
Ниже приведён примерный фрагмент кода (внутри файла много других строк, но ключевые показаны здесь):
<?xml version="1.0"?>
<doc xmlns:tcx="http://www.3cx.com">
<header>
<type>gateway-template</type>
<version>150003</version>
<time>2023-01-26 16:00:00</time>
<name>Beeline MPBX IP-Based</name>
<url>https://www.3cx.ru/docs/manual/sip-trunks/</url>
<description>RU</description>
<priority>2</priority>
<tags>registrar,port</tags>
<templatetype>dedicated</templatetype>
</header>
<data>
<device>
<type>provider</type>
<manufacturer>Beeline MPBX IP-Based</manufacturer>
<model>Provider</model>
<!-- Friendly Name -->
<field name="Name">Beeline MPBX IP-Based</field>
<!-- Hostnames and Port Numbers -->
<field name="RegistrarHost">[Enter Registrar provided to you by Beeline]</field>
<field name="RegistrarPort">5060</field>
<field name="ProxyHost"></field>
<field name="ProxyPort">5060</field>
<!-- Registration Settings -->
<field name="LineAuthenticationPassword" status="readonly"></field>
<field name="TimeBetweenRegistration">180</field>
<field name="RequireAuthFor">1</field>
<field name="IpInContactReg">1</field>
<field name="IpInContactRegValue"></field>
<field name="3wayauthenticationid" status="readonly"></field>
<!-- Provider Capabilities -->
<field name="IsSupportReinvite">0</field>
<field name="IsSupportReplaces">0</field>
<field name="DisableVideo">1</field>
<field name="RegistrarInvite">1</field>
<!-- Location of Destination Number -->
<field name="DestNumberIn_TO">1</field>
<field name="DestNumberIn_REQLINEURI">1</field>
<field name="DestNumberIn_RPID_CALLED">0</field>
<!-- Other Options -->
<field name="IPRestriction">IPV4</field>
<field name="TransportRestriction">UDP</field>
<field name="SecondaryRegistrar"></field>
<field name="IsBindToMS">1</field>
<field name="UseIPInContact">0</field>
<field name="CallerIDIn">1</field>
<field name="CalledNumberIn">2</field>
<codecs>
<codec rfcname="pcma"/>
<codec rfcname="pcmu"/>
<codec rfcname="g729"/>
</codecs>
<!-- Source Identification -->
<field status="readonly" name="MatchStrategy">0</field>
<field status="readonly" name="Source" parameter="ContactHost" custom="">$GWHostPort</field>
<!-- Параметра "Source" с ToUserPart нет -->
<!-- Gateway / Provider Inbound Parameters -->
<field name="ParameterIn" custom="" parameter="ToUserPart">$CalledNum</field>
<field name="ParameterIn" custom="" parameter="FromUserPart">$CallerNum</field>
<field name="ParameterIn" custom="" parameter="FromDisplayName">$CallerName</field>
<!-- Gateway / Provider Outbound Parameters -->
<field name="ParameterOut" custom="" parameter="RequestLineURIUser">$CalledNum</field>
<field name="ParameterOut" custom="" parameter="RequestLineURIHost">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="ContactUser">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="ContactHost">$ContactURI</field> <!-- СТАРАЯ СТРОКА -->
<field name="ParameterOut" custom="" parameter="ToDisplayName">$CalledName</field>
<field name="ParameterOut" custom="" parameter="ToUserPart">$CalledNum</field>
<field name="ParameterOut" custom="" parameter="ToHostPart">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="FromDisplayName">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="FromUserPart">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="FromHostPart">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="P-AssertedIdentityDisplayName">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="P-AssertedIdentityUserPart">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="P-AssertedIdentityHostPart">$GWHostPort</field>
</device>
</data>
</doc>
В таком виде 3CX может неправильно определять номер вызывающего абонента и/или Called Number, что приводит к ошибке Unidentified Incoming Call.
2. Исправленный фрагмент файла beeline.pv.xml
Для корректной работы входящей маршрутизации нужно изменить (или добавить) следующие настройки:
Заменить \$ContactURI на \$GWHostPort в строке ContactHost.
Добавить поле ToUserPart в секцию Source Identification.
Переключить DestNumberIn_REQLINEURI в 0, если необходимо извлекать Called Number только из поля To.
Пример обновлённого файла (фрагмент):
<?xml version="1.0"?>
<doc xmlns:tcx="http://www.3cx.com">
<header>
<type>gateway-template</type>
<version>150003</version>
<time>2023-01-26 16:00:00</time>
<name>Beeline MPBX IP-Based</name>
<url>https://www.3cx.ru/docs/manual/sip-trunks/</url>
<description>RU</description>
<priority>2</priority>
<tags>registrar,port</tags>
<templatetype>dedicated</templatetype>
</header>
<data>
<device>
<type>provider</type>
<manufacturer>Beeline MPBX IP-Based</manufacturer>
<model>Provider</model>
<!-- Friendly Name -->
<field name="Name">Beeline MPBX IP-Based</field>
<!-- Hostnames and Port Numbers -->
<field name="RegistrarHost">[Enter Registrar provided to you by Beeline]</field>
<field name="RegistrarPort">5060</field>
<field name="ProxyHost"></field>
<field name="ProxyPort">5060</field>
<!-- Registration Settings -->
<field name="LineAuthenticationPassword" status="readonly"></field>
<field name="TimeBetweenRegistration">180</field>
<field name="RequireAuthFor">1</field>
<field name="IpInContactReg">1</field>
<field name="IpInContactRegValue"></field>
<field name="3wayauthenticationid" status="readonly"></field>
<!-- Provider Capabilities -->
<field name="IsSupportReinvite">0</field>
<field name="IsSupportReplaces">0</field>
<field name="DisableVideo">1</field>
<field name="RegistrarInvite">1</field>
<!-- Location of Destination Number -->
<field name="DestNumberIn_TO">1</field>
<field name="DestNumberIn_REQLINEURI">0</field> <!-- Извлекаем номер только из поля To -->
<field name="DestNumberIn_RPID_CALLED">0</field>
<!-- Other Options -->
<field name="IPRestriction">IPV4</field>
<field name="TransportRestriction">UDP</field>
<field name="SecondaryRegistrar"></field>
<field name="IsBindToMS">1</field>
<field name="UseIPInContact">0</field>
<field name="CallerIDIn">1</field>
<field name="CalledNumberIn">2</field>
<codecs>
<codec rfcname="pcma"/>
<codec rfcname="pcmu"/>
<codec rfcname="g729"/>
</codecs>
<!-- Source Identification -->
<field status="readonly" name="MatchStrategy">0</field>
<!-- Добавляем строку "Source" с параметром="ToUserPart" -->
<field status="readonly" name="Source" parameter="ToUserPart" custom="">$ToUserPart</field>
<!-- Gateway / Provider Inbound Parameters -->
<field name="ParameterIn" custom="" parameter="ToUserPart">$CalledNum</field>
<field name="ParameterIn" custom="" parameter="FromUserPart">$CallerNum</field>
<field name="ParameterIn" custom="" parameter="FromDisplayName">$CallerName</field>
<!-- Gateway / Provider Outbound Parameters -->
<field name="ParameterOut" custom="" parameter="RequestLineURIUser">$CalledNum</field>
<field name="ParameterOut" custom="" parameter="RequestLineURIHost">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="ContactUser">$OutboundCallerId</field>
<!-- Заменяем $ContactURI на $GWHostPort -->
<field name="ParameterOut" custom="" parameter="ContactHost">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="ToDisplayName">$CalledName</field>
<field name="ParameterOut" custom="" parameter="ToUserPart">$CalledNum</field>
<field name="ParameterOut" custom="" parameter="ToHostPart">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="FromDisplayName">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="FromUserPart">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="FromHostPart">$GWHostPort</field>
<field name="ParameterOut" custom="" parameter="P-AssertedIdentityDisplayName">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="P-AssertedIdentityUserPart">$OutboundCallerId</field>
<field name="ParameterOut" custom="" parameter="P-AssertedIdentityHostPart">$GWHostPort</field>
</device>
</data>
</doc>
Итог: после подобных изменений 3CX корректно обрабатывает входящие вызовы, определяя Called Number из поля To и сопоставляя его с DID в 6-значном или каком-либо ином требуемом формате. Ошибка Unidentified Incoming Call исчезает, и маршруты входящих звонков начинают работать правильно.