No se puede enviar SMS a través del código C # utilizando System.IO.Ports utilizando módem gsm

Cuando se hace clic en un botón, se envía un sms al número ingresado en el cuadro de texto NumTxt y se envía el texto ingresado en el cuadro de texto SMSTxt. Nombre de puerto ingresado en texbox ComPort Aquí está el controlador de eventos del evento de clic de botón.

using System.IO.Ports; private void button1_Click(object sender, EventArgs e) { try { int mSpeed = 1; serialport.PortName = ComPort.Text; serialport.BaudRate = 96000; serialport.Parity = Parity.None; serialport.DataBits = 8; serialport.StopBits = StopBits.One; serialport.Handshake = Handshake.XOnXOff; serialport.DtrEnable = true; serialport.RtsEnable = true; serialport.NewLine = Environment.NewLine; Console.WriteLine("1a"); try { serialport.Open(); } catch (Exception) { MessageBox.Show("Try another Port." + Environment.NewLine + "Phone not detected or The requested resource is in use.", "CONNECTION ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } Console.WriteLine("2a"); serialport.WriteLine("AT+CMGF=1" + Environment.NewLine); System.Threading.Thread.Sleep(200); serialport.WriteLine("AT+CSCS=GSM" + Environment.NewLine); System.Threading.Thread.Sleep(200); serialport.WriteLine("AT+CMGS=" + (char)34 + NumTxt.Text + (char)34 + Environment.NewLine); System.Threading.Thread.Sleep(200); serialport.WriteLine(SMSTxt.Text + (char)26); System.Threading.Thread.Sleep(mSpeed); serialport.Close(); } catch (Exception) { if (serialport.IsOpen) serialport.Close(); MessageBox.Show("Couldn't send the SMS.", "CONNECTION ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } } 

Pude enviar el sms usando este mismo código ayer, pero no sé por qué no funciona más … sin excepciones. Cuando uso el software que viene con el módem gsm, puedo enviar sms. Pero no a través del código C #. Si alguien puede señalar el error en el código anterior, estaré muy agradecido.

Nunca debe , nunca, nunca utilizar el sueño como un sustituto para esperar el código de resultado final del módem. Del mismo modo que no escribiría un cliente http que ignora por completo todas las respuestas del servidor http, no debería enviar comandos AT a un módem e ignorar por completo las respuestas que envía. Debe leer y analizar todo lo que el módem le devuelve. Nada más funcionará de manera confiable.

Mi sugerencia es que empiece buscando una copia del estándar V.250 y lea al menos todo el capítulo 5. Este estándar es la biblia para el manejo de comandos AT y le enseñará una cantidad enorme con respecto al manejo de comandos AT. Como por ejemplo que usar WriteLine y / o Environment.NewLine es incorrecto; Las líneas de comando AT deben terminar con \r solo y nada más.


Solo para enfatizar la importancia de ese documento: incluso después de trabajar con la implementación del comando AT en teléfonos móviles en Ericsson durante más de una década, yo y mis colegas seguimos consultando ese estándar regularmente .

De hecho, deje de leer esta respuesta aquí ahora, descargue ese documento, lea todo el capítulo 5 antes de volver a leer el rest.


Para enviar comandos en los que no le interesa particularmente la respuesta 1 , el único enfoque confiable es hacer algo similar a

 serialport.Open(); ... // start sending AT+CMGF=1 serialport.Write("AT+CMGF=1\r"); do { line = readLine(serialport); } while (! is_final_result_code(line)) // Sending of AT+CMGF=1 command finished (successfully or not) ... serialport.Close(); 

donde la función readLine lee uno y un byte del puerto serie hasta que haya recibido una línea completa terminada con \r\n y luego devuelve esa línea.

Puede ver el código de al principio para ver un ejemplo de la función is_final_result_code (también se puede comparar con isFinalResponseError y isFinalResponseSuccess 2 en ST-Ericsson U300 RIL ).

El comando AT + CMGS debe manejarse de manera diferente. Debe esperar la respuesta "\r\n> " del módem antes de enviar la carga, consulte la primera parte de esta respuesta para obtener más información.


1 Aunque lo más probable es que le importe si el comando se ejecutó correctamente o no. Vea esta respuesta para una forma realista de enviar una línea de comando y analizar las líneas de respuesta.

2 Tenga en cuenta que CONNECT no es un código de resultado final, es un código de resultado intermedio, por lo que el nombre es FinalResponseSuccess estrictamente hablando no es 100% correcto.