Skip to main content

Supported Readers

VIDPIDDescription
0x0C270x3BFAStandard multi-technology reader
0x0C270x3B4CLEGIC enabled reader
0x0C270x3B1EBluetooth Low Energy (BLE) reader
N/AN/ASerial Interface (RS-232)

Connection Strategies

RIK provides three ways to identify which USB reader to connect to. The strategy is determined by which DeviceId fields you populate.

1. VID/PID Only

The simplest approach. RIK opens the first device matching the given Vendor ID and Product ID.

ReaderDefinition readerDef{};
readerDef.DeviceId.VendorId = 0x0C27;
readerDef.DeviceId.ProductId = 0x3BFA;
readerDef.ProtocolType = PROTOCOL_TYPE_FEATURE_REPORT;

auto handle = AbstractReader::CreateReaderInstance(readerDef, 3);
warning

If multiple readers with the same VID/PID are connected, this opens whichever one the OS enumerates first. The result is non-deterministic. Use serial number or USB path to target a specific device.

2. VID/PID + Serial Number

Adding a serial number narrows the match to a specific device. The USB serial number is part of the USB Device Descriptor -- on newer rf IDEAS readers it matches the reader's ESN (Electronic Serial Number), but on older readers it may be empty or non-unique.

ReaderDefinition readerDef{};
readerDef.DeviceId.VendorId = 0x0C27;
readerDef.DeviceId.ProductId = 0x3BFA;
readerDef.DeviceId.SerialNumber = L"ABC123";
readerDef.ProtocolType = PROTOCOL_TYPE_FEATURE_REPORT;

auto handle = AbstractReader::CreateReaderInstance(readerDef, 3);
Finding serial numbers

Connect one reader at a time and read its ESN from the metadata (GetMetadataStruct().ESN in C++, GetMetadata().ESN in C#, get_metadata()["ESN"] in Python). On newer readers, this ESN matches the USB serial number in the device descriptor.

note

VID/PID should be provided alongside the serial number. Both are passed to the underlying USB library as match criteria. Providing VID/PID narrows the search and avoids accidentally matching a non-reader device that happens to share a serial number.

3. USB Path

The USB path is a topological identifier for a physical USB port. When set, VID/PID and serial number are ignored entirely -- the connection is made purely by port location. This is the most deterministic strategy and is ideal for fixed installations with multiple identical readers.

Path formats:

  • Linux: "B-P" or "B-P.P.P" (e.g., "1-7", "1-7.2") where B = bus number, P = port number
  • Windows: Location path string (e.g., "PCIROOT(0)#PCI(1400)#USBROOT(0)#USB(7)")
ReaderDefinition readerDef{};
readerDef.ProtocolType = PROTOCOL_TYPE_FEATURE_REPORT;

// USB path -- VID/PID are not required in this mode
std::wstring usbPath = L"1-7"; // Linux bus-port path
std::wcsncpy(readerDef.DeviceId.UsbPath, usbPath.c_str(),
sizeof(readerDef.DeviceId.UsbPath) / sizeof(wchar_t) - 1);

auto handle = AbstractReader::CreateReaderInstance(readerDef, 3);
note

The USB path identifies a physical port, not a device. If you move a reader to a different port, its path changes. If you swap two readers between ports, each will take on the other's path.

See Discovering USB Paths for how to find topological paths on Linux and Windows.

Strategy Summary

StrategyDeviceId FieldsBehavior
VID/PIDVendorId + ProductIdOpens the first matching device. Simple, but non-deterministic with duplicates.
VID/PID + SerialVendorId + ProductId + SerialNumberFilters by USB serial number. Reliable when readers have unique serial numbers.
USB PathUsbPath (VID/PID ignored)Opens by physical port location. Most deterministic. Ideal for fixed multi-reader setups.

Finding Your Reader's VID/PID

Windows: Device Manager > Universal Serial Bus devices > Properties > Details > Hardware Ids

Linux:

lsusb | grep -i rfideas
# Or for all USB devices:
lsusb

Reader Capabilities

rf IDEAS readers (Reader) support:

  • Card data reading
  • Beeper control (volume, beep count, duration)
  • LED configuration
  • Reader configuration (get/set)
  • Extended configuration
  • Keystroking enable/disable
  • Transparent mode (capability check, enable/disable)
  • Module state control (LF radio, HF radio, BLE)
  • LUID get/set
  • BLE configuration read/write
  • HWG file import/export
  • Smart card configuration
  • Supported card type enumeration

Serial Readers

Serial readers use SerialBinary protocol with Reader. Configure the serial port:

ReaderDefinition readerDef{};
readerDef.ProtocolType = PROTOCOL_TYPE_SERIAL_BINARY;
std::strcpy(readerDef.SerialPortSettings.PortName, "COM3"); // Windows
// std::strcpy(readerDef.SerialPortSettings.PortName, "/dev/ttyACM0"); // Linux
readerDef.SerialPortSettings.BaudRate = SERIAL_PORT_BAUD_9600;
readerDef.SerialPortSettings.Parity = SERIAL_PORT_PARITY_NONE;
readerDef.SerialPortSettings.DataBits = SERIAL_PORT_DATA_BITS_8;
readerDef.SerialPortSettings.StopBits = SERIAL_PORT_STOP_BITS_ONE;

Linux USB Permissions

Create a udev rule for reader access. This rule covers all known rf IDEAS reader VID/PID combinations:

/etc/udev/rules.d/99-rfideas.rules
sudo tee /etc/udev/rules.d/99-rfideas.rules << 'EOF'
# rf IDEAS readers (VID 0x0C27)
SUBSYSTEM=="usb", ATTR{idVendor}=="0c27", MODE="0660", GROUP="plugdev"
KERNEL=="hidraw*", SUBSYSTEM=="hidraw", ATTRS{idVendor}=="0c27", MODE="0660", GROUP="plugdev"
EOF

sudo udevadm control --reload-rules && sudo udevadm trigger
tip

The rf IDEAS rules above use a vendor-wide match (ATTR{idVendor}=="0c27") instead of per-PID rules. This covers all current and future rf IDEAS readers without needing rule updates.

Ensure your user is in the plugdev group:

sudo usermod -aG plugdev $USER
warning

You must log out and back in (or reboot) for group membership changes to take effect.

For serial readers, add your user to dialout:

sudo usermod -aG dialout $USER