public static string SaveSimpleReadPlan(Object value) { string readPlan = string.Empty; ReadPlan rp = (ReadPlan)value; readPlan += "SimpleReadPlan:["; SimpleReadPlan srp = (SimpleReadPlan)rp; readPlan += "Antennas=" + ArrayToString(srp.Antennas); readPlan += "," + "Protocol=" + srp.Protocol.ToString(); if (srp.Filter != null) { if (srp.Filter is Gen2.Select) { Gen2.Select sf = (Gen2.Select)srp.Filter; readPlan += "," + string.Format("Filter=Gen2.Select:[Invert={0},Bank={1},BitPointer={2},BitLength={3},Mask={4}]", (sf.Invert?"true" : "false"), sf.Bank, sf.BitPointer, sf.BitLength, ByteFormat.ToHex(sf.Mask)); } else { Gen2.TagData td = (Gen2.TagData)srp.Filter; readPlan += "," + string.Format("Filter=TagData:[EPC={0}]", td.EpcString); } } else { readPlan += ",Filter=null"; } if (srp.Op != null) { if (srp.Op is Gen2.ReadData) { Gen2.ReadData rd = (Gen2.ReadData)srp.Op; readPlan += "," + string.Format("Op=ReadData:[Bank={0},WordAddress={1},Len={2}]", rd.Bank, rd.WordAddress, rd.Len); } else { readPlan += ",Op=null"; } } else { readPlan += ",Op=null"; } readPlan += "," + "UseFastSearch=" + srp.UseFastSearch.ToString(); readPlan += "," + "Weight=" + srp.Weight.ToString() + "]"; return(readPlan); }
public static string SaveReadPlan(Object value) { string readPlan = string.Empty; ReadPlan rp = (ReadPlan)value; if (rp is SimpleReadPlan) { return(SaveSimpleReadPlan(value)); } else { MultiReadPlan mrp = (MultiReadPlan)rp; List <ReadPlan> MRP = new List <ReadPlan>(mrp.Plans); readPlan += "MultiReadPlan:["; foreach (ReadPlan rap in MRP) { readPlan += SaveSimpleReadPlan(rap) + ","; } readPlan = readPlan.Remove(readPlan.Length - 1, 1); readPlan += "]"; return(readPlan); } }
/// <summary> /// Create WHERE clauses representing a ReadPlan /// </summary> /// <param name="readPlan">Read plan</param> /// <returns>List of strings to be incorporated into "WHERE ... AND ..." phrase. /// List may be empty.</returns> private List<string> ReadPlanToWhereClause(ReadPlan readPlan) { List<string> wheres = new List<string>(); if (readPlan is SimpleReadPlan) { SimpleReadPlan srp = (SimpleReadPlan) readPlan; wheres.AddRange(TagProtocolToWhereClause(srp.Protocol)); wheres.AddRange(AntennasToWhereClause(srp.Antennas)); if (null != srp.Op && srp.Op is Gen2.ReadData) { wheres.Add(String.Format("mem_bank={0:D}", ((Gen2.ReadData)(srp.Op)).Bank)); wheres.Add(String.Format("block_count={0:D}", ((Gen2.ReadData)(srp.Op)).Len)); wheres.Add(String.Format("block_number={0:D}", (((Gen2.ReadData)(srp.Op)).WordAddress)).ToString()); } } else throw new ArgumentException("Unrecognized /reader/read/plan type " + typeof(ReadPlan).ToString()); return wheres; }
/// <summary> /// Convert ReadPlan to RQL SELECT statements /// </summary> /// <param name="rp">ReadPlan to convert</param> /// <param name="milliseconds">Total number of milliseconds to allocate to ReadPlan</param> /// <param name="subTimeouts">Optional output of milliseconds allocated to each RQL subquery</param> /// <returns>List of RQL subqueries</returns> private List<string> GenerateRql(ReadPlan rp, int milliseconds, out List<int> subTimeouts) { List<string> queries = new List<String>(); List<int> timeoutList = new List<int>(); if (rp is MultiReadPlan) { MultiReadPlan mrp = (MultiReadPlan)rp; foreach (ReadPlan r in mrp.Plans) { // Ideally, totalWeight=0 would allow reader to // dynamically adjust timing based on tags observed. // For now, just divide equally. int subtimeout = (mrp.TotalWeight != 0) ? (int)milliseconds * r.Weight / mrp.TotalWeight : milliseconds / mrp.Plans.Length; subtimeout = Math.Min(subtimeout, UInt16.MaxValue); List<int> subTimeoutList = new List<int>(); queries.AddRange(GenerateRql(r, subtimeout, out subTimeoutList)); timeoutList.AddRange(subTimeoutList); } } else if (rp is SimpleReadPlan) { List<string> wheres = new List<string>(); wheres.AddRange(ReadPlanToWhereClause(rp)); wheres.AddRange(TagFilterToWhereClause(((SimpleReadPlan)rp).Filter)); DateTime baseTime = DateTime.Now; TagOp op = ((SimpleReadPlan)rp).Op; String query; if(op!=null && op is Gen2.ReadData) { _readFieldNames = _readMetaData; } query = MakeSelect(_readFieldNames, "tag_id", wheres, milliseconds); queries.Add(query); timeoutList.Add(milliseconds); } else { throw new ArgumentException("Unrecognized /reader/read/plan type " + typeof(ReadPlan).ToString()); } subTimeouts = timeoutList; return queries; }
private List<string> GenerateRql(ReadPlan rp, int milliseconds) { List<int> timeoutList = null; return GenerateRql(rp, milliseconds, out timeoutList); }
private List<string> SetupCursors(ReadPlan rp, int timeout, out List<int> ctimesOut) { List<int> ctimes = null; List<string> rql = GenerateRql(rp, timeout, out ctimes); int cnum = 0; List<string> cnames = new List<string>(); for (int i = 0; i < rql.Count; i++) { string line = rql[i]; int ctime = ctimes[i]; cnum++; string cname = String.Format("mapic{0}", cnum); cnames.Add(cname); string decl = String.Format( "DECLARE {0} CURSOR FOR {1}", cname, line); Query(decl); } ctimesOut = ctimes; return cnames; }
private void ReadInternal(ReadPlan rp, int milliseconds, ref List<TagReadData> reads) { ResetRql(); List<int> timeouts; List<string> cnames = SetupCursors(rp, milliseconds, out timeouts); string cmd = String.Format( "FETCH {0}", String.Join(",", cnames.ToArray())); SendQuery(cmd, 0); for (int i=0; i<cnames.Count; i++) { DateTime baseTime = DateTime.Now; String[] rows = ReceiveBatch(timeouts[i]); foreach (string row in rows) { if (0 < row.Length) { reads.Add(ParseRqlResponse(row, baseTime)); } } } reads = RemoveDuplicates(reads); ResetRql(); }
private void ReadInternal(int timeOut, ReadPlan rp) { roSpecId = 0; endOfAISpec = false; DeleteRoSpec(); DeleteAccessSpecs(); TagQueueEmptyEvent.Reset(); List<PARAM_ROSpec> roSpecList = new List<PARAM_ROSpec>(); roSpecProtcolTable = new Hashtable(); BuildRoSpec(rp, timeOut, roSpecList,false); foreach (PARAM_ROSpec roSpec in roSpecList) { if (AddRoSpec(roSpec)) { if (EnableRoSpec(roSpec.ROSpecID)) { if (!StartRoSpec(roSpec.ROSpecID)) return; WaitForSearchStart(); WaitForSearchEnd(timeOut); } else { return; } } else { return; } } llrp.OnRoAccessReportReceived -= new delegateRoAccessReport(OnRoAccessReportReceived); }
private void BuildRoSpec(ReadPlan rp, int timeOut, List<PARAM_ROSpec> roSpecList, bool isStandaloneOp) { string response = string.Empty; if (rp is MultiReadPlan) { MultiReadPlan mrp = (MultiReadPlan)rp; numPlans = mrp.Plans.Length; foreach (ReadPlan r in mrp.Plans) { // Ideally, totalWeight=0 would allow reader to // dynamically adjust timing based on tags observed. // For now, just divide equally. int subtimeout = (mrp.TotalWeight != 0) ? (int)timeOut * r.Weight / mrp.TotalWeight : timeOut / mrp.Plans.Length; totalWeight = (uint)mrp.TotalWeight; subtimeout = Math.Min(subtimeout, UInt16.MaxValue); BuildRoSpec(r, subtimeout, roSpecList,false); } } else if (rp is SimpleReadPlan) { //MSG_ADD_ROSPEC msg = new MSG_ADD_ROSPEC(); // Create a Reader Operation Spec (ROSpec). PARAM_ROSpec roSpec = new PARAM_ROSpec(); roSpec.CurrentState = ENUM_ROSpecState.Disabled; roSpec.Priority = 0; roSpec.ROSpecID = ++roSpecId; //Add rospec id and protocol in the hashtable. So that it can be used to populate the tagdata's protocol member with the read tag protocol. roSpecProtcolTable.Add(roSpec.ROSpecID,((SimpleReadPlan)rp).Protocol); // Set up the ROBoundarySpec // This defines the start and stop triggers. roSpec.ROBoundarySpec = new PARAM_ROBoundarySpec(); // Set the start trigger to null. // This means the ROSpec will start as soon as it is enabled. roSpec.ROBoundarySpec.ROSpecStartTrigger = new PARAM_ROSpecStartTrigger(); uint asyncOnTime = Convert.ToUInt16(ParamGet("/reader/read/asyncOnTime")); if (continuousReading && numPlans > 1) { roSpec.ROBoundarySpec.ROSpecStartTrigger.ROSpecStartTriggerType = ENUM_ROSpecStartTriggerType.Periodic; PARAM_PeriodicTriggerValue pValue = new PARAM_PeriodicTriggerValue(); pValue.Offset = 0; pValue.Period = asyncOnTime; roSpec.ROBoundarySpec.ROSpecStartTrigger.PeriodicTriggerValue = pValue; } else { roSpec.ROBoundarySpec.ROSpecStartTrigger.ROSpecStartTriggerType = ENUM_ROSpecStartTriggerType.Null; } // Set the stop trigger is null. This means the ROSpec // will keep running until an STOP_ROSPEC message is sent. roSpec.ROBoundarySpec.ROSpecStopTrigger = new PARAM_ROSpecStopTrigger(); roSpec.ROBoundarySpec.ROSpecStopTrigger.ROSpecStopTriggerType = ENUM_ROSpecStopTriggerType.Null; roSpec.SpecParameter = new UNION_SpecParameter(); PARAM_AISpec aiSpec = new PARAM_AISpec(); // Select which antenna ports we want to use based on the read plan settings aiSpec.AntennaIDs = new LTKD.UInt16Array(); SimpleReadPlan srp = (SimpleReadPlan)rp; //Check for fast search enable isFastSearch = srp.UseFastSearch; //Validate protocol ValidateProtocol(srp.Protocol); int[] antennas = srp.Antennas; if (null == antennas) { aiSpec.AntennaIDs.Add(0); //0 : applys to all antennae, } else { foreach (int antenna in antennas) aiSpec.AntennaIDs.Add((ushort)antenna); } //Specify AI spec trigger type aiSpec.AISpecStopTrigger = new PARAM_AISpecStopTrigger(); //Specify Report spec roSpec.ROReportSpec = new PARAM_ROReportSpec(); if (continuousReading) { // ASYNC Mode - Set the AI stop trigger to null. AI spec will run until the ROSpec stops. if(numPlans > 1) { // ASYNC Mode - Set the AI stop trigger to Duration - AsyncOnTime. AI spec will run until the Disable ROSpec is sent. aiSpec.AISpecStopTrigger.AISpecStopTriggerType = ENUM_AISpecStopTriggerType.Duration; aiSpec.AISpecStopTrigger.DurationTrigger = (uint)timeOut; } else { aiSpec.AISpecStopTrigger.AISpecStopTriggerType = ENUM_AISpecStopTriggerType.Null; aiSpec.AISpecStopTrigger.DurationTrigger = 0; } // Receive a report every time a tag is read. roSpec.ROReportSpec.N = 1; } else { // SYNC Mode - Set the AI stop trigger to inputted duration. AI spec will run for particular duration aiSpec.AISpecStopTrigger.AISpecStopTriggerType = ENUM_AISpecStopTriggerType.Duration; aiSpec.AISpecStopTrigger.DurationTrigger = (uint)timeOut; roSpec.ROReportSpec.N = 0; } PARAM_InventoryParameterSpec inventoryParam = new PARAM_InventoryParameterSpec(); List<PARAM_InventoryParameterSpec> invParamList = new List<PARAM_InventoryParameterSpec>(); inventoryParam.InventoryParameterSpecID = 1; TagFilter tagFilter = srp.Filter; //Filter if(tagFilter != null) { List<PARAM_AntennaConfiguration> antennaConfigList = new List<PARAM_AntennaConfiguration>(); PARAM_AntennaConfiguration antConfig = new PARAM_AntennaConfiguration(); antConfig.AntennaID = 0; if (TagProtocol.GEN2.Equals(srp.Protocol)) { List<PARAM_C1G2Filter> filterList = new List<PARAM_C1G2Filter>(); PARAM_C1G2Filter filter = new PARAM_C1G2Filter(); PARAM_C1G2TagInventoryMask mask; filter.T = ENUM_C1G2TruncateAction.Do_Not_Truncate; PARAM_C1G2InventoryCommand inventoryCommand = new PARAM_C1G2InventoryCommand(); inventoryCommand.TagInventoryStateAware = false; PARAM_C1G2TagInventoryStateUnawareFilterAction unAwareAction = new PARAM_C1G2TagInventoryStateUnawareFilterAction(); unAwareAction.Action = ENUM_C1G2StateUnawareAction.Select_Unselect; if (tagFilter is Gen2.Select) { Gen2.Select selectFilter = (Gen2.Select)tagFilter; mask = new PARAM_C1G2TagInventoryMask(); // Memory Bank mask.MB = new LTKD.TwoBits((ushort)selectFilter.Bank); mask.TagMask = LTKD.LLRPBitArray.FromHexString(ByteFormat.ToHex(selectFilter.Mask).Split('x')[1].ToString()); mask.Pointer = (ushort)selectFilter.BitPointer; filter.C1G2TagInventoryMask = mask; if (selectFilter.Invert) { unAwareAction.Action = ENUM_C1G2StateUnawareAction.Unselect_Select; } filter.C1G2TagInventoryStateUnawareFilterAction = unAwareAction; } else if (tagFilter is TagData) { TagData tagDataFilter = (TagData)tagFilter; mask = new PARAM_C1G2TagInventoryMask(); // EPC Memory Bank mask.MB = new LTKD.TwoBits((ushort)Gen2.Bank.EPC); mask.TagMask = LTKD.LLRPBitArray.FromHexString(tagDataFilter.EpcString); //For epc bit pointer is 32 mask.Pointer = 32; filter.C1G2TagInventoryMask = mask; filter.C1G2TagInventoryStateUnawareFilterAction = unAwareAction; } else { throw new Exception("Unsupported operation"); } filterList.Add(filter); inventoryCommand.C1G2Filter = filterList.ToArray(); antConfig.AirProtocolInventoryCommandSettings.Add(inventoryCommand); antennaConfigList.Add(antConfig); inventoryParam.AntennaConfiguration = antennaConfigList.ToArray(); } else if (TagProtocol.ISO180006B.Equals(srp.Protocol)) { if (tagFilter is Iso180006b.Select) { PARAM_ThingMagicISO180006BTagPattern tagPattern = new PARAM_ThingMagicISO180006BTagPattern(); //Filter type tagPattern.FilterType = ENUM_ThingMagicISO180006BFilterType.ISO180006BSelect; //Invert tagPattern.Invert = ((Iso180006b.Select)tagFilter).Invert; //Address tagPattern.Address = Convert.ToByte(((Iso180006b.Select)tagFilter).Address.ToString("X")); //Mask tagPattern.Mask = ((Iso180006b.Select)tagFilter).Mask; //SelectOp tagPattern.SelectOp = new Org.LLRP.LTK.LLRPV1.DataType.TwoBits(Convert.ToUInt16(((Iso180006b.Select)tagFilter).Op)); //TagData tagPattern.TagData = LTKD.ByteArray.FromHexString(ByteFormat.ToHex(((Iso180006b.Select)tagFilter).Data).Split('x')[1]); PARAM_ThingMagicISO180006BInventoryCommand iso18k6bInventoryCmd = new PARAM_ThingMagicISO180006BInventoryCommand(); iso18k6bInventoryCmd.ThingMagicISO180006BTagPattern = tagPattern; antConfig.AirProtocolInventoryCommandSettings.Add(iso18k6bInventoryCmd); antennaConfigList.Add(antConfig); inventoryParam.AntennaConfiguration = antennaConfigList.ToArray(); } else if(tagFilter is TagData) { PARAM_ThingMagicISO180006BTagPattern tagPattern = new PARAM_ThingMagicISO180006BTagPattern(); //Filter type tagPattern.FilterType = ENUM_ThingMagicISO180006BFilterType.ISO180006BTagData; //Invert tagPattern.Invert = false; //Address tagPattern.Address = 0; //Mask tagPattern.Mask = 0xff; //SelectOp tagPattern.SelectOp = new Org.LLRP.LTK.LLRPV1.DataType.TwoBits(Convert.ToUInt16(((Iso180006b.SelectOp.EQUALS)))); //TagData tagPattern.TagData = LTKD.ByteArray.FromHexString(((TagData)tagFilter).EpcString); PARAM_ThingMagicISO180006BInventoryCommand iso18k6bInventoryCmd = new PARAM_ThingMagicISO180006BInventoryCommand(); iso18k6bInventoryCmd.ThingMagicISO180006BTagPattern = tagPattern; antConfig.AirProtocolInventoryCommandSettings.Add(iso18k6bInventoryCmd); antennaConfigList.Add(antConfig); inventoryParam.AntennaConfiguration = antennaConfigList.ToArray(); } else { throw new Exception("Unsupported operation"); } } } if (isFastSearch) { List<PARAM_AntennaConfiguration> antennaConfigList = new List<PARAM_AntennaConfiguration>(); PARAM_AntennaConfiguration antConfig = new PARAM_AntennaConfiguration(); PARAM_ThingMagicFastSearchMode fastSearch = new PARAM_ThingMagicFastSearchMode(); fastSearch.ThingMagicFastSearch = ENUM_ThingMagicFastSearchValue.Enabled; PARAM_C1G2InventoryCommand inventoryCommandFastSearch = new PARAM_C1G2InventoryCommand(); inventoryCommandFastSearch.AddCustomParameter(fastSearch); antConfig.AirProtocolInventoryCommandSettings.Add(inventoryCommandFastSearch); antennaConfigList.Add(antConfig); inventoryParam.AntennaConfiguration = antennaConfigList.ToArray(); } //Emebeded tagops TagOp tagOperation = srp.Op; PARAM_AccessCommand accessCommand = new PARAM_AccessCommand(); PARAM_AccessSpec accessSpec = new PARAM_AccessSpec(); if (null != tagOperation) { accessSpec.AccessSpecID = ++AccessSpecID; accessSpec.AccessCommand = accessCommand; accessSpec.ROSpecID = roSpecId; PARAM_AccessSpecStopTrigger trigger = new PARAM_AccessSpecStopTrigger(); if (!isStandaloneOp)//Embedded operation { if (tagOperation is Gen2.NxpGen2TagOp.EasAlarm) { throw new FeatureNotSupportedException("Gen2.NxpGen2TagOp.EasAlarm command can be standalone tag operation "); } if (tagOperation is Gen2.NXP.G2X.ResetReadProtect) { throw new FeatureNotSupportedException("NXP Reset Read protect command can be embedded only if the chip-type is G2il"); } accessSpec.AntennaID = 0; trigger.AccessSpecStopTrigger = ENUM_AccessSpecStopTriggerType.Null; trigger.OperationCountValue = 0; } else { //standalone operation if (tagOperation is Gen2.Alien.Higgs2.PartialLoadImage) { if (null != tagFilter) { throw new ReaderException("Filter is not supported on this operation."); } } accessSpec.AntennaID = Convert.ToUInt16(ParamGet("/reader/tagop/antenna")); trigger.AccessSpecStopTrigger = ENUM_AccessSpecStopTriggerType.Operation_Count; trigger.OperationCountValue = 1; } accessCommand.AccessCommandOpSpec.Add(BuildOpSpec(srp)); accessSpec.ProtocolID = ENUM_AirProtocols.EPCGlobalClass1Gen2; accessSpec.CurrentState = ENUM_AccessSpecState.Disabled; accessSpec.AccessSpecStopTrigger = trigger; // Add a list of target tags to the tag spec. PARAM_C1G2TagSpec tagSpec = new PARAM_C1G2TagSpec(); PARAM_C1G2TargetTag targetTag = new PARAM_C1G2TargetTag(); targetTag.MB = new LTKD.TwoBits(0); targetTag.Match = false; targetTag.Pointer = 0; targetTag.TagData = LTKD.LLRPBitArray.FromBinString("0"); targetTag.TagMask = LTKD.LLRPBitArray.FromBinString("0"); List<PARAM_C1G2TargetTag> targetTagList = new List<PARAM_C1G2TargetTag>(); targetTagList.Add(targetTag); tagSpec.C1G2TargetTag = targetTagList.ToArray(); //Add the tag spec to the access command. accessCommand.AirProtocolTagSpec.Add(tagSpec); AddAccessSpec(accessSpec); EnableAccessSpec(accessSpec.AccessSpecID); } // Reading Gen2 Tags, specify in InventorySpec if (TagProtocol.GEN2 == srp.Protocol) { inventoryParam.ProtocolID = ENUM_AirProtocols.EPCGlobalClass1Gen2; } else if (TagProtocol.ISO180006B == srp.Protocol) { inventoryParam.ProtocolID = ENUM_AirProtocols.Unspecified; PARAM_ThingMagicCustomAirProtocols airProtocol = new PARAM_ThingMagicCustomAirProtocols(); airProtocol.customProtocolId = ENUM_ThingMagicCustomAirProtocolList.Iso180006b; inventoryParam.Custom.Add(airProtocol); } else { throw new FeatureNotSupportedException("Only GEN2 and ISO18K6B protocol is supported as of now"); } invParamList.Add(inventoryParam); aiSpec.InventoryParameterSpec = invParamList.ToArray(); // Specify what type of tag reports we want to receive and when we want to receive them. roSpec.ROReportSpec.ROReportTrigger = ENUM_ROReportTriggerType.Upon_N_Tags_Or_End_Of_ROSpec; roSpec.SpecParameter.Add(aiSpec); // Selecting which fields we want in the report. roSpec.ROReportSpec.TagReportContentSelector = new PARAM_TagReportContentSelector(); roSpec.ROReportSpec.TagReportContentSelector.EnableAccessSpecID = true; roSpec.ROReportSpec.TagReportContentSelector.EnableAntennaID = true; roSpec.ROReportSpec.TagReportContentSelector.EnableChannelIndex = true; roSpec.ROReportSpec.TagReportContentSelector.EnableFirstSeenTimestamp = true; roSpec.ROReportSpec.TagReportContentSelector.EnableInventoryParameterSpecID = true; roSpec.ROReportSpec.TagReportContentSelector.EnableLastSeenTimestamp = true; roSpec.ROReportSpec.TagReportContentSelector.EnablePeakRSSI = true; roSpec.ROReportSpec.TagReportContentSelector.EnableROSpecID = true; roSpec.ROReportSpec.TagReportContentSelector.EnableSpecIndex = true; roSpec.ROReportSpec.TagReportContentSelector.EnableTagSeenCount = true; // By default both PC and CRC bits are set, so sent from tmmpd PARAM_C1G2EPCMemorySelector gen2MemSelector = new PARAM_C1G2EPCMemorySelector(); gen2MemSelector.EnableCRC = true; gen2MemSelector.EnablePCBits = true; roSpec.ROReportSpec.TagReportContentSelector.AirProtocolEPCMemorySelector.Add(gen2MemSelector); // Since Spruce release firmware doesn't support phase, don't add PARAM_ThingMagicTagReportContentSelector // custom paramter in ROReportSpec string[] ver = softwareVersion.Split('.'); if (((Convert.ToInt32(ver[0]) == 4) && (Convert.ToInt32(ver[1]) >= 17)) || (Convert.ToInt32(ver[0]) > 4)) { PARAM_ThingMagicTagReportContentSelector tagReportContentSelector = new PARAM_ThingMagicTagReportContentSelector(); tagReportContentSelector.PhaseMode = ENUM_ThingMagicPhaseMode.Enabled; roSpec.ROReportSpec.AddCustomParameter(tagReportContentSelector); } roSpecList.Add(roSpec); } }