Маршрутизация по DID номеру

Введение

При настройке входящей маршрутизации часто возникает ситуация, когда провайдер предоставляет учетную одну запись SIP для нескольких купленных номеров телефонов.

К примеру у МИКО есть номера телефонов:

  • +7(495)229-30-42

  • +7(499)638-25-84

В интерфейсе MikoPBX создана только одна учетная запись «Провайдер телефонии». Каждый номер телефона необходимо направить на свой маршрут, к примеру на различные IVR.

Тут к приходит на помощь DID номер, который провайдер может передавать при входящих звонках. Зная DID номер, можно для провайдера описать несколько входящие маршрутов, с различными DID, что позволит решить описанную выше задачу.

Как это работает

Для анализа звонков я обычно использую «приложение Sngrep». Вот пример запроса от провайдера при входящем:

INVITE sip:84996382584@93.188.XX.XX SIP/2.0
Via: SIP/2.0/UDP 81.88.86.65:5060;branch=z9hG4bK1cf7.16247c44.0;cid=2
Max-Forwards: 67
Contact: <sip:81.88.86.65>
To: <sip:84996382584@93.188.XX.XX>
From: "79260577653"<sip:79260577653@mangosip.ru>;tag=5e1a5a28
Call-ID: JUm-E_ISk4DPaL8Npv2Hlw..
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, UPDATE, UPDATE, INFO, REFER, MESSAGE
Content-Type: application/sdp
Supported: replaces
User-Agent: Softswitch3
Content-Length: 351

При получении такого пакета, MikoPBX проанализирует первую строку с ключевым словом «INVITE», значение «84996382584» и будет являться DID номером.

Возможные особенности

DID в заголовке To

На практике, не всегда все так просто. К примеру я встречал провайдера, который присылает следующий INVITE:

INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 81.88.86.65:5060;branch=z9hG4bK1cf7.16247c44.0;cid=2
Max-Forwards: 67
Contact: <sip:81.88.86.65>
To: <sip:[email protected]>
From: "79260577653"<sip:[email protected]>;tag=5e1a5a28
Call-ID: JUm-E_ISk4DPaL8Npv2Hlw..
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, UPDATE, UPDATE, INFO, REFER, MESSAGE
Content-Type: application/sdp
Supported: replaces
User-Agent: Softswitch3
Content-Length: 351

В этом случае в строке «INVITE» описывается логин учетной записи, в вот DID уже описывается в заголовке «». Для корректной настройки достаточно в разделе Кастомизация системных файлов добавить в конец файла «extensions.conf» следующие строки:

[SIP-1622040384-incoming-custom]
exten => _[0-9*#+a-zA-Z][0-9*#+a-zA-Z]!,1,NoOp(------)
	same => n,Set(toNum=${PJSIP_PARSE_URI(${PJSIP_HEADER(read,To)},user)})
	same => n,ExecIf($["${toNum}" != "${EXTEN}"]?Goto(${CUT(CONTEXT,,1-3)},${toNum},1))
	same => n,return
  • функция «PJSIP_HEADER» считывает значение заголовка «To»

  • функция «PJSIP_PARSE_URI» получает из значения заголовка поле «user», которое соответствует значению DID

  • Goto перемещает канал в начало, для повторной инициализации маршрута

  • "1-3" - означает, что нужно взять первые три слова из "SIP-1622040384-incoming-custom", по сути, нужно из этой строки получить все до "-custom", в старых версиях АТС может потребоваться скорректировать это правило

  • SIP-1622040384 - это ID учетной записи провайдера MikoPBX, можно подсмотреть в адресной строке браузера при редактировании учетной записи

Код для решения проблемы

Замена DID на произвольный

Следующий пример удобно применять, когда провайдер не предоставляет информации по номеру, на который пришел вызов, поступает информация только о логине. При этом, важно, чтобы одному логину соответствовал один DID.

[add-trim-prefix-clid-custom]
exten => user1,1,Goto(SIP-1622040384-incoming,74952293042,1)
exten => admin,1,Goto(SIP-1622040000-incoming,74952291111,1)

exten => _[0-9*#+a-zA-Z]!,2,return
  • "user1" и "admin" - это примеры популярных логин

Установить CID на основании DID

[add-trim-prefix-clid-custom]
exten => _[0-9*#+a-zA-Z][0-9*#+a-zA-Z]!,1,NoOp(...)
	same => n,GosubIf($["${DIALPLAN_EXISTS(did-from-cid-map,${EXTEN},1)}" == "1"]?cid-from-did-map,${EXTEN},1)
	same => n,return
[cid-from-did-map]
exten => 74952293042,1,Set(CALLERID(name)=Sales)
exten => 74952291111,1,Set(CALLERID(name)=Support)

exten => _[0-9*#+a-zA-Z]!,2,return
  • Если вызов поступен на номер 74952293042, то CID (name) будет установлен в значение Sales

  • Если вызов поступен на номер 74952291111, то CID (name) будет установлен в значение Support

DID произвольном заголовке

Такое встречается при использовании сервиса roistat. Сервис при входящем может прислать следующий запрос:

INVITE sip:[email protected] SIP/2.0
Via: SIP/2.0/UDP 81.88.86.65:5060;branch=z9hG4bK1cf7.16247c44.0;cid=2
Max-Forwards: 67
Contact: <sip:81.88.86.65>
To: <sip:[email protected]>
From: "79260577653"<sip:[email protected]>;tag=5e1a5a28
Call-ID: JUm-E_ISk4DPaL8Npv2Hlw..
CSeq: 1 INVITE
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, UPDATE, UPDATE, INFO, REFER, MESSAGE
Content-Type: application/sdp
Supported: replaces
User-Agent: Softswitch3
x-roistat-phone: 84996382584
Content-Length: 351

Корректного DID нет ни в INVITE, ни в поле To, но при этом появился новый заголовок «x-roistat-phone».

Для корректной настройки достаточно в разделе Кастомизация системных файлов добавить в конец файла «extensions.conf» следующие строки:

[SIP-1622040384-incoming-custom]
exten => _[0-9*#+a-zA-Z][0-9*#+a-zA-Z]!,1,NoOp(------)
	same => n,Set(toNum=${PJSIP_HEADER(read,x-roistat-phone)})
	same => n,ExecIf($["${toNum}x" != "x" && "${toNum}" != "${EXTEN}"]?Goto(${CUT(CONTEXT,,1-3)},${toNum},1))
	same => n,return
  1. функция «PJSIP_HEADER» считывает значение заголовка «x-roistat-phone»

  2. Goto перемещает канал в начало, для повторной инициализации маршрута

Манго офис

Получение номера, на который позвонил клиент из поля «Diversion»:

[SIP-1622040384-incoming-custom]
exten => _[0-9*#+a-zA-Z][0-9*#+a-zA-Z]!,1,NoOp(------)
	same => n,Set(tmpDiversion=${PJSIP_HEADER(read,Diversion)})
	same => n,ExecIf($["x${tmpDiversion}" != "x"]?Set(toNum=${CUT(CUT(tmpDiversion,>,1),:,2)}))
	same => n,ExecIf($["${toNum}x" != "x" && "${toNum}" != "${EXTEN}"]?Goto(${CUT(CONTEXT,,1-3)},${toNum},1))
	same => n,return
	

Более универсальный вариант:

[add-trim-prefix-clid-custom]
exten => _[0-9*#+a-zA-Z][0-9*#+a-zA-Z]!,1,NoOp(------)
	same => n,Set(tmpDiversion=${PJSIP_HEADER(read,Diversion)})
	same => n,ExecIf($["x${tmpDiversion}" != "x"]?Set(toNum=${CUT(CUT(tmpDiversion,@,1),:,2)}))
	same => n,ExecIf($["${toNum}x" != "x" && "${toNum}" != "${EXTEN}"]?Goto(${contextID},${toNum},1))
	same => n,return

Novafon (zadarma)

Получение номера, на который позвонил клиент из заголовка «CALLED_DID»:

[SIP-1622040384-incoming-custom]
exten => _[0-9*#+a-zA-Z][0-9*#+a-zA-Z]!,1,NoOp(------)
	same => n,Set(toNum=${PJSIP_HEADER(read,CALLED_DID)})
	same => n,ExecIf($["${toNum}x" != "x" && "${toNum}" != "${EXTEN}"]?Goto(${CUT(CONTEXT,,1-3)},${toNum},1))
	same => n,return

Last updated

Was this helpful?