Últimamente nos llegan cada vez más consultas técnicas referentes a si permitimos enviar un mensaje de texto SMS a un puerto concreto de un dispositivo. La respuesta es que sí; sin embargo, esta acción se considera como un procedimiento avanzado, muy manual y que la mayoría de los usuarios no necesitarán nunca. En otras palabras: si tienes ganas de empaparse sobre el tema y meterte en faena, sigue leyendo, pero ten en cuenta que vamos a ir al grano. Además, las instrucciones parten del supuesto de que sabes utilizar un servicio web o hacer llamadas HTTP POST a una página web.
Una breve introducción a SMPP y PDU
La mayoría de nuestras conexiones con operadores de red se realizan mediante el protocolo SMPP (consulta smsforum.net, donde encontrarás descargas de la especificación). Para enviar un SMS a un puerto concreto, necesitarás un conocimiento al menos rudimentario de los conceptos relacionados con este protocolo y, en concreto, de la unidad de datos del protocolo (PDU) SubmitSM. Dicho de la manera más general posible, SMPP funciona utilizando PDU de solicitud y respuesta. Para enviar un mensaje, enviamos una PDU de SubmitSM al operador, que, a su vez, devuelve una PDU de respuesta para indicar que ha aceptado la nuestra.
La PDU SubmitSM contiene todo lo que el operador necesita para enviar un mensaje de texto: los números de móvil del originador y el destino (en los parámetros de dirección de origen y destino), el texto del mensaje que se quiere enviar (en la sección de datos de usuario), y una serie de parámetros adicionales que debemos establecer para describir el contenido del mensaje.
De estos últimos parámetros, los dos más importantes son el esquema de codificación de datos y la clase ESM. El esquema de codificación de datos (o DCS) se utiliza para describir la forma de codificar los bytes de la sección de datos de usuario de la PDU. La clase ESM sirve para describir atributos especiales que se aplican al mensaje (volveremos sobre este tema más adelante).
Hay que destacar que no hay parámetros en una PDU SubmitSM que tomen directamente los puertos de origen y destino de la aplicación del dispositivo al que se va a enviar el mensaje.
En ese caso, ¿cómo especificamos los valores de puerto en la PDU si no hay parámetros para ellos? La respuesta es poniendo un encabezado en la sección de datos de usuario.
Introducción a los encabezados de datos de usuario (UDH)
Un UDH es una serie de bytes dentro de la sección de datos de usuario de una PDU SubmitSM. Un mensaje de texto estándar no tiene UDH, por lo que se trata como un mensaje de texto normal en el teléfono y se entrega en la bandeja de entrada estándar. Un UDH puede contener información de puerto y concatenación para indicarle al dispositivo dónde enviar el mensaje y si todavía tiene que esperar alguna otra parte del mensaje.
A efectos de este ejemplo, sólo necesitamos la información del puerto en la UDH.
Aquí tenemos una cadena de bytes (con codificación hexadecimal) que estarían en la sección de datos de usuario de la PDU para un mensaje WAP Push (los mensajes WAP Push deben incluir información sobre el puerto):
0605040B8423F025060A03AE81EAAF828DADB48401056A0045C60C0364657670726F6A32302E626C6F6773706F742 E636F6D2F000801034D7920426C6F67000101
El encabezado de este mensaje es el siguiente:
0605040B8423F0
Los primeros tres bytes (060504) describen las diferentes longitudes dentro del encabezado. La información de puerto figura en los siguientes cuatro bytes (0B8423F0). En resumen, el mensaje completo podría dividirse de la siguiente manera:
060504: Indicadores de longitud
0B84: Puerto de destino (2948)
23F0: Puerto originador (9200)
25060.... : los bytes del mensaje que describen la URL y un fragmento de texto.
Así, un mensaje WAP Push es una serie de bytes con un UDH que especifica el puerto de destino 2948 y el puerto de origen 9200. Pero, dado que los encabezados son opcionales en la sección de datos de usuario, ¿cómo sabe el teléfono si hay un encabezado? Esto lo indicamos en el parámetro de clase ESM de la PDU.
Indicador de UDH y codificación de datos
Aunque sea un solo byte, el parámetro de clase ESM tiene un papel muy importante en la forma en que el mensaje se interpreta y se muestra en el teléfono. Las combinaciones de bits individuales dentro de este byte indican diferentes requisitos, pero el que nos interesa es el indicador de UDH. Si configura estos bits (y no necesita configurar otros), el valor del byte de clase ESM será 64 (0x40). Esto indica que hay un UDH en la sección de datos de usuario.
Aquí entra en juego el parámetro DCS, que indica la forma de descodificar los bytes situados tras el encabezado (si es que lo hay). En un mensaje normal sin encabezado, este parámetro tiene el valor 0, que indica el alfabeto predeterminado utilizado por el operador. En un mensaje WAP Push, el valor es 4, que indica una combinación binaria de 8 bits.
¿Qué hago para enviar un mensaje a un puerto?
Ahora que conoces los conceptos, pasaré a explicarte lo que querías saber al leer este artículo. Exponemos un servicio de envío avanzado como servicio web y una interfaz HTTP POST. Si te fijas, observarás los parámetros ESMClass y DataCodingScheme. (¿Lo ves? Ya te dije que eran importantes. Si te has saltado todo hasta ahora y no sabes de qué estoy hablando, vuelve atrás y léelo todo.)
Vamos a ver un ejemplo. Supongamos que necesitas enviar un mensaje de texto "ab" (sin las comillas) al puerto 5000 (los valores de los puertos deberás consultarlos en la documentación de la aplicación a la que estés efectuando el envío).
1. Construye el encabezado
Deberás construir el encabezado y, al final de éste, codificar el texto.
En este ejemplo, el encabezado sería:
06050413880000
Porque:
060504: Indicadores de longitud
1388: Puerto de destino (5000)
0000: Puerto originador (cero si no necesita uno en concreto)
2. Codifica el texto
Codifica el texto en ASCII y añade el encabezado. El texto "ab" es 0x6162, así que el mensaje completo con encabezado sería:
060504138800006162
3. Envía el mensaje
En este caso, el valor para el parámetro ESMClass sería 64 y habría que establecer el valor 0 para DataCodingScheme. Pon la cadena 060504138800006162 como parámetro del cuerpo, escribe los valores para el resto de parámetros (originador, destino, etc.) y envíalo.
¡Y ya está! Si tu encabezado es correcto y has codificado el texto correctamente, el mensaje debería entregarse a la aplicación del teléfono que lo necesita.
Notas importantes
Hay algunas cosas que debes tener en cuenta al enviar mensajes como este.
- Normalmente, si el dispositivo de destino no puede interpretar el mensaje que estás enviando, sencillamente no hará nada. Recibirás una confirmación de entrega indicándote que el mensaje se ha entregado al dispositivo, pero no verás nada en pantalla. Esto dificulta muchísimo la depuración.
- En este caso, el parámetro del cuerpo debe ser una cadena con codificación hexadecimal y que incluya los bytes que desees enviar. Eso significa 2 caracteres hexadecimales por byte, es decir, 0xA debe enviarse como 0A, no simplemente como A.
- Los valores para ESMClass y DCS deben ser números decimales.
- Respecto a la codificación de caracteres, hemos recibido informes aislados sobre caracteres alfanuméricos que no se mostraban correctamente, pero no hemos podido averiguar la causa exacta. Si experimentas problemas de codificación, ponte en contacto con nuestro servicio de soporte técnico soporte@esendex.es.