Каждое сообщение SMPP — это PDU (Protocol Data Unit) с фиксированным 16-байтовым заголовком, за которым следует тело, зависящее от операции. Заголовок — это четыре 4-байтовых целых числа в обратном порядке байтов: command_length, command_id, command_status и sequence_number. command_length учитывает весь PDU, включая заголовок, поэтому получатель сначала читает 4 байта, а затем остальное.
bind_transceiverОткрыть и аутентифицировать сессиюbind_transceiver_respСессия принятаsubmit_smОтправить сообщениеsubmit_sm_respПринято, возвращен ID сообщенияdeliver_smПодтверждение доставки или входящее сообщениеdeliver_sm_respПодтвержденоenquire_linkKeepalive в режиме ожидания
16-байтовый заголовок
Каждый PDU начинается с одних и тех же четырёх беззнаковых 32-битных целых чисел в сетевом порядке байтов (big-endian). command_length — это полный размер PDU в октетах, включая эти 16 байт заголовка: анализатор читает первые 4 байта, узнаёт полную длину и затем читает остаток. command_id идентифицирует операцию. command_status равен 0 (ESME_ROK) в запросах и несёт код ошибки в ответах. sequence_number связывает запрос с его ответом.
| Смещение | Поле | Размер | Назначение |
|---|---|---|---|
| 0 | command_length | 4 октета | Общая длина PDU в октетах, включая заголовок |
| 4 | command_id | 4 октета | Идентификатор операции (например, submit_sm = 0x00000004) |
| 8 | command_status | 4 октета | 0 в запросе; код ошибки в ответе |
| 12 | sequence_number | 4 октета | Сопоставляет запрос↔ответ (0x00000001–0x7FFFFFFF) |
command_id и бит ответа
У каждой операции есть свой command_id. Соответствующий ответ использует то же значение со старшим битом, установленным в 1 (логическое ИЛИ с 0x80000000). Так, submit_sm — это 0x00000004, а submit_sm_resp — 0x80000004. generic_nack (0x80000000) — универсальный ответ об ошибке для неразбираемого или недопустимого PDU.
| Операция | Запрос | Ответ |
|---|---|---|
| generic_nack | — | 0x80000000 |
| bind_receiver | 0x00000001 | 0x80000001 |
| bind_transmitter | 0x00000002 | 0x80000002 |
| query_sm | 0x00000003 | 0x80000003 |
| submit_sm | 0x00000004 | 0x80000004 |
| deliver_sm | 0x00000005 | 0x80000005 |
| unbind | 0x00000006 | 0x80000006 |
| replace_sm | 0x00000007 | 0x80000007 |
| cancel_sm | 0x00000008 | 0x80000008 |
| bind_transceiver | 0x00000009 | 0x80000009 |
| enquire_link | 0x00000015 | 0x80000015 |
| data_sm | 0x00000103 | 0x80000103 |
Тело и кодирование полей
После заголовка следует тело, зависящее от операции, с обязательными параметрами, за которыми могут идти опциональные параметры TLV. SMPP использует три типа кодирования полей. Целые числа имеют фиксированный размер, беззнаковые, в обратном порядке байтов. C-Octet String — это ASCII-текст, завершаемый нулём (0x00), с объявленной максимальной длиной, включающей завершающий символ. Octet String — это поле необработанных байтов, длина которого задаётся предшествующим полем длины (например, short_message, размер которого задаётся sm_length).
| Тип | Кодировка |
|---|---|
| Integer | Фиксированные 1/2/4-октетные беззнаковые, big-endian (сетевой порядок байтов) |
| C-Octet String | ASCII с завершающим NUL; максимальная длина включает терминатор 0x00 |
| C-Octet String (Decimal/Hex) | Как указано выше, но с ограничением на десятичные или шестнадцатеричные цифры ASCII |
| Octet String | Необработанные байты; длина указывается отдельным полем длины, без терминатора |
Разбор примера: submit_sm в канале
Минимальный PDU submit_sm. Значение command_length в заголовке (0x0000003D = 61) — это полный размер в байтах; command_id 0x00000004 — это submit_sm; command_status 0 обозначает запрос; sequence_number 0x0000000F связывает ответ. Далее следует тело в фиксированном порядке полей, определённом спецификацией.
00 00 00 3D command_length = 61
00 00 00 04 command_id = submit_sm
00 00 00 00 command_status = ESME_ROK (request)
00 00 00 0F sequence_number = 15
-- body --
00 service_type = "" (NULL)
05 source_addr_ton = 5 (alphanumeric)
00 source_addr_npi = 0 (unknown)
42 4E 00 source_addr = "BN" + NULL
01 dest_addr_ton = 1 (international)
01 dest_addr_npi = 1 (E.164/ISDN)
... destination_addr, esm_class, ... short_messageЧасто задаваемые вопросы
Включает ли command_length заголовок?
Да. command_length — это полная длина всего PDU в октетах, включая 16-байтовый заголовок. Получатель читает ровно command_length байт, чтобы извлечь один целый PDU из потока TCP.
Какой порядок байтов использует SMPP?
Сетевой порядок байтов — big-endian — для всех многобайтовых целочисленных полей, включая каждое поле заголовка. 4-байтовое значение 61 передаётся как 00 00 00 3D.
Как завершаются текстовые поля?
Текстовые поля — это C-Octet String: символы ASCII, завершаемые одним нулевым байтом (0x00). Пустая C-Octet String — это просто нулевой байт. Объявленная максимальная длина включает этот завершающий символ.
Что такое generic_nack?
generic_nack (command_id 0x80000000) — это ответ, который получатель возвращает, когда PDU невозможно разобрать или он принципиально недопустим — например, при неверном command_length или неизвестном command_id. Его command_status несёт причину.
Как получатель выделяет PDU из потока TCP?
TCP — это поток байтов без границ сообщений, поэтому получатель читает первые 4 байта, чтобы получить command_length, а затем читает указанное общее число байтов, чтобы выделить один полный PDU перед разбором остальной части заголовка и тела.
Технические характеристики источника
На этой странице представлены опубликованные стандарты, на которых они основаны. (Открывается в новой вкладке)