# Anatomía de una PDU SMPP: cabecera y cuerpo

> Cada mensaje SMPP es una PDU (Protocol Data Unit) con una cabecera fija de 16 bytes seguida de un cuerpo específico de la operación. La cabecera son cuatro enteros big-endian de 4 bytes: command_length, command_id, command_status y sequence_number. command_length cuenta la PDU completa incluida la cabecera, de modo que el receptor lee primero 4 bytes y después el resto.

- URL canónica: https://www.broadnet.me/es/reference/smpp-pdu-anatomy
- Idioma: es
- Última actualización: 2026-07-18
- Editor: BroadNet (https://www.broadnet.me)

La disposición exacta en bytes de una PDU SMPP: la cabecera de 16 bytes (command_length, command_id, command_status, sequence_number), el cuerpo y cómo se codifican los campos.

## La cabecera de 16 bytes

Toda PDU comienza con los mismos cuatro enteros sin signo de 32 bits en orden de red (big-endian). command_length es el número total de octetos de la PDU incluidos estos 16 bytes de cabecera: un analizador lee los primeros 4 bytes, averigua la longitud completa y luego lee el resto. command_id identifica la operación. command_status es 0 (ESME_ROK) en las solicitudes y transporta un código de error en las respuestas. sequence_number correlaciona una solicitud con su respuesta.

*Campos de la cabecera SMPP (16 bytes, big-endian)*

| Desplazamiento | Campo | Tamaño | Propósito |
|---|---|---|---|
| 0 | command_length | 4 octetos | Longitud total de la PDU en octetos, encabezado incluido |
| 4 | command_id | 4 octetos | Identificador de operación (p. ej., submit_sm = 0x00000004) |
| 8 | command_status | 4 octetos | 0 en una solicitud; código de error en una respuesta |
| 12 | sequence_number | 4 octetos | Correlaciona solicitud↔respuesta (0x00000001–0x7FFFFFFF) |

## command_id y el bit de respuesta

Cada operación tiene un command_id. La respuesta correspondiente usa el mismo valor con el bit más significativo activado (OR lógico con 0x80000000). Así, submit_sm es 0x00000004 y submit_sm_resp es 0x80000004. generic_nack (0x80000000) es la respuesta de error genérica para una PDU no analizable o no válida.

*Valores comunes de command_id*

| Operación | Solicitud | Respuesta |
|---|---|---|
| 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 |

## El cuerpo y cómo se codifican los campos

Tras la cabecera viene el cuerpo específico de la operación con parámetros obligatorios, seguido opcionalmente de parámetros opcionales TLV. SMPP usa tres codificaciones de campo. Los enteros son de tamaño fijo, sin signo y big-endian. Las C-Octet String son texto ASCII terminado en NULL (0x00), con una longitud máxima declarada que incluye el terminador. Las Octet String son campos de bytes en bruto cuya longitud viene dada por un campo de longitud previo (por ejemplo, short_message, cuyo tamaño lo fija sm_length).

*Codificaciones de campo en SMPP*

| Tipo | Codificación |
|---|---|
| Integer | Entero sin signo fijo de 1/2/4 octetos, big-endian (orden de bytes de red) |
| C-Octet String | ASCII terminado en NUL; la longitud máxima incluye el terminador 0x00 |
| C-Octet String (Decimal/Hex) | Igual que lo anterior, pero restringido a dígitos ASCII decimales o hexadecimales |
| Octet String | Bytes sin procesar; la longitud se proporciona mediante un campo de longitud independiente, sin terminador |

## Un ejemplo práctico: submit_sm en el cable

Una PDU submit_sm mínima. El command_length de la cabecera (0x0000003D = 61) es el número total de bytes; command_id 0x00000004 es submit_sm; command_status 0 marca una solicitud; sequence_number 0x0000000F correlaciona la respuesta. A continuación sigue el cuerpo en el orden fijo de campos definido por la especificación.

*Cabecera de submit_sm + inicio del cuerpo (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
```

## Preguntas frecuentes

### ¿command_length incluye la cabecera?

Sí. command_length es la longitud total de toda la PDU en octetos, incluida la cabecera de 16 bytes. El receptor lee exactamente command_length bytes para consumir una PDU completa del flujo TCP.

### ¿Qué orden de bytes usa SMPP?

Orden de red (big-endian) para todos los campos enteros de varios octetos, incluidos todos los de la cabecera. Un valor de 4 bytes igual a 61 se transmite como 00 00 00 3D.

### ¿Cómo se terminan los campos de texto?

Los campos de texto son C-Octet String: caracteres ASCII terminados por un único byte NULL (0x00). Una C-Octet String vacía es solo el byte NULL. La longitud máxima declarada incluye ese terminador.

### ¿Qué es un generic_nack?

generic_nack (command_id 0x80000000) es la respuesta que devuelve el receptor cuando una PDU no puede analizarse o es fundamentalmente inválida, por ejemplo un command_length erróneo o un command_id desconocido. Su command_status transporta el motivo.

### ¿Cómo delimita el receptor las PDU en el flujo TCP?

TCP es un flujo de bytes sin fronteras de mensaje, así que el receptor lee los primeros 4 bytes para obtener command_length y luego lee ese número total de bytes para aislar una PDU completa antes de analizar el resto de la cabecera y el cuerpo.

## Fuentes

- [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)

## Relacionado

- [Descripción general del protocolo SMPP](https://www.broadnet.me/es/reference/smpp-protocol-overview)
- [Decodificador de PDU SMPP (herramienta gratuita)](https://www.broadnet.me/es/tools/smpp-pdu-decoder)
- [Parámetros opcionales SMPP TLV](https://www.broadnet.me/es/reference/smpp-tlv-parameters)
- [Códigos de error SMPP command_status](https://www.broadnet.me/es/reference/smpp-command-status-errors)
- [Documentación para desarrolladores](https://www.broadnet.me/es/developers)
