📄 mprreader.cs
字号:
{
UpdateInventory();
// Console.WriteLine("{0}",pt.Duration);
// A bit kludgy:
// "don't fire event if it is occuring,
// but shouldn't be (InvTimerEnabled == false)...
if ((InvTimerEnabled) && (InvPollEvent != null))
InvPollEvent(this, new EventArgs());
KickInvTimer();
}
catch (ObjectDisposedException)
{
// Turn off timer
InvTimerEnabled = false;
}
catch (Exception ex)
{
// Turn off timer
InvTimerEnabled = false;
LogIt(ex.Message);
}
}
/// <summary>
/// Form's copy of current persisted inventory
/// </summary>
private Inventory TagsRead = new Inventory();
/// <summary>
/// Returns an Inventory Object populated with the tags that have been read and not expired.
/// </summary>
public Inventory CurrentInventory
{
get
{
Inventory TempInventory = new Inventory();
lock (TagsRead)
{
foreach(RFIDTag T in TagsRead)
{
TempInventory.Add(T);
}
}
return TempInventory;
}
}
/// <summary>
/// Whether or not to perform EPC Class 0 inventories.
/// </summary>
public bool Class0InventoryEnabled = true;
/// <summary>
/// Whether to perform EPC Class 1 inventories.
/// </summary>
public bool Class1InventoryEnabled = true;
/// <summary>
/// Whether to perform EPC UHF Gen2 inventories.
/// </summary>
public bool Gen2InventoryEnabled = true;
private TagFilter tagFilter = new TagFilter(0, "");
/// <summary>
/// Filter used for Class 0 and Class 1 Inventories.
/// Tags must match bits of Filter, starting at the MSbit of MSByte.
/// </summary>
public TagFilter Filter {
get { return tagFilter; }
set { tagFilter = value; }
}
private bool isConnected = false;
/// <summary>
/// Whether we are connected to the MPR or not.
/// </summary>
public bool IsConnected { get { return isConnected; } }
#endregion
#region Private Properties
/// <summary>
/// Underlying serial port communications object for the reader.
/// </summary>
protected MPRComm comm;
/// <summary>
/// Inventory loop timer
/// </summary>
private System.Threading.Timer InventoryUpdateTimer;
private bool ReconnectOnResume = false;
// Properties for connecting to an MPR via a COM Port
private string SerialPortName;
private string BaudRate;
private Inventory inventory = new Inventory();
#endregion
#region Private Functions
/// <summary>
/// Asynchronously log some status by calling the commlogger
/// delegate (if it has been assigned).
/// </summary>
/// <param name="s">string: The string to log.</param>
protected void LogIt(string s)
{
if (StatusEvent != null)
StatusEvent(s);
}
#region Message Processing
/// <summary>
/// Process the Status byte of a message response, and
/// log an error message if the message is not OK.
/// </summary>
/// <param name="aMsg">The Msg to process</param>
/// <param name="enableLogging">Whether to log the raw serial port transaction.</param>
/// <returns>Whether the message response status was OK</returns>
protected bool ProcMsgStat(MPRMsg aMsg, bool enableLogging)
{
// Display the serial port traffic
if (enableLogging) LogIt("Txed: " + aMsg.TxFrame.ToHexString());
foreach(MPRFrame rxFrame in aMsg.RxFrames)
if (enableLogging) LogIt("Rxed: " + rxFrame.ToHexString());
// Process response status
if (aMsg.Status != RspStatus.OK)
{
if (enableLogging) LogIt(aMsg.MsgID.ToString()
+ ": " + aMsg.Status.ToString()
+ " " + aMsg.Error.ToString());
if (aMsg.commErrorString != null)
if (enableLogging) LogIt(aMsg.commErrorString);
return false;
}
else
return true;
}
/// <summary>
///
/// </summary>
/// <param name="aMsg"></param>
/// <returns></returns>
protected bool ProcMsgStat(MPRMsg aMsg) { return ProcMsgStat(aMsg, true); }
/// <summary>
/// Most frames end with three counts,
/// Tags Processed,
/// Under-run errors (Tags whose TagID had less bits than the EPC header suggests it should have had)
/// CRC errors
/// </summary>
/// <param name="Summary">A bytelist of the 6 bytes that comprise the Message Summary</param>
/// <returns>The number of tags successfully processed; 0 if Summary wasn't exactly 6 bytes.</returns>
private ushort ProcessSummary(byteList Summary)
{
if (Summary.Count != 6) return 0;
ushort TagsProcessed = Helpers.b2us(Summary[0], Summary[1]);
LogIt("Tags Processed: " + TagsProcessed);
LogIt("Under-run error count: " + Helpers.b2us(Summary[2], Summary[3]));
LogIt("Tag CRC error count: " + Helpers.b2us(Summary[4], Summary[5]));
LogIt("");
return TagsProcessed;
}
/// <summary>
/// Decode the Tag IDs in the accumulated frame payloads received in response to an inventory command.
/// </summary>
/// <param name="rawBytes">The accumulated payload bytes.</param>
/// <param name="Protocol">The RFID Protocol of the inventory being processed.</param>
/// <param name="tagLengthOpt">How to parse the length of a Tag ID. EPC option implies use 1st byte. Else, look for delimiter.</param>
/// <returns>An Inventory (Tag List) containing the Tags parsed from the payload.</returns>
private Inventory InventoryParse(byteList rawBytes, RFIDProtocol Protocol, TagLengthOptionEnum tagLengthOpt)
{
// If there are less than 7 bytes, there cannot be a valid (even empty) inventory in this byteList
if (rawBytes.Count < 6) return new Inventory();
LogIt(Protocol.ToString() + " Inventory");
ProcessSummary(rawBytes.subList(rawBytes.Count - 6));
Inventory mInv = new Inventory();
int bPtr = 0;
while (bPtr < rawBytes.Count - 6)
{
byte TagsInPkt = rawBytes[bPtr++];
while (TagsInPkt-- > 0)
{
byte TagType = rawBytes[bPtr];
int TagLen;
if ((tagLengthOpt == TagLengthOptionEnum.EPC_NoParam)
|| (tagLengthOpt == TagLengthOptionEnum.EPC))
{
// TagType MSbits = 00b for ePC-96 (12 bytes), all other 2MSbits => ePC-64 (8 bytes)
TagLen = (((TagType & 0xC0) == 0x00)&&((TagType & 0xF8) != 0x08))?12:8;
}
else // This packet uses explicit T5ag Length Style Delimiters
{
bPtr++; // Advance byte pointer past the Tag Length Style delimiter
TagLen = (TagType == (byte)TagLengthStyleEnum.TagID64)?8:12;
}
RFIDTag aTag = new RFIDTag(rawBytes.subList(bPtr, bPtr + TagLen), Protocol);
mInv.Add(aTag);
LogIt(string.Format("{0}-bit {1} Tag Found: {2}", TagLen * 8, Protocol.ToString(), aTag.TagID));
bPtr += TagLen;
}
}
LogIt("");
return mInv;
}
/// <summary>
/// InventoryParse with default (EPC_NoParam) TagLengthOption.
/// </summary>
/// <param name="rawBytes"></param>
/// <param name="Protocol"></param>
/// <returns></returns>
private Inventory InventoryParse(byteList rawBytes, RFIDProtocol Protocol)
{ return InventoryParse(rawBytes, Protocol, TagLengthOptionEnum.EPC_NoParam); }
#region Gen2 Response Packet Processing
/// <summary>
///
/// tags
/// slots
/// epcCRCErrors
/// cmdCRCErrors
/// collisions
/// rounds
/// </summary>
/// <param name="Summary"></param>
/// <returns></returns>
protected ushort ProcessGen2Summary(byteList Summary)
{
const int SummaryLength = 12;
if (Summary.Count != SummaryLength) return 0;
ushort TagsProcessed = Helpers.b2us(Summary[0], Summary[1]);
LogIt(" Tags Processed: " + TagsProcessed);
LogIt(" Slots: " + Helpers.b2us(Summary[2], Summary[3]));
LogIt(" EPC CRC errors: " + Helpers.b2us(Summary[4], Summary[5]));
LogIt(" Response CRC errors: " + Helpers.b2us(Summary[6], Summary[7]));
LogIt(" Collisions: " + Helpers.b2us(Summary[8], Summary[9]));
LogIt(" Rounds: " + Helpers.b2us(Summary[10], Summary[11]));
LogIt("");
return TagsProcessed;
}
/// <summary>
/// Decode the Tag IDs in the accumulated frame payloads received in response to an inventory command.
/// </summary>
/// <param name="rawBytes">The accumulated payload bytes.</param>
/// <returns>An Inventory (Tag List) containing the Tags parsed from the payload.</returns>
private Inventory G2InventoryParse(byteList rawBytes)
{
const int SummaryLength = 12;
RFIDProtocol Protocol = RFIDProtocol.EPCGen2;
// If there are less than 7 bytes, there cannot be a valid (even empty) inventory in this byteList
if (rawBytes.Count < SummaryLength) return new Inventory();
LogIt(Protocol.ToString() + " Inventory");
ProcessGen2Summary(rawBytes.subList(rawBytes.Count - SummaryLength));
Inventory mInv = new Inventory();
int bPtr = 0;
while (bPtr < rawBytes.Count - SummaryLength)
{
if (bPtr < rawBytes.Count - SummaryLength)
{
// <Tag Response> = <EPC>
// <EPC> = <EPC Length> <EPC PC> <EPC Tag ID>
// <EPC Length> = { 0 .. 32 }, 1 byte.
int EPC_Length = rawBytes[bPtr++]; // Length of just <EPC Tag ID>, in words.
// <EPC PC> = <Word>
ushort EPC_PC = Helpers.b2us(rawBytes[bPtr++], rawBytes[bPtr++]);
// <EPC Tag ID> = [<Word>]
int tagID_Length = 2*(EPC_Length); // * 2 to convert words to bytes
byteList EPC_TagID = rawBytes.subList(bPtr, bPtr + tagID_Length);
bPtr += tagID_Length;
LogIt(string.Format("{0} {1}-byte Tag ID Found with PC = {2:X4} and EPC: {3}", Protocol.ToString(), tagID_Length, EPC_PC, EPC_TagID.ToHexString()));
// Add the Tag to the new inventory
mInv.Add(new RFIDTag(EPC_TagID, Protocol));
}
}
LogIt("");
return mInv;
}
/// <summary>
/// Parse the response of a Gen2 read subcommand.
/// Each response frame consists of:
/// For each tag in the frame:
/// TagIDLength - 1 byte
/// the Tag ID - TagIDLength bytes
/// TagDataLength - 1 byte
/// TagData - TagDataLength bytes
/// </summary>
/// <param name="rawBytes">The combined payloads of all response packets for this message.</param>
/// <returns>An Inventory (collection of RFID tags with EPCs parsed from response)</returns>
private Inventory Gen2AccessParse(byteList rawBytes)
{
const int SummaryLength = 12;
RFIDProtocol Protocol = RFIDProtocol.EPCGen2;
// If there are less than 7 bytes, there cannot be a valid (even empty) inventory in this byteList
if (rawBytes.Count < SummaryLength) return new Inventory();
LogIt(Protocol.ToString() + " Inventory");
ProcessGen2Summary(rawBytes.subList(rawBytes.Count - SummaryLength));
Inventory mInv = new Inventory();
int bPtr = 0;
while (bPtr < rawBytes.Count - SummaryLength)
{
// <Tag Response> = <EPC>
// <EPC> = <EPC Length> <EPC PC> <EPC Tag ID>
// <EPC Length> = { 0 .. 32 }, 1 byte.
int EPC_Length = rawBytes[bPtr++]; // Length of just <EPC Tag ID>, in words.
// <EPC PC> = <Word>
ushort EPC_PC = Helpers.b2us(rawBytes[bPtr++], rawBytes[bPtr++]);
// <EPC Tag ID> = [<Word>]
int tagID_Length = 2*(EPC_Length); // * 2 to convert words to bytes
byteList EPC_TagID = rawBytes.subList(bPtr, bPtr + tagID_Length);
bPtr += tagID_Length;
LogIt(string.Format("{0} {1}-byte Tag ID Found with PC = {2:X4} and EPC: {3}", Protocol.ToString(), tagID_Length, EPC_PC, EPC_TagID.ToHexString()));
// Now parse <Access Response> = <Access Status> <Access Data Length> <Access Data>
// <Access Status> = { <OK> | <Tag Lost> | <CMD CRC Error> | <Tag Error> }
Gen2AccessStatus accessStatus = (Gen2AccessStatus)rawBytes[bPtr++];
// <Access Data Length> = <Word>
ushort accessDataLength = Helpers.b2us(rawBytes[bPtr++], rawBytes[bPtr++]);
// <Access Data> = { <> | <Tag Error> | <Read Data> | <Write Data> }
byteList accessData = rawBytes.subList(bPtr, bPtr + accessDataLength);
bPtr += accessDataLength;
LogIt(string.Format(" Access Status = <{0}>", accessStatus));
LogIt(string.Format(" {0} bytes of Access Data = {1}", accessDataLength, accessData.ToHexString()));
// If the tag reported a successful access, add it to the new inventory
if (accessStatus == Gen2AccessStatus.OK)
mInv.Add(new RFIDTag(EPC_TagID, Protocol, accessStatus, accessData));
}
LogIt("");
return mInv;
}
private SelectList Gen2SelectListParse(byteList rawBytes)
{
// If there are less than 7 bytes, there cannot be a valid (even empty) inventory in this byteList
if (rawBytes.Count < 1 ) return new SelectList();
LogIt("Gen 2 Select List");
int bPtr = 0;
int nRecs = rawBytes[bPtr++]; // Number of Select Records <Select List Size>
SelectList srList = new SelectList();
LogIt(string.Format(" {0} Select Records in Select List.", nRecs));
if (nRecs == 0)
{
LogIt(string.Format(" Default Record: "));
srList.DefaultRecordOnly = true;
}
while (bPtr < rawBytes.Count - 1)
{
// Must have at least 1 full SelectRecord in what is left of rawBytes
if (rawBytes.Count < SelectRecord.ByteLength)
break;
SelectRecord sr = new SelectRecord(r
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -