How to: sending ASCII control characters in serial application - c#

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

Related

Send SMS containting Emojis with AT Commands

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.

Printing from Datecs FML 10KL

I am using .NET CF and my task is to print fiscal and non-fiscal receipt.
So I need to connect to the FML 10 KL via bluetooth.
I am using SerialPort to do this, but after sending commands nothing happens.
I tried sending the commands like this :
byte[] buf = new byte[218];
using (StreamWriter writer = new StreamWriter(inPort.BaseStream))
{
writer.Write(buf);
//inPort.NewLine = "\n";
//var msg = inPort.ReadLine();
}
I populate "buf" with my command.
After that I try to read the responce but everytime I get timeout.Also I tried to "write" with text and not byte array, but I get the same result.
If anyone can give me some advice that would be great.
Most serial devices including Bluetooth SPP and Socket controlled devices do not support Unicode. If you have a string, you need to use Encoding ASCII (or UTF8) getBytes to get a byte arry suitable for the serial or direct socket connection. If you do not care for this, you may get a byte sequence of {0x00, 0x41} (Unicode) for an 'A' instead of the needed {0x41} only.
If you try to print something, verify that the code you send is valid by writing the data to a file and send the file as it is using a terminal application (former HyperTerminal).
Most printers support a Dump mode. Verify that the code you build is transmitted un-altered to the printer by using the dump mode and compare with the validated code that you used to print.
The Operating System and the target device may use a buffer. Ensure the buffer is flushed and then close the Stream before disconnecting.
With the Serial Port class ensure the device and the class use the same parameters, ie both 8Bit etc. For Bluetooth SPP the baud rate is adopted, you may use 115200 or 57600 without failing.
I found a Class that supports the Datecs Fiscal Printing Protocol: https://github.com/wqweto/UcsFiscalPrinters/blob/master/Samples/Demo1/Program.cs you should probably use this or look at how the class does print on the Datecs.
I figured out my problem.It was the connection to the mobile printer.
I am connecting and writing like this:
SerialPort inport = new SerialPort("COM5", 115200, Parity.None, 8,
StopBits.One);
inport.Write(buf, 0, buf.Length);
Thread.Sleep(1000);
I need to use Thread.Sleep because the buffer is getting full and some of data is not getting printed.

C# Sending Hex string to tcp socket

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.

Encoding problem between C# TCP server and Java TCP Client

i'm facing some encoding issue which i'm not able to find the correct solution.
I have a C# TCP server, running as a window service which received and respond XML, the problem comes down when passing special characters in the output such as spanish characters with accents (like á,é,í and others).
Server response is being encoded as UTF-8, and java client is reading using UTF-8. But when i print its output the character is totally different.
This problem only happens in Java client(C# TCP client works as expected).
Following is an snippet of the server code that shows the encoding issue:
C# Server
byte[] destBytes = System.Text.Encoding.UTF8.GetBytes("á");
try
{
clientStream.Write(destBytes, 0, destBytes.Length);
clientStream.Flush();
}catch (Exception ex)
{
LogErrorMessage("Error en SendResponseToClient: Detalle::", ex);
}
Java Client:
socket.connect(new InetSocketAddress(param.getServerIp(), param.getPort()), 20000);
InputStream sockInp = socket.getInputStream();
InputStreamReader streamReader = new InputStreamReader(sockInp, Charset.forName("UTF-8"));
sockReader = new BufferedReader(streamReader);
String tmp = null;
while((tmp = sockReader.readLine()) != null){
System.out.println(tmp);
}
For this simple test, the output show is:
ß
I did some testing printing out the byte[] on each language and while on C# á output as:
195, 161
In java byte[] read print as:
-61,-95
Will this have to do with the Signed (java), UnSigned (C#) of byte type?.
Any feedback is greatly appreciated.
To me this seems like an endianess problem... you can check that by reversing the bytes in Java before printing the string...
which usually would be solved by including a BOM... see http://de.wikipedia.org/wiki/Byte_Order_Mark
Are you sure that's not a unicode character you are attemping to encode to bytes as UTF-8 data?
I found the below has a useful way of testing to see if the data in that string is ccorrect UTF-8 before you send it.
How to test an application for correct encoding (e.g. UTF-8)

Converting TN5250 Encoding in C#

I have a connection to IBM i (an AS/400) that communicates over a protocol/encoding called TN5250. I haven't been able to match it against any of the encodings listed here; how can I convert this text to something I can use? UTF8, ASCII; anything in a Windows-friendly text format will do. It must not involve buying a third-party library.
Here's some "working" code I found elsewhere. "address" is an IP address.
Socket SocketClient = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
System.Net.IPEndPoint remoteEndPoint = new System.Net.IPEndPoint(IPAddress.Parse("address"), 23);
SocketClient.Connect(remoteEndPoint);
byte[] buffer = new byte[10];
textBox1.Text += Receive(SocketClient, buffer, 0, buffer.Length, 10000).Trim() + "\r\n";
}
public static string Receive(Socket socket, byte[] buffer, int offset, int size, int timeout)
{
int startTickCount = Environment.TickCount;
int received = 0; // how many bytes is already received
do
{
if (Environment.TickCount > startTickCount + timeout)
throw new Exception("Timeout.");
try
{
received += socket.Receive(buffer, offset + received, size - received, SocketFlags.None);
return Encoding.GetEncoding(37).GetString(buffer, 0, buffer.Length);
//byte[] buf = Encoding.Convert(Encoding.GetEncoding("iso-8859-1"), Encoding.UTF8, buffer);
//return Encoding.GetEncoding("IBM500").GetString(buf, 0, buffer.Length);
}
catch (SocketException ex)
{
if (ex.SocketErrorCode == SocketError.WouldBlock ||
ex.SocketErrorCode == SocketError.IOPending ||
ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
{
// socket buffer is probably empty, wait and try again
Thread.Sleep(30);
}
else
throw ex; // any serious error occurr
}
} while (received < size);
return "";
}
This is a Telnet connection. Works fine in a Windows telnet window. The solution I really want is a way to capture the stdout from the telnet session, but apparently terminal programs like Telnet don't write to stdout.
The TN5250J project is a working TN5250 client written in Java.
TN5250 is the IBM protocol that rides on top of Telnet. It is intended for the IBM midrange family of 'dumb' green screen terminals. This family is block mode, meaning the host sends a full display panel out to the client in one transmission, and the client sends a full display panel back to the host in one single transmission. This, as opposed to a character-by-character transmission.
As a very high level overview, the 5250 protocol describes how to format the display (start/stop field, field attributes like underline and colour) as well as what function keys are acceptable. The client needs to understand these formatting instructions in order to properly render the data coming from the host. Likewise, the client does not send back the full display panel including constants and formatting; instead, it sends back the input-capable fields.
There is no stdout per se; the human readable display panel requires rendering by the client. You may get a good sense for the raw data by using Wireshark to capture the packets and comparing them to an actual TN5250 display showing the same transaction.
From this article, it looks the encoding scheme is EBCDIC character-encoding scheme.
See How to convert between ASCII and EBCDIC character codes for conversion details. It's in VB, but you should be able to convert it to C#. There is also an implementation on John Skeet's page here
How to convert from EBCDIC to ASCII in C#. From this post, looks like you might be able to use the 37 IBM037 IBM EBCDIC (US-Canada) encoding from the list you provided: Encoding ebcdic = Encoding.GetEncoding("IBM037");
TN 5250 is not an encoding. It is a highly complex protocol.
The specification can be found here:
http://www.ietf.org/rfc/rfc1205.txt
(Note that this spec is not even complete)
There is no easy conversion. You have to write thousands of lines of code or use an already existing project like for example this one in C++ for Linux and Windows:
http://sourceforge.net/projects/tn5250/files/
I did not find anything in C#

Categories