Search code examples
c#smsportgsmat-command

Sending multi part sms with GSM using AT Commands


I have a windows application for sending SMS connecting to a GSM Modem. I only use AT Commands for connecting to port and sending text.

My problem is I can't send a message more that one part (each part is 160 characters for English and 70 characters for Farsi).

Here is the part I command the port to send sms using AT commands:

ExecCommand(port, "AT", 300, "No phone connected at " + strPortName + ".");
ExecCommand(port, "AT+CMGF=1", 300, "Failed to set message format.");
var command = "AT+CSCS=\"" + "HEX" + "\"";
ExecCommand(port, command, 300, "Failed to support unicode");
ExecCommand(port, "AT+CSMP=1,167,0,8", 300, "Failed to set message properties.");
command = "AT+CMGS=\"" + phoneNo + "\"";
ExecCommand(port, command, 300, "Failed to accept phoneNo");
message = message.ToCharArray().Select(Convert.ToInt32).Select(value => String.Format("{0:X}", value)).Aggregate("", (current, hexOutput) => current + hexOutput.PadLeft(4, '0'));
command = message + char.ConvertFromUtf32(26) + "\r";
var recievedData = ExecCommand(port, command, 3000, "Failed to send message"); 

And here is ExecCommand method

    public string ExecCommand(SerialPort port, string command, int responseTimeout, string errorMessage)
    {
        try
        {
            // receiveNow = new AutoResetEvent();
            port.DiscardOutBuffer();
            port.DiscardInBuffer();
            receiveNow.Reset();
            port.Write(command + "\r");

            //Thread.Sleep(3000); //3 seconds
            string input = ReadResponse(port, responseTimeout);
            if ((input.Length == 0) || ((!input.EndsWith("\r\n> ")) && (!input.EndsWith("\r\nOK\r\n"))))
                throw new ApplicationException("No success message was received.");
            return input;
        }
        catch (Exception ex)
        {
            throw new ApplicationException(errorMessage, ex);
        }
    }

Solution

  • General AT command handling

    You are on the right track, I am pleased to see several basic things done right (terminating AT command lines with \r, waiting for "\r\n> " for AT+CMGS, and waiting for the OK final result code instead of sleeping), very good start!

    You do need however to change the structure somewhat. First you need to handle all the other final result codes and not just OK. And you should treat the AT+CMGS command differently from the other commands since you should wait for two things (first the prefix and later the final result code after sending the message text) for that command compared to waiting only for one thing (e.g. the final result code) for those. Also all responses from the modem are complete lines (except the "\r\n> " prefix), so change your algorithm to process the response(s) line by line.

    String input;
    do {
            input = ReadLine(port, responseTimeout);
    } while (!isFinalResultCode(input));
    

    None of the commands you are using in the question produces an intermediate response for consumption, but if you were to run a command like AT+CPBR you would consume those intermediate responses inside that loop (and you would have to move the final result test into the loop before attempting to consume the line as an intermediate response).

    You can see the is_final_result function in atinout or corresponding functions in ST-Ericsson's U300 RIL (see link and notes in this answer).

    Multipart SMS

    I think this is not possible in text mode. See the link suggested by Naser Asadi for details on multipart SMS in PDU mode. Also some useful information at http://mobiletidings.com/2009/02/18/combining-sms-messages/ and http://developer.nokia.com/community/discussion/showthread.php/109602-Concatenated-SMS-in-PDU-Mode.