Невозможно отправить SMS через код C# с помощью System.IO.Ports с помощью модема gsm
При нажатии кнопки отправляется смс на номер, введенный в текстовом поле NumTxt, и отправляется текст, введенный в текстовом поле SMSTxt. Имя порта, введенное в texbox ComPort Вот обработчик события нажатия кнопки.
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);
}
}
Мне удалось отправить смс с использованием этого кода вчера, но я не знаю, почему он больше не работает... без исключений. Когда я использую программное обеспечение, которое поставляется с модемом GSM, я могу отправлять смс. Но не через код C#. Если кто-то может указать на ошибку в приведенном выше коде, я буду очень признателен.
1 ответ
Вы никогда не должны использовать спящий режим вместо ожидания ожидания кода конечного результата от модема. Точно так же, как вы не пишете http-клиент, который полностью игнорирует все ответы от http-сервера, вы не должны отправлять AT-команды модему и полностью игнорировать ответы, которые он отправляет обратно. Вы должны прочитать и проанализировать все, что модем отправляет вам обратно. Ничто другое не будет работать надежно.
Мое предложение состоит в том, чтобы начать с получения копии стандарта V.250 и прочитать по крайней мере всю главу 5. Этот стандарт является библией для обработки команд AT и научит вас огромному количеству в отношении обработки команд AT. Как, например, что с помощью WriteLine
и / или Environment.NewLine
неправильно; AT командные строки должны заканчиваться \r
один и ничего больше.
Просто чтобы подчеркнуть, насколько важен этот документ: даже после более десяти лет работы с AT-командами в мобильных телефонах Ericsson я и мои коллеги все еще регулярно консультировались по этому стандарту.
На самом деле, перестаньте читать этот ответ здесь, скачайте этот документ, прочитайте всю главу 5, прежде чем вернуться, чтобы прочитать остальные.
Для отправки команд, когда вы не особенно заботитесь об ответе1, единственный надежный подход - сделать что-то похожее на
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();
где readLine
Функция считывает один и один байт из последовательного порта, пока не получит полную строку, оканчивающуюся на \r\n
а затем возвращает эту строку.
Вы можете посмотреть на код для atinout для примера для is_final_result_code
функция (вы также можете сравнить с isFinalResponseError
а также isFinalResponseSuccess
2 в U300 RIL ST-Ericsson).
Команда AT+CMGS должна обрабатываться по-разному. Вы должны ждать "\r\n> "
Ответ от модема перед отправкой полезной нагрузки, см. первую часть этого ответа для деталей.
1 Хотя вас, скорее всего, должно волновать, была ли команда выполнена успешно или нет. Посмотрите этот ответ для реалистичного способа отправки командной строки и анализа строк ответа.
2 Обратите внимание, что CONNECT
это не окончательный код результата, это промежуточный код результата, поэтому имя isFinalResponseSuccess, строго говоря, не на 100% правильно.