I'm trying to emulate Lego EV3 brick connection via wifi. First I found the repo 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:
I saw that I received something weird to my buffer after establishing a connection (it was weird because there is nothing in the document 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 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?