# Anatomia do PDU SMPP: cabeçalho e corpo

> Cada mensagem SMPP é um PDU (Protocol Data Unit) com um cabeçalho fixo de 16 bytes seguido de um corpo específico da operação. O cabeçalho são quatro inteiros big-endian de 4 bytes: command_length, command_id, command_status e sequence_number. O command_length conta o PDU inteiro incluindo o cabeçalho, pelo que o recetor lê primeiro 4 bytes e depois o resto.

- URL canônico: https://www.broadnet.me/pt/reference/smpp-pdu-anatomy
- Idioma: pt
- Última atualização: 2026-07-18
- Editor: BroadNet (https://www.broadnet.me)

A disposição exata de bytes de um PDU SMPP: o cabeçalho de 16 bytes (command_length, command_id, command_status, sequence_number), o corpo e como os campos são codificados.

## O cabeçalho de 16 bytes

Cada PDU começa com os mesmos quatro inteiros de 32 bits sem sinal em ordem de rede (big-endian). O command_length é a contagem total de octetos do PDU incluindo estes 16 bytes de cabeçalho — um parser lê os primeiros 4 bytes, fica a saber o comprimento total e depois lê o restante. O command_id identifica a operação. O command_status é 0 (ESME_ROK) nos pedidos e transporta um código de erro nas respostas. O sequence_number correlaciona um pedido com a sua resposta.

*Campos do cabeçalho SMPP (16 bytes, big-endian)*

| Offset | Campo | Tamanho | Finalidade |
|---|---|---|---|
| 0 | command_length | 4 octetos | Comprimento total da PDU em octetos, incluindo o cabeçalho |
| 4 | command_id | 4 octetos | Identificador de operação (ex: submit_sm = 0x00000004) |
| 8 | command_status | 4 octetos | 0 numa solicitação; código de erro numa resposta |
| 12 | sequence_number | 4 octetos | Correlaciona solicitação↔resposta (0x00000001–0x7FFFFFFF) |

## command_id e o bit de resposta

Cada operação tem um command_id. A resposta correspondente usa o mesmo valor com o bit mais significativo ativado (OR lógico com 0x80000000). Assim, submit_sm é 0x00000004 e submit_sm_resp é 0x80000004. O generic_nack (0x80000000) é a resposta de erro genérica para um PDU não interpretável ou inválido.

*Valores comuns de command_id*

| Operação | Requisição | Resposta |
|---|---|---|
| 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 |

## O corpo e como os campos são codificados

A seguir ao cabeçalho vem o corpo específico da operação com parâmetros obrigatórios, opcionalmente seguido de parâmetros opcionais TLV. O SMPP usa três codificações de campo. Os inteiros são de tamanho fixo, sem sinal, big-endian. As C-Octet Strings são texto ASCII terminado por um NULL (0x00), com um comprimento máximo declarado que inclui o terminador. As Octet Strings são campos de bytes em bruto cujo comprimento é dado por um campo de comprimento anterior (por exemplo short_message, cujo tamanho é definido por sm_length).

*Codificações de campo do SMPP*

| Tipo | Codificação |
|---|---|
| Integer | 1/2/4 octetos fixos, sem sinal, big-endian (ordem de bytes de rede) |
| C-Octet String | ASCII terminado em NUL; o comprimento máximo inclui o terminador 0x00 |
| C-Octet String (Decimal/Hex) | Como acima, mas restrito a dígitos ASCII decimais ou hexadecimais |
| Octet String | Bytes brutos; comprimento fornecido por um campo de comprimento separado, sem terminador |

## Um exemplo prático: submit_sm em trânsito

Um PDU submit_sm mínimo. O command_length do cabeçalho (0x0000003D = 61) é a contagem total de bytes; o command_id 0x00000004 é submit_sm; o command_status 0 marca um pedido; o sequence_number 0x0000000F correlaciona a resposta. O corpo segue depois na ordem fixa de campos definida pela especificação.

*cabeçalho submit_sm + início do corpo (anotado)*

```hex
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
```

## Perguntas frequentes

### O command_length inclui o cabeçalho?

Sim. O command_length é o comprimento total do PDU inteiro em octetos, incluindo o cabeçalho de 16 bytes. Um recetor lê exatamente command_length bytes para consumir um PDU completo do fluxo TCP.

### Que ordem de bytes usa o SMPP?

Ordem de rede — big-endian — para todos os campos inteiros de vários octetos, incluindo todos os campos do cabeçalho. Um valor de 4 bytes igual a 61 é transmitido como 00 00 00 3D.

### Como são terminados os campos de texto?

Os campos de texto são C-Octet Strings: caracteres ASCII terminados por um único byte NULL (0x00). Uma C-Octet String vazia é apenas o byte NULL. O comprimento máximo declarado inclui esse terminador.

### O que é um generic_nack?

O generic_nack (command_id 0x80000000) é a resposta que o recetor devolve quando um PDU não pode ser interpretado ou é fundamentalmente inválido — por exemplo um command_length incorreto ou um command_id desconhecido. O seu command_status transporta o motivo.

### Como delimita um recetor os PDUs no fluxo TCP?

O TCP é um fluxo de bytes sem fronteiras de mensagem, pelo que o recetor lê os primeiros 4 bytes para obter o command_length e depois lê esse número total de bytes para isolar um PDU completo antes de interpretar o resto do cabeçalho e do corpo.

## Fontes

- [SMPP v3.4 specification — §2, §3 PDU format](https://smpp.org/SMPP_v3_4_Issue1_2.pdf)
- [SMPP v5.0 specification](https://smpp.org/SMPP_v5.pdf)

## Relacionados

- [Visão geral do protocolo SMPP](https://www.broadnet.me/pt/reference/smpp-protocol-overview)
- [Decodificador de PDU SMPP (ferramenta gratuita)](https://www.broadnet.me/pt/tools/smpp-pdu-decoder)
- [Parâmetros opcionais SMPP TLV](https://www.broadnet.me/pt/reference/smpp-tlv-parameters)
- [Códigos de erro command_status SMPP](https://www.broadnet.me/pt/reference/smpp-command-status-errors)
- [Documentação do desenvolvedor](https://www.broadnet.me/pt/developers)
