Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
273 views
in Technique[技术] by (71.8m points)

Unable to send SMS through C# code using System.IO.Ports using gsm modem

A button, when clicked, sends an sms to the number entered in NumTxt textbox, and sends the text entered in SMSTxt textbox. Port name entered in texbox ComPort Here's the event handler of the button click event.

  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);
        }
    }

I was able to send the sms using this very code yesterday, but i do not know why it doesn't work any more.. no exceptions thrown. When I use the software that comes with gsm modem, I am able to send sms. But not through C# code. If anyone can pin point the mistake in the above code, I will be very grateful.

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You should never, never, ever use sleep as a substitute for waiting for the Final result code from the modem. Just as you would not write a http client that completely ignores all responses from the http server, you should not send AT commands to a modem and completely ignore the responses it sends back. You must read and parse everything the modem sends back to you. Nothing else will work reliably.

My suggestion is that you start by fetching a copy of the V.250 standard and read at least all of chapter 5. This standard is the bible for AT command handling and will teach you an enormous amount regarding AT command handling. Like for instance that using WriteLine and/or Environment.NewLine is wrong; AT command lines should be terminated with alone and nothing else.


Just to emphasis how important that document is: Even after working with implementing AT command in mobile phones in Ericsson for over a decade I and my colleagues still consulted that standard regularly.

In fact stop reading this answer here now, download that document, read all of chapter 5 before returning to read the rest.


For sending commands where you do not particularly care about the response1, the only reliably approach is to do something similar to

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

where the readLine function reads one and one byte from the serial port until it has received a complete line terminated with and then returns that line.

You can look at the code for atinout for an example for the is_final_result_code function (you can also compare to isFinalResponseError and isFinalResponseSuccess2 in ST-Ericsson's U300 RIL).

The AT+CMGS command must be handled differently. You must wait for the " > " response from the modem before sending the payload, see the first part of this answer for details.


1 Although you most likely should care about if the command was executed successfully or not. See this answer for a realistic way to send a command line and parse the response lines.

2 Note that CONNECT is not a final result code, it is an intermediate result code, so the name isFinalResponseSuccess is strictly speaking not 100% correct.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...