Настройки SMPP подключения к SMSC в Kannel

В этой статье я хочу описать опции, которые используются в SMS-шлюзе Kannel при настройке подключний к SMSC по протоколу SMPP.

Минимальная конфигурация выглядит примерно так:

group = smsc
smsc = smpp
host = 10.11.12.13
port = 9876
smsc-username = customer
smsc-password = topsecret
system-type = "VMA"

Как можно заметить, ничего принципиально непонятного:

  • Общие реквизиты (группа - smsc; тип SMSC - smpp)
  • Куда подключаться (host, port)
  • Аутентификация (smsc-username, smsc-password)
  • Каким типом системы представляться (в примере "VMA", но часто для SMSC все равно, что тут прописано)

Но это слишком уж простая конфигурация - в реальной жизни обычно все несколько сложнее.

Реалистичный пример настройки подключения к SMSC

# SMPP подключение к SMSC
# Используется режим TRANSCEIVER
# Комментарии даны по ходу
group = smsc smsc = smpp
# Используем идентификатор smpp1
smsc-id = "smpp1"
allowed-smsc-id = "smpp1" preferred-smsc-id = "smpp1"
# Выставляем тип системы в "VAS" (или что оператор скажет)
system-type = "VAS"
# Ограничение пропускной способности - 10 MT SM/сек
throughput = 10
# IP адрес, на котором находится SMSC
host = 10.0.0.11
# TCP порт, на котором принимают SMPP
port = 3775
# Используем режим transceiver
transceiver-mode = 1
# Логин (system-id) и пароль, полученные от оператора
smsc-username = "vasp" smsc-password = "secret"
# Проверка работоспособности линка раз в минуту
enquire-link-interval = 60
# Используем кодировку CP1252 вместо GSM 03.38
alt-charset = "CP1252"
# Прибиваем гвоздями TON и NPI для получателей в отправляемых нами MT SM
dest-addr-ton = 1 dest-addr-npi = 1
# В submit_sm_resp нам отдают шестнадцатиричный message-id, а в deliver_sm (DLR) - десятичный
msg-id-type = 0x01
# Записываем отдельно логи подключения в режиме отладки (log-level = 0)
log-file = "/var/log/kannel/smpp-smsc.log" log-level = 0

Общие параметры

  • group = smsc - указание группы настроек подключения к SMSC.
  • smsc = smpp - указание типа SMSC (мы рассматриваем SMPP, но есть и много других)
  • smsc-id = <STRING> - идентификатор подключения к SMSC, который используется при протоколировании и маршрутизации сообщений.
Сразу стоит заметить, что для нормальной работы маршрутизации лучше сразу использовать параметры allowed-smsc-id, preferred-smsc-id и denied-smsc-id. В частности, для нормальной работы с уведомлениями о доставке (DLR).
  • smsc-admin-id = <STRING> - идентификатор, используемый в административном HTTP API. Чаще всего он не требуется, но в ситуации, когда используется несколько параллельных и равнозначных подключений к SMSC (например, при балансировке нагрузки). При этом, для работы сервисов будет применяться один и тот же идентификатор, но при управлении можно будет использовать этот параметр, который будет уникальным.

Пример:

# Первое подключение к SMSC
group = smsc
smsc = smpp
smsc-id = carrier
preferred-smsc-id = carrier
smsc-admin-id = carrier1
# Второе подключение к SMSC
group = smsc
smsc = smpp
smsc-id = carrier
preferred-smsc-id = carrier
smsc-admin-id = carrier2

Таким образом, при отправке и получении сообщений можно использовать идентификатор carrier, а управлять подключениями независимо - по идентификаторам carrier1 и carrier2.

Параметры для маршрутизации MT сообщений

Kannel обладает достаточно большими возможностями маршрутизации. Кроме явного указания подключения к SMSC можно также предоставить Kannel возможность самостоятельно выбрать маршрут по различным параметрам.

  • allowed-smsc-id = <СПИСОК> - допустимые идентификаторы для данного подключения. Возможно использовать несколько идентификаторов, разделенных точкой с запятой ("ukraine;kyivstar"). Также можно использовать один идентификатор для разных подключений.
  • preferred-smsc-id = <СПИСОК> - предпочтительный идентификатор. Если указанный при отправке сообщения идентификатор присутствует в списке preferred-smsc-id, то сообщение будет доставляться через данное подключение (если оно доступно в момент отправки). Пример использования можно посмотреть в моей заметке про резервирование подключений к SMSC.
  • denied-smsc-id = <СПИСОК> - не пропускать через данное подключение сообщения с перечисленными smsc-id
  • allowed-prefix = <СПИСОК> - список допустимых префиксов номеров (через точку с запятой), на которые можно отправлять сообщения. Например, "+38067;+38096;+38097"
  • preferred-prefix = <СПИСОК> - для каких префиксов номеров назначения подключение является предпочтительным
  • denied-prefix = <СПИСОК> - не пропускать сообщения на номера с указанными префиксами через данное подключение

Параметры SMPP

  • host = <SMSC HOST> - имя или IP-адрес SMSC (или другого сервера, принимающего соединения SMPP).
  • port = <SMSC PORT> - TCP порт, на котором SMSC принимает подключения по SMPP.
  • receive-port = <SMSC-RECV PORT> - TCP порт, к которому нужно подключаться в режиме receiver.
  • transceiver-mode = <1 или 0> - нужно установить в 1, если ожидается использование режима transceiver, когда входящие и исходящие сообщения передаются по одному TCP соединению.

Большинство современных SMSC используют версию SMPP v3.4 и работают в режиме transceiver (одна TCP сессия), так что хватит опций host и port. А вот при необходимости подключения в режиме receiver придется также указать параметр receive-port.

  • use-ssl = <1 или 0> - использовать (1) или нет (0) шифрование SSL для SMPP.
  • ssl-client-certkey-file = <SSL СЕРТИФИКАТ> - путь к PEM-файлу с клиентским сертификатом SSL.

Честно говоря, шифрование SMPP трафика лично в реальной жизни встречалось крайне редко, т.к. операторы предпочитают зашифровать весь трафик с помощью какого-нибудь IPSec, а не возиться с частными решениями.

  • smsc-username = <SYSTEM-ID> - идентификатор ESME для аутентификации (system_id согласно спецификации SMPP).
  • smsc-password = <ПАРОЛЬ> - пароль ESME для аутентификации.
  • system-type = <ТИП СИСТЕМЫ> - параметр, которым теоретически должно определяться назначение ESME. Например, VMS для Voice Mail System или OTA для системы отправки OTA-настроек. Однако, очень часто SMSC этот параметр просто игнорирует.

Кстати, один из вариантов применения, который я встречал - использование параметра system_type для поиска маршрутизационной информации (HLR Lookup). При этом, запрос информации выглядит попыткой отправки сообщения командой submit_sm, а информация приходит в виде DLR в пакете deliver_sm с большой кучей опциональных TLV, в которых содержатся полезные сведения.

  • service-type = <SRV TYPE> - параметр service_type для данного подключения. Часто используется для интеграции с биллинговой системой при MT-тарификации, но VAS-провайдеров туда не пускают.
  • interface-version = <VERSION STRING> - версия протокола SMPP. Либо "34" (по умолчанию), либо "33" для протокола
    SMPP v3.3.
  • address-range = <СТРОКА> - список адресов (номеров), которые должен обслуживать данный ESME. В спецификации присутствует, но чаще всего игнорируется.
  • my-number = <НОМЕР> - явная установка сервисного номера, если не устраивает то, что приходит от SMSC.
  • enquire-link-interval = <ЧИСЛО> - промежуток в секундах, через который нужно повотрять отправку enquire_link (своеобразный аналог ping в протоколе SMPP). По умолчанию устанавливается в 30.
  • max-pending-submits = <ЧИСЛО> - максимальное количество пакетов SMPP, которые могут ожидать подтверждения (по умолчанию 10). Т.к. протокол асинхронный, то Kannel может передавать сообщения, не дожидаясь ответа на предыдущие.
  • reconnect-delay = <СЕКУНДЫ> - через сколько секунд производить попытку подключения в случае неудачного либо разорванного соединения. По умолчанию - 10 секунд.

Следующие несколько параметров используются для управления адресами в сообщениях. Для этих целей используются следующие два параметра: NPI (Numbering Plan Identifier) и TON (Type Of Number).

Из существующих NPI при передаче SMS используются либо 1 (план нумерации E.163/E.164, определяющий адресацию в цифровых телефонных сетях) либо 0 (неопределенный, но реально тот же самый).

В рамках плана нумерации E.163/E.164 может использоваться несколько типов номеров (TON): 0 - неопределенный, 1 - международный (MSISDN), 2 - национальный, 3 - специфичный для сети, 4 - номер подписчика, 5 - алфавитно-цифровой, 6 - сокращенный. Чаще всего встречаются 0, 1, 2 и 5.

  • source-addr-ton = <TON> - тип номера отправителя для MO сообщений
  • source-addr-npi = <NPI> - план нумерации отправителя для MO сообщений
  • source-addr-autodetect = <1 или 0> - использовать или нет автоопределение TON и NPI для адреса отправителя
  • dest-addr-ton = <TON> - тип номера получателя для MO сообщений
  • dest-addr-npi = <NPI> - план нумерации получателя для MO сообщений
  • bind-addr-ton = <TON> - тип номера ESME (при подключении, обычно NULL)
  • bind-addr-npi = <NPI> - план нумерации для адреса ESME (при подключении, обычно NULL)

Установка этих параметров зависит от настроек SMSC и обычно предоставляется оператором. Иногда (кстати, часто) оператора нужно явно спросить об этом.

  • msg-id-type = <битовая маска> - соответствие форматов идентификатора сообщения:
    • 0x00 - deliver_sm decimal, submit_sm_resp decimal;
    • 0x01 - deliver_sm decimal, submit_sm_resp hex;
    • 0x02 - deliver_sm hex, submit_sm_resp decimal;
    • 0x03 - deliver_sm hex, submit_sm_resp hex;
    • если параметр отсутствует, то идентификатор считается строкой

Если в логах подключения к SMSC появляются записи о том, что получен DLR, но непонятно, что с ним делать (got DLR but could not find message or was not interested in it) - первым делом стоит посмотреть на этот параметр. Дело в том, что сперва Kannel получает идентификатор MO SM в пакете submit_sm_resp (поле message_id), а потом уведомление о доставке в пакете deliver_sm (вот тут может быть и в теле сообщения, и в TLV параметре receipted_message_id). Спецификацией SMPP формат явно не определяется и регулярно встречаются SMSC, которые в одном месте передают десятичное число, а в другом - шестнадцатиричное. И для выяснения, на какое же сообщение пришло уведомление, приходится проводить преобразование форматов.

  • alt-charset = <ENCODING> - какую кодировку тела сообщения использовать при передаче MO SM с coding = 0. По умолчанию передается строка, в которой каждый байт содержит 7-битный символ в кодировке GSM. Но некоторые SMSC ожидают там другую кодировку (например, CP-1252). Если у вас не проходят в сообщениях символы "@" или "~" - стоит посмотреть на этот параметр.
  • alt-addr-charset = <ENCODING> - кодировка для указания адресов, если используется отличная от GSM-алфавита, определенного в спецификации GSM 03.38.

Внимание! Кодировки, указываемые в параметрах alt-charset и alt-addr-charset, должны поддерживаться iconv(). Кроме того, Kannel должен быть собран с поддержкой GNU libiconv, что не на всех системах происходит.

Дополнительные TLV параметры SMPP

Дополнительные TLV (от Tag-Length-Value) параметры предназначены для передачи различных необязательных данных с сообщениями. Часть этих параметров стандартизирована и описана в спецификации SMPP, а часть являются специфичными для конкретной системы (vendor specific).

Каждый такой параметр в протоколе SMPP представлен тройкой:

  • тег (числовой идентификатор параметра)
  • длина данных параметра
  • значение

TLV параметры определяются в группах smpp-tlv, каждая из которых описывает один параметр.

  • group = smpp-tlv - группа описания TLV параметра SMPP
  • name = <СТРОКА> - мнемонический идентификатор параметра для обработки
  • tag = <HEX> - шестнадцатиричный идентификатор TLV параметра
  • type = <ТИП> - тип данных параметра (integer, nulterminated или octetstring)
  • length = <ДЛИНА> - максимальная длина данных в байтах
  • smsc-id = <СПИСОК> - список SMSC через точку с запятой, для которых нужно обрабатывать данный параметр. Если не указать, то считается, что параметр действителен для всех SMSC.

Пример описания параметра:

# Идентификатор операции USSD
group = smpp-tlv
name = ussd_service_op
tag = 0x0501
type = integer
length = 1
smsc-id = "ussd-1;ussd-2;ussd-3"

 Теперь его можно передать по HTTP в таком виде:

http://localhost:13013/cgi-bin/sendsms?...&meta-data=%3Fsmpp%3Fussd_service_op%3D17