# Anatomia della PDU SMPP: header e body

> Ogni messaggio SMPP è una PDU (Protocol Data Unit) con un header fisso di 16 byte seguito da un body specifico dell'operazione. L'header è costituito da quattro interi big-endian da 4 byte: command_length, command_id, command_status e sequence_number. command_length conteggia l'intera PDU header incluso, quindi il ricevente legge prima 4 byte e poi il resto.

- URL canonico: https://www.broadnet.me/it/reference/smpp-pdu-anatomy
- Lingua: it
- Ultimo aggiornamento: 2026-07-18
- Editore: BroadNet (https://www.broadnet.me)

Il layout esatto in byte di una PDU SMPP: l'header di 16 byte (command_length, command_id, command_status, sequence_number), il body e come sono codificati i campi.

## L'header di 16 byte

Ogni PDU inizia con gli stessi quattro interi a 32 bit senza segno in ordine di rete (big-endian). command_length è il numero totale di ottetti della PDU inclusi questi 16 byte di header: un parser legge i primi 4 byte, ricava la lunghezza completa e legge il resto. command_id identifica l'operazione. command_status vale 0 (ESME_ROK) nelle richieste e trasporta un codice di errore nelle risposte. sequence_number correla una richiesta con la sua risposta.

*Campi dell'header SMPP (16 byte, big-endian)*

| Offset | Campo | Dimensione | Scopo |
|---|---|---|---|
| 0 | command_length | 4 octets | Lunghezza totale della PDU in ottetti, intestazione inclusa |
| 4 | command_id | 4 octets | Identificatore operazione (es. submit_sm = 0x00000004) |
| 8 | command_status | 4 octets | 0 in una richiesta; codice di errore in una risposta |
| 12 | sequence_number | 4 octets | Correlaziona richiesta↔risposta (0x00000001–0x7FFFFFFF) |

## command_id e il bit di risposta

Ogni operazione ha un command_id. La risposta corrispondente usa lo stesso valore con il bit più significativo impostato (OR logico con 0x80000000). Così submit_sm è 0x00000004 e submit_sm_resp è 0x80000004. generic_nack (0x80000000) è la risposta di errore generica per una PDU non interpretabile o non valida.

*Valori comuni di command_id*

| Operazione | Richiesta | Risposta |
|---|---|---|
| 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 |

## Il body e come sono codificati i campi

Dopo l'header viene il body specifico dell'operazione con i parametri obbligatori, opzionalmente seguito dai parametri opzionali TLV. SMPP utilizza tre codifiche di campo. Gli interi sono a dimensione fissa, senza segno, big-endian. Le C-Octet String sono testo ASCII terminato da un NULL (0x00), con una lunghezza massima dichiarata che include il terminatore. Le Octet String sono campi di byte grezzi la cui lunghezza è indicata da un campo di lunghezza precedente (ad esempio short_message, la cui dimensione è fissata da sm_length).

*Codifiche dei campi SMPP*

| Tipo | Codifica |
|---|---|
| Integer | Interi senza segno a 1/2/4 ottetti fissi, big-endian (ordine dei byte di rete) |
| C-Octet String | ASCII terminato da NUL; la lunghezza massima include il terminatore 0x00 |
| C-Octet String (Decimal/Hex) | Come sopra, ma limitato alle cifre ASCII decimali o esadecimali |
| Octet String | Byte grezzi; la lunghezza è fornita da un campo di lunghezza separato, senza terminatore |

## Un esempio pratico: submit_sm sul filo

Una PDU submit_sm minimale. Il command_length dell'header (0x0000003D = 61) è il numero totale di byte; command_id 0x00000004 è submit_sm; command_status 0 indica una richiesta; sequence_number 0x0000000F correla la risposta. Il body segue poi nell'ordine fisso dei campi definito dalla specifica.

*Header submit_sm + inizio del body (annotato)*

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

## Domande frequenti

### command_length include l'header?

Sì. command_length è la lunghezza totale dell'intera PDU in ottetti, inclusi i 16 byte di header. Un ricevente legge esattamente command_length byte per consumare un'intera PDU dallo stream TCP.

### Quale ordine dei byte usa SMPP?

L'ordine di rete — big-endian — per tutti i campi interi multi-ottetto, inclusi tutti i campi dell'header. Un valore a 4 byte pari a 61 viene trasmesso come 00 00 00 3D.

### Come sono terminati i campi di testo?

I campi di testo sono C-Octet String: caratteri ASCII terminati da un singolo byte NULL (0x00). Una C-Octet String vuota è composta dal solo byte NULL. La lunghezza massima dichiarata include quel terminatore.

### Che cos'è una generic_nack?

generic_nack (command_id 0x80000000) è la risposta che il ricevente restituisce quando una PDU non può essere interpretata o è fondamentalmente non valida — ad esempio per un command_length errato o un command_id sconosciuto. Il suo command_status ne indica il motivo.

### Come delimita le PDU un ricevente sullo stream TCP?

TCP è uno stream di byte senza confini di messaggio, quindi il ricevente legge i primi 4 byte per ottenere command_length, poi legge quel numero totale di byte per isolare una PDU completa prima di interpretare il resto dell'header e il body.

## Fonti

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

## Correlati

- [Panoramica del protocollo SMPP](https://www.broadnet.me/it/reference/smpp-protocol-overview)
- [Decoder PDU SMPP (strumento gratuito)](https://www.broadnet.me/it/tools/smpp-pdu-decoder)
- [Parametri opzionali TLV di SMPP](https://www.broadnet.me/it/reference/smpp-tlv-parameters)
- [Codici di errore command_status di SMPP](https://www.broadnet.me/it/reference/smpp-command-status-errors)
- [Documentazione per sviluppatori](https://www.broadnet.me/it/developers)
