agrobot_base/AgroBase/AgroBase/Models/UdpCtrlMessage.cs

105 lines
2.5 KiB
C#

using System;
using System.Buffers.Binary; // se seu .NET não tiver, eu te passo versão sem isso
using System.Windows.Forms;
using static AgroBase.Models.Enums;
[Flags]
public enum UdpCtrlFlags : byte
{
None = 0,
Emergencia = 1 << 0,
Pausa = 1 << 1,
HasKey = 1 << 2,
HasPayload = 1 << 3,
}
public sealed class UdpCtrlMessage
{
public byte Version = 1;
public byte Device;
public UdpCtrlFlags Flags;
public BotoesJoystick Key;
public bool released;
public short P1;
public short P2;
public byte[] ToBytes()
{
// 11 bytes fixos
var buf = new byte[11];
buf[0] = Version;
buf[1] = Device;
buf[2] = (byte)Flags;
// key UInt16 BE
ushort k = (ushort)Key;
buf[3] = (byte)(k >> 8);
buf[4] = (byte)(k & 0xFF);
// botao solto
buf[5] = (byte)(released ? 1 : 0);
// p1 int16 BE
buf[6] = (byte)((ushort)P1 >> 8);
buf[7] = (byte)((ushort)P1 & 0xFF);
// p2 int16 BE
buf[8] = (byte)((ushort)P2 >> 8);
buf[9] = (byte)((ushort)P2 & 0xFF);
// reservado (checksum simples futuro / seq local etc)
buf[10] = 0;
return buf;
}
public static bool TryParse(byte[] payload, out UdpCtrlMessage msg)
{
msg = null;
if (payload == null || payload.Length < 10) return false;
var m = new UdpCtrlMessage();
m.Version = payload[0];
if (m.Version != 1) return false;
m.Device = payload[1];
m.Flags = (UdpCtrlFlags)payload[2];
ushort k = (ushort)((payload[3] << 8) | payload[4]);
m.Key = (BotoesJoystick)k;
m.released = payload[5] == 1;
m.P1 = (short)((payload[6] << 8) | payload[7]);
m.P2 = (short)((payload[8] << 8) | payload[9]);
msg = m;
return true;
}
}
public static class UdpKeyPayload
{
// [0] device
// [1..2] key (UInt16 BE)
public static byte[] Build(byte device, Keys key)
{
byte[] buf = new byte[3];
buf[0] = device;
BinaryPrimitives.WriteUInt16BigEndian(buf.AsSpan(1, 2), (ushort)key);
return buf;
}
public static bool TryParse(byte[] payload, out byte device, out Keys key)
{
device = 0;
key = Keys.None;
if (payload == null || payload.Length < 3) return false;
device = payload[0];
ushort raw = BinaryPrimitives.ReadUInt16BigEndian(payload.AsSpan(1, 2));
key = (Keys)raw;
return true;
}
}