I would like to send an SMS containing Emojis from my GSM Modem with AT Commands.
However, no matter which encoding I try, it never works (Encoding.BigEndianUnicode, Encoding.Unicode or Default) make the SMS unreadable.
My code looks a bit like this:
// [..]
// send message with UCS2
command = "AT+CSCS=\"UCS2\"" + char.ConvertFromUtf32(13);
send(command);
// [..]
// convert my message (string from a WPF TextBox) to a unicode hex-string
byte[] ba = Encoding.BigEndianUnicode.GetBytes(message);
var hexString = BitConverter.ToString(ba);
hexString = hexString.Replace("-", "");
// send the converted string
command = hexString + char.ConvertFromUtf32(26);
send(command);
// [..]
The SMS successfully reaches its destination but the message is just some unreadable stuff.
Is this even possible to do? My GSM Modem would also support "HEX" as encoding.
Update:
It kinda works if i replace this line:
command = hexString + char.ConvertFromUtf32(26);
With this:
command = "80 " + hexString + char.ConvertFromUtf32(26);
But then i get this 㣩 letter at the start of the message...
Make sure that your modem uses the correct data coding scheme for the SMS. See this answer and
Set the modem to text mode using AT+CMGF=1
Set the coding scheme to "UCS2" using AT+CSCS="UCS2"
Send AT+CSMP=1,167,0,8 to the modem.
Now in UCS2 mode, the modem needs the recipient number in UCS2 form as well, i.e. for +123456890 send
AT+CGMS="002B003100320033003400350036003800390030",145 (145 is type-of-address for numbers with country code, use 129 otherwise.
The modem should respond with a > prompt. Then, send the message in the right encoding i.e. sending the message as what I would describe as an ASCII hex sequence of UCS2/UTF-16 bytes, i.e. encoding the string to UTF-16BE, then taking each byte and formatting it as ASCII HEX characters, i.e. 🐈 which is U+1F408 becomes D83DDC08 that is sent to the modem, 012ABC becomes 003000310032 004100420043.
Related
I have a POS-80C thermal printer, printing to it using PrinterUtility Library from NuGet. This library converts a string to ByteArray and sends it to the printer directly, so it's RAW printing. it works really well with Latin characters, but not with Hebrew or Arabic. it Prints "???" when the characters are not in English. I know that I must use ESC/POS commands to switch to for example Arabic character sets when my text is in Arabic but I tried a lot and figure out how to do so.
PrinterUtility.EscPosEpsonCommands.EscPosEpson obj = new PrinterUtility.EscPosEpsonCommands.EscPosEpson();
var BytesValue = Encoding.ASCII.GetBytes(string.Empty);
BytesValue = PrintExtensions.AddBytes(BytesValue, Encoding.ASCII.GetBytes("English Text")); //works fine
BytesValue = PrintExtensions.AddBytes(BytesValue, Encoding.ASCII.GetBytes(String.Format("{0,-25}", "تيست"))); //Arabic Charecter, prints as ????
I know that somewhere in between the English and Arabic text I have to switch to Arabic Character Set
BytesValue = PrintExtensions.AddBytes(BytesValue, Encoding.ASCII.GetBytes("English Text"));
//Here i have to switch To Arabic Charecter set
BytesValue = PrintExtensions.AddBytes(BytesValue, Encoding.Unicode.GetBytes(String.Format("{0,-25}", "تيست")));
//Here I have to switch back To English Character set
And then send the file containing byte array to the printer
if (File.Exists("Receipt")
File.Delete("Receipt");
File.WriteAllBytes(txtPrinterName.Text, BytesValue);
RawPrinterHelper.SendFileToPrinter("PrinterName", "Receipt");
My printer does support Arabic, but it's a matter for sending command to switch to it or to any other language.
If you could teach me how to do this, I will appreciate it.
I haven't been able to find the command reference for your exact printer model, so some of this is going to be guess work from experience. The closest I could find was this command reference from POS-X.
You are correct that special commands are prefixed with ESC. In this particular case, the command you want is ESC t - Select character code table to change the code page. The code page you want is PC864 - Arabic which is 37 decimal (25 hexidecimal). The code page for English is simply 0 for PC437 - English.
I'm not exactly sure how the PrinterUtility package functions and I couldn't find any documentation for it either.
Essentially, you need to send the following:
byte[] CodePageArabic = new byte[] { 0x1B, 0x74, 0x25 };
byte[] CodePageEnglish = new byte[] { 0x1B, 0x74, 0x00 };
I created TCP server that is distributing client's messages and run on a problem. When I'm sending Cyrillic messages through stream they're not decoding properly. Anyone knows how can I repair that?
Here's the code for sending the message:
var message = Console.ReadLine().ToCharArray().Select(x => (byte)x).ToArray();
stream.Write(message);`
Here's the code for receiving:
var numberOfBytes = stream.Read(buffer,0,1024);
Console.WriteLine($"{numberOfBytes} bytes received");
var chars = buffer.Select(x=>(char)x).ToArray();
var message = new string(chars);
The problem is that a character in C# represents a 2-byte UTF-16 character. A cyrillic character is bigger than 255 in UTF-16, so you lose information when converting it to a byte.
To convert a string to a byte array, use the Encoding class:
byte[] buffer = System.Text.Encoding.UTF8.GetBytes(Console.ReadLine());
To convert it back to a string on the receiver's end, write:
string message = System.Text.Encoding.UTF8.GetString(buffer);
Another problem is that Stream.Read does not guarantee to read all bytes of your message at once (Your stream does not know that you send packets with a certain size). So it could happen, for example, that the last byte of the received byte array is only the first byte of a 2-byte character, and you receive the other byte the next time you call Stream.Read.
There are several solutions to this issue:
Wrap the Stream in a StreamWriter at the sender's end and in a StreamReader at the receiver's end. This is probably the simplest method if you transmit only text.
Transmit the length of your message at the beginning of your message as an integer. This number tells the receiver how many bytes he has to read.
To convert a string to bytes, use System.Text.Encoding.GetBytes(string). I suggest you change the sending code to:
// using System.Text;
var messageAsBytes = Encoding.UTF8.GetBytes(Console.ReadLine());
To convert bytes to a string, use System.Text.Encoding.GetString(byte[]). If you receive UTF-8-encoded bytes:
// using System.Text;
var messageAsString = Encoding.UTF8.GetString(buffer);
Some suggested reading:
https://www.joelonsoftware.com/2003/10/08/the-absolute-minimum-every-software-developer-absolutely-positively-must-know-about-unicode-and-character-sets-no-excuses/
https://learn.microsoft.com/en-us/dotnet/api/system.text.encoding?view=netframework-4.7.2
I have an application which is developed using C#. I am using a third party API (Telnore Corporate SMS) for sending SMS to users. When I write my message in English (I am using a textbox for writing SMS) then the message delivered to mobile is fine and readable. But when I use the Urdu language instead, then it becomes something unreadable:
I consulted multiple tutorials and techniques of UTF-8 encoding, etc., but when I used the UTF-8 encoding the delivered message still wasn't readable (everything turned to question marks in this case).
This is what I have tried so far.
string s = themessage.Text;//themessage is my textbox name
//utf8
byte[] utf = System.Text.Encoding.UTF8.GetBytes(s);
string s2 = System.Text.Encoding.UTF8.GetString(utf);
//ASCII
byte[] utf = System.Text.Encoding.ASCII.GetBytes(s);
string s2 = System.Text.Encoding.ASCII.GetString(utf);
//Unicode
byte[] utf = System.Text.Encoding.Unicode.GetBytes(s);
string s2 = System.Text.Encoding.Unicode.GetString(utf);
I don't know what I am doing wrong. After getting the string s2 I am passing it to a method that is sending the message.
Using the simple serial program created awhile back(http://csharp.simpleserial.com/) but I am having trouble sending ASCII control commands to my serial device. I need to send: 01P00104##. Is there a certain way to modify the code so that it sends out these “ASCII unprintable character commands” for C#?
I tried:
private void linkLabel_HC1_100_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
if serialPort1.IsOpen()
{
serialPort1.Write( (char)2 + “01P00104##” + (char)3);
}
}
Where (char)2 and (char)3 are supposedly the character representations for the start and end of text commands. I also tried using escape codes such as \u0002 or even sendKeys.Send(“^(b)”) or ^(c) but it wont seem to work. When I use Hyperterminal or PuTTy software, I can copy and past the full command in from a notepad.txt file and it sends correctly but when I copy and past the same code into this application, I don’t get a response from the serial device. This app uses .net 2.0. The stx and etx commands in the notepad look like a small 7 and small L
You could use the SerialPort.Write(Byte[], Int32, Int32) method.
var content = new List<byte>();
content.Add(2); // ASCII STX
content.AddRange(Encoding.ASCII.GetBytes("01P00104##"));
content.Add(3); // ASCII ETX
byte[] buffer = content.ToArray();
serialPort1.Write(buffer, 0, buffer.Length);
I'm trying to send a hex string to a tcp socket. I have some problems with the format or conversion of this string, cause I'm not very sure what the format its using.
I've written a WindowsPhone app which is working fine based on Socket Class.
This app emulates request, that are normaly send from a desktop program to a device which hosts a webservice.
Via wireshark, I found out, that the webservice will accept an input stream (think its in hex) and returns a 2nd. hex stream which contains the data I need.
So the desktop app is sending a stream
and Wireshark shows when :
Data (8 bytes)
Data: 62ff03fff00574600
Length: 8
Now I've tried a lot to reproduce this stream. I thougt, it used to be a UTF8 string and converted this stream to this format. But every time I send it, is see in Wireshark the following output: 62c3bf03c3bf00574600
As far as i've investigated 62 = b but ff send always c3bf.
Does somebody know how to send this stream in the right format?
Cheers,
Jo
The socket transport shouldn't care, the content of a TCP packet is binary representing "whatever".
From the code you pointed to in the comments:
byte[] payload = Encoding.UTF8.GetBytes(data);
socketEventArg.SetBuffer(payload, 0, payload.Length);
...
response = Encoding.UTF8.GetString(e.Buffer, e.Offset, e.BytesTransferred);
response = response.Trim('\0');
At the end of the socket send/receive (data == response). If that isn't occurring you need to figure how where the problem is. The first step is to write some very simple code like so:
string source = "your problem text string";
byte[] encode = Encoding.UTF8.GetBytes(source);
target = Encoding.UTF8.GetString(encode, 0, encode.Length);
Debug.Assert(source == target);
If that works, then output the 'encode' array can check to make sure that is contained in the packet data where it is being send, then verify that that is what is being received. If you are sending the right data but receiving it corrupted you have serious problems ... I doubt you find that but if so write a very simple test program that sends and receives on the same machine (localhost) to see if it is repeatable.
If I had to guess I would say that the characters being encoded are not Unicode or that Win phone doesn't properly support it (Proper unicode support).
As long as you don't know the protocol / the encoding the server expects you can only replay the known messages, like the bytes you provided in your question.
Therefore you just define directly the byte array like this:
byte[] payload = new byte[] {0x62, 0xff, 0x03, 0xff, 0xf0, 0x05, 0x74, 0x60};
and send it over the socket like you did with the encoded string before. The server should now accept the message like it was sent by the client you sniffed.