Colabora .NET |
Envío de Mensajes SMS y Lectura de los Mensajes Almacenados en C# 2.0
Fecha: 17/Ago/2006 (16-08-06)
|
Nombre: Mauro Maximiliano Melgar Ocupación: Desarrollador Ubicación: Buenos Aires, Argentina
Envío de Mensajes SMS y Lectura de los Mensajes Almacenados en C# 2.0
Antes de comenzar a explicar un poco el funcionamiento, quiero aclarar, que vengo de muchos años de programar con Visual Basic, he decidido cambiar a C#, y seguramente puedo tener algún error en el código, ya sea de performance o de concepto, si así lo fuere, le pido disculpas al lector y se que con el tiempo y la practica mejorare en el lenguaje.
Proyecto: Utilizar la clase SerialPort del Framework 2.0 para comunicarnos mediante comandos AT con el modem de un celular GSM.
Equipo Utilizado para el desarrollo y el testing: MOTOROLA E398 CABLE DE DATOS USB
Celulares Compatibles: Todo celular GSM que tenga modem incorporado (hoy en día, por lo general, todos los celulares lo traen) y conexión usb.
Repaso General del Proyecto:
El proyecto se compone de 2 clases, una llamada Gsm y la otra Sms. Gsm, comprende las funciones básicas para la comunicación con el celular, ya sea, desde abrir el puerto de comunicaciones, leer o enviar los mensajes y cerrar el puerto. Y Sms, es una clase que posee propiedades Get y Set para los mensajes de texto.
En la clase Gsm, los 2 rasgos más importantes, seguramente son, que implementa la interfaz IEnumerable para que la propiedad Buzon, pueda devolver un objeto del tipo Sms y que utiliza una lista genérica del tipo Sms para almacenar los mensajes que se encuentran en el celular.
Documentación del Proyecto:
Acá podemos ver que el constructor de la clase GSM asigna los valores por default
public Gsm() { _PuertoCom=""; _BitsDeParada=StopBits.One; _Paridad=Parity.None; _DataBits=8; _Baudios=Baudios.BPS_115200; _PuertoAbierto=false; }
Definimos las variables a utilizar en nuestra clase para manejar el puerto COM a donde se va a conectar, los Baudios, etc.
private string _PuertoCom; private StopBits _BitsDeParada; private Parity _Paridad; private int _DataBits; private int _Baudios; private Boolean _PuertoAbierto;
Creamos la variable Puerto del tipo SerialPort, la cual, utilizaremos en todo el proyecto
private SerialPort Puerto = new SerialPort();
Esta estructura es algo importante, ya que aca definimos cual es el comando AT que vamos a enviar para obtener el tipo de mensaje que necesitemos.
public struct TipoMensaje { public const string Recibidos_Leidos = "REC READ"; public const string Recibidos_No_Leidos = "REC UNREAD"; public const string Enviados = "STO UNSEND"; public const string Escritos_Sin_Enviar = "STO SENT"; public const string Todos = "ALL"; }
Definición de la estructura para configurar la velocidad de los baudios
public struct Baudios { public const int BPS_1200=1200; public const int BPS_9600=9600; public const int BPS_28800=28800; public const int BPS_57600=57600; public const int BPS_115200=115200; }
Una manera sencilla de especificar algunos de los puertos COM que tengamos disponibles en la PC.
public struct PuertoComunicacion { public const string COM1 = "COM1"; public const string COM2 = "COM2"; public const string COM3 = "COM3"; public const string COM4 = "COM4"; public const string COM5 = "COM5"; public const string COM6 = "COM6"; public const string COM7 = "COM7"; public const string COM8 = "COM8"; public const string COM9 = "COM9"; public const string COM10 = "COM10"; }
Esta propiedad la vamos a utilizar para especificar el tipo de mensaje (TipoMensaje) que vamos a buscar cuando comencemos a utilizar la clase en una aplicación.
public string TipoDeMensaje { get { return _TipoDeMensaje; } set { _TipoDeMensaje = value; } }
Variable de uso interno de la clase donde almacenamos el TipoMensaje
private string _TipoDeMensaje;
Propiedad para especificar el DataBit
public int DataBits { get { return _DataBits; }
set { _DataBits = value; } }
Propiedad para especificar la Paridad, donde el valor es del tipo Parity, por ejemplo: Parity.None
public Parity Paridad { get { return _Paridad; }
set { _Paridad = value; } }
Propiedad a la cual le especificamos el puerto de comunicacion
public string PuertoCom { get { return _PuertoCom; }
set { _PuertoCom = value; }
}
Propiedad a la cual le especificamos el Bit de Stop
public StopBits BitsDeStop { get { return _BitsDeParada; }
set { _BitsDeParada = value; } }
Propiedad que recibe como parametro un valor de la estructura Baudios
public int Velocidad { get { return _Baudios; }
set { _Baudios = value; } }
Propiedad de tipo boolean donde sabremos si el puerto COM esta abierto o no
public Boolean PuertoAbierto { get { return _PuertoAbierto; } }
Funcion que establece los parametros principales para el uso de SerialPort, establecer que procedimiento se utilizara como evento para la recepcion de los datos y devolver true si se pudo abrir el puerto, en caso contrario, devuelve false
public Boolean AbrirPuerto() {
try { Puerto.PortName = _PuertoCom; Puerto.Parity = _Paridad; Puerto.BaudRate = _Baudios; Puerto.StopBits = _BitsDeParada; Puerto.DataReceived += new SerialDataReceivedEventHandler(RecibiendoDatos);
Puerto.Open(); _PuertoAbierto = true; return true; } catch { _PuertoAbierto = false; return false; } }
Devuelve tru si el puerto esta abrierto y lo cerro, false en el caso de que no este abierto
public Boolean CerrarPuerto() { if (_PuertoAbierto) { Puerto.Close(); return true; } else { return false; } }
La propiedad buzon, devuelve un objeto del tipo Sms para poder recorrerlo desde nuestra aplicación mediante un foreach
public IEnumerable<Sms> Buzon { get { BuscarMensajes(_TipoDeMensaje);
for (int i = 0; i <= (BandejaEntrada.Count-1); i++) { yield return BandejaEntrada[i]; } }
}
Funcion que nos permite enviar un mensaje de texto y devolver true si el envio fue satisfactorio.
public Boolean EnviarMensaje(string NroTelefono, string Mensaje) {
try {
Puerto.WriteLine("AT\r"); Puerto.WriteLine("AT+CMGF=1\r"); Puerto.WriteLine("AT+CMGS=\"" + NroTelefono.Trim() + "\"\r"); Puerto.WriteLine(Mensaje.Trim() + '\x001a');
return true; } catch (Exception Error) { return false; }
}
El procedimiento BuscarMensajes recibe como parametro un string, se debe utilizar algunos de los valores de la estructura TipoMensaje
private void BuscarMensajes(string TipoDeMensaje) {
Puerto.WriteLine("AT+CMGF=1\r"); Thread.Sleep(50); Puerto.WriteLine("AT+CPMS=\"MT\"\r"); Thread.Sleep(50); Puerto.WriteLine("AT+CMGL=\"" + TipoDeMensaje +"\"\r"); Thread.Sleep(1000); }
Este es el procedimiento que se utiliza como evento para la busqueda de los mensajes cuando se envia el comando AT en especifico, podemos notar que solamente esta implemantado los del tipo “+CMGL” que son los de SMS almacenados en el celular, aunque es totalmente modificable y adaptable a todas las necesidades.
private void RecibiendoDatos(object sender, SerialDataReceivedEventArgs e) {
String Linea; int Indice = 0;
SerialPort Serie = (SerialPort)sender;
Thread.Sleep(200);
Linea = Serie.ReadExisting();
while (Linea.IndexOf("+CMGL:", Indice) > 0) {
int Comienzo = Linea.IndexOf("+CMGL:", Indice); int Final = Linea.IndexOf("+CMGL:", Comienzo + 1);
if (Final <= 0) { Final = Linea.Length; }
string Mensaje;
Mensaje = Linea.Substring(Comienzo, Final - Comienzo);
string[] Componentes = Mensaje.Split(','); string Tel = Componentes[2]; string IndiceMensaje = Componentes[0];
int IIndice = 0; int FIndice = 0;
IIndice = IndiceMensaje.IndexOf("+CMGL:") + "+CMGL:".Length; FIndice = IndiceMensaje.Length - IIndice;
IndiceMensaje = IndiceMensaje.Substring(IIndice, FIndice);
int FinalIndice = Tel.IndexOf("\r\n");
if (FinalIndice <= 0) { FinalIndice = Tel.Length; }
Tel = Tel.Substring(0, FinalIndice);
int ComienzoMsgIdx = Mensaje.IndexOf("\r\n");
int FinalMsgIdx = Mensaje.IndexOf("\r\n", ComienzoMsgIdx + 1);
if (FinalMsgIdx <= 0) { FinalMsgIdx = Mensaje.Length; }
string Msg = Mensaje.Substring(ComienzoMsgIdx, FinalMsgIdx - ComienzoMsgIdx);
Sms _Mensaje = new Sms();
_Mensaje.IDSms = IndiceMensaje.Trim(); _Mensaje.Telefono = Tel.Trim(); _Mensaje.Mensaje = Msg.Trim();
BandejaEntrada.Add(_Mensaje);
Indice = Comienzo + 1;
} }
Espero que este ejemplo les halla sido de utilidad y que le saquen el mayor probecho posible para los que desean realizar un desarrollo con caracteristicas similares o implementando estas mismas.
|
Código de ejemplo (ZIP): |
Fichero con el código de ejemplo: mauro_melgar_envio_sms.zip - 86,48 KB
|