bind_transceiverAbrir y autenticar la sesiónbind_transceiver_respSesión aceptadasubmit_smEnviar un mensajesubmit_sm_respAceptado, ID de mensaje devueltodeliver_smConfirmación de entrega o mensaje entrantedeliver_sm_respConfirmadoenquire_linkKeepalive en estado de inactividad
Qué es SMPP
SMPP — Short Message Peer-to-Peer — es el protocolo binario y basado en sesiones que los agregadores y operadores exponen para la mensajería A2P de alto rendimiento. Mientras que una API REST es cómoda y sin estado, SMPP es una conexión TCP persistente construida para el volumen y la baja latencia.
Un ESME (External Short Messaging Entity — su lado) abre una sesión con el SMSC e intercambia PDU (Protocol Data Units). El protocolo es compacto y eficiente, razón por la cual sigue siendo la columna vertebral de los grandes remitentes incluso cuando REST cubre el uso cotidiano.
La versión más ampliamente desplegada es SMPP v3.4; la v5.0 añade señalización del estado de congestión y parámetros mejorados, pero es compatible hacia atrás. Nunca debe asumirse que una función de v5.0 está disponible hasta que la respuesta del bind confirme la versión negociada.
Tipos de bind y sesiones
Antes de enviar nada, un ESME debe hacer bind — autenticarse y declarar un rol. Un bind de transmisor solo envía mensajes; un bind de receptor solo recibe mensajes originados en el móvil y confirmaciones de entrega; un bind de transceptor hace ambas cosas sobre una sola conexión.
El transceptor suele preferirse porque reduce a la mitad el número de conexiones y simplifica la correlación de los DLR con los envíos. El número de binds concurrentes y los mensajes por segundo por bind (TPS) los aprovisiona el proveedor y deben respetarse.
El bind transporta un system_id, una contraseña, un system_type y un address_range. Un address_range mal configurado rompe silenciosamente el enrutamiento de MO y DLR en los binds de receptor — un error clásico de integración que no produce errores, solo tráfico ausente.
PDU y el submit_sm
Cada interacción de SMPP es un PDU con una cabecera de comando (longitud, id de comando, estado, número de secuencia) y un cuerpo. El caballo de batalla es submit_sm, que transporta un único mensaje saliente.
Dos pares de campos deciden el direccionamiento: source_addr con su TON/NPI (tipo de número / indicador del plan de numeración) y dest_addr con el suyo propio. Un sender ID alfanumérico usa TON 5; un MSISDN internacional usa TON 1, NPI 1. Si se configuran mal, el sender ID se muestra incorrectamente o el mensaje se rechaza.
El campo data_coding define la codificación — GSM de 7 bits (0), 8 bits (4) o UCS-2 (8) para Unicode. Los mensajes largos se concatenan con bytes UDH en el cuerpo o con los parámetros opcionales SAR (sar_msg_ref_num, sar_total_segments, sar_segment_seqnum); elija un método y manténgalo, porque las rutas difieren en cuál aceptan.
La ventana, el throttling y los keepalives
SMPP utiliza una ventana de transmisión: un límite al número de PDU submit_sm enviados antes de que regresen sus respuestas. Superar la ventana, o el TPS aprovisionado, dispara ESME_RTHROTTLED (0x58). La respuesta correcta es reducir el ritmo con jitter, no reintentar en bucle.
Para detectar una conexión TCP semiabierta, cada lado envía enquire_link con un temporizador de inactividad (habitualmente cada 30-60 segundos) y espera un enquire_link_resp. Una respuesta ausente significa que la sesión está muerta y debe rehacerse el bind con retroceso exponencial.
El cierre ordenado usa unbind / unbind_resp. Las desconexiones inesperadas deben desencadenar una reconexión con retroceso y reintentos idempotentes, para que una ventana caída no cause envíos duplicados ni facturación doble.
Confirmaciones de entrega sobre SMPP
Las confirmaciones de entrega llegan como PDU deliver_sm. El texto del recibo en el campo short_message transporta id, sub, dlvrd, fecha de envío, fecha de finalización, el stat terminal (DELIVRD, UNDELIV, EXPIRED, REJECTD) y un código err.
Correlacione el DLR con su envío original usando el message_id del proveedor, no solo el texto del recibo — el message_id puede devolverse en hexadecimal en submit_resp pero en decimal en el DLR, así que normalice ambos formatos.
Responda siempre con un deliver_sm_resp. Un DLR no confirmado se reenvía por el SMSC y puede bloquear la ventana de recepción, así que confírmelo con prontitud aunque su procesamiento posterior sea asíncrono.
- SMPP es una sesión binaria persistente para A2P de alto volumen; v3.4 es la base común, v5.0 es compatible hacia atrás.
- Haga bind como transmisor, receptor o transceptor; el transceptor reduce a la mitad las conexiones y facilita la correlación de DLR.
- TON/NPI deciden cómo se muestra el sender ID y data_coding decide la codificación — ambos son fáciles de configurar mal.
- Respete la ventana y el TPS, reduzca el ritmo ante ESME_RTHROTTLED y mantenga la sesión viva con enquire_link.