locked
C# read server with socket (ASCII) RRS feed

  • Question

  • I'm trying to read a server (energy meter) using socket or tcpclient. To read the server you need to send commands.

    Commands (ASCII communication):

    Octet 001: SOH; 
    Octet 002: Access code: "0" - Read "1" - Demand "2" - Update 
    Octet 003: STX; 
    Octet 004-135: Command for convencional communication server/reader, converted nibble to nibble to ASCII code including CRC; 
    Octet 136: ETX; 
    Octet 137: LRC;

    My Tcp Client code:

    static void Connect(String server, String message)
            {
                try
                {
                    // Create a TcpClient.
                    // Note, for this client to work you need to have a TcpServer
                    // connected to the same address as specified by the server, port
                    // combination.
                    Int32 port = 80;
                    TcpClient client = new TcpClient(server, port);
    
                    // Translate the passed message into ASCII and store it as a Byte array.
                    Byte[] data = System.Text.Encoding.ASCII.GetBytes(message);                
    
                    // Get a client stream for reading and writing.
                    //  Stream stream = client.GetStream();
    
                    NetworkStream stream = client.GetStream();
    
                    // Send the message to the connected TcpServer.
                    stream.Write(data, 0, data.Length);
    
                    Console.WriteLine("Sent: {0}", message);
    
                    // Receive the TcpServer.response.
    
                    // Buffer to store the response bytes.
                    data = new Byte[256];
    
                    // String to store the response ASCII representation.
                    String responseData = String.Empty;
    
                    // Read the first batch of the TcpServer response bytes.
                    Int32 bytes = stream.Read(data, 0, data.Length);
                    responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                    Console.WriteLine("Received: {0}", responseData);
    
                    // Close everything.
                    stream.Close();
                    client.Close();
                }
                catch (ArgumentNullException e)
                {
                    Console.WriteLine("ArgumentNullException: {0}", e);
                }
                catch (SocketException e)
                {
                    Console.WriteLine("SocketException: {0}", e);
                }
    
                Console.WriteLine("\n Press Enter to continue...");
                Console.Read();
            }      

    My question is how to convert this commands to send to server? I have no idea what SOH, STX, ETX, LRC means.

    What i've tried:

    Connect("192.168.0.250", "0");
    Connect("192.168.0.250", "1");
    Connect("192.168.0.250", "2");

    But no server response.

    Tuesday, August 25, 2020 5:05 PM

Answers

  • No I don't believe that is correct. Wireshark is showing you the raw byte stream, not ASCII. It has no way of knowing how to translate that data so whether it is a string, float or whatever doesn't matter. If you wanted to send that exact command then put it into a byte array.

    var command = new byte[] {
      0x2, 0, 0x42, 0x5, 0x14, ...
    }
    I noticed that the command ended with an F so that must be the hex string. Thus to convert to a byte array you use hex. Of course that is a lot of typing so from this SO post somebody produced a cleaner version that is unfortunately slower.

    public static byte[] StringToByteArray ( string hex )
    {
       return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
    }
    
    //And usage
    var stringCommand = "0200420514000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050f";
    
    //command will have the byte array equivalent
    var command = StringToByteArray(stringCommand);


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Guilherme_ Friday, August 28, 2020 10:11 PM
    Friday, August 28, 2020 3:15 PM

All replies

  •  I have no idea what SOH, STX, ETX, LRC means.

    They are special names to denote the first 16 codes in the ASCII table. For example, if you examine the table here:

    http://www.asciitable.com/

    you will find that SOH is character number 1 (in binary), STX is 2, ETX is 3.

    LRC is different. This means "Linear Redundancy Code", and it is a mathematical operation performed on all the preceding characters in the message. There is no unique way to do this; it could be as simple as a parity byte (a XOR of the preceding bytes) or it could be, for example, a Cyclic Redundancy Check. You will need to read the manual of your device to find out what is the specific algorithm that it requires for its LRC.

    Tuesday, August 25, 2020 6:24 PM
  • Looks like an old school mode interface. Thus an octet is basically a byte. SOH, STX, etc are ASCII codes as defined here. So if you are told to send SOH followed by a 0 or 1 followed by an STX you would need to put that into a byte buffer and send it, not as a string. Your current solution isn't going to work as you are trying to use strings and the protocol is binary based.

    Ultimately it depends upon the protocol being used. In most cases we create a structure to represent the required format of the data and then we fill in the parts we need. 

    [StructLayout(LayoutKind.Sequential)]
    public struct PacketHeader
    {
       public byte Byte1 { get; set; }
       public byte Byte2 { get; set; }   
    }
    
    //Write to socket
    var header = new PacketHeader() {
       Byte1 = 1,
       Byte2 = 1
    };
    
    //Helper method to write the header to a stream
    public static class StreamExtensions
    {
       public static void Write<T> ( this Stream stream, T value )
       {
          //Going to use BinaryFormatter here but there are other approaches
          var formatter = new BinaryFormatter();
          formatter.Serialize(stream, value);
       }
    }
    

    If the data is all over the place such that a simple structure won't work then you can also use a byte array directly but you are responsible for ensuring the data structure is properly set up. Given your very specific example it has a fixed format so you are probably better off using a byte array since there are only 2 "fields" you can set anyway.

    //NOT TESTED
    public enum AccessCode
    {
       Read = 0,
       Demand = 1,
       Update = 2
    }
    
    static void Connect ( string server, AccessCode code, byte[] command )
    {
       var data = BuildCommand(code, command);
    
       //Send it, note you don't want to keep creating a TcpClient each time, create it once and connect and keep it open for the life of the app if possible
       ...
    
    
       //Send the command
       stream.Write(data, 0, data.Length);
    }
    
    static byte[] BuildCommand ( AccessCode code, byte[] command )
    {
       //Assumption is that the command contains the properly formatted command with the CRC, this is specific to your server so we cannot provide this information to you...
    
       //Ensure the command is not too long
       if (command.Length > 132)  //May be off by 1 here: 4-135
          throw new ArgumentException("Command too large");
    
       //Allocate the buffer
       var buffer = new byte[137];
    
       //TODO: The description shows octet starting at 1 but C# arrays start at zero. Assuming here that octet values are offset by 1
       buffer[0] = 1; //SOH
       buffer[1] = (byte)code;  //Access code
       buffer[2] = 2; //STX
    
       //Copy the command itself
       Array.Copy(buffer, 3, command, 0, command.Length);
    
       //Footer
       buffer[135] = 3; //ETX
       buffer[136] = 0xD;  //Have no idea what LRC is...
    }


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, August 25, 2020 6:37 PM
  • Unfortunately, the manual is really bad. I have to find out what to use myself.

    Using my example code, I can connect. If is connected, the socket is probably correct, right? Because I checked with:

    if (client.Connected)

    ..returns true

    According to this line:

    Octet 004-135: Command for convencional communication server/reader, converted nibble to nibble to ASCII code including CRC; 
    Probably is "Cyclic Redundancy Check".

    Tuesday, August 25, 2020 6:57 PM
  • Hi Michael, I implemented and tested your example, but the same thing happens as my example. Timeout on the "Read" line. It connects, but doesnt return data. 

    Full code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace test6
    {
        class Program
        {
            public enum AccessCode
            {
                Read = 0,
                Demand = 1,
                Update = 2
            }
    
            static void Connect(string server, AccessCode code, byte[] command)
            {
                var data = BuildCommand(code, command);
    
                //Send it, note you don't want to keep creating a TcpClient each time, create it once and connect and keep it open for the life of the app if possible
    
                Int32 port = 80;
                TcpClient client = new TcpClient(server, port);
    
                //Send the command
                NetworkStream stream = client.GetStream();
                stream.Write(data, 0, data.Length);
    
                // Buffer to store the response bytes.
                data = new Byte[256];
    
                // String to store the response ASCII representation.
                String responseData = String.Empty;
    
                // Read the first batch of the TcpServer response bytes.
                Int32 bytes = stream.Read(data, 0, data.Length);
                responseData = System.Text.Encoding.ASCII.GetString(data, 0, bytes);
                Console.WriteLine("Received: {0}", responseData);
    
                // Close everything.
                stream.Close();
                client.Close();
            }
    
            private static byte[] BuildCommand(AccessCode code, byte[] command)
            {
                //Assumption is that the command contains the properly formatted command with the CRC, this is specific to your server so we cannot provide this information to you...
    
                //Ensure the command is not too long
                if (command.Length > 132)  //May be off by 1 here: 4-135
                    throw new ArgumentException("Command too large");
    
                //Allocate the buffer
                var buffer = new byte[137];
    
                //TODO: The description shows octet starting at 1 but C# arrays start at zero. Assuming here that octet values are offset by 1
                buffer[0] = 1; //SOH
                buffer[1] = (byte)code;  //Access code
                buffer[2] = 2; //STX
    
                //Copy the command itself
                Array.Copy(buffer, 3, command, 0, command.Length);
    
                //Footer
                buffer[135] = 3; //ETX
                buffer[136] = 0xD;  //Have no idea what LRC is...
    
                return buffer;
            }
            static void Main(string[] args)
            {
                string command = "004";            
                Byte[] data = System.Text.Encoding.ASCII.GetBytes(command);
                Connect("192.168.0.250", AccessCode.Read, data);
            }
        }
    }


    • Edited by Guilherme_ Tuesday, August 25, 2020 7:36 PM
    Tuesday, August 25, 2020 7:35 PM
  • My code was for sending data to the server in the correct format. I didn't include any reading coming back. As I mentioned before you are working with a binary format, not strings so your string reading won't work at all.

    Additionally you are not properly reading the results even if you got them back properly. Read only returns what is currently available. You have to call this in a loop until you have read all the data you expect. This is discussed in the documentation here where you keep calling Read until you've read all the data. To know how much to read you have to understand the message that was sent to you. None of this is standardized so you have to look at the device's documentation to figure this out.

    If even the first read isn't coming back then you most likely aren't sending the proper request so the remote device is either ignoring it altogether or waiting for the response. Again you need to look at the docs to understand how to call this because there is no standard approach.

    Personally I would recommend that you find something that already communicates with it like a UI they provide you. Then monitor the network call to get the information being sent and received and combine that with the docs to figure out what you need to send. As mentioned earlier if your CRC check (which can vary by algorithm) is wrong or any of the bytes are out of place then the device will not respond and we have no way of knowing that information. 

    Another good idea is to step outside your app for testing right now until you get the actual format figured out. Telnet might be useful here, depends on the device, with it you can connect to the device and then send raw data streams and get responses. Unfortunately it has been a long time since I've used it so it might or might not be easy given your protocol.



    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, August 25, 2020 7:53 PM
  • Yeah.. I thought about monitoring the server with the UI, using something like Wireshark. The problem is, the server is really old, and I don't know if it support Wireshark.

    I just tested your Telnet idea.. it connect, but I have no idea how to send commands to this: 

    [root@r210 ~]# telnet 192.168.0.250 80
    Trying 192.168.0.250...
    Connected to 192.168.0.250.
    Escape character is '^]'.
    Connection closed by foreign host.



    Tuesday, August 25, 2020 8:48 PM
  • Wireshark (or Fiddler) work at the TCP level so it wouldn't matter how old it was. Provided it communicates via TCP then you are fine. Of course I'm assuming it is TCP communication and not a serial port or something.

    Telnet may not be the best tool to test with given the binary data. Here's an SO post about useful tools for testing binary data sent over TCP that you might try instead. I've not used any of them so I cannot answer to how well they work.


    Michael Taylor http://www.michaeltaylorp3.net

    Tuesday, August 25, 2020 9:25 PM
  • The server is old.. I think is running WinXP or something... tomorrow I'll check the server and the SO tools.

    Thanks for now!

    Wednesday, August 26, 2020 1:11 AM
  • Ok, new tests today.

    The server admin has been quarantined for 15 days. But, I have access to the Firewall (CentOS). Running tcpdump, it revealed something:

    [root@r210 ~]# tcpdump -n host 192.168.0.250 -i em1
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on em1, link-type EN10MB (Ethernet), capture size 262144 bytes
    09:00:01.232566 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], ack 3579261804, win 1024, length 0
    09:00:01.232607 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], ack 3579261804, win 1024, length 0
    09:00:01.341320 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 0:262, ack 1, win 1536, length 262
    09:00:01.341357 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 0:262, ack 1, win 1536, length 262
    09:00:01.341810 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], seq 1:71, ack 262, win 65392, length 70
    09:00:01.341837 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], seq 1:71, ack 262, win 65392, length 70
    09:00:01.432486 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 262:266, ack 1, win 1536, length 4
    09:00:01.432517 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 262:266, ack 1, win 1536, length 4
    09:00:01.472081 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 266, win 65388, length 0
    09:00:01.472114 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 266, win 65388, length 0
    09:00:01.534821 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], ack 71, win 1024, length 0
    09:00:01.534851 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], ack 71, win 1024, length 0
    09:00:01.770764 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 266:528, ack 71, win 1536, length 262
    09:00:01.770797 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 266:528, ack 71, win 1536, length 262
    09:00:01.812116 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 528, win 65126, length 0
    09:00:01.812148 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 528, win 65126, length 0
    09:00:01.869369 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 528:532, ack 71, win 1536, length 4
    09:00:01.869397 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 528:532, ack 71, win 1536, length 4
    09:00:01.910061 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 532, win 65122, length 0
    09:00:01.910111 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 532, win 65122, length 0
    09:00:03.148690 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], seq 71:141, ack 532, win 65122, length 70
    09:00:03.148722 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], seq 71:141, ack 532, win 65122, length 70
    09:00:03.182484 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], ack 141, win 1024, length 0
    09:00:03.182515 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], ack 141, win 1024, length 0
    09:00:03.283448 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 532:794, ack 141, win 1536, length 262
    09:00:03.283486 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 532:794, ack 141, win 1536, length 262
    09:00:03.283937 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], seq 141:211, ack 794, win 64860, length 70
    09:00:03.283954 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], seq 141:211, ack 794, win 64860, length 70
    09:00:03.387646 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 794:798, ack 141, win 1536, length 4
    09:00:03.387682 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 794:798, ack 141, win 1536, length 4
    09:00:03.387891 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 798, win 65392, length 0
    09:00:03.387908 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 798, win 65392, length 0
    09:00:03.484745 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], ack 211, win 1024, length 0
    09:00:03.484782 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], ack 211, win 1024, length 0
    09:00:03.721074 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 798:1060, ack 211, win 1536, length 262
    09:00:03.721113 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 798:1060, ack 211, win 1536, length 262
    09:00:03.762026 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 1060, win 65130, length 0
    09:00:03.762049 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 1060, win 65130, length 0
    09:00:03.819608 IP 192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], seq 1060:1064, ack 211, win 1536, length 4
    09:00:03.819644 IP 192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], seq 1060:1064, ack 211, win 1536, length 4
    09:00:03.860033 IP 192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 1064, win 65126, length 0
    09:00:03.860053 IP 192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], ack 1064, win 65126, length 0
    

    This means that all data traffic is passing through the Firewall. So if I install Wireshark on the firewall (Linux), I will most likely be able to monitor the data between the server and the reader. 

    Do you know any Linux tool, besides Wireshark, that I can monitor the data? Or even using TCPDump?

    Wednesday, August 26, 2020 12:10 PM
  • Using tcpdump with "-s0" parameter, shows me something:

    [root@r210 ~]# tcpdump -i em1 host 192.168.0.250 -s0 -vv -X -c 1000
    tcpdump: listening on em1, link-type EN10MB (Ethernet), capture size 262144 bytes
    09:23:27.152776 IP (tos 0x0, ttl 128, id 34969, offset 0, flags [none], proto TCP (6), length 110)
        192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], cksum 0x735c (correct), seq 3579360154:3579360224, ack 7724219, win 65388, length 70
            0x0000:  4500 006e 8899 0000 8006 2515 c0a8 0015  E..n......%.....
            0x0010:  ac1c 2002 e424 0884 d558 b39a 0075 dcbb  .....$...X...u..
            0x0020:  5018 ff6c 735c 0000 0200 4205 1400 0000  P..ls\....B.....
            0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 050f       ..............
    09:23:27.152817 IP (tos 0x0, ttl 127, id 34969, offset 0, flags [none], proto TCP (6), length 110)
        192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], cksum 0x66ff (correct), seq 3579360154:3579360224, ack 7724219, win 65388, length 70
            0x0000:  4500 006e 8899 0000 7f06 19b8 ac1c 20fe  E..n............
            0x0010:  ac1c 2002 e424 0884 d558 b39a 0075 dcbb  .....$...X...u..
            0x0020:  5018 ff6c 66ff 0000 0200 4205 1400 0000  P..lf.....B.....
            0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 050f       ..............
    09:23:27.177088 IP (tos 0x0, ttl 64, id 41825, offset 0, flags [DF], proto TCP (6), length 40)
        192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], cksum 0xbf88 (correct), seq 1, ack 70, win 1024, length 0
            0x0000:  4500 0028 a361 4000 4006 fe35 ac1c 2002  E..(.a@.@..5....
            0x0010:  ac1c 20fe 0884 e424 0075 dcbb d558 b3e0  .......$.u...X..
            0x0020:  5010 0400 bf88 0000 0000 0000 0000 0000  P...............
            0x0030:  0000 0000 0000 0000 0000 0000            ............
    09:23:27.177114 IP (tos 0x0, ttl 63, id 41825, offset 0, flags [DF], proto TCP (6), length 40)
        192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], cksum 0xcbe5 (correct), seq 1, ack 70, win 1024, length 0
            0x0000:  4500 0028 a361 4000 3f06 0b93 ac1c 2002  E..(.a@.?.......
            0x0010:  c0a8 0015 0884 e424 0075 dcbb d558 b3e0  .......$.u...X..
            0x0020:  5010 0400 cbe5 0000                      P.......
    09:23:27.277970 IP (tos 0x0, ttl 64, id 41826, offset 0, flags [DF], proto TCP (6), length 302)
        192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], cksum 0xfe66 (correct), seq 1:263, ack 70, win 1536, length 262
            0x0000:  4500 012e a362 4000 4006 fd2e ac1c 2002  E....b@.@.......
            0x0010:  ac1c 20fe 0884 e424 0075 dcbb d558 b3e0  .......$.u...X..
            0x0020:  5010 0600 fe66 0000 0201 0205 1440 0923  P....f.......@.#
            0x0030:  2309 2450 2608 2052 9a9c 477c d09c 47ab  #.$P&..R..G|..G.
            0x0040:  2c9c 4773 d307 4816 9e07 480e 3c07 48c5  ,.Gs..H...H.<.H.
            0x0050:  b18a 4119 8a91 416d 5c9b 417b 8582 4001  ..A...Am\.A{..@.
            0x0060:  5da9 c9fa a1af c9a7 cabc c968 7285 ca4e  ]..........hr..N
            0x0070:  798a c7f0 d567 c853 45e2 c7a0 1acf c8df  y....g.SE.......
            0x0080:  afa9 495c 4db2 49dc 8ebd 4906 6386 4a93  ..I\M.I...I.c.J.
            0x0090:  95a9 49ea 01b2 490f 52bd 49bd 1286 4aea  ..I...I.R.I...J.
            0x00a0:  e73c 4715 f5a3 4743 c697 47a7 174d 489a  .<G...GC..G..MH.
            0x00b0:  aa7f 3fb3 957c 3fe7 487f 3fdd cd7e 3f4c  ..?..|?.H.?..~?L
            0x00c0:  4c4c 4cfc 827f 3fd2 2a7c 3f06 f77e 3fa3  LLL...?.*|?..~?.
            0x00d0:  357e 3f1e 1331 436f a12a 4353 b72f 4300  5~?..1Co.*CS./C.
            0x00e0:  5ec8 41f9 f96f 4201 0000 0000 0000 0000  ^.A..oB.........
            0x00f0:  0e00 0000 0037 54f0 c2c8 68ef 4237 54f0  .....7T...h.B7T.
            0x0100:  c201 43f0 c2c8 68ef c276 e89a 3f84 0eb9  ..C...h..v..?...
            0x0110:  3fcc 66b6 3f00 0000 0000 0000 0000 0000  ?.f.?...........
            0x0120:  0000 0000 0000 0000 0000 0000 a242       .............B
    09:23:27.277999 IP (tos 0x0, ttl 63, id 41826, offset 0, flags [DF], proto TCP (6), length 302)
        192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], cksum 0x0ac4 (correct), seq 1:263, ack 70, win 1536, length 262
            0x0000:  4500 012e a362 4000 3f06 0a8c ac1c 2002  E....b@.?.......
            0x0010:  c0a8 0015 0884 e424 0075 dcbb d558 b3e0  .......$.u...X..
            0x0020:  5010 0600 0ac4 0000 0201 0205 1440 0923  P............@.#
            0x0030:  2309 2450 2608 2052 9a9c 477c d09c 47ab  #.$P&..R..G|..G.
            0x0040:  2c9c 4773 d307 4816 9e07 480e 3c07 48c5  ,.Gs..H...H.<.H.
            0x0050:  b18a 4119 8a91 416d 5c9b 417b 8582 4001  ..A...Am\.A{..@.
            0x0060:  5da9 c9fa a1af c9a7 cabc c968 7285 ca4e  ]..........hr..N
            0x0070:  798a c7f0 d567 c853 45e2 c7a0 1acf c8df  y....g.SE.......
            0x0080:  afa9 495c 4db2 49dc 8ebd 4906 6386 4a93  ..I\M.I...I.c.J.
            0x0090:  95a9 49ea 01b2 490f 52bd 49bd 1286 4aea  ..I...I.R.I...J.
            0x00a0:  e73c 4715 f5a3 4743 c697 47a7 174d 489a  .<G...GC..G..MH.
            0x00b0:  aa7f 3fb3 957c 3fe7 487f 3fdd cd7e 3f4c  ..?..|?.H.?..~?L
            0x00c0:  4c4c 4cfc 827f 3fd2 2a7c 3f06 f77e 3fa3  LLL...?.*|?..~?.
            0x00d0:  357e 3f1e 1331 436f a12a 4353 b72f 4300  5~?..1Co.*CS./C.
            0x00e0:  5ec8 41f9 f96f 4201 0000 0000 0000 0000  ^.A..oB.........
            0x00f0:  0e00 0000 0037 54f0 c2c8 68ef 4237 54f0  .....7T...h.B7T.
            0x0100:  c201 43f0 c2c8 68ef c276 e89a 3f84 0eb9  ..C...h..v..?...
            0x0110:  3fcc 66b6 3f00 0000 0000 0000 0000 0000  ?.f.?...........
            0x0120:  0000 0000 0000 0000 0000 0000 a242       .............B
    09:23:27.278450 IP (tos 0x0, ttl 128, id 34970, offset 0, flags [none], proto TCP (6), length 110)
        192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], cksum 0x20dc (correct), seq 70:140, ack 263, win 65126, length 70
            0x0000:  4500 006e 889a 0000 8006 2514 c0a8 0015  E..n......%.....
            0x0010:  ac1c 2002 e424 0884 d558 b3e0 0075 ddc1  .....$...X...u..
            0x0020:  5018 fe66 20dc 0000 0200 4205 2300 0000  P..f......B.#...
            0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 4849       ............HI
    09:23:27.278474 IP (tos 0x0, ttl 127, id 34970, offset 0, flags [none], proto TCP (6), length 110)
        192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [P.], cksum 0x147f (correct), seq 70:140, ack 263, win 65126, length 70
            0x0000:  4500 006e 889a 0000 7f06 19b7 ac1c 20fe  E..n............
            0x0010:  ac1c 2002 e424 0884 d558 b3e0 0075 ddc1  .....$...X...u..
            0x0020:  5018 fe66 147f 0000 0200 4205 2300 0000  P..f......B.#...
            0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 4849       ............HI
    09:23:27.386248 IP (tos 0x0, ttl 64, id 41827, offset 0, flags [DF], proto TCP (6), length 44)
        192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], cksum 0xba7a (correct), seq 263:267, ack 70, win 1536, length 4
            0x0000:  4500 002c a363 4000 4006 fe2f ac1c 2002  E..,.c@.@../....
            0x0010:  ac1c 20fe 0884 e424 0075 ddc1 d558 b3e0  .......$.u...X..
            0x0020:  5010 0600 ba7a 0000 0200 0004 0000 0000  P....z..........
            0x0030:  0000 0000 0000 0000 0000 0000            ............
    09:23:27.386273 IP (tos 0x0, ttl 63, id 41827, offset 0, flags [DF], proto TCP (6), length 44)
        192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], cksum 0xc6d7 (correct), seq 263:267, ack 70, win 1536, length 4
            0x0000:  4500 002c a363 4000 3f06 0b8d ac1c 2002  E..,.c@.?.......
            0x0010:  c0a8 0015 0884 e424 0075 ddc1 d558 b3e0  .......$.u...X..
            0x0020:  5010 0600 c6d7 0000 0200 0004            P...........
    09:23:27.427097 IP (tos 0x0, ttl 128, id 34971, offset 0, flags [none], proto TCP (6), length 40)
        192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], cksum 0xd032 (correct), seq 140, ack 267, win 65122, length 0
            0x0000:  4500 0028 889b 0000 8006 2559 c0a8 0015  E..(......%Y....
            0x0010:  ac1c 2002 e424 0884 d558 b426 0075 ddc5  .....$...X.&.u..
            0x0020:  5010 fe62 d032 0000 0000 0000 0000       P..b.2........
    09:23:27.427120 IP (tos 0x0, ttl 127, id 34971, offset 0, flags [none], proto TCP (6), length 40)
        192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], cksum 0xc3d5 (correct), seq 140, ack 267, win 65122, length 0
            0x0000:  4500 0028 889b 0000 7f06 19fc ac1c 20fe  E..(............
            0x0010:  ac1c 2002 e424 0884 d558 b426 0075 ddc5  .....$...X.&.u..
            0x0020:  5010 fe62 c3d5 0000                      P..b....
    09:23:27.479656 IP (tos 0x0, ttl 64, id 41828, offset 0, flags [DF], proto TCP (6), length 40)
        192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], cksum 0xbe38 (correct), seq 267, ack 140, win 1024, length 0
            0x0000:  4500 0028 a364 4000 4006 fe32 ac1c 2002  E..(.d@.@..2....
            0x0010:  ac1c 20fe 0884 e424 0075 ddc5 d558 b426  .......$.u...X.&
            0x0020:  5010 0400 be38 0000 0000 0000 0000 0000  P....8..........
            0x0030:  0000 0000 0000 0000 0000 0000            ............
    09:23:27.479672 IP (tos 0x0, ttl 63, id 41828, offset 0, flags [DF], proto TCP (6), length 40)
        192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], cksum 0xca95 (correct), seq 267, ack 140, win 1024, length 0
            0x0000:  4500 0028 a364 4000 3f06 0b90 ac1c 2002  E..(.d@.?.......
            0x0010:  c0a8 0015 0884 e424 0075 ddc5 d558 b426  .......$.u...X.&
            0x0020:  5010 0400 ca95 0000                      P.......
    09:23:27.715810 IP (tos 0x0, ttl 64, id 41829, offset 0, flags [DF], proto TCP (6), length 302)
        192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], cksum 0x79c7 (correct), seq 267:529, ack 140, win 1536, length 262
            0x0000:  4500 012e a365 4000 4006 fd2b ac1c 2002  E....e@.@..+....
            0x0010:  ac1c 20fe 0884 e424 0075 ddc5 d558 b426  .......$.u...X.&
            0x0020:  5010 0600 79c7 0000 0201 0205 2340 0923  P...y.......#@.#
            0x0030:  2300 0060 3049 0000 0518 1000 0000 0000  #..`0I..........
            0x0040:  0000 5512 5900 0000 0000 0000 0000 0000  ..U.Y...........
            0x0050:  0000 0000 0000 1700 0023 0000 0000 0021  .........#.....!
            0x0060:  0000 0000 0000 0000 0000 1248 0000 0000  ...........H....
            0x0070:  1421 0000 0000 0000 0000 0000 0060 9451  .!...........`.Q
            0x0080:  0000 0523 1800 0000 0000 0000 5571 3100  ...#........Uq1.
            0x0090:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00a0:  1800 0024 0000 0000 0022 0000 0000 0000  ...$....."......
            0x00b0:  0000 0000 1254 0000 0000 1426 0000 0000  .....T.....&....
            0x00c0:  0000 0000 0000 0063 0343 0000 0537 9400  .......c.C...7..
            0x00d0:  0000 0000 0000 5765 3800 0000 0000 0000  ......We8.......
            0x00e0:  0000 0000 0000 0000 0000 1900 0025 0000  .............%..
            0x00f0:  0000 0023 0000 0000 0000 0000 0000 1281  ...#............
            0x0100:  0000 0000 1459 0000 0000 0000 0000 0000  .....Y..........
            0x0110:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0120:  0000 0000 0000 0000 0000 0000 d914       ..............
    09:23:27.715840 IP (tos 0x0, ttl 63, id 41829, offset 0, flags [DF], proto TCP (6), length 302)
        192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], cksum 0x8624 (correct), seq 267:529, ack 140, win 1536, length 262
            0x0000:  4500 012e a365 4000 3f06 0a89 ac1c 2002  E....e@.?.......
            0x0010:  c0a8 0015 0884 e424 0075 ddc5 d558 b426  .......$.u...X.&
            0x0020:  5010 0600 8624 0000 0201 0205 2340 0923  P....$......#@.#
            0x0030:  2300 0060 3049 0000 0518 1000 0000 0000  #..`0I..........
            0x0040:  0000 5512 5900 0000 0000 0000 0000 0000  ..U.Y...........
            0x0050:  0000 0000 0000 1700 0023 0000 0000 0021  .........#.....!
            0x0060:  0000 0000 0000 0000 0000 1248 0000 0000  ...........H....
            0x0070:  1421 0000 0000 0000 0000 0000 0060 9451  .!...........`.Q
            0x0080:  0000 0523 1800 0000 0000 0000 5571 3100  ...#........Uq1.
            0x0090:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x00a0:  1800 0024 0000 0000 0022 0000 0000 0000  ...$....."......
            0x00b0:  0000 0000 1254 0000 0000 1426 0000 0000  .....T.....&....
            0x00c0:  0000 0000 0000 0063 0343 0000 0537 9400  .......c.C...7..
            0x00d0:  0000 0000 0000 5765 3800 0000 0000 0000  ......We8.......
            0x00e0:  0000 0000 0000 0000 0000 1900 0025 0000  .............%..
            0x00f0:  0000 0023 0000 0000 0000 0000 0000 1281  ...#............
            0x0100:  0000 0000 1459 0000 0000 0000 0000 0000  .....Y..........
            0x0110:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0120:  0000 0000 0000 0000 0000 0000 d914       ..............
    09:23:27.757131 IP (tos 0x0, ttl 128, id 34972, offset 0, flags [none], proto TCP (6), length 40)
        192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], cksum 0xd032 (correct), seq 140, ack 529, win 64860, length 0
            0x0000:  4500 0028 889c 0000 8006 2558 c0a8 0015  E..(......%X....
            0x0010:  ac1c 2002 e424 0884 d558 b426 0075 decb  .....$...X.&.u..
            0x0020:  5010 fd5c d032 0000 0000 0000 0000       P..\.2........
    09:23:27.757159 IP (tos 0x0, ttl 127, id 34972, offset 0, flags [none], proto TCP (6), length 40)
        192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], cksum 0xc3d5 (correct), seq 140, ack 529, win 64860, length 0
            0x0000:  4500 0028 889c 0000 7f06 19fb ac1c 20fe  E..(............
            0x0010:  ac1c 2002 e424 0884 d558 b426 0075 decb  .....$...X.&.u..
            0x0020:  5010 fd5c c3d5 0000                      P..\....
    09:23:27.814674 IP (tos 0x0, ttl 64, id 41830, offset 0, flags [DF], proto TCP (6), length 44)
        192.168.0.250.mc-gt-srv > 192.168.0.25054.58404: Flags [.], cksum 0xb92a (correct), seq 529:533, ack 140, win 1536, length 4
            0x0000:  4500 002c a366 4000 4006 fe2c ac1c 2002  E..,.f@.@..,....
            0x0010:  ac1c 20fe 0884 e424 0075 decb d558 b426  .......$.u...X.&
            0x0020:  5010 0600 b92a 0000 0200 0004 0000 0000  P....*..........
            0x0030:  0000 0000 0000 0000 0000 0000            ............
    09:23:27.814699 IP (tos 0x0, ttl 63, id 41830, offset 0, flags [DF], proto TCP (6), length 44)
        192.168.0.250.mc-gt-srv > 192.168.0.21.58404: Flags [.], cksum 0xc587 (correct), seq 529:533, ack 140, win 1536, length 4
            0x0000:  4500 002c a366 4000 3f06 0b8a ac1c 2002  E..,.f@.?.......
            0x0010:  c0a8 0015 0884 e424 0075 decb d558 b426  .......$.u...X.&
            0x0020:  5010 0600 c587 0000 0200 0004            P...........
    09:23:27.856143 IP (tos 0x0, ttl 128, id 34973, offset 0, flags [none], proto TCP (6), length 40)
        192.168.0.21.58404 > 192.168.0.250.mc-gt-srv: Flags [.], cksum 0xce1a (correct), seq 140, ack 533, win 65392, length 0
            0x0000:  4500 0028 889d 0000 8006 2557 c0a8 0015  E..(......%W....
            0x0010:  ac1c 2002 e424 0884 d558 b426 0075 decf  .....$...X.&.u..
            0x0020:  5010 ff70 ce1a 0000 0000 0000 0000       P..p..........
    09:23:27.856169 IP (tos 0x0, ttl 127, id 34973, offset 0, flags [none], proto TCP (6), length 40)
        192.168.0.25054.58404 > 192.168.0.250.mc-gt-srv: Flags [.], cksum 0xc1bd (correct), seq 140, ack 533, win 65392, length 0
            0x0000:  4500 0028 889d 0000 7f06 19fa ac1c 20fe  E..(............
            0x0010:  ac1c 2002 e424 0884 d558 b426 0075 decf  .....$...X.&.u..
            0x0020:  5010 ff70 c1bd 0000                      P..p....
    ^C
    22 packets captured
    22 packets received by filter
    0 packets dropped by kernel

    Is that binary data? Do you know what is sent to the server? The server is 192.168.0.250 and the reader is 192.168.0.21. Looks like the reader always send the same data (command). This:

            0x0000:  4500 006e 8899 0000 8006 2515 c0a8 0015  E..n......%.....
            0x0010:  ac1c 2002 e424 0884 d558 b39a 0075 dcbb  .....$...X...u..
            0x0020:  5018 ff6c 735c 0000 0200 4205 1400 0000  P..ls\....B.....
            0x0030:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0040:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0050:  0000 0000 0000 0000 0000 0000 0000 0000  ................
            0x0060:  0000 0000 0000 0000 0000 0000 050f       ..............




    • Edited by Guilherme_ Wednesday, August 26, 2020 12:36 PM
    Wednesday, August 26, 2020 12:29 PM
  • It is binary data but we have absolutely no way of understanding what it means. Without knowing the underlying data being sent it is impossible to know for sure. 4500 006e could be a character, a byte value or part of the larger 2/4-byte int or float or double. There is no reliable way at the binary level to tell the difference between types. 

    None of this data is lining up with your original information about requiring a SOH followed by 0/1/2, etc. I think you need to take a closer look at the docs for this.

    Just as a starting guess the 4500 is a marker value of some sort if they all start with that value. The next value varies so it might be the length of the data since it is small and sometimes the same. After that you're in variable data so it is not possible to tell what is going on. The docs should clarify this. What you originally posted might just be the initialization message that is sent to start talking to the remote device. After the initialization it probably switches to a standard message format which is what you are seeing in your logs. But that is just a guess. The docs should clarify this.


    Michael Taylor http://www.michaeltaylorp3.net

    Wednesday, August 26, 2020 1:28 PM
  • There is other information in the documentation, which may be useful. But they are for serial connection:

    CONNECTION:
    In order for one device to detect the presence of the other, there are connection and disconnection rules between them. Whenever the reader is going to start a communication section with the meter, he must put MARK (1 logic) on his serial output. This signal is felt by the meter as an indication of a connection request by the reader and can only be considered valid after 1 second of stabilization.

    Once the connection request is accepted, the meter starts sending the ENQ signaling characters. The reader connects when it receives the first ENQ. Whenever not connected, the meter must send SPACE (logic 0) on its serial output.

    COMMAND:
    Data block with fixed size of 64 octets (plus 2 of CRC), whose function is to transfer information from the reader to the meter.

    ANSWER:
    256 octet data block (plus 2 CRC), whose function is to transfer information from the meter to the reader.

    MESSAGE FORMATION RULES
    ENQ = 05 Hexadecimal
    ACK = 06 Hexadecimal
    NAK = 15 Hexadecimal
    WAIT = 10 Hexadecimal
    BYTE = 00 to FF Hexadecimal
    CODE = 01 to 99 BCD, except 05, 06, 10 and 15
    CRC = CRC16 (x16 + x15 + x2 + 1)
    COM = 63 bytes
    RES = 255 byte
    SIGNALER = ENQ or ACK or NAK or WAIT
    COMMAND = <CODE><COM> <CRC>
    ANSWER = <CODE><RES> <CRC>
    * NOTE: CRC is calculated on <CODE> <COM> or <CODE> <RES>




    • Edited by Guilherme_ Wednesday, August 26, 2020 2:13 PM
    Wednesday, August 26, 2020 2:12 PM
  • Monitoring with Wireshark, it seems to have a pattern and decimal numbers. 

    The reader sends 2 commands with length 124 and 3 with length 60.

    Screen 01:
    https://prnt.sc/u6bvyu

    Length 124:
    https://prnt.sc/u6busg
    https://prnt.sc/u6bv1h
    https://prnt.sc/u6bv7w

    Length 60:
    https://prnt.sc/u6bvdp
    https://prnt.sc/u6bvl1

    Original Pcap file:
    Download

    * Note: Im using another meter with IP 172.28.32.2. The reader IP is 192.168.0.21.

    • Edited by Guilherme_ Wednesday, August 26, 2020 5:42 PM
    Wednesday, August 26, 2020 5:40 PM
  • Detailing the Packet 1:

    Image1

    Value:
    
    0200420514000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050f
    

    Which apparently aligns with the SOH rule followed by 0/1/2.

    Commands (ASCII communication):
    
    Octet 001: SOH; 
    Octet 002: Access code: "0" - Read "1" - Demand "2" - Update 
    Octet 003: STX; 
    Octet 004-135: Command for convencional communication server/reader, converted nibble to nibble to ASCII code including CRC; 
    Octet 136: ETX; 
    Octet 137: LRC;



    • Edited by Guilherme_ Wednesday, August 26, 2020 6:36 PM
    Wednesday, August 26, 2020 6:33 PM
  • Glad to hear you're figuring this out. We aren't going to be able to help you with this decoding because we don't have the docs or device to test with. But by using an external listener you can see valid request responses and then build up your C# code to generate the same. We can help you build specific sets of data if you have a specific example. But note that the CRC information can vary so you're going to have to know how to calculate that.

    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, August 27, 2020 3:22 PM
  • Hi Michael.

    Yea, i'm trying a lot.. xD

    But I guess the server uses Telnet, without authentication and plain text to send the commands. I just opened a new topic on this, but with no answers.

    Any idea on how to send command in Plain Text to the server?


    • Edited by Guilherme_ Thursday, August 27, 2020 7:10 PM
    Thursday, August 27, 2020 7:08 PM
  • If the server actually accepted plain text then your original code of using TcpClient, getting the stream, converting the string to a byte array using Encoding.ASCII and then sending that would work (or use a StreamWriter). But plain text wouldn't line up with the codes you posted originally around SOH and CRC stuff as that is binary. 

    Maybe you'll get an answer on the other thread. Be sure to link to this thread so others have context though. Good luck.


    Michael Taylor http://www.michaeltaylorp3.net

    Thursday, August 27, 2020 8:46 PM
  • Hi Michael.

    Just one last question. Monitoring the reader with Wireshark, it always sends the same command. Which seems to follow the command rules that I had posted.

    Command:

    0200420514000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050f

    Using my example (TCPClient or Socket), I need to convert it to a byte array using Encoding.ASCII. Monitoring my example with Wireshark, the same command looks like this:

    3032303034323035313430303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030303030353066

    Therefore, I believe that I need to send the command in plain text, without converting it to ASCII. Is there any way to do this? Thanks in advance.

    Friday, August 28, 2020 11:39 AM
  • No I don't believe that is correct. Wireshark is showing you the raw byte stream, not ASCII. It has no way of knowing how to translate that data so whether it is a string, float or whatever doesn't matter. If you wanted to send that exact command then put it into a byte array.

    var command = new byte[] {
      0x2, 0, 0x42, 0x5, 0x14, ...
    }
    I noticed that the command ended with an F so that must be the hex string. Thus to convert to a byte array you use hex. Of course that is a lot of typing so from this SO post somebody produced a cleaner version that is unfortunately slower.

    public static byte[] StringToByteArray ( string hex )
    {
       return Enumerable.Range(0, hex.Length)
                     .Where(x => x % 2 == 0)
                     .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                     .ToArray();
    }
    
    //And usage
    var stringCommand = "0200420514000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000050f";
    
    //command will have the byte array equivalent
    var command = StringToByteArray(stringCommand);


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by Guilherme_ Friday, August 28, 2020 10:11 PM
    Friday, August 28, 2020 3:15 PM
  • Thanks Michael.

    That worked! =)

    Friday, August 28, 2020 10:12 PM