Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending Unicode Messages (such as in Persian and Arabic) in C# using AT Commands through GSM Modem

I am developing an application for GSM Modems (D-Link DWM-156) in C#.Net using AT commands. I have a problem sending Unicode messages (Such as messages written in Persian or Arabic). Here it is the core of my program:

SerialPort GSMPort = new SerialPort();

GSMPort.PortName = "COM6";
GSMPort.BaudRate = 9600;
GSMPort.Parity = Parity.None;
GSMPort.DataBits = 8;
GSMPort.StopBits = StopBits.One;
GSMPort.Handshake = HandShake.RequestToSend;
GSMPort.DtrEnable = true;
GSMPort.RtsEnable = true;

GSMPort.Open();

GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write(shortMessage+ "\x1A");

It works fine for English and ASCII letters. I have read this article and can send Unicode messages in Hyperterminal using AT commands:

AT [Enter]
OK
AT+CSCS="UCS2" or AT+CSCS="HEX" [Enter] ---> We have to convert our message to hex 
OK
AT+CMGF=1 [Enter]
OK
AT+CMGS="destinationNumber" [Enter]
> 0633064406270645002006450631062D06280627 ---> The hex format of our message (سلام مرحبا)
+CMGS: 139
OK

Since this commands worked correctly, I have added GSMPort.Write("AT+CSCS=\"UCS2\"\r"); to my application, and tried to send 0645 0631 062D 0628 0627 (مرحبا) or 0633 0644 0627 0645 (سلام).

GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A");

But unlike AT commands in Hyperterminal, destination does not receive correct letters. What is the difference between these AT commands in C# code and Hyperterminal code? I will appreciate if you help me to resolve this problem.


Additional information: As you know I have no problem for sending Unicode messages (such as Persian letters) by hyperterminal and using AT commands. In below code I try to send سلام, and "0633064406270645" is the hexadecimal form of it. But I receive □□□□ in my phone.

GSMPort.Encoding = UnicodeEncoding.GetEncoding(1256);
GSMPort.Write("AT\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\r");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\r\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A");

In the hyperterminal environment, On the other hand, everything goes fine and I receive سلام.

AT [Enter]
OK
AT+CSCS="UCS2"
OK
AT+CMGF=1 [Enter]
OK
AT+CMGS="destinationNumber" [Enter]
> 0633064406270645 [Ctrl+Z]
+CMGS: 139
OK

I have noticed that in the hyperterminal properties if I check the "send line ends with line feeds" (it is in properties->Settings-> ASCII Setups, please check the picture below), I will have the same problem as I had in C# code. I think "send line ends with line feeds" is enabled in GSMPort.Write by default? If yes, how can I disable it?

enter image description here

like image 498
Yasser Mohseni Avatar asked Mar 09 '13 14:03

Yasser Mohseni


People also ask

How to send Unicode text with custom data coding over binary?

On the other hand, if you want to send Unicode with custom data coding over binary Send SMS methods, the message text should be converted into hexadecimal representation. The hexadecimal content should be inserted in the “hex” parameter and also, you should set “dataCoding” parameter to 8 (UTF-8):

How do I send Unicode (UTF-8) messages?

To avoid generating such unreadable messages, we are offering you two ways of sending Unicode (UTF-8) messages – with textual or binary ”Send SMS” methods. If you choose to send Unicode messages over textual Send SMS methods, unconverted Unicode text should be inserted in the “text” parameter:

What is the Unicode range of Arabic script?

As of Unicode 14.0, the Arabic script is contained in the following blocks: The basic Arabic range encodes the standard letters and diacritics, but does not encode contextual forms (U+0621–U+0652 being directly based on ISO 8859-6 ); and also includes the most common diacritics and Arabic-Indic digits .

What alphabets can be used in SMS messaging?

Even though a large portion of professional SMS messaging uses the basic GSM alphabet (which supports all Latin characters, digits and a few special characters), some apps, companies and brands prefer to use their own alphabets when communicating with their audiences over SMS.


3 Answers

I have finally found out how to resolve this problem. As I said in in the "Additional Information" section of my question, sending line ends with line feeds caused this mismatching between SerialPort in C# and AT commands in hyperterminal for sending Unicode messages. I have just replaced \r with \n line feeds. The modified code is as follow:

GSMPort.Write("AT\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CSCS=\"UCS2\"\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGF=1\n");
Thread.Sleep(1000);
GSMPort.Write("AT+CMGS=\"" + destinationNumber + "\"\n");
Thread.Sleep(1000);
GSMPort.Write("0633064406270645" + "\x1A"); 

Leave SerialPort.Encoding and SerialPort.NewLine properties unchanged. It is not necessary to change their default values, just set AT+CSCS="UCS2" to send messages in Unicode format.

like image 132
Yasser Mohseni Avatar answered Oct 19 '22 15:10

Yasser Mohseni


First of all check your modem support unicode then change your code to this
we have to specify the correct DCS (Data Coding Scheme) for Unicode messages, which is 0x08.

We can set this value by changing the fourth parameter of the AT+CSMP command to '8':

AT+CSMP=1,167,0,8

    GSMPort.Write("AT\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CSCS=\"UCS2\"\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CMGF=1\r");
    Thread.Sleep(1000);
    GSMPort.Write("AT+CSMP=1,167,0,8\r"); //AT+CSMP=1,167,0,8
    Thread.Sleep(1000);
    GSMPort.WriteLine("AT+CMGS=\"" + destinationNumber + "\"\r\n");
    Thread.Sleep(1000);
    GSMPort.WriteLine("0633064406270645" + "\x1A");
like image 23
saeed Avatar answered Oct 19 '22 15:10

saeed


The default encoding for SerialPort is Encoding.ASCII. Either set SerialPort.Encoding to an encoding to supports the character set you're using (like Encoding.UTF32) or use SerialPort.Write(char[], int, int) and convert your Unicode string to bytes in whatever way'd prefer.

like image 2
Peter Ritchie Avatar answered Oct 19 '22 15:10

Peter Ritchie