Search code examples
node.jsiotrfidllrpzebra-scanners

LLRP for Zebra FX7500 with llrpjs doesn't read tags


Using the llrpjs library for Node.js, we are attempting to read tags from the Zebra FX7500 (Motorola?). This discussion points to the RFID Reader Software Interface Control Guide pages 142-144, but does not indicate potential values to set up the device.

From what we can gather, we should issue a SET_READER_CONFIG with a custom parameter (MotoDefaultSpec = VendorIdentifier: 161, ParameterSubtype: 102, UseDefaultSpecForAutoMode: true). Do we need to include the ROSpec and/or AccessSpec values as well (are they required)? After sending the SET_READER_CONFIG message, do we still need to send the regular LLRP messages (ADD_ROSPEC, ENABLE_ROSPEC, START_ROSPEC)? Without the MotoDefaultSpec, even after sending the regular LLRP messages, sending a GET_REPORT does not retrieve tags nor does a custom message with MOTO_GET_TAG_EVENT_REPORT. They both trigger a RO_ACCESS_REPORT event message, but the tagReportData is null.

The README file for llrpjs lists "Vendor definitions support" as a TODO item. While that is somewhat vague, is it possible that the library just hasn't implemented custom LLRP extension (messages/parameters) support, which is why none of our attempts are working? The MotoDefaultSpec parameter and MOTO_GET_TAG_EVENT_REPORT are custom to the vendor/chipset. The MOTO_GET_TAG_EVENT_REPORT custom message seems to trigger a RO_ACCESS_REPORT similar to the base LLRP GET_REPORT message, so we assume that part is working.

It is worth noting that Zebra's 123RFID Desktop setup and optimization tool connects and reads tags as expected, so the device and antenna are working (reading tags).

Could these issues be related to the ROSPEC file we are using (see below)?

{
  "$schema": "https://llrpjs.github.io/schema/core/encoding/json/1.0/llrp-1x0.schema.json",
  "id": 1,
  "type": "ADD_ROSPEC",
  "data": {
    "ROSpec": {
      "ROSpecID": 123,
      "Priority": 1,
      "CurrentState": "Disabled",
      "ROBoundarySpec": {
        "ROSpecStartTrigger": {
          "ROSpecStartTriggerType": "Immediate"
        },
        "ROSpecStopTrigger": {
          "ROSpecStopTriggerType": "Null",
          "DurationTriggerValue": 0
        }
      },
      "AISpec": {
        "AntennaIDs": [1, 2, 3, 4],
        "AISpecStopTrigger": {
          "AISpecStopTriggerType": "Null",
          "DurationTrigger": 0
        },
        "InventoryParameterSpec": {
          "InventoryParameterSpecID": 1234,
          "ProtocolID": "EPCGlobalClass1Gen2"
        }
      },
      "ROReportSpec": {
        "ROReportTrigger": "Upon_N_Tags_Or_End_Of_ROSpec",
        "N": 1,
        "TagReportContentSelector": {
          "EnableROSpecID": true,
          "EnableAntennaID": true,
          "EnableFirstSeenTimestamp": true,
          "EnableLastSeenTimestamp": true,
          "EnableSpecIndex": false,
          "EnableInventoryParameterSpecID": false,
          "EnableChannelIndex": false,
          "EnablePeakRSSI": false,
          "EnableTagSeenCount": true,
          "EnableAccessSpecID": false
        }
      }
    }
  }
}

Solution

  • For anyone having a similar issue, we found that attempting to configure more antennas than the Zebra device has connected caused the entire spec to fail. In our case, we had two antennas connected, so including antennas 3 and 4 in the spec was causing the problem.

    See below for the working ROSPEC. The extra antennas in the data.AISpec.AntennaIDs property were removed and allowed our application to connect and read tags.

    We are still having some issues with llrpjs when trying to STOP_ROSPEC because it sends an RO_ACCESS_REPORT response without a resName value. See the issue on GitHub for more information.

    That said, our application works without sending the STOP_ROSPEC command.

    {
      "$schema": "https://llrpjs.github.io/schema/core/encoding/json/1.0/llrp-1x0.schema.json",
      "id": 1,
      "type": "ADD_ROSPEC",
      "data": {
        "ROSpec": {
          "ROSpecID": 123,
          "Priority": 1,
          "CurrentState": "Disabled",
          "ROBoundarySpec": {
            "ROSpecStartTrigger": {
              "ROSpecStartTriggerType": "Null"
            },
            "ROSpecStopTrigger": {
              "ROSpecStopTriggerType": "Null",
              "DurationTriggerValue": 0
            }
          },
          "AISpec": {
            "AntennaIDs": [1, 2],
            "AISpecStopTrigger": {
              "AISpecStopTriggerType": "Null",
              "DurationTrigger": 0
            },
            "InventoryParameterSpec": {
              "InventoryParameterSpecID": 1234,
              "ProtocolID": "EPCGlobalClass1Gen2",
              "AntennaConfiguration": {
                "AntennaID": 1,
                "RFReceiver": {
                  "ReceiverSensitivity": 0
                },
                "RFTransmitter": {
                  "HopTableID": 1,
                  "ChannelIndex": 1,
                  "TransmitPower": 170
                },
                "C1G2InventoryCommand": {
                  "TagInventoryStateAware": false,
                  "C1G2RFControl": {
                    "ModeIndex": 23,
                    "Tari": 0
                  },
                  "C1G2SingulationControl": {
                    "Session": 1,
                    "TagPopulation": 32,
                    "TagTransitTime": 0,
                    "C1G2TagInventoryStateAwareSingulationAction": {
                      "I": "State_A",
                      "S": "SL"
                    }
                  }
                }
              }
            }
          },
          "ROReportSpec": {
            "ROReportTrigger": "Upon_N_Tags_Or_End_Of_AISpec",
            "N": 1,
            "TagReportContentSelector": {
              "EnableROSpecID": true,
              "EnableAntennaID": true,
              "EnableFirstSeenTimestamp": true,
              "EnableLastSeenTimestamp": true,
              "EnableTagSeenCount": true,
              "EnableSpecIndex": false,
              "EnableInventoryParameterSpecID": false,
              "EnableChannelIndex": false,
              "EnablePeakRSSI": false,
              "EnableAccessSpecID": false
            }
          }
        }
      }
    }