using System;
using System.Collections.Concurrent;
using System.Net.Sockets;
using System.Text;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
namespace OpenRfid.LlrpService
{
///
/// High-throughput .NET 8 LLRP Fixed Reader Socket Service
/// Connects to Impinj Speedway / Zebra FX9600 dock door portals on Port 5084
///
public class Program
{
private static readonly ConcurrentDictionary CooldownCache = new();
public static async Task Main(string[] args)
{
string host = args.Length > 0 ? args[0] : "192.168.1.100";
int port = args.Length > 1 ? int.Parse(args[1]) : 5084;
Console.WriteLine($"[INFO] Initializing .NET 8 LLRP Client -> {host}:{port}...");
using var cts = new CancellationTokenSource();
Console.CancelKeyPress += (s, e) => { e.Cancel = true; cts.Cancel(); };
try
{
using var client = new TcpClient();
await client.ConnectAsync(host, port, cts.Token);
Console.WriteLine($"[SUCCESS] Connected to LLRP portal reader at {host}:{port}");
using var stream = client.GetStream();
byte[] buffer = new byte[8192];
while (!cts.Token.IsCancellationRequested)
{
int bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length, cts.Token);
if (bytesRead == 0) break;
// Parse LLRP frame header (Type & Length)
ushort messageType = (ushort)(((buffer[0] & 0x03) << 8) | buffer[1]);
uint messageLength = (uint)((buffer[2] << 24) | (buffer[3] << 16) | (buffer[4] << 8) | buffer[5]);
// Message Type 61 = RO_ACCESS_REPORT
if (messageType == 61)
{
ProcessRoAccessReport(buffer, bytesRead);
}
}
}
catch (OperationCanceledException)
{
Console.WriteLine("[INFO] LLRP Service shutdown requested.");
}
catch (Exception ex)
{
Console.WriteLine($"[ERROR] Connection error: {ex.Message}");
}
}
private static void ProcessRoAccessReport(byte[] frame, int length)
{
// Simple fast EPC hex extraction demo from LLRP parameter stream
long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
// Clean cooldown cache every 30s
foreach (var kvp in CooldownCache)
{
if (now - kvp.Value > 10000) CooldownCache.TryRemove(kvp.Key, out _);
}
Console.WriteLine($"[LLRP] Received RO_ACCESS_REPORT ({length} bytes). Processing tag batch...");
}
}
}