Answers.Body: <p>There are two types of commands. &quot;System&quot; commands and &quot;Direct&quot; command. The document that you linked lists all of the system commands but only gives examples of direct commands and does not exhaustively list all of the direct commands. Direct commands are any valid bytecodes to be interpreted directly by the VM running on the EV3, so to completely emulate the EV3, you will need to recreate the full lms2012 VM.</p>
  <p>You can find more documentation on the bytecodes used in direct commands at <a href="http://ev3.fantastic.computer/doxygen/bytecodes.html" rel="nofollow noreferrer">http://ev3.fantastic.computer/doxygen/bytecodes.html</a> (this is documentation from the official LEGO source code that has been built and published by a fan). Beware that the documentation isn't always 100% accurate - you should always check the source code to see how things are actually implemented as well.</p>
  <p>There is a machine-readable file of all bytecodes in YAML format at <a href="https://github.com/ev3dev/lmsasm/blob/master/bytecodes/data/ev3.yml" rel="nofollow noreferrer">https://github.com/ev3dev/lmsasm/blob/master/bytecodes/data/ev3.yml</a>. This is useful if you want to automatically generate code instead of manually implementing all of the bytecodes.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-10-02T06:48:36.453Z
Answers.Text: Thank You so much for the reply. Honestly, I wasn't expecting that this is so difficult. I found the [repo](https://github.com/ev3dev/lms2012-compat/tree/ev3dev-stretch) and as I undestand the *lms2012* folder is only required for me. By now I only want to understand the way of replying the Lego Mindstorms Editor to its strange requests. My main idea is only to reverse engineer the c# library so I would accept only direct commands (like move "the" motor with "the" speed)
Answers.UserDisplayName: crackanddie
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-10-01T21:18:20.180Z
Answers.LastActivityDate: 2023-10-03T13:50:23.017Z
Answers.LastEditDate: 2023-10-03T13:50:23.017Z
Answers.UserDisplayName: David Lechner
Body: <p>I'm trying to emulate Lego EV3 brick connection via wifi. First I found the <a href="https://github.com/SaturnHafen/ev3-connect/tree/main" rel="nofollow noreferrer">repo</a> and rewrote it a bit in C# so now I have this:<br />
  <em>LabVIEW.cs</em></p>
  <pre><code>public class LabVIEW
  {
      public string Serial { get; set; }
      public UInt16 Port { get; set; }
      public string? Name { get; set; }
      public string Protocol { get; set; }
  
  
      public LabVIEW() 
      {
          Serial = &quot;001612345678&quot;;
          Port = 5555;
          Name = &quot;EV3-rcv&quot;;
          Protocol = &quot;EV3&quot;;
      }
  
      public void SpawnConnectThread()
      {
          var udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
          var localIP = new IPEndPoint(IPAddress.Parse(&quot;0.0.0.0&quot;), 0);
          udpSocket.Bind(localIP);
          udpSocket.ReceiveTimeout = 10000;
          udpSocket.EnableBroadcast = true;
  
          var task = Task.Run(() =&gt;
          {
              var sendStr = string.Format(
                  &quot;Serial-Number: {0}\r\nPort: {1}\r\nName: {2}\r\nProtocol: {3}\r\n&quot;,
                  Serial, Port, Name, Protocol
              );
              var remoteIP = new IPEndPoint(IPAddress.Parse(&quot;127.255.255.255&quot;), 3015);
              Console.WriteLine(sendStr);
              while (true)
              {
                  byte[] toSend = Encoding.UTF8.GetBytes(sendStr);
                  int sentAmount = udpSocket.SendTo(toSend, remoteIP);
                  if (sentAmount == toSend.Length)
                  {
                      byte[] recvBuff = new byte[64];
                      udpSocket.Receive(recvBuff, 0, 64, SocketFlags.None, out SocketError err);
                      if (err != SocketError.Success)
                      {
                          continue;
                      }
  
                      Console.WriteLine(Encoding.UTF8.GetString(recvBuff));
                  }
                  Task.Delay(5000);
              }
          });
      }
  
      public Socket Connect()
      {
          IPAddress localAddr = IPAddress.Parse(&quot;127.0.0.1&quot;);
          TcpListener server = new TcpListener(localAddr, Port);
          server.Start();
          var sct = server.AcceptSocket();
          byte[] recvBuff = new byte[64];
          sct.Receive(recvBuff);
          Console.WriteLine(Encoding.UTF8.GetString(recvBuff));
          byte[] toSend = Encoding.UTF8.GetBytes(&quot;Accept:EV340\r\n\r\n&quot;);
          sct.Send(toSend);
          return sct;
      }
  }
  </code></pre>
  <p>And the <em>Main</em> part:</p>
  <pre><code>public class Program
  {
      public static void Main(string[] args)
      {
          var lv = new LabVIEW();
          lv.SpawnConnectThread();
          var conn = lv.Connect();
  
  
          while (true)
          {
              if (conn.Available &gt; 0)
              {
                  byte[] buff = conn.ReadLVReply();
                  Console.WriteLine(ByteArrayToString(buff));
                  if (buff[4] == 0x80 || buff[4] == 0x81)
                  {
                      // No response expected
                      continue;
                  }
              }
  
              Thread.Sleep(300);
          }
      }
  
      public static string ByteArrayToString(byte[] ba)
      {
          StringBuilder hex = new StringBuilder(ba.Length * 2);
          foreach (byte b in ba)
              hex.AppendFormat(&quot;{0:x2} &quot;, b);
          return hex.ToString();
      }
  }
  </code></pre>
  <p>And some extensions for sockets:</p>
  <pre><code>public static class SocketExtensions
  {
      public static void SendLVReply(this Socket sct, byte[] dataIn)
      {
          byte[] data = null;
          ushort length = (ushort)dataIn.Length;
          data = new byte[length + 2];
          data[0] = (byte)(length &amp; 0x00ff);
          data[1] = (byte)((length &amp; 0xff00) &gt;&gt; 2);
          Array.Copy(dataIn, 0, data, 2, dataIn.Length);
          sct.Send(data);
      }
  
      public static byte[] ReadLVReply(this Socket sct)
      {
          byte[] lengthBytes = new byte[2];
          byte[] data = new byte[0];
          int expectedlength = 0;
  
          sct.Receive(lengthBytes);
          expectedlength = (ushort) (0x0000 | lengthBytes[0] | (lengthBytes[1] &lt;&lt; 2));
          if(expectedlength &gt; 0){
              data = new byte[expectedlength];
              sct.Receive(data);
          }
          return data;
      }
  }
  </code></pre>
  <p>So what is the problem? The brick is successfully visible in Lego Mindstorms editor (or something, I don't know what it is) but when I click to connect to it, the error appears:
  <a href="https://i.sstatic.net/DNfUJ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/DNfUJ.png" alt="enter image description here" /></a><br />
  I saw that I received something weird to my buffer after establishing a connection (it was weird because there is nothing in the <a href="https://education.lego.com/v3/assets/blt293eea581807678a/blt09ac3101d9df2051/5f88037a69efd81ab4debf2e/lego-mindstorms-ev3-communication-developer-kit.pdf" rel="nofollow noreferrer">document</a> about the bytes). So I decided to take a real EV3 brick and check out what are they sending to each other. Using RawCap and opening the result through WireShark I saw that they are &quot;messaging&quot; a lot sending each other different things like the version of firmware on the brick, the name of the brick, the location of my project and so on. Here are the bytes:</p>
  <pre><code>after the brick sent &quot;Accept:EV340\r\n\r\n&quot;. The PC sends to the brick this
  14 00 01 00 00 18 00 8f 60 c0 0c 83 bb 69 17 65 60 d3 0d 14 64 0a
  and the brick replies with this
  1b 00 01 00 02 5a e5 c5 51 45 56 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  and so on
  </code></pre>
  <p>As I said before - there is nothing about it in the communication document.<br />
  And I want to say one more thing. If I use the C# <a href="https://www.nuget.org/packages/MonoBrickCore/" rel="nofollow noreferrer">library</a> to control the real EV3 brick - there is none of this strange communication after establishing.<br />
  So now the question. Is there a way to control or ignore these messages from the Lego Mindstorms editor?</p>
  
Tags: <ev3><mindstorms><programming><wi-fi>
Title: Problem with emulating EV3 brick via wifi
UserDisplayName: crackanddie
ThreadText: # Problem with emulating EV3 brick via wifi
  
  (Asked by: username_0 on 2023-10-01)
  
  I'm trying to emulate Lego EV3 brick connection via wifi. First I found the [repo](https://github.com/SaturnHafen/ev3-connect/tree/main) and rewrote it a bit in C# so now I have this:  
  *LabVIEW.cs*
  
  ```
  public class LabVIEW
  {
      public string Serial { get; set; }
      public UInt16 Port { get; set; }
      public string? Name { get; set; }
      public string Protocol { get; set; }
  
      public LabVIEW() 
      {
          Serial = "001612345678";
          Port = 5555;
          Name = "EV3-rcv";
          Protocol = "EV3";
      }
  
      public void SpawnConnectThread()
      {
          var udpSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
          var localIP = new IPEndPoint(IPAddress.Parse("0.0.0.0"), 0);
          udpSocket.Bind(localIP);
          udpSocket.ReceiveTimeout = 10000;
          udpSocket.EnableBroadcast = true;
  
          var task = Task.Run(() =>
          {
              var sendStr = string.Format(
                  "Serial-Number: {0}\r\nPort: {1}\r\nName: {2}\r\nProtocol: {3}\r\n",
                  Serial, Port, Name, Protocol
              );
              var remoteIP = new IPEndPoint(IPAddress.Parse("127.255.255.255"), 3015);
              Console.WriteLine(sendStr);
              while (true)
              {
                  byte[] toSend = Encoding.UTF8.GetBytes(sendStr);
                  int sentAmount = udpSocket.SendTo(toSend, remoteIP);
                  if (sentAmount == toSend.Length)
                  {
                      byte[] recvBuff = new byte[64];
                      udpSocket.Receive(recvBuff, 0, 64, SocketFlags.None, out SocketError err);
                      if (err != SocketError.Success)
                      {
                          continue;
                      }
  
                      Console.WriteLine(Encoding.UTF8.GetString(recvBuff));
                  }
                  Task.Delay(5000);
              }
          });
      }
  
      public Socket Connect()
      {
          IPAddress localAddr = IPAddress.Parse("127.0.0.1");
          TcpListener server = new TcpListener(localAddr, Port);
          server.Start();
          var sct = server.AcceptSocket();
          byte[] recvBuff = new byte[64];
          sct.Receive(recvBuff);
          Console.WriteLine(Encoding.UTF8.GetString(recvBuff));
          byte[] toSend = Encoding.UTF8.GetBytes("Accept:EV340\r\n\r\n");
          sct.Send(toSend);
          return sct;
      }
  }
  
  ```
  
  And the *Main* part:
  
  ```
  public class Program
  {
      public static void Main(string[] args)
      {
          var lv = new LabVIEW();
          lv.SpawnConnectThread();
          var conn = lv.Connect();
  
          while (true)
          {
              if (conn.Available > 0)
              {
                  byte[] buff = conn.ReadLVReply();
                  Console.WriteLine(ByteArrayToString(buff));
                  if (buff[4] == 0x80 || buff[4] == 0x81)
                  {
                      // No response expected
                      continue;
                  }
              }
  
              Thread.Sleep(300);
          }
      }
  
      public static string ByteArrayToString(byte[] ba)
      {
          StringBuilder hex = new StringBuilder(ba.Length * 2);
          foreach (byte b in ba)
              hex.AppendFormat("{0:x2} ", b);
          return hex.ToString();
      }
  }
  
  ```
  
  And some extensions for sockets:
  
  ```
  public static class SocketExtensions
  {
      public static void SendLVReply(this Socket sct, byte[] dataIn)
      {
          byte[] data = null;
          ushort length = (ushort)dataIn.Length;
          data = new byte[length + 2];
          data[0] = (byte)(length & 0x00ff);
          data[1] = (byte)((length & 0xff00) >> 2);
          Array.Copy(dataIn, 0, data, 2, dataIn.Length);
          sct.Send(data);
      }
  
      public static byte[] ReadLVReply(this Socket sct)
      {
          byte[] lengthBytes = new byte[2];
          byte[] data = new byte[0];
          int expectedlength = 0;
  
          sct.Receive(lengthBytes);
          expectedlength = (ushort) (0x0000 | lengthBytes[0] | (lengthBytes[1] << 2));
          if(expectedlength > 0){
              data = new byte[expectedlength];
              sct.Receive(data);
          }
          return data;
      }
  }
  
  ```
  
  So what is the problem? The brick is successfully visible in Lego Mindstorms editor (or something, I don't know what it is) but when I click to connect to it, the error appears:
  [![enter image description here](https://i.sstatic.net/DNfUJ.png)](https://i.sstatic.net/DNfUJ.png)  
  I saw that I received something weird to my buffer after establishing a connection (it was weird because there is nothing in the [document](https://education.lego.com/v3/assets/blt293eea581807678a/blt09ac3101d9df2051/5f88037a69efd81ab4debf2e/lego-mindstorms-ev3-communication-developer-kit.pdf) about the bytes). So I decided to take a real EV3 brick and check out what are they sending to each other. Using RawCap and opening the result through WireShark I saw that they are "messaging" a lot sending each other different things like the version of firmware on the brick, the name of the brick, the location of my project and so on. Here are the bytes:
  
  ```
  after the brick sent "Accept:EV340\r\n\r\n". The PC sends to the brick this
  14 00 01 00 00 18 00 8f 60 c0 0c 83 bb 69 17 65 60 d3 0d 14 64 0a
  and the brick replies with this
  1b 00 01 00 02 5a e5 c5 51 45 56 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  and so on
  
  ```
  
  As I said before - there is nothing about it in the communication document.  
  And I want to say one more thing. If I use the C# [library](https://www.nuget.org/packages/MonoBrickCore/) to control the real EV3 brick - there is none of this strange communication after establishing.  
  So now the question. Is there a way to control or ignore these messages from the Lego Mindstorms editor?
  
  **Tags:** ev3, mindstorms, programming, wi-fi
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-10-01. Score: 5 | Accepted answer
  
  There are two types of commands. "System" commands and "Direct" command. The document that you linked lists all of the system commands but only gives examples of direct commands and does not exhaustively list all of the direct commands. Direct commands are any valid bytecodes to be interpreted directly by the VM running on the EV3, so to completely emulate the EV3, you will need to recreate the full lms2012 VM.
  
  You can find more documentation on the bytecodes used in direct commands at <http://ev3.fantastic.computer/doxygen/bytecodes.html> (this is documentation from the official LEGO source code that has been built and published by a fan). Beware that the documentation isn't always 100% accurate - you should always check the source code to see how things are actually implemented as well.
  
  There is a machine-readable file of all bytecodes in YAML format at <https://github.com/ev3dev/lmsasm/blob/master/bytecodes/data/ev3.yml>. This is useful if you want to automatically generate code instead of manually implementing all of the bytecodes.
  
  > **Comments:**
  > **username_0**: Thank You so much for the reply. Honestly, I wasn't expecting that this is so difficult. I found the [repo](https://github.com/ev3dev/lms2012-compat/tree/ev3dev-stretch) and as I undestand the *lms2012* folder is only required for me. By now I only want to understand the way of replying the Lego Mindstorms Editor to its strange requests. My main idea is only to reverse engineer the c# library so I would accept only direct commands (like move "the" motor with "the" speed)  
  
  ---
  
  