Reader & Middleware EPCglobal / ISO/IEC 24730
OpenRFID Driver: OpenRFID.Plugins.LLRP

Low Level Reader Protocol (LLRP v1.0.1 / v1.1)

LLRP provides standard binary message serialization between host middleware and physical RFID readers. It allows granular configuration of reader operations (ROSpecs), antenna ports, RF power (dBm), filter algorithms, and real-time RO_ACCESS_REPORT event notifications.

Layer / Stack
Transport & Application (TCP)
Default Port / Freq
TCP Port 5084
Throughput / Speed
1,000+ tag reads/sec over Gigabit Ethernet
Standard Body
EPCglobal

Core Protocol Architecture & Specifications

  • ✓ Standardized binary encoding with 10-bit Message Type and 32-bit Length headers
  • ✓ Configurable ROSpec (Reader Operation Specification) with periodic and trigger-based inventory runs
  • ✓ Granular antenna port power, sensitivity, and tag dwell time control
  • ✓ Real-time RO_ACCESS_REPORT message decoding with Peak RSSI, Antenna ID, and PC/EPC bytes
  • ✓ Zero vendor lock-in across Impinj, Zebra, Alien, and generic UHF readers
OpenRFID .NET 8 LLRP Binary RO_ACCESS_REPORT Decoder
csharp
using System.Buffers.Binary;

public static class LlrpMessageDecoder
{
    public const ushort RO_ACCESS_REPORT_MSG_TYPE = 61;
    public const ushort PARAM_TAG_REPORT_DATA = 240;
    public const ushort PARAM_PEAK_RSSI = 218;
    public const ushort PARAM_ANTENNA_ID = 221;

    public static List<(string EPC, float RSSI, int Antenna)> DecodeRoAccessReport(byte[] buffer)
    {
        var tags = new List<(string EPC, float RSSI, int Antenna)>();
        if (buffer == null || buffer.Length < 10) return tags;

        ushort msgTypeHeader = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(0, 2));
        ushort msgType = (ushort)(msgTypeHeader & 0x03FF);
        uint length = BinaryPrimitives.ReadUInt32BigEndian(buffer.AsSpan(2, 4));

        if (msgType != RO_ACCESS_REPORT_MSG_TYPE || buffer.Length < length) return tags;

        int index = 10;
        int maxIndex = (int)length;

        while (index + 4 <= maxIndex)
        {
            ushort paramHeader = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(index, 2));
            ushort paramType = (ushort)(paramHeader & 0x03FF);
            ushort paramLength = BinaryPrimitives.ReadUInt16BigEndian(buffer.AsSpan(index + 2, 2));
            if (paramLength == 0 || index + paramLength > maxIndex) break;

            if (paramType == PARAM_TAG_REPORT_DATA)
            {
                // Parse EPC-96, RSSI, and Antenna Port
                var tag = ParseTagReportData(buffer, index + 4, index + paramLength);
                if (!string.IsNullOrEmpty(tag.EPC)) tags.Add(tag);
            }
            index += paramLength;
        }
        return tags;
    }
}

Verified Hardware Implementations

Our engineering team has thoroughly tested and validated LLRP across the following reader models, embedded modules, and smart transponders:

Impinj Speedway R420 / R700 Zebra FX9600 / FX7500 Alien ALR-F800 Chainway Fixed Portals Identium Fixed Readers

Target Deployments

  • High-speed conveyor portals
  • Warehouse dock door loading gates
  • Automated manufacturing lines
  • Multi-antenna smart shelves

Deploy with OpenRFID

Integrate LLRP into your ERP, warehouse software, or custom mobile app with pre-built C# / C++ drivers.

Frequently Asked Questions (LLRP)

Engineering insights on EPCglobal / ISO/IEC 24730 implementation challenges

Why use LLRP over proprietary reader SDKs?
LLRP is an open EPCglobal standard supported natively by Zebra, Impinj, and Alien readers. By using LLRP, your middleware can connect to any reader brand over TCP port 5084 without rewriting device drivers or licensing vendor-locked SDKs.
Does LLRP support Keep-Alive heartbeats?
Yes. The LLRP specification defines KEEPALIVE messages (Type 62) and KEEPALIVE_ACK (Type 72). Our OpenRFID middleware continuously verifies reader link health every 3,000ms.
How does LLRP binary framing structure its 10-bit Message Type and 32-bit Length headers?
Every LLRP message begins with a 16-bit header: 3 reserved bits, a 3-bit Protocol Version (e.g., 001 for v1.0.1), and a 10-bit Message Type integer (e.g. 61 for RO_ACCESS_REPORT, 20 for ADD_ROSPEC). The subsequent 32 bits define the total byte length of the message payload including nested parameters.
How do you configure an `ADD_ROSPEC` message for trigger-based conveyor scanning?
Inside the ROSpec, define an ROBoundarySpec containing an ROSpecStartTrigger set to GPI (General Purpose Input) Trigger Type. When the photoelectric sensor detects an approaching box, the reader immediately starts inventory execution and shuts down upon a timer or trailing edge trigger.
What is the difference between client-initiated and reader-initiated LLRP connections?
In client-initiated mode, the host software opens a TCP socket to reader port 5084. In reader-initiated mode (often used behind corporate firewalls or dynamic cellular connections), the reader automatically initiates an outbound TCP socket to the central middleware server upon boot.
Hi, Can I Help ? 💬
AI