1

I want to send sms using AT commands in C#. Now it works for one message. It comes with natonial characters. It's encoded in UCS2. But I can't send longer message because I have strange characters when added User Data Header. My code:

string messageSmsEncoded1 = "050003CC0201" + UnicodeStr2HexStr("dddd");
targetPhoneNo = UnicodeStr2HexStr(PhoneNumber);
                          
    
    string phone_number = Char.ConvertFromUtf32(34) + targetPhoneNo + Char.ConvertFromUtf32(34);
    serialPort.Write("AT");
    Thread.Sleep(100);
    var responseAt = serialPort.ReadExisting();
    serialPort.Write("AT+CSCS = ?" + Char.ConvertFromUtf32(13));
    Thread.Sleep(100);
    var responseCscs = serialPort.ReadExisting();
    serialPort.Write("AT+CSCS=\"UCS2\"" + Char.ConvertFromUtf32(13));
    Thread.Sleep(100);
    var responseUcs2 = serialPort.ReadExisting();
    serialPort.Write("AT+CMGF=1" + Char.ConvertFromUtf32(13));
    Thread.Sleep(100);
    var responseCmgf = serialPort.ReadExisting();
    // set data coding scheme
    serialPort.Write("AT+CSMP=17,167,0,8" + Char.ConvertFromUtf32(13));
    Thread.Sleep(100);
    var responseCsmp = serialPort.ReadExisting();
    serialPort.Write("AT+CMGS=" + phone_number + Char.ConvertFromUtf32(13));
    Thread.Sleep(100);
    var responseCmgs = serialPort.ReadExisting();
    serialPort.Write(messageSmsEncoded1 + Char.ConvertFromUtf32(26) + char.ConvertFromUtf32(13));

And I got:

Ԁόȁdddd

How to add UDH to message encoded in UCS2 ?

Mark
  • 13
  • 3

1 Answers1

0

You have several things you need to fix here.


The absolutely worst offender is the use of Thread.Sleep. You should never, never, ever use sleep as a substitute for waiting for the Final result code from the modem. For instance your code

serialPort.Write("AT");
Thread.Sleep(100);
var responseAt = serialPort.ReadExisting();

has a bug because the "\r" command line terminator is missing here and thus no command is actually executed on the modem and no response will be given back. But since you are not parsing the response this goes undetected.

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.


Then Char.ConvertFromUtf32(13) is wrong; you should terminate an AT command line with the '\r' character (a single, 8 bit byte) directly, AT+CSCS encoding is completely irrelevant for this.

You attempt to encode the string as UCS2 seems ok, except that Char.ConvertFromUtf32(34) is wrong for the same reason as for carriage return. The double quote characters are better left out from the phone_number variable, just write

"AT+CMGS=\"" + phone_number + "\"\r"

Or actually, here is a good opportunity to perhaps start making wrong code look wrong by using say ucs2_phone_number or phone_number_ucs2.


For the AT+CMGS command you MUST wait for the modem to signal that it is ready to receive the data payload. Otherwise you will in worst case abort the command. In best case it might work, but it is not unlikely that some of the payload might be lost if sent too early. See the first part of this answer.


Finally, in order to send SMS messages containing User Data Header you must send the messages in PDU mode, AT+CMGF=0. See the 27.005 specification for details (any non-ancient version should be fine for this).

hlovdal
  • 26,565
  • 10
  • 94
  • 165