eDosStationFull/CheckCom/Program.cs

190 lines
5.7 KiB
C#
Raw Permalink Normal View History

2026-08-18 12:15:26 +02:00
using System.Buffers;
using System.Buffers.Binary;
using System.ComponentModel.DataAnnotations;
using System.IO.Ports;
//string bx = "4F000000780000004F00000078000000000000000000";
//ReadOnlySpan<byte> rs = Convert.FromHexString(bx);
//int x = rs.Length;
//ushort checksum = Crc16IbmSdlc.ComputeChecksum(rs);
string bufp = "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff";
string buf = "ffffffffc0ffffff003f00c1";
Span<byte> discoverID = [ 0xff, 0xff, 0xff];
Span<byte> curID = [ 0xff, 0xf9, 0x07 ];
Span<byte> curIDrest = [ 0x00, 0x00, 0xc2, 0x01, 0x00 ];
byte[] bufferp = Convert.FromHexString(bufp);
byte[] buffer = Convert.FromHexString(buf);
byte[] buffer2 = new byte[256];
ReadOnlySpan<byte> bConnect = MakeConnect(4, curID, curIDrest);
ReadOnlySpan<byte> bDiscover = MakeDiscover(discoverID);
string hexString;
SerialPort sp = new SerialPort("COM3", 9600);
sp.Open();
sp.BaudRate = 9600; sp.Parity = Parity.None; sp.DataBits = 8; sp.StopBits = StopBits.One;
sp.DtrEnable = true;
sp.RtsEnable = true;
sp.ReadTimeout = 1000;
sp.Handshake = Handshake.RequestToSend;
for (int ix = 0; ix < 2; ix++)
{
hexString = Convert.ToHexString(bDiscover);
Console.WriteLine($"-> Discover {hexString}");
sp.BaseStream.Write(bDiscover);
int b = sp.Read(buffer2, 0, 255);
hexString = Convert.ToHexString(buffer2,0,b);
Console.WriteLine($"<- ok {b} bytes: {hexString}");
Thread.Sleep(500);
}
sp.ReadTimeout = 1000;
sp.DiscardInBuffer();
sp.DiscardOutBuffer();
for (int ix = 0; ix < 2; ix++)
{
hexString = Convert.ToHexString(bConnect);
Console.WriteLine($"-> Connect {hexString}");
sp.BaseStream.Write(bConnect);
int b = sp.Read(buffer2, 0, 255);
hexString = Convert.ToHexString(buffer2, 0, b);
Console.WriteLine($"<- ok {b} bytes: {hexString}");
Thread.Sleep(500);
} //-> "C0FFF907879994C1"
//for (int ix = 0; ix < 32; ix++)
//{
// //hexString = Convert.ToHexString(makeBuf, 0, makeBuf.Length);
// //Console.WriteLine($"-> {hexString}");
// //sp.Write(makeBuf, 0, makeBuf.Length);
// int b = 0;
// try
// {
// b = sp.Read(buffer2, 0, 255);
// }
// catch (TimeoutException)
// {
// Console.WriteLine("Read timeout");
// }
// if (b > 0)
// {
// hexString = Convert.ToHexString(buffer2, 0, b);
// Console.WriteLine($"ok {b} bytes: {hexString}");
// }
//} //-> "C0FFF907879994C1"
sp.Close();
Console.ReadLine();
ReadOnlySpan<byte> MakeDiscover(Span<byte> discoverID)
{
return BuildPacket(64, discoverID , new byte[] { 0x00 });
}
ReadOnlySpan<byte> MakeConnect(int syncbytes, ReadOnlySpan<byte> ID, ReadOnlySpan<byte> IDrest)
{
byte[] packet = new byte[1 + ID.Length + IDrest.Length];
packet[0] = 0x07; //connectcommnand
ID.CopyTo(packet.AsSpan(1));
IDrest.CopyTo(packet.AsSpan(1 + ID.Length));
return BuildPacket(syncbytes, ID, packet);
}
ReadOnlySpan<byte> BuildPacket(int syncbytes, ReadOnlySpan<byte> ID, byte[] payload)
{
ArrayBufferWriter<byte> writer = new ArrayBufferWriter<byte>();
if (syncbytes > 0)
{
Span<byte> span = writer.GetSpan(syncbytes);
span.Fill(0xFF);
writer.Advance(syncbytes);
}
writer.Write(new byte[] { 0xC0 }); // STX
int startCS = writer.WrittenCount;
if (ID!=ReadOnlySpan<byte>.Empty) writer.Write(ID);
// 3. Schrijf de dynamische payload
writer.Write(payload);
// 4. Pak alle geschreven data, maar sla de eerste byte (index 0) over via Slice(1)
ReadOnlySpan<byte> dataToChecksum = writer.WrittenSpan.Slice(startCS);
// Bereken de 16-bit checksum
ushort checksum = Crc16IbmSdlc.ComputeChecksum(dataToChecksum);
// 5. Reserveer ruimte voor de staart: 2 bytes checksum + 1 finale byte = 3 bytes
Span<byte> tailSpan = writer.GetSpan(3);
// Checksum wegschrijven in Little Endian (LSB eerst, dan MSB)
tailSpan[0] = (byte)(checksum & 0xFF); // Least Significant Byte
tailSpan[1] = (byte)((checksum >> 8) & 0xFF); // Most Significant Byte
// Finale byte toevoegen
tailSpan[2] = 0xc1; // ETX (End of Text)
// Geef door aan de writer dat we exact 3 bytes hebben toegevoegd
writer.Advance(3);
// 6. Return het resultaat (of stuur writer.WrittenSpan direct naar je Socket)
return writer.WrittenSpan;
}
byte[] MakeBuf(int synccount, string prefix, string id, string playloadrest, string suffix)
{
// Calculate lengths
int prefixLen = prefix.Length / 2;
int idLen = id.Length / 2;
int payloadLen = playloadrest.Length / 2;
int suffixLen = suffix.Length / 2;
int chkLen = 2; // 2 bytes for the CRC16
int blen = synccount + chkLen + prefixLen + idLen + payloadLen + suffixLen;
byte[] buf = new byte[blen];
// 1. Fill sync count bytes with 0xFF
buf.AsSpan(0, synccount).Fill(0xFF);
int currentOffset = synccount;
Convert.FromHexString(prefix, buf.AsSpan(currentOffset), out _, out int written);
currentOffset += written;
int chkstart = currentOffset;
Convert.FromHexString(id, buf.AsSpan(currentOffset), out _, out int idWritten);
currentOffset += idWritten;
Convert.FromHexString(playloadrest, buf.AsSpan(currentOffset), out _, out int payloadWritten);
currentOffset += payloadWritten;
int chkOffset = currentOffset;
int chkend = chkOffset - chkstart;
currentOffset += 2;
Convert.FromHexString(suffix, buf.AsSpan(currentOffset), out _, out int suffixWritten);
currentOffset += suffixWritten;
UInt16 chk = (UInt16)Crc16IbmSdlc.ComputeChecksum(buf.AsSpan(chkstart, chkend));
BinaryPrimitives.WriteUInt16LittleEndian(buf.AsSpan(chkOffset, 2), chk);
return buf;
}