Smpp протокол что это
Протокол SMPP
Версия 1.0 предназначена только для отправки сообщений и получения статуса доставки. Прием сообщений в данный момент не поддерживается.
Расшифровку ошибок можно найти в спецификации SMPP версии 3.4.
Внимание: Вам необходимо прислать список IP адресов, с которых Вы будете подключаться, перед тем как начать использовать SMPP протокол.
Параметры подключения
Поддерживаемые команды
Команда | Описание |
---|---|
BIND_TRANSMITTER | Подключиться как TRANSMITTER |
BIND_TRANSCEIVER | Подключиться как TRANSCEIVER |
SUBMIT_SM | Отправить сообщение |
QUERY_SM | Запросить статус сообщения |
DELIVER_SM | Отправка Delivery Receipt сервером |
ENQUIRE_LINK | Проверка связи |
GENERIC_NAK | Ошибочная команда |
UNBIND | Отключение |
На не поддерживаемые команды сервер будет отвечать GENERIC_NAK сообщением с кодом ошибки ESME_RINVCMDID.
Параметры отправки сообщения (SUBMIT_SM)
Правила работы с SMPP подключением
При установке подключения клиенту дается 10 секунд, что бы отправить команду BIND_TRANSMITTER или BIND_TRANSCEIVER. Иначе соединение будет разорвано сервером.
Клиент обязан отвечать на все пакеты отправленные сервером соответствующим resp пакетом в течение 1 минуты. Иначе соединение будет разорвано сервером без отсылки UNBIND.
После установки подключения и авторизации сервер будет отправлять ENQUIRE_LINK пакеты каждую минуту. На этот пакет клиент также обязан ответить в течение 1 минуты.
Одновременно возможно только одно подключение от одного имени пользователя. На все дополнительные подключения будет отправлена ошибка (0x00000005 ESME Already in Bound State). Если необходимо сделать несколько подключений для одного кабинета, для каждого необходимо создать отдельного пользователя и использовать его подключение.
Если при отправке в пакете Submit_sm установлен флаг registered_delivery, то статус сообщения будет возвращен только в подключение, установленное от имени пользователя, отправившего сообщения.
Получение статуса доставки сообщения
Есть две возможности получения статуса доставки (активный и пассивный). Пассивный вариант является предпочтительным.
Пассивный вариант предусматривает установки флага registered_delivery пакета SUBMIT_SM. После перехода сообщения в финальное состояние сервер отправит DELIVER_SM пакет с Delivery Receipt сообщением. Формат Delivery Receipt сообщения ниже.
Активный вариант предусматривает периодический опрос статуса сообщения отсылкой QUERY_SM.
Формат Delivery Receipt
Поле | Описание |
---|---|
id ID | сообщения |
sub | Количество отправленных сообщений |
dlvrd | Количество доставленных сообщений |
submit date | Время отправки сообщения |
done date | Время перехода сообщение в финальное состояние |
stat | Статус сообщения (расшифровка статусов см. ниже) |
err | Может содержать код ошибки в случае не доставки сообщения |
text | Первые 20 байт сообщения |
Статус | Описание |
---|---|
delivrd | Доставлено |
expired | Не доставлено из-за истечения периода ожидания доставки |
deleted | Удалено |
undeliv | Не может быть доставлено |
acceptd | Принято на обработку |
unknown | Статус не известен (поле err может содержать код ошибки) |
rejectd | Сообщение отвергнуто |
Зарезервированные коды ошибок
Код | Описание |
---|---|
0x0400 (1024) | Кодировка не распознана |
0x0401 (1025) | Слишком большой текст сообщения. Максимальная длина не должна превышать 160 байт. |
0x0402 (1026) | Ошибка регистрации сообщения на отправку. При возникновении этой ошибки обратитесь в службу поддержки. |
0x0403 (1027) | Не прошла проверка текста сообщения на наличие недопустимых слов и/или фраз |
0x0404 (1028) | Отправитель или получатель в черном списке |
0x0453 (1107) | Сработало ограничение по отправке одинакового текста на один и тот же номер в течение небольшого промежутка времени. Обратитесь в поддержку, если хотите отключить или уменьшить период. |
0x043C (1084) | Нет доступного тарифа для запрашиваемого направления. |
0x043F (1087) | Нет подходящего тарифа у вышестоящего контрагента. |
0x045A (1114) | Политика маршрутизации не найдена. |
0x0446 (1094) | Ошибка транспорта. При возникновении этой ошибки обратитесь в службу поддержки. |
0x433 (1075) | Недостаточно средств на счете. |
Установка защищенного соединения
Для обеспечения более высокого уровня безопасности передаваемых данных предусмотрена возможность устанавливать защищенное соединение по протоколу TLS или SSL. TLS-соединение позволяет передавать в зашифрованном виде не только текст сообщения, но и параметры учетной записи (логин и пароль). Дополнительно может осуществляться проверка сертификата SMPP-сервера, что предотвращает реализацию фишинговых атак, направленных на перехват учетных данных.
Аутентификация по сертификатам предусматривает наличие корневого сертификата доверенного издателя и самого сертификата SMPP-сервера.
Проверяются следующие параметры:
1. Корневой сертификат издателя действителен (не истек срок действия сертификата);
2. Сертификат SMPP-сервера выдан доверенным издателем (подписан доверенным корневым сертификатом);
3. Сертификат SMPP-сервера также действителен (не истек срок действия).
Параметры подключения остаются стандартными, необходимо только изменить порт на 8057.
Поддерживаемые протоколы: TLSv1.2, TLSv1.1, TLSv1, SSLv3
Согласование протоколов при установке соединения происходит от наиболее новой версии, к более ранним:
(больший приоритет) TLSv1.2 › TLSv1.1 › TLSv1 › SSLv3 (меньший приоритет)
SMPP-клиенты с поддержкой TLS или SSL
Если используемое приложение (SMPP-клиент) поддерживает работу по указанным протоколам, необходимо:
1) изменить стандартный порт 8056 на порт 8057;
2) добавить корневой сертификат издателя и/или сертификат SMPP-сервера в доверенные (опционально, если проверка сертификатов поддерживается SMPP-клиентом).
SMPP-клиенты без поддержки TLS или SSL
SMPP-клиенты, в которых не реализована возможность работы по SSL или TLS, также могут устанавливать защищенное соединение, используя бесплатное кроссплатформенное приложение для проксирования траффика Stunnel (www.stunnel.org).
Приложение Stunnel позволяет выполнить проверку сертификата SMPP-сервера.
Пример раздела файла конфигурации Stunnel:
Расшифровка параметров файла конфигурации
accept — принимает значение, на которое будет отправляться трафик SMPP-клиентом.
connect — адрес и порт, с которыми устанавливается защищененое соединение.
checkHost — проверка DNS-имени сервера
CAfile — тектовый файл со списком доверенных сертификатов. По умолчанию данный файл находится в той же директории, что и файл конфигурации Stunnel.
verify — определяет, проводить ли проверку сертификатов SMPP-сервера:
0 — не производить проверку сертификата SMPP-сервера;
1 — проверить, действителен ли сертификат SMPP-сервера, только если соответствующий корневой сертификат присутствует в файле ca-certs.pem;
2 — проверить, действителен ли сертификат SMPP-сервера, но если соответствующего корневого сертификата нет в файле ca-certs.pem, не устанавливать соединение;
Следующий текст — корневой сертификат издателя в кодировке Base64 — нужно добавить в конец файла ca-certs.pem (или другой файл, указанный в параметре CAfile конфигурации Stunnel):
Уровни проверки (параметр verify в файле конфигурации) могут отличаться в разных версиях Stunnel.
SMPP — одноранговый протокол коротких сообщений
Привет! Хотя мессенджеры и соцсети с каждым днем вытесняют традиционные способы связи, это не умаляет популярность смс. Верификация на популярном сайте, или оповещение о транзакции демонстрируют — они жыви и будут жить. А задумывались как это все работает? Очень часто для рассылки массовых сообщений используется протокол SMPP, о котором и пойдет речь под катом.
На Хабре уже были статьи о smpp, 1,2, но их целью не было описание самого протокола. Безусловно вы можете сразу начать с первоисточника — спецификации, но думаю будет неплохо, чтобы существовало и краткое ее содержание. Буду объяснять на примере v3.4 Рад вашей объективной критике.
Протокол SMPP это протокол одноранговых сообщений. Это означает, что каждый пир/хаб сервер равноправный. В простейшем случае схема обмена смс сообщениями выглядит так:
Однако, если национальный оператор не имеет маршрута в какой-то отдаленный регион он просит об этом посредника — смс хаб. Иногда, чтобы отправить одну смс, нужно выстроить цепочку между несколькими странами, или даже континентами.
О протоколе
Режим связи
Transmitter (передатчик) — передача сообщения в одну сторону, поочередно
Receiver (приемник) — только прием сообщение от SMSC.
Transreceiver (приемопередатчик) — Обмен сообщениями между SMSC и пользователем
Структура
Длина сообщения
Data Coding Scheme
Однако для передачи сообщения символы требуют кодирования. В протоколе SMPP за кодирование отвечает специальное поле — Data Coding Scheme, или DCS. Это поле, которое указывает как нужно распознавать сообщения. Кроме этого поле DCS включает в себя:
UTF-16 (в GSM UCS2) Для включения отсутствующих символов в 7-битного кодирования была разработана кодировка UTF-16 которая и добавляет дополнительные символы (в том числе и кириллические) за счет уменьшения размера сообщения с 160 до 70 этот тип кодирования почти полностью повторяет Unicode.
8- битные данные определенные пользователем. К таковым относятся KOI8-R и Windows-1251. Хотя такое решение кажется более экономичным по сравнению с тем же UTF-1, но для использования таких кодировок требуется предварительная настройка на принимающем и передающим устройстве. Если на каком – то из них данные кодировки не поддерживаются сообщение будет отображаться не корректно. Поскольку в таком случае оба устройства должны быть заблаговременно настроены.
Клас сообщения
Тип сообщения
Silent message (SMS0) Тип смс сообщения без контента. Такое смс приходит без уведомления и не отображается на экране устройства.
Каждая pdu операция парная и состоит из запроса и ответа. Например: команда что говорит об установлении соединения (bind_transmitter / bind_transmitter_resp), или о том, что сообщение передано (deliver_sm / deliver_sm_resp)
Каждый pdu пакет состоит из двух частей — заголовок (header) и тело (body). Структура заголовка одинакова для любого pdu пакета: command length это длина пакета, id это название пакета, а команда status показывает успешно передано сообщение, или с ошибкой.
Дополнительные параметры TLV
TLV (Tag Length Value), или дополнительные поля. Такие параметры используются для расширения функций протокола и не являются обязательными. Данное поле указывается в конце поля pdu. В качестве примера с помощью TLV dest_addr_np_information можно организовать передачу информации о портированности номера.
Ton и Npi
TON (Type of Number) параметр, сообщает SMSC о формате адресации и тип сети.
NPI (Numbering Plan Identification) параметр, указывающий на план нумерации.
Адрес источника сообщения, или альфа имя
Сообщения, отправляемые на телефон бывают двух разновидностей: цифровые и буквенные. Цифровые могут быть длинными (похожими на номер телефона) и короткими. Иногда у операторов существуют ограничения на отправку от нейтральных имен, например Infosms, Alert etc. Иногда операторы не пропускают трафик, если имя не зарегистрировано в их сети. Однако это скорее особенности оператора.
Стадии отправки
SMS-SUBMIT — это отправка сообщения MO FSM (короткое сообщение от мобильного терминала)
SMS-SUBMIT REPORT — подтверждение, что сообщение отправлено SMSC
SRI SM (SendRoutingInfo) — SMSC получает информацию от HLR относительно MSC / VLR места нахождения абонента
SRI SM RESP — ответ от HLR относительно мясца положения абонента
MT-FSM — после получения местоположения отправляется сообщение используя операцию «Forward Short Message»
MT-FSM ACK — ответ от SMSC о том, что сообщение отправлено
SMS-STATUS REPORT — SMSC отправляет статус о доставке сообщения.
Статус доставки сообщения
SMS-STATUS REPORT может принимать несколько значений:
DELIVRD сообщение успешно доставлено
REJECTD — сообщение отвергнуто SMS-центром
EXPIRED — сообщение удалено из очереди отправки после окончания TTL (время жизни сообщения)
UNDELIV — другие случаи недоставки
UNKNOWN-не получен ответ об отправке.
Ошибки передачи
Иногда сообщения не доставляются. Вследствие чего возникают ошибки. Ошибки возвращаются в PDUs_sms_resp. Все ошибки можно разделить на временные (Temporary) и постоянные (Permanent).
В качестве примера, к временным можно отнести absent_subscriber абонент не доступен или не в сети, а к постоянным — абонент не существует. В зависимости от ошибок, которые возникают формируется политика переотправки этих сообщений.
Например, если абонент был занят разговором и получил ошибку MT handset is busy, сообщение можно отправить повторно через несколько минут, однако, если у абонента заблокирован сервис приема сообщений повторная переотправка не будет иметь смысла. Список ошибок вы сможете найти на страницах SMSC, например, как эта.
Инструкция к спецификации SMPP
Различные сервисы, использующие SMS уведомления или SMS авторизацию, с каждым днем набирают популярность, т.к. это действительно очень удобно с точки зрения пользователя и достаточно безопасно с точки зрения разработчиков. Большинство компаний, предоставляющие сервис SMS рассылок, предлагают свои API для реализации процесса отправки (как правило на основе HTTP), но у всех есть стандартный вариант подключения — протокол SMPP. Мой опыт работы с пользователями SMPP протокола показывает, что они испытываю довольно много сложностей. Причиной этого (по моему мнению) является бездумное использование готовых библиотек и в результате полное непонимание что происходит «под капотом».
В этой статье я опишу один из самых частых вопросов от клиентов — «Как прочитать текст входящего сообщения? Я нашёл on-line декодер, но он показывает абракадабру». Дело в том, что у некоторых сервисов есть не только возможность отправки сообщений, но и получения на них ответных сообщений. Однако алгоритм, описанный мной, применим к любому действию в SMPP протоколе, т.к. по сути является инструкцией к спецификации протокола.
Разбор входящего сообщения без использования какого-либо SMPP ПО
Общий порядок обмена пакетами в SMPP выглядит следующим образом:
Как видно в случае входящего сообщения нас интересует пакет deliver_sm. Определение типа пакета происходит по полю command_id, которое в случае deliver_sm имеет значение 0x00000005 (пункт 5.1.2.1 в спецификации).
В итоге фильтр в wireshark выглядит так:
После того как нашли пакет по фильтру копируем его содержимое в HEX формате:
Итоговая строка, которую предстоит расшифровать:
Пункт, описывающий формат пакета deliver_sm, в спецификации, имеет номер 4.6.1 “DELIVER_SM” Syntax. В этом пункте имеется таблица, в которой расписывается каждое поле пакета:
Приступим к разбору пакета
Первое поле пакета — command_length имеет размер 4 октета (столбец size octets) и тип Integer. Это означает что от начала нашей HEX строки необходимо отсчитать 4 х 2 = 8 символов.
00 00 00 48 000000050000000000000003000101636F6F6.
Следующее поле command_id — аналогично 4 октета и Integer.
00000048 00 00 00 05 0000000000000003000101636F6F6.
Преобразуем в читаемый вид: 00000005 = deliver_sm
Поля command_status и sequence_number так же имею по 4 октета. Где посмотреть их значения, я предполагаю Вы уже догадываетесь.
0000004800000005 00 00 00 00 00 00 00 03 000101636F6F6.
Поле service_type может содержать максимум 6 октетов и имеет тип C-Octet String. В пункте 3.1 SMPP PDU — Type Definitions сказано:
C-Octet String A series of ASCII characters terminated with the NULL character
Другими словами это последовательность ASCII символов с нулевым октетом как знак окончания поля. Т.е. это поле может содержать максимум 6 символов, но может быть и меньше — конец данного поля обозначается HEX 00. В данном конкретном примере мы сразу видим 00 — поле не содержит ни какого значения.
00000048000000050000000000000003 00 0101636F6F6.
Если бы этот столбец был заполнен, то расшифровать его можно по таблице ASCII символов.
Пропустим следующие 2 поля source_addr_ton и source_addr_npi, т.к. как их расшифровать уже ясно и разберем еще одно поле с типом C-Octet String — source_addr.
Source_addr может содержать максимум 21 октет, но в данном случае оно состоит из 13 октетов включая нулевой октет который означает окончание поля:
63 6F 6F 6E 6F 6C 61 6E 64 2E 72 75 00
В поисковике делаем запрос «ascii table» и начинаем расшифровывать:
63 = c
6F = o
6F = o
6E = n
6F = o
6C = l
61 = a
6E = n
64 = d
И так далее до символов 00.
Остальные поля я тоже пропускаю — их много и их определение ни чем не отличается от выше описанного. Перейдём к полю data_coding, без значения данного поля мы не сможем прочитать текст сообщения.
Я разделил все поля в HEX строке примера, а поле data_coding выделил жирным и вот что получилось:
00000047;00000005;00000000;00000003;00;01;01;373932393937333630333000;01;01;373932333235303039353900;00;00;00;00;00;00;00;
08;00;00;0424;000c;043f04400438043204350442
Ищем таблицу символов по запросу: «ucs2 code chart»
Выбираем первые 2 октета текста «043f» и ищем их на странице
Продолжаем выделять по 2 октета и искать:
[р] 0440 CYRILLIC SMALL LETTER ER
[и] 0438 CYRILLIC SMALL LETTER I
[в] 0432 CYRILLIC SMALL LETTER VE
[е] 0435 CYRILLIC SMALL LETTER IE
[т] 0442 CYRILLIC SMALL LETTER TE
На этом разбор пакета окончен. Надеюсь что описание получилось понятное и достаточно полное. В целом если у Вас получилось осознать как прочитать сообщение, то отправить его не составит ни какого труда. Поменяется несколько полей.
Читайте спецификации — там почти все уже написано.
Отправляем SMS из Erlang/Elixir. Короткая инструкция
Photo by Science in HD
Если вам когда-либо приходилось решать задачу отправки SMS из кода вашего приложения, скорее всего, вы использовали готовое REST API поставщика дополнительных услуг. Но что происходит после того, как поставщик получит ваш запрос? Какие протоколы используются и какой путь проходит текст сообщения, прежде чем оказаться на экране мобильного терминала пользователя?
В этой статье вы найдёте:
Чего тут точно нет, так это информации по отправке коротких сообщений через SIGTRAN.
Определимся с терминами и понятиями
Прежде чем погружаться в протоколы и код, предлагаю разобраться в терминологии. Если быть придирчивым к определениям, то отправить SMS невозможно. Вспоминается момент из «Джентльменов удачи»: «Кто ж его отправит — он же сервис!» SMS — акроним от short message service, что на русский переводится как «сервис/служба коротких сообщений». Если возвращаться к шутке, то отправляем мы SM, т. е. короткие сообщения, используя SMS — сервис коротких сообщений.
У каждого оператора мобильной связи есть компонент, отвечающий за работу службы коротких сообщений. Это так называемый SMS-центр, он же SMSC, он же SMS-SC. Его задачами являются хранение, передача, конвертация и доставка SM-сообщений. Наиболее распространенным внешним протоколом взаимодействия с SMSC является SMPP. SMPP — клиент-серверный протокол-комбайн, отвечающий за обмен короткими сообщениями в одноранговой сети. Источником SM могут быть устройства и приложения. В терминологии SMPP их называют ESME.
Давайте ответим на вопросы в начале статьи. Итак, ваше сообщение по REST API или SMPP попало к поставщику услуг, у которого заключён договор с одним или несколькими операторами связи или другими посредниками. Сервер поставщика подключается к SMSC и отправляет по SMPP ваше SM, затем получает отчёт о доставке или ответное SM. В процессе обработки SM могут проходить через маршрутизаторы — RE. SMSC, сходив в HLR, узнает местоположение абонента и доставит SM абоненту. Общая картина и понимание проблемы, надеюсь, у вас появились. Давайте погрузимся в протокольные тонкости.
Выше я сказал, что SMPP — протокол-комбайн. Подобный эвфемизм я позволил себе из-за того, что SMPP применим не только для организации обмена SMS, с его помощью можно организовать различные сервисы: ESM, голосовой почты, уведомлений, сотового радиовещания, WAP, USSD и прочие. Весь обмен происходит с помощью пар запрос-ответ. Их называют PDU — блоками данных или пакетами.
Инициализация подключения
Перед началом обмена мы должны указать, в каком направлении будет работать наше подключение. За это отвечают соответствующие команды:
Безопасность
При выполнении команды привязки мы должны передать параметры безопасности для идентификации нашего ESME: system_id, system_type и password.
SMPP в экосистеме OTP
Недавно у хорошего друга возник вопрос по работе с SMPP в Erlang. Собственно, благодаря этому и родился этот текст.
Казалось бы, никаких проблем. Проверенный временем телеком-протокол с давно известными проблемами с одной стороны и телеком-язык с другой. Все должно быть просто и весело, как в песенке PPAP.
Но есть нюанс… Найти адекватную реализацию оказалось непросто.
Наверняка все, кто пытался серьёзно работать с Erlang, знают про его недостаток, связанный с ограниченным выбором библиотек. С SMPP такая же история — в OTP нет штатной поддержки этого протокола, а на первой странице выдачи Гугла творится что-то странное:
Лично я бы загрустил от такого разнообразия существующих решений. Особенно, когда хочется асинхронного режима, адекватной поддержки SMPP 3.4 и возможности написать как клиент, так и сервер. Но на помощь приходит Elixir и библиотека SMPPEX.
SMPPEX
Про сам проект скажу только то, что он активный и готов для продакшен-применения. Это стабильная, всесторонняя библиотека для SMPP с продуманным API, хорошей поддержкой разработчиков и отсутствием проблем с лицензией.
От слов к делу
Сначала можно ознакомиться с примерами синхронного и асинхронного клиента в документации. Затем можно перейти к более сложным вещам в контексте использования SMPPEX в Erlang-проекте.
Для иллюстрации возможностей библиотеки возьмём простой сценарий:
Придумаем дополнительные требования. Допустим, мы хотим отправлять MT SM, получать отчёты о доставке и MO SM. При этом по каким-то причинам нам нужны кастомные PDU и полный контроль над линком, поэтому за формирование submit_sm PDU и обработку всех входящих PDU мы будем отвечать сами. При этом мы не должны забывать про требование асинхронности.
Работа с линком
Надеюсь, что сложностей с установкой зависимости из hex.pm у вас не возникло и мы можем приступить к написанию кода. Как говорилось выше, работать мы будем в асинхронном режиме, поэтому запускаем клиента с помощью модуля SMPPEX.ESME:
Для синхронного режима существует SMPPEX.ESME.Sync.
Наш клиент готов, и мы можем сделать привязку к SMSC. Предположим, что SMSC поддерживает SMPPv3.4 и мы можем использовать transceiver режим:
Если всё прошло хорошо, нам должен прийти PDU с командой bind_transceiver_resp:
Формирование PDU для MT SM
Линк поднят, и мы можем отправить наше сообщение. В терминах SMPP, сообщения адресуемые абоненту называются Mobile Terminated (MT SM). Соберём PDU для него:
Обработка отчетов о доставке и MO SM
Mobile originated (MO SM) — сообщения от абонента.
После отправки сообщения в линк SMSC ответит нам submit_sm_resp, в котором указан уникальный ID нашего сообщения:
Теперь нам необходимо дождаться deliver_sm с этим message_id.
Чтобы отличить отчёты о доставке от MO SM, проанализируем esm_class:
При этом для обработки отчётов о доставке нам достаточно узнать ID доставленного сообщения:
А для входящих сообщений узнать номер отправителя:
и полезное содержимое сообщения:
Как известно, спецификация SMPP требует deliver_sm_resp в ответ на deliver_sm. Поэтому после обработки отчёта о доставке и входящего сообщения мы должны ответить deliver_sm_resp. Создадим PDU для него:
Я специально не указываю номер команды, добавим его автоматически:
Весь код демопроекта можно найти в репозитории.
OTP-тренды
В 2020 году на тренды развития OTP и BEAM всё большее влияние оказывает сообщество Elixir. Чаще и чаще хорошие инструменты и полезные библиотеки можно найти на Elixir, а не на Erlang. Это не повод для тревоги за Erlang, просто Elixir смог заинтересовать и привлечь больше людей в своё сообщество, и это прекрасно. А благодаря OTP для использования той или иной библиотеки нам не важно, на чём она написана. Надеюсь, пример из статьи смог показать гибкость SMPPEX как инструмента и удобство применения библиотек, написанных на Elixir в Erlang-проектах.