11 octubre, 2010

Enviar sms en formato PDU

-->


 Como siempre: No es tan difícil como parece.

     Al conectar nuestra alarma a siemens C60 se encuentra el problema del envío del sms en modo Texto. Este teléfono sólo acepta formato PDU.
     Este formato parece complicado pero no lo es. Aquí tenemos las primeras pruebas enviando "Hola Mundo" al numero de teléfono 123456789.


     Desglosando la trama:
  1. 00 Centro de envío del sms. Se usa el del teléfono.
  2. 11 Tipo de sms. se usa PDU.
  3. 00 Referencia sms. Es indiferente.
  4. 09 Longitud Telf destinatario. Es este caso 9
  5. 81 Tipo de Num Telf. Es nacional
  6. 21 Número de teléfono del destinatario. Como se ve hay que invertir los números
  7. 43    "
  8. 65    "
  9. 87    "
  10. F9    "
  11. 00 Protocolo
  12. 00 Codificación
  13. A7 Periodo de validez del sms (el máximo)
  14. 0A Número de bytes del Texto a enviar (no tiene porque coincidir una vez codificado a PDU)
  15. C8 Texto del sms a enviar
  16. 37     "
  17. 3B     "
  18. 0C     "
  19. 6A     "
  20. D6     "
  21. DD     "
  22. E4     "
  23. 37     "
 Codificación del Número de teléfono a formato PDU
     Por lo general lo tendremos en una cadena de caracteres. La forma más sencilla es leer el segundo caracter y restarle 0x30. Después desplazamos 4 veces a la izquierda y le sumamos el primer caracter -0x30.
               base= telefono[1]-0x30;
               base <<=4;
               code[xbuff++]= base+ (telefono[0]-0x30);
     El número lo tenemos guardado en la cadena teléfono[] y guardamos sobre la cadena code[] para después enviar toda la secuencia. Sólo queda hacer lo mismo con los demás números hasta llegar al último que tenemos que rellenar el nibble más alto con F.
              code[xbuff++]= 0xF0+ (telefono[8]-0x30);
     Con esto ya tenemos el número codificado.
Codificación del Texto a enviar a formato PDU
     Para moverse en código ASCII basta con 7bits por lo que se desaprovecha uno en la transmisión de bytes(8bits) El formato PDU aprovecha ese bit. Veamos como se hace:


     Una forma de realizarlo, La más sencilla y comprensible es:
                base = cadena[contador+1]& 0x01;
                base <<=7;
                code[xbuff++]=base+ cadena[contador+0]; //1
                cadena[contador+1]>>=1;
                base= cadena[contador+2] &0x03;
                base <<=6;
                code[xbuff++]=base+ cadena[contador+1]; //2
                cadena[contador+2]>>=2;
                base= cadena[contador+3] &0x07;
                base <<=5;
                code[xbuff++]=base+ cadena[contador+2]; //3
                cadena[contador+3]>>=3;
                base= cadena[contador+4] &0x0f;
                base <<=4;
                code[xbuff++]=base+ cadena[contador+3];
                cadena[contador+4]>>=4;
                base= cadena[contador+5] &0x1f;
                base <<=3;
                code[xbuff++]=base+ cadena[contador+4];
                cadena[contador+5]>>=5;
                base= cadena[contador+6] &0x3F;
                base <<=2;
                code[xbuff++]=base+ cadena[contador+5];
                cadena[contador+6]>>=6;
                base= cadena[contador+7] &0x7F;
                base <<=1;
                code[xbuff++]=base+ cadena[contador+6];
                base = cadena[contador+9]& 0x01;
                base <<=7;
                code[xbuff++]=base+ cadena[contador+8]; //1
                cadena[contador+9]>>=1;
                base= cadena[contador+10] &0x03;
                base <<=6;
                code[xbuff++]=base+ cadena[contador+9]; //2
    
Ahora queda meterlo en una subrutina para poder manejar cualquier longitud de texto y simplificar lo expuesto y ya lo tenemos. No olvidar que hay que incluir otros datos antes detallados.Para ver si está correctamente configurado

     Para enviarlo no queda ahí la cosa. Lo primero,  al arrancar el móvil, le cargamos:
          printf("AT+CSMS=0\r\n" ); //Formato PDU
     Cuando deseemos enviar un sms procedemos así:
  1. Enviamos:      printf("AT+CMGS=");
  2. Seguido de la cantidad de bytes a enviar (o la cantidad de septetos del sms +12) pero OJO en ascii y en decimal contando desde cero. Si tenemos 22 no lo podemos enviar tal cual. Hay que enviar 0x32 0x32. Ojo a eso!. Por tanto;     printf("%U",22);  seguido del retorno de carro;   printf("\r");
  3. Esperamos que nos devuelva ">" y le enviamos la cadena de texto (también es ascii) que tenemos:  printf("00110009917689x99xFx0000AA0AC8373B0C6AD7DDE437");
  4. seguido de ctrl+Z. o lo que es lo mismo 0x1A : printf("\x1A"); 
  5. seguido de un fin de linea:   printf("\r\n");
     Ojo a la cadena que hemos formado que hay que enviarla en ascii. Es decir:
el primer dato de la cadena era 0x00. Por tanto hay que enviar 0x30,0x30. El segundo es 0x11. Por tanto hay que enviar 0x31,0x31. Así sucesivamente. Ojito a eso que se tiene la tendencia a enviar la cadena en hexadecimal y nos devuelve, al ratito de enviar la trama: +CMS: ERROR 500.


 Como siempre: No es tan difícil como parece.

Gracias por visitar mi blog personal. Si te ha gustado: haz el favor de hacer clic en los anuncios de google que aparecen al principio de cada entrada y date una vuelta por por ellos. Son céntimos lo que aporta pero me ayudas a seguir subiendo cosas. Gracias.


-->

4 comentarios:

  1. Anónimo9:40 p. m.

    como meto esto a pic C ???

    gracias

    ResponderEliminar
  2. No entiendo bien la pregunta.
    Por lo mormal se hace con una subrutina (o funcion).

    ResponderEliminar
  3. Es mas rapido el envio por texto o formato pdu en sms

    ResponderEliminar
    Respuestas
    1. La diferencia la puedes encontrar a la hora de formar el texto. Insignificante.

      Eliminar