public static PARAM_C1G2TargetTag WispTag(ushort?id) { if (id != null) { return(new PARAM_C1G2TargetTag() { Match = true, MB = new TwoBits(1), Pointer = 0x20, TagMask = LLRPBitArray.FromHexString("FF0000000000000000000FFF"), TagData = LLRPBitArray.FromHexString($"0B000000000000000000{id:X4}") }); } return(new PARAM_C1G2TargetTag() { Match = true, MB = new TwoBits(1), Pointer = 0x20, TagMask = LLRPBitArray.FromHexString("FF"), TagData = LLRPBitArray.FromHexString($"0B") }); }
static void Main(string[] args) { LLRPClient reader; if (args.Length != 1) { usage(); return; } string readerName = args[0]; Console.WriteLine( "Impinj C# LTK.NET RFID Application DocSample3 reader - " + readerName + "\n"); #region Initializing { Console.WriteLine("Initializing\n"); //Create an instance of LLRP reader client. reader = new LLRPClient(); //Impinj Best Practice! Always Install the Impinj extensions Impinj_Installer.Install(); } #endregion #region EventHandlers { Console.WriteLine("Adding Event Handlers\n"); reader.OnReaderEventNotification += new delegateReaderEventNotification(reader_OnReaderEventNotification); reader.OnRoAccessReportReceived += new delegateRoAccessReport(reader_OnRoAccessReportReceived); } #endregion #region Connecting { Console.WriteLine("Connecting To Reader\n"); ENUM_ConnectionAttemptStatusType status; //Open the reader connection. Timeout after 5 seconds bool ret = reader.Open(readerName, 5000, out status); //Ensure that the open succeeded and that the reader // returned the correct connection status result if (!ret || status != ENUM_ConnectionAttemptStatusType.Success) { Console.WriteLine("Failed to Connect to Reader \n"); return; } } #endregion #region EnableExtensions { Console.WriteLine("Enabling Impinj Extensions\n"); MSG_IMPINJ_ENABLE_EXTENSIONS imp_msg = new MSG_IMPINJ_ENABLE_EXTENSIONS(); MSG_ERROR_MESSAGE msg_err; imp_msg.MSG_ID = msgID++; // note :this doesn't need to bet set as the library will default //Send the custom message and wait for 8 seconds MSG_CUSTOM_MESSAGE cust_rsp = reader.CUSTOM_MESSAGE(imp_msg, out msg_err, 8000); MSG_IMPINJ_ENABLE_EXTENSIONS_RESPONSE msg_rsp = cust_rsp as MSG_IMPINJ_ENABLE_EXTENSIONS_RESPONSE; if (msg_rsp != null) { if (msg_rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(msg_rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("Enable Extensions Command Timed out\n"); reader.Close(); return; } } #endregion #region FactoryDefault { Console.WriteLine("Factory Default the Reader\n"); // factory default the reader MSG_SET_READER_CONFIG msg_cfg = new MSG_SET_READER_CONFIG(); MSG_ERROR_MESSAGE msg_err; msg_cfg.ResetToFactoryDefault = true; msg_cfg.MSG_ID = msgID++; //this doesn't need to bet set as the library will default //if SET_READER_CONFIG affects antennas it could take several seconds to return MSG_SET_READER_CONFIG_RESPONSE rsp_cfg = reader.SET_READER_CONFIG(msg_cfg, out msg_err, 12000); if (rsp_cfg != null) { if (rsp_cfg.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp_cfg.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("SET_READER_CONFIG Command Timed out\n"); reader.Close(); return; } } #endregion #region getReaderCapabilities { Console.WriteLine("Getting Reader Capabilities\n"); MSG_GET_READER_CAPABILITIES cap = new MSG_GET_READER_CAPABILITIES(); cap.MSG_ID = msgID++; cap.RequestedData = ENUM_GetReaderCapabilitiesRequestedData.All; //Send the custom message and wait for 8 seconds MSG_ERROR_MESSAGE msg_err; MSG_GET_READER_CAPABILITIES_RESPONSE msg_rsp = reader.GET_READER_CAPABILITIES(cap, out msg_err, 8000); if (msg_rsp != null) { if (msg_rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(msg_rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("GET reader Capabilities Command Timed out\n"); reader.Close(); return; } // Get the reader model number since some features are not // available on Speedway revolution. PARAM_GeneralDeviceCapabilities dev_cap = msg_rsp.GeneralDeviceCapabilities; // Check to make sure the model number mathces and that this device // is an impinj reader (deviceManufacturerName == 25882) if ((dev_cap == null) || (dev_cap.DeviceManufacturerName != 25882)) { Console.WriteLine("Could not determine reader model number\n"); reader.Close(); return; } // Find out how many inventory filters we support // don't run the application unless we support at least // two inventory filters and 1 access Spec PARAM_C1G2LLRPCapabilities g2_cap = (PARAM_C1G2LLRPCapabilities)msg_rsp.AirProtocolLLRPCapabilities[0]; if ((g2_cap == null) || (g2_cap.MaxNumSelectFiltersPerQuery < 2)) { Console.WriteLine(" reader supports " + g2_cap.MaxNumSelectFiltersPerQuery + " inventory filters \n"); Console.WriteLine("Reader does not support enough" + " inventory (select) filters--- closing\n"); reader.Close(); return; } // find out how many access spec we support. Don't run // the application unless we have 1 accessSpec PARAM_LLRPCapabilities llrp_cap = msg_rsp.LLRPCapabilities; if ((llrp_cap == null) || (llrp_cap.MaxNumAccessSpecs < 1)) { Console.WriteLine(" reader supports " + llrp_cap.MaxNumAccessSpecs + " accessSpecs \n"); Console.WriteLine("Reader does not support enough" + " accessSpecs --- closing\n"); reader.Close(); return; } } #endregion #region SetReaderConfigWithXML { Console.WriteLine("Adding SET_READER_CONFIG from XML file \n"); Org.LLRP.LTK.LLRPV1.DataType.Message obj; ENUM_LLRP_MSG_TYPE msg_type; // read the XML from a file and validate its an ADD_ROSPEC try { FileStream fs = new FileStream(@"..\..\setReaderConfig.xml", FileMode.Open); StreamReader sr = new StreamReader(fs); string s = sr.ReadToEnd(); fs.Close(); LLRPXmlParser.ParseXMLToLLRPMessage(s, out obj, out msg_type); if (obj == null || msg_type != ENUM_LLRP_MSG_TYPE.SET_READER_CONFIG) { Console.WriteLine("Could not extract message from XML"); reader.Close(); return; } } catch { Console.WriteLine("Unable to convert to valid XML"); reader.Close(); return; } // Communicate that message to the reader MSG_SET_READER_CONFIG msg = (MSG_SET_READER_CONFIG)obj; msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; MSG_SET_READER_CONFIG_RESPONSE rsp = reader.SET_READER_CONFIG(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("SET_READER_CONFIG Command Timed out\n"); reader.Close(); return; } } #endregion #region ADDRoSpecWithXML { Console.WriteLine("Adding RoSpec from XML file \n"); Org.LLRP.LTK.LLRPV1.DataType.Message obj; ENUM_LLRP_MSG_TYPE msg_type; // read the XML from a file and validate its an ADD_ROSPEC try { string filename; filename = @"..\..\addRoSpec.xml"; FileStream fs = new FileStream(filename, FileMode.Open); StreamReader sr = new StreamReader(fs); string s = sr.ReadToEnd(); fs.Close(); LLRPXmlParser.ParseXMLToLLRPMessage(s, out obj, out msg_type); if (obj == null || msg_type != ENUM_LLRP_MSG_TYPE.ADD_ROSPEC) { Console.WriteLine("Could not extract message from XML"); reader.Close(); return; } } catch { Console.WriteLine("Unable to convert to valid XML"); reader.Close(); return; } MSG_ADD_ROSPEC msg = (MSG_ADD_ROSPEC)obj; msg.MSG_ID = msgID++; // Communicate that message to the reader MSG_ERROR_MESSAGE msg_err; MSG_ADD_ROSPEC_RESPONSE rsp = reader.ADD_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ADD_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region ADDAccessSpecWithXML { Console.WriteLine("Adding AccessSpec from XML file \n"); Org.LLRP.LTK.LLRPV1.DataType.Message obj; ENUM_LLRP_MSG_TYPE msg_type; // read the XML from a file and validate its an ADD_ACCESS_SPEC try { FileStream fs = new FileStream(@"..\..\addAccessSpec.xml", FileMode.Open); StreamReader sr = new StreamReader(fs); string s = sr.ReadToEnd(); fs.Close(); LLRPXmlParser.ParseXMLToLLRPMessage(s, out obj, out msg_type); if (obj == null || msg_type != ENUM_LLRP_MSG_TYPE.ADD_ACCESSSPEC) { Console.WriteLine("Could not extract message from XML"); reader.Close(); return; } } catch { Console.WriteLine("Unable to convert to valid XML"); reader.Close(); return; } // Communicate that message to the reader MSG_ADD_ACCESSSPEC msg = (MSG_ADD_ACCESSSPEC)obj; msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; MSG_ADD_ACCESSSPEC_RESPONSE rsp = reader.ADD_ACCESSSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ADD_ACCESSSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region ADDAccessSpec { /* This section adds a second accessSpec identical to the * first (except for its ID). This is duplicate code with * the goal of showing an example of how to build LLRP specs * from C# objects rather than XML */ Console.WriteLine("Adding AccessSpec from C# objects \n"); // create the target tag filter spec to perform access only on these tags // This only requires a single filter (LTK/LLRP supports up to 2 ) PARAM_C1G2TargetTag[] targetTag = new PARAM_C1G2TargetTag[1]; targetTag[0] = new PARAM_C1G2TargetTag(); targetTag[0].Match = true; targetTag[0].MB = new TwoBits(1); targetTag[0].Pointer = 16; targetTag[0].TagData = LLRPBitArray.FromHexString("300035"); targetTag[0].TagMask = LLRPBitArray.FromHexString("f800ff"); PARAM_C1G2TagSpec tagSpec = new PARAM_C1G2TagSpec(); tagSpec.C1G2TargetTag = targetTag; // create the read operation to perform when this accessSpec is run PARAM_C1G2Read read = new PARAM_C1G2Read(); read.AccessPassword = 0; read.MB = new TwoBits(3); read.WordCount = 2; read.WordPointer = 0; read.OpSpecID = 2; // add the opSpec and the TagSpec to the AccessCmd PARAM_AccessCommand accessCmd = new PARAM_AccessCommand(); accessCmd.AirProtocolTagSpec = new UNION_AirProtocolTagSpec(); accessCmd.AirProtocolTagSpec.Add(tagSpec); accessCmd.AccessCommandOpSpec.Add(read); // create the stop trigger for the Access Spec PARAM_AccessSpecStopTrigger stop = new PARAM_AccessSpecStopTrigger(); stop.AccessSpecStopTrigger = ENUM_AccessSpecStopTriggerType.Null; stop.OperationCountValue = 0; // Create and set up the basic accessSpec PARAM_AccessSpec accessSpec = new PARAM_AccessSpec(); accessSpec.AccessSpecID = 24; accessSpec.AntennaID = 0; accessSpec.ROSpecID = 0; accessSpec.CurrentState = ENUM_AccessSpecState.Disabled; accessSpec.ProtocolID = ENUM_AirProtocols.EPCGlobalClass1Gen2; // add the access command and stop trigger to the accessSpec accessSpec.AccessCommand = accessCmd; accessSpec.AccessSpecStopTrigger = stop; // Add the Access Spec to the ADD_ACCESSSPEC message MSG_ADD_ACCESSSPEC addAccess = new MSG_ADD_ACCESSSPEC(); addAccess.MSG_ID = msgID++; addAccess.AccessSpec = accessSpec; // communicate the message to the reader MSG_ERROR_MESSAGE msg_err; MSG_ADD_ACCESSSPEC_RESPONSE rsp = reader.ADD_ACCESSSPEC(addAccess, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ADD_ACCESSSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region EnableAccessSpec { Console.WriteLine("Enabling AccessSpec\n"); MSG_ENABLE_ACCESSSPEC msg = new MSG_ENABLE_ACCESSSPEC(); msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; msg.AccessSpecID = 23; // this better match the ACCESSSPEC we created above MSG_ENABLE_ACCESSSPEC_RESPONSE rsp = reader.ENABLE_ACCESSSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ENABLE_ACCESSSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region EnableRoSpec { Console.WriteLine("Enabling RoSpec\n"); MSG_ENABLE_ROSPEC msg = new MSG_ENABLE_ROSPEC(); msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; msg.ROSpecID = 1111; // this better match the ROSpec we created above MSG_ENABLE_ROSPEC_RESPONSE rsp = reader.ENABLE_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ENABLE_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region StartRoSpec { Console.WriteLine("Starting RoSpec\n"); MSG_START_ROSPEC msg = new MSG_START_ROSPEC(); msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; msg.ROSpecID = 1111; // this better match the RoSpec we created above MSG_START_ROSPEC_RESPONSE rsp = reader.START_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("START_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion // wait around to collect some data. for (int delay = 0; delay < 5; delay++) { Thread.Sleep(30000); #region PollReaderReports { Console.WriteLine("Polling Report Data\n"); MSG_GET_REPORT msg = new MSG_GET_REPORT(); MSG_ERROR_MESSAGE msg_err; msg.MSG_ID = msgID++; reader.GET_REPORT(msg, out msg_err, 10000); } #endregion } #region StopRoSpec { Console.WriteLine("Stopping RoSpec\n"); MSG_STOP_ROSPEC msg = new MSG_STOP_ROSPEC(); MSG_ERROR_MESSAGE msg_err; msg.ROSpecID = 1111; // this better match the RoSpec we created above MSG_STOP_ROSPEC_RESPONSE rsp = reader.STOP_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("STOP_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region Clean Up Reader Configuration { Console.WriteLine("Factory Default the Reader\n"); // factory default the reader MSG_SET_READER_CONFIG msg_cfg = new MSG_SET_READER_CONFIG(); MSG_ERROR_MESSAGE msg_err; msg_cfg.ResetToFactoryDefault = true; msg_cfg.MSG_ID = msgID++;; // note this doesn't need to bet set as the library will default // Note that if SET_READER_CONFIG affects antennas it could take several seconds to return MSG_SET_READER_CONFIG_RESPONSE rsp_cfg = reader.SET_READER_CONFIG(msg_cfg, out msg_err, 12000); if (rsp_cfg != null) { if (rsp_cfg.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp_cfg.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("SET_READER_CONFIG Command Timed out\n"); reader.Close(); return; } } #endregion Console.WriteLine(" Received " + accessCount + " Access Reports."); Console.WriteLine(" Received " + reportCount + " Tag Reports."); Console.WriteLine(" Received " + eventCount + " Events."); Console.WriteLine("Closing\n"); // clean up the reader reader.Close(); reader.OnReaderEventNotification -= new delegateReaderEventNotification(reader_OnReaderEventNotification); reader.OnRoAccessReportReceived -= new delegateRoAccessReport(reader_OnRoAccessReportReceived); }
public void Add_AccessSpec() { MSG_ERROR_MESSAGE msg_err; MSG_ADD_ACCESSSPEC msg = new MSG_ADD_ACCESSSPEC(); msg.AccessSpec = new PARAM_AccessSpec(); ///////////////////////////////////////////////// // AccessSpec ///////////////////////////////////////////////// // AccessSpecID should be set to a unique identifier. msg.AccessSpec.AccessSpecID = 456; msg.AccessSpec.AntennaID = 0; // We're writing to a Gen2 tag msg.AccessSpec.ProtocolID = ENUM_AirProtocols.EPCGlobalClass1Gen2; // AccessSpecs must be disabled when you add them. msg.AccessSpec.CurrentState = ENUM_AccessSpecState.Disabled; msg.AccessSpec.ROSpecID = 0; // Setup the triggers msg.AccessSpec.AccessSpecStopTrigger = new PARAM_AccessSpecStopTrigger(); msg.AccessSpec.AccessSpecStopTrigger.AccessSpecStopTrigger = ENUM_AccessSpecStopTriggerType.Null; // OperationCountValue indicate the number of times this Spec is // executed before it is deleted. If set to 0, this is equivalent // to no stop trigger defined. msg.AccessSpec.AccessSpecStopTrigger.OperationCountValue = 0; ///////////////////////////////////////////////// // AccessCommand // // Define which tags we want to write to. ///////////////////////////////////////////////// msg.AccessSpec.AccessCommand = new PARAM_AccessCommand(); msg.AccessSpec.AccessCommand.AirProtocolTagSpec = new UNION_AirProtocolTagSpec(); PARAM_C1G2TagSpec tagSpec = new PARAM_C1G2TagSpec(); // Specify the target tag. Which tag do we want to write to? tagSpec.C1G2TargetTag = new PARAM_C1G2TargetTag[1]; tagSpec.C1G2TargetTag[0] = new PARAM_C1G2TargetTag(); tagSpec.C1G2TargetTag[0].Match = true; // We'll use the tag's EPC to determine if this is the label we want. // Set the memory bank to 1 (The EPC memory bank on a Monza 4 tag). tagSpec.C1G2TargetTag[0].MB = new TwoBits(1); // The first (msb) bit location of the specified memory // bank against which to compare the TagMask. // We'll set it to 0x20, to skip the protocol // control bits and CRC. tagSpec.C1G2TargetTag[0].Pointer = 0x20; tagSpec.C1G2TargetTag[0].TagMask = LLRPBitArray.FromHexString("FFFFFFFFFFFFFFFFFFFFFFFF"); tagSpec.C1G2TargetTag[0].TagData = LLRPBitArray.FromHexString("300833B2DDD9014000000000"); msg.AccessSpec.AccessCommand.AirProtocolTagSpec.Add(tagSpec); ///////////////////////////////////////////////// // AccessCommandOpSpec // // Define the data we want to write. ///////////////////////////////////////////////// msg.AccessSpec.AccessCommand.AccessCommandOpSpec = new UNION_AccessCommandOpSpec(); PARAM_C1G2Write wr = new PARAM_C1G2Write(); wr.AccessPassword = 0; // Bank 3 is user memory on a Monza 4 tag. wr.MB = new TwoBits(3); // OpSpecID should be set to a unique identifier. wr.OpSpecID = 111; // Write to the base of user memory. wr.WordPointer = 0x00; // Data to be written. wr.WriteData = UInt16Array.FromHexString("0123456789ABCDEF"); msg.AccessSpec.AccessCommand.AccessCommandOpSpec.Add(wr); ///////////////////////////////////////////////// // AccessReportSpec // // Define when we want to receive AccessReports ///////////////////////////////////////////////// msg.AccessSpec.AccessReportSpec = new PARAM_AccessReportSpec(); msg.AccessSpec.AccessReportSpec.AccessReportTrigger = ENUM_AccessReportTriggerType.End_Of_AccessSpec; // Send the message and check the reply MSG_ADD_ACCESSSPEC_RESPONSE rsp = reader.ADD_ACCESSSPEC(msg, out msg_err, 2000); if (rsp != null) { // Success Console.WriteLine(rsp.ToString()); } else if (msg_err != null) { // Error Console.WriteLine(msg_err.ToString()); } else { // Timeout Console.WriteLine("Timeout Error."); } }
static void Main(string[] args) { LLRPClient reader; int i; #region ProcessCommandLine if (args.Length < 1) { usage(); return; } /* get the options. Skip the last one as its the hostname */ for (i = 0; i < args.Length - 1; i++) { if ((args[i] == "-p") && (i < (args.Length - 1))) { i++; m_password = System.Convert.ToUInt32(args[i]); } else if ((args[i] == "-n") && (i < (args.Length - 1))) { i++; m_newPassword = System.Convert.ToUInt32(args[i]); } else if (args[i] == "-t") { m_tid = ENUM_ImpinjSerializedTIDMode.Enabled; } else if (args[i] == "-s") { m_shortRange = ENUM_ImpinjQTAccessRange.Short_Range; } else if ((args[i] == "-v") && (i < (args.Length - 1))) { i++; m_Verbose = System.Convert.ToUInt32(args[i]); } else if ((args[i] == "-q") && (i < (args.Length - 1))) { i++; m_qtmode = System.Convert.ToUInt32(args[i]); } else { usage(); return; } } m_readerName = args[i]; Console.WriteLine( "Impinj C# LTK.NET RFID Application DocSample5 reader - " + m_readerName + "\n"); Console.WriteLine( " qtMode:" + m_qtmode.ToString() + " Verbose:" + m_Verbose.ToString() + " Range:" + m_shortRange.ToString() + " SerializeTID:" + m_tid.ToString() + " OldPassword:"******" NewPassword:"******"Initializing\n"); //Create an instance of LLRP reader client. reader = new LLRPClient(); //Impinj Best Practice! Always Install the Impinj extensions Impinj_Installer.Install(); } #endregion #region EventHandlers { Console.WriteLine("Adding Event Handlers\n"); reader.OnReaderEventNotification += new delegateReaderEventNotification(reader_OnReaderEventNotification); reader.OnRoAccessReportReceived += new delegateRoAccessReport(reader_OnRoAccessReportReceived); } #endregion #region Connecting { Console.WriteLine("Connecting To Reader\n"); ENUM_ConnectionAttemptStatusType status; //Open the reader connection. Timeout after 5 seconds bool ret = reader.Open(m_readerName, 5000, out status); //Ensure that the open succeeded and that the reader // returned the correct connection status result if (!ret || status != ENUM_ConnectionAttemptStatusType.Success) { Console.WriteLine("Failed to Connect to Reader \n"); return; } } #endregion #region EnableExtensions { Console.WriteLine("Enabling Impinj Extensions\n"); MSG_IMPINJ_ENABLE_EXTENSIONS imp_msg = new MSG_IMPINJ_ENABLE_EXTENSIONS(); MSG_ERROR_MESSAGE msg_err; imp_msg.MSG_ID = msgID++; // note :this doesn't need to bet set as the library will default //Send the custom message and wait for 8 seconds MSG_CUSTOM_MESSAGE cust_rsp = reader.CUSTOM_MESSAGE(imp_msg, out msg_err, 8000); MSG_IMPINJ_ENABLE_EXTENSIONS_RESPONSE msg_rsp = cust_rsp as MSG_IMPINJ_ENABLE_EXTENSIONS_RESPONSE; if (msg_rsp != null) { if (msg_rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(msg_rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("Enable Extensions Command Timed out\n"); reader.Close(); return; } } #endregion #region FactoryDefault { Console.WriteLine("Factory Default the Reader\n"); // factory default the reader MSG_SET_READER_CONFIG msg_cfg = new MSG_SET_READER_CONFIG(); MSG_ERROR_MESSAGE msg_err; msg_cfg.ResetToFactoryDefault = true; msg_cfg.MSG_ID = msgID++; //this doesn't need to bet set as the library will default //if SET_READER_CONFIG affects antennas it could take several seconds to return MSG_SET_READER_CONFIG_RESPONSE rsp_cfg = reader.SET_READER_CONFIG(msg_cfg, out msg_err, 12000); if (rsp_cfg != null) { if (rsp_cfg.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp_cfg.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("SET_READER_CONFIG Command Timed out\n"); reader.Close(); return; } } #endregion #region getReaderCapabilities { Console.WriteLine("Getting Reader Capabilities\n"); MSG_GET_READER_CAPABILITIES cap = new MSG_GET_READER_CAPABILITIES(); cap.MSG_ID = msgID++; cap.RequestedData = ENUM_GetReaderCapabilitiesRequestedData.All; //Send the custom message and wait for 8 seconds MSG_ERROR_MESSAGE msg_err; MSG_GET_READER_CAPABILITIES_RESPONSE msg_rsp = reader.GET_READER_CAPABILITIES(cap, out msg_err, 8000); if (msg_rsp != null) { if (msg_rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(msg_rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("GET reader Capabilities Command Timed out\n"); reader.Close(); return; } // Get the reader model number since some features are not // available on Speedway revolution. PARAM_GeneralDeviceCapabilities dev_cap = msg_rsp.GeneralDeviceCapabilities; // Check to make sure the model number mathces and that this device // is an impinj reader (deviceManufacturerName == 25882) if ((dev_cap == null) || (dev_cap.DeviceManufacturerName != 25882)) { Console.WriteLine("Could not determine reader model number\n"); reader.Close(); return; } // Need to parse version number strings and compare to make sure // that the reader version is higher than 4.4. Version readerVersion = new Version(dev_cap.ReaderFirmwareVersion); Version minimumVersion = new Version("4.4.0.0"); if (readerVersion < minimumVersion) { Console.WriteLine("Must use Octane 4.4 or later\n"); reader.Close(); return; } } #endregion #region SetReaderConfig { Console.WriteLine("Adding SET_READER_CONFIG n"); // Communicate that message to the reader MSG_SET_READER_CONFIG msg = new MSG_SET_READER_CONFIG(); msg.MSG_ID = msgID++; msg.ResetToFactoryDefault = false; // turn off all reports msg.ROReportSpec = new PARAM_ROReportSpec(); msg.ROReportSpec.TagReportContentSelector = new PARAM_TagReportContentSelector(); msg.ROReportSpec.TagReportContentSelector.EnableAccessSpecID = false; msg.ROReportSpec.TagReportContentSelector.EnableAntennaID = false; msg.ROReportSpec.TagReportContentSelector.EnableChannelIndex = false; msg.ROReportSpec.TagReportContentSelector.EnableFirstSeenTimestamp = false; msg.ROReportSpec.TagReportContentSelector.EnableInventoryParameterSpecID = false; msg.ROReportSpec.TagReportContentSelector.EnableLastSeenTimestamp = false; msg.ROReportSpec.TagReportContentSelector.EnablePeakRSSI = false; msg.ROReportSpec.TagReportContentSelector.EnableROSpecID = false; msg.ROReportSpec.TagReportContentSelector.EnableSpecIndex = false; msg.ROReportSpec.TagReportContentSelector.EnableTagSeenCount = false; /* report all tags immediately */ msg.ROReportSpec.ROReportTrigger = ENUM_ROReportTriggerType.Upon_N_Tags_Or_End_Of_ROSpec; msg.ROReportSpec.N = 1; /* turn on serialized TID if we are asked to */ PARAM_ImpinjTagReportContentSelector impinjTagData = new PARAM_ImpinjTagReportContentSelector(); impinjTagData.ImpinjEnableGPSCoordinates = new PARAM_ImpinjEnableGPSCoordinates(); impinjTagData.ImpinjEnableGPSCoordinates.GPSCoordinatesMode = ENUM_ImpinjGPSCoordinatesMode.Disabled; impinjTagData.ImpinjEnablePeakRSSI = new PARAM_ImpinjEnablePeakRSSI(); impinjTagData.ImpinjEnablePeakRSSI.PeakRSSIMode = ENUM_ImpinjPeakRSSIMode.Disabled; impinjTagData.ImpinjEnableRFPhaseAngle = new PARAM_ImpinjEnableRFPhaseAngle(); impinjTagData.ImpinjEnableRFPhaseAngle.RFPhaseAngleMode = ENUM_ImpinjRFPhaseAngleMode.Disabled; impinjTagData.ImpinjEnableSerializedTID = new PARAM_ImpinjEnableSerializedTID(); impinjTagData.ImpinjEnableSerializedTID.SerializedTIDMode = m_tid; msg.ROReportSpec.Custom.Add(impinjTagData); /* report access specs immediately as well */ msg.AccessReportSpec = new PARAM_AccessReportSpec(); msg.AccessReportSpec.AccessReportTrigger = ENUM_AccessReportTriggerType.End_Of_AccessSpec; // set the antenna configuration for all antennas msg.AntennaConfiguration = new PARAM_AntennaConfiguration[1]; msg.AntennaConfiguration[0] = new PARAM_AntennaConfiguration(); msg.AntennaConfiguration[0].AntennaID = 0; /* all antennas */ // use DRM autset mode PARAM_C1G2InventoryCommand c1g2Inv = new PARAM_C1G2InventoryCommand(); c1g2Inv.C1G2RFControl = new PARAM_C1G2RFControl(); c1g2Inv.C1G2RFControl.ModeIndex = 1000; c1g2Inv.C1G2RFControl.Tari = 0; // Use session 1 so we don't get too many reads c1g2Inv.C1G2SingulationControl = new PARAM_C1G2SingulationControl(); c1g2Inv.C1G2SingulationControl.Session = new TwoBits(1); c1g2Inv.C1G2SingulationControl.TagPopulation = 1; c1g2Inv.C1G2SingulationControl.TagTransitTime = 0; // add to the message msg.AntennaConfiguration[0].AirProtocolInventoryCommandSettings.Add(c1g2Inv); MSG_ERROR_MESSAGE msg_err; MSG_SET_READER_CONFIG_RESPONSE rsp = reader.SET_READER_CONFIG(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("SET_READER_CONFIG Command Timed out\n"); reader.Close(); return; } } #endregion #region ADDRoSpecWithXML { Console.WriteLine("Adding RoSpec from XML file \n"); Org.LLRP.LTK.LLRPV1.DataType.Message obj; ENUM_LLRP_MSG_TYPE msg_type; // read the XML from a file and validate its an ADD_ROSPEC try { string filename; filename = @"..\..\addRoSpec.xml"; FileStream fs = new FileStream(filename, FileMode.Open); StreamReader sr = new StreamReader(fs); string s = sr.ReadToEnd(); fs.Close(); LLRPXmlParser.ParseXMLToLLRPMessage(s, out obj, out msg_type); if (obj == null || msg_type != ENUM_LLRP_MSG_TYPE.ADD_ROSPEC) { Console.WriteLine("Could not extract message from XML"); reader.Close(); return; } } catch { Console.WriteLine("Unable to convert to valid XML"); reader.Close(); return; } MSG_ADD_ROSPEC msg = (MSG_ADD_ROSPEC)obj; msg.MSG_ID = msgID++; // Communicate that message to the reader MSG_ERROR_MESSAGE msg_err; MSG_ADD_ROSPEC_RESPONSE rsp = reader.ADD_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ADD_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region ADDAccessSpec { /* This section adds a second accessSpec identical to the * first (except for its ID). This is duplicate code with * the goal of showing an example of how to build LLRP specs * from C# objects rather than XML */ Console.WriteLine("Adding AccessSpec from C# objects \n"); // create the target tag filter spec to perform access only on these tags // This only requires a single filter (LTK/LLRP supports up to 2 ) PARAM_C1G2TargetTag[] targetTag = new PARAM_C1G2TargetTag[1]; targetTag[0] = new PARAM_C1G2TargetTag(); targetTag[0].Match = true; targetTag[0].MB = new TwoBits(1); targetTag[0].Pointer = 16; targetTag[0].TagData = LLRPBitArray.FromHexString(""); targetTag[0].TagMask = LLRPBitArray.FromHexString(""); PARAM_C1G2TagSpec tagSpec = new PARAM_C1G2TagSpec(); tagSpec.C1G2TargetTag = targetTag; PARAM_AccessCommand accessCmd = new PARAM_AccessCommand(); accessCmd.AirProtocolTagSpec = new UNION_AirProtocolTagSpec(); accessCmd.AirProtocolTagSpec.Add(tagSpec); switch (m_qtmode) { case 0: PARAM_C1G2Read readStdTID = new PARAM_C1G2Read(); readStdTID.AccessPassword = 0; readStdTID.MB = new TwoBits(2); readStdTID.OpSpecID = 1; readStdTID.WordCount = 2; readStdTID.WordPointer = 0; accessCmd.AccessCommandOpSpec.Add(readStdTID); break; case 1: PARAM_C1G2Write writePassword = new PARAM_C1G2Write(); writePassword.OpSpecID = 2; writePassword.MB = new TwoBits(0); writePassword.AccessPassword = m_password; writePassword.WordPointer = 2; writePassword.WriteData = new UInt16Array(); writePassword.WriteData.Add((UInt16)((m_newPassword >> 16) & 0x0000ffff)); writePassword.WriteData.Add((UInt16)(m_newPassword & 0x0000ffff)); accessCmd.AccessCommandOpSpec.Add(writePassword); break; case 2: PARAM_C1G2Read readSerializedTID = new PARAM_C1G2Read(); readSerializedTID.AccessPassword = 0; readSerializedTID.MB = new TwoBits(2); readSerializedTID.OpSpecID = 3; readSerializedTID.WordCount = 6; readSerializedTID.WordPointer = 0; accessCmd.AccessCommandOpSpec.Add(readSerializedTID); PARAM_C1G2Read readPublicEPC = new PARAM_C1G2Read(); readPublicEPC.AccessPassword = 0; readPublicEPC.MB = new TwoBits(2); readPublicEPC.OpSpecID = 4; readPublicEPC.WordCount = 6; readPublicEPC.WordPointer = 6; accessCmd.AccessCommandOpSpec.Add(readPublicEPC); PARAM_C1G2Read readUser = new PARAM_C1G2Read(); readUser.AccessPassword = 0; readUser.MB = new TwoBits(3); readUser.OpSpecID = 5; readUser.WordCount = 32; readUser.WordPointer = 0; accessCmd.AccessCommandOpSpec.Add(readUser); break; case 3: PARAM_ImpinjGetQTConfig getQT = new PARAM_ImpinjGetQTConfig(); getQT.OpSpecID = 6; getQT.AccessPassword = m_password; accessCmd.AccessCommandOpSpec.Add(getQT); break; case 4: PARAM_ImpinjSetQTConfig setQTPrivate = new PARAM_ImpinjSetQTConfig(); setQTPrivate.OpSpecID = 7; setQTPrivate.AccessPassword = m_password; setQTPrivate.Persistence = ENUM_ImpinjQTPersistence.Permanent; setQTPrivate.DataProfile = ENUM_ImpinjQTDataProfile.Private; setQTPrivate.AccessRange = m_shortRange; accessCmd.AccessCommandOpSpec.Add(setQTPrivate); break; case 5: PARAM_ImpinjSetQTConfig setQTPublic = new PARAM_ImpinjSetQTConfig(); setQTPublic.OpSpecID = 8; setQTPublic.AccessPassword = m_password; setQTPublic.Persistence = ENUM_ImpinjQTPersistence.Permanent; setQTPublic.DataProfile = ENUM_ImpinjQTDataProfile.Public; setQTPublic.AccessRange = m_shortRange; accessCmd.AccessCommandOpSpec.Add(setQTPublic); break; case 6: PARAM_ImpinjSetQTConfig setQTPeek = new PARAM_ImpinjSetQTConfig(); setQTPeek.OpSpecID = 9; setQTPeek.AccessPassword = m_password; setQTPeek.Persistence = ENUM_ImpinjQTPersistence.Temporary; setQTPeek.DataProfile = ENUM_ImpinjQTDataProfile.Private; setQTPeek.AccessRange = ENUM_ImpinjQTAccessRange.Normal_Range; accessCmd.AccessCommandOpSpec.Add(setQTPeek); PARAM_C1G2Read readSerializedTIDPeek = new PARAM_C1G2Read(); readSerializedTIDPeek.AccessPassword = 0; readSerializedTIDPeek.MB = new TwoBits(2); readSerializedTIDPeek.OpSpecID = 10; readSerializedTIDPeek.WordCount = 6; readSerializedTIDPeek.WordPointer = 0; accessCmd.AccessCommandOpSpec.Add(readSerializedTIDPeek); PARAM_C1G2Read readPrivateEPC = new PARAM_C1G2Read(); readPrivateEPC.AccessPassword = 0; readPrivateEPC.MB = new TwoBits(1); readPrivateEPC.OpSpecID = 11; readPrivateEPC.WordCount = 8; readPrivateEPC.WordPointer = 2; accessCmd.AccessCommandOpSpec.Add(readPrivateEPC); PARAM_C1G2Read readUserPeek = new PARAM_C1G2Read(); readUserPeek.AccessPassword = 0; readUserPeek.MB = new TwoBits(3); readUserPeek.OpSpecID = 12; readUserPeek.WordCount = 32; readUserPeek.WordPointer = 0; accessCmd.AccessCommandOpSpec.Add(readUserPeek); break; case 7: PARAM_C1G2Write writeUser = new PARAM_C1G2Write(); writeUser.AccessPassword = m_password; writeUser.OpSpecID = 13; writeUser.WordPointer = 0; writeUser.MB = new TwoBits(3); writeUser.WriteData = new UInt16Array(); for (int x = 0; x < 32; x++) { writeUser.WriteData.Add((UInt16)m_random.Next(65536)); } accessCmd.AccessCommandOpSpec.Add(writeUser); break; case 8: PARAM_C1G2Write writePubEPC = new PARAM_C1G2Write(); writePubEPC.AccessPassword = m_password; writePubEPC.MB = new TwoBits(2); writePubEPC.OpSpecID = 14; writePubEPC.WordPointer = 6; writePubEPC.WriteData = new UInt16Array(); for (int x = 0; x < 6; x++) { writePubEPC.WriteData.Add((UInt16)m_random.Next(65536)); } accessCmd.AccessCommandOpSpec.Add(writePubEPC); break; case 9: PARAM_C1G2Read readRsvd = new PARAM_C1G2Read(); readRsvd.AccessPassword = m_password; readRsvd.MB = new TwoBits(0); readRsvd.OpSpecID = 15; readRsvd.WordCount = 4; readRsvd.WordPointer = 0; accessCmd.AccessCommandOpSpec.Add(readRsvd); break; } // create the stop trigger for the Access Spec PARAM_AccessSpecStopTrigger stop = new PARAM_AccessSpecStopTrigger(); stop.AccessSpecStopTrigger = ENUM_AccessSpecStopTriggerType.Null; stop.OperationCountValue = 0; // Create and set up the basic accessSpec PARAM_AccessSpec accessSpec = new PARAM_AccessSpec(); accessSpec.AccessSpecID = 24; accessSpec.AntennaID = 0; accessSpec.ROSpecID = 0; accessSpec.CurrentState = ENUM_AccessSpecState.Disabled; accessSpec.ProtocolID = ENUM_AirProtocols.EPCGlobalClass1Gen2; // add the access command and stop trigger to the accessSpec accessSpec.AccessCommand = accessCmd; accessSpec.AccessSpecStopTrigger = stop; // Add the Access Spec to the ADD_ACCESSSPEC message MSG_ADD_ACCESSSPEC addAccess = new MSG_ADD_ACCESSSPEC(); addAccess.MSG_ID = msgID++; addAccess.AccessSpec = accessSpec; // communicate the message to the reader MSG_ERROR_MESSAGE msg_err; MSG_ADD_ACCESSSPEC_RESPONSE rsp = reader.ADD_ACCESSSPEC(addAccess, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ADD_ACCESSSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region EnableAccessSpec { Console.WriteLine("Enabling AccessSpec\n"); MSG_ENABLE_ACCESSSPEC msg = new MSG_ENABLE_ACCESSSPEC(); msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; msg.AccessSpecID = 24; // this better match the ACCESSSPEC we created above MSG_ENABLE_ACCESSSPEC_RESPONSE rsp = reader.ENABLE_ACCESSSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ENABLE_ACCESSSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region EnableRoSpec { Console.WriteLine("Enabling RoSpec\n"); MSG_ENABLE_ROSPEC msg = new MSG_ENABLE_ROSPEC(); msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; msg.ROSpecID = 1111; // this better match the ROSpec we created above MSG_ENABLE_ROSPEC_RESPONSE rsp = reader.ENABLE_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("ENABLE_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region StartRoSpec { Console.WriteLine("Starting RoSpec\n"); MSG_START_ROSPEC msg = new MSG_START_ROSPEC(); msg.MSG_ID = msgID++; MSG_ERROR_MESSAGE msg_err; msg.ROSpecID = 1111; // this better match the RoSpec we created above MSG_START_ROSPEC_RESPONSE rsp = reader.START_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("START_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion // this should be plenty long enough to do these commands Thread.Sleep(3000); #region StopRoSpec { Console.WriteLine("Stopping RoSpec\n"); MSG_STOP_ROSPEC msg = new MSG_STOP_ROSPEC(); MSG_ERROR_MESSAGE msg_err; msg.ROSpecID = 1111; // this better match the RoSpec we created above MSG_STOP_ROSPEC_RESPONSE rsp = reader.STOP_ROSPEC(msg, out msg_err, 12000); if (rsp != null) { if (rsp.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("STOP_ROSPEC Command Timed out\n"); reader.Close(); return; } } #endregion #region Clean Up Reader Configuration { Console.WriteLine("Factory Default the Reader\n"); // factory default the reader MSG_SET_READER_CONFIG msg_cfg = new MSG_SET_READER_CONFIG(); MSG_ERROR_MESSAGE msg_err; msg_cfg.ResetToFactoryDefault = true; msg_cfg.MSG_ID = msgID++;; // note this doesn't need to bet set as the library will default // Note that if SET_READER_CONFIG affects antennas it could take several seconds to return MSG_SET_READER_CONFIG_RESPONSE rsp_cfg = reader.SET_READER_CONFIG(msg_cfg, out msg_err, 12000); if (rsp_cfg != null) { if (rsp_cfg.LLRPStatus.StatusCode != ENUM_StatusCode.M_Success) { Console.WriteLine(rsp_cfg.LLRPStatus.StatusCode.ToString()); reader.Close(); return; } } else if (msg_err != null) { Console.WriteLine(msg_err.ToString()); reader.Close(); return; } else { Console.WriteLine("SET_READER_CONFIG Command Timed out\n"); reader.Close(); return; } } #endregion Console.WriteLine(" Received " + opSpecCount + " OpSpec Results."); Console.WriteLine(" Received " + reportCount + " Tag Reports."); Console.WriteLine(" Received " + eventCount + " Events."); Console.WriteLine("Closing\n"); // clean up the reader reader.Close(); reader.OnReaderEventNotification -= new delegateReaderEventNotification(reader_OnReaderEventNotification); reader.OnRoAccessReportReceived -= new delegateRoAccessReport(reader_OnRoAccessReportReceived); }