Маршрутизация по 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:mikoteam@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

В этом случае в строке «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:mikoteam@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:mikoteam@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
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