private void MenuItem_getTagInfo_Click(object sender, EventArgs e) { // byte[] uid = new byte[8]; GetTagInfoResult result = _driver.GetTagInfo(GetCurrentReaderName(), _inventory_info); MessageBox.Show(this, result.ToString()); }
private void ToolStripMenuItem_testLockBlocks_Click(object sender, EventArgs e) { GetTagInfoResult result = _driver.GetTagInfo(GetCurrentReaderName(), null); MessageBox.Show(this, "初始芯片内容: " + result.ToString()); if (result.Value == -1) { return; } TagInfo new_chip = result.TagInfo.Clone(); new_chip.Bytes = Element.FromHexString( @"91 00 05 1c be 99 1a 14 02 01 d0 14 02 04 b3 46 07 44 1c b6 e2 e3 35 d6 83 02 07 ac c0 9e ba a0 6f 6b 00 00"); new_chip.LockStatus = "ll....www"; NormalResult write_result = _driver.WriteTagInfo(GetCurrentReaderName(), result.TagInfo, new_chip); MessageBox.Show(this, write_result.ToString()); }
public GetTagInfoResult GetTagInfo(string reader_name, string uid) { foreach (Reader reader in Program.Rfid.Readers) { if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } InventoryInfo info = new InventoryInfo { UID = uid }; GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1 && result0.ErrorCode == "errorFromReader=4") { continue; } if (result0.Value == -1) { return(result0); } // not found return(result0); } return(new GetTagInfoResult()); }
void GetTagInfo(ListViewItem item) { ItemInfo item_info = (ItemInfo)item.Tag; OneTag tag = item_info.OneTag; RfidChannel channel = StartRfidChannel( Program.MainForm.RfidCenterUrl, out string strError); if (channel == null) { strError = "StartRfidChannel() error"; goto ERROR1; } try { GetTagInfoResult result = channel.Object.GetTagInfo("*", tag.UID); if (result.Value == -1) { strError = result.ErrorInfo; goto ERROR1; } tag.TagInfo = result.TagInfo; string hex_string = Element.GetHexString(result.TagInfo.Bytes, "4"); item_info.LogicChipItem = LogicChipItem.FromTagInfo(result.TagInfo); item_info.LogicChipItem.PropertyChanged += LogicChipItem_PropertyChanged; this.Invoke((Action)(() => { string pii = item_info.LogicChipItem.PrimaryItemIdentifier; // .FindElement(ElementOID.PII)?.Text; ListViewUtil.ChangeItemText(item, COLUMN_PII, pii); if (this.SelectedPII != null && pii == this.SelectedPII) { item.Font = new Font(item.Font, FontStyle.Bold); } })); return; } catch (Exception ex) { strError = "ListTags() 出现异常: " + ex.Message; goto ERROR1; } finally { EndRfidChannel(channel); } ERROR1: this.Invoke((Action)(() => { ListViewUtil.ChangeItemText(item, COLUMN_PII, "error:" + strError); // 把 item 修改为红色背景,表示出错的状态 SetItemColor(item, "error"); })); }
public NormalResult WriteTagInfo( string reader_name, TagInfo old_tag_info, TagInfo new_tag_info) { // TODO: 对 old_tag_info 和 new_tag_info 合法性进行一系列检查 foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif if (Reader.MatchReaderName(reader_name, reader.Name, out string antenna_list) == false) { continue; } InventoryInfo info = new InventoryInfo { UID = old_tag_info.UID, AntennaID = old_tag_info.AntennaID // 2019/9/27 }; GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1 && result0.ErrorCode == "errorFromReader=4") { continue; } if (result0.Value == -1) { return(new NormalResult(result0)); } // TODO: 是否对照检查 old_tag_info 和 result0.TagInfo ? return(Program.Rfid.WriteTagInfo(reader.Name, old_tag_info, new_tag_info)); } return(new NormalResult { Value = -1, ErrorInfo = $"没有找到 UID 为 {old_tag_info.UID} 的标签", ErrorCode = "notFound" }); }
// 2019/9/25 // 新版本。根据 InventoryInfo 获得标签详细信息 // result.Value // -1 // 0 public GetTagInfoResult GetTagInfo(string reader_name, InventoryInfo info) { if (Program.MainForm.ErrorState != "normal") { return new GetTagInfoResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <GetTagInfoResult> errors = new List <GetTagInfoResult>(); foreach (Reader reader in Program.Rfid.Readers) { if (Reader.MatchReaderName(reader_name, reader.Name, out string antenna_list) == false) { continue; } // result.Value // -1 // 0 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); // 继续尝试往后寻找 if (result0.Value == -1 // && result0.ErrorCode == "errorFromReader=4" ) { errors.Add(result0); continue; } if (result0.Value == -1) { return(result0); } // found return(result0); } if (errors.Count > 0) { return(errors[0]); } return(new GetTagInfoResult { ErrorCode = "notFoundReader" }); }
void GetTagInfo(ListViewItem item) { OneTag tag = (OneTag)item.Tag; RfidChannel channel = StartRfidChannel( Program.MainForm.RfidCenterUrl, out string strError); if (channel == null) { strError = "StartRfidChannel() error"; goto ERROR1; } try { GetTagInfoResult result = channel.Object.GetTagInfo("*", tag.UID); if (result.Value == -1) { strError = result.ErrorInfo; goto ERROR1; } tag.TagInfo = result.TagInfo; LogicChip chip = LogicChip.From(result.TagInfo.Bytes, (int)result.TagInfo.BlockSize); this.Invoke((Action)(() => { string pii = chip.FindElement(ElementOID.PII)?.Text; ListViewUtil.ChangeItemText(item, COLUMN_PII, pii); if (pii == this.SelectedPII) { item.Font = new Font(item.Font, FontStyle.Bold); } })); return; } catch (Exception ex) { strError = "ListTags() 出现异常: " + ex.Message; goto ERROR1; } finally { EndRfidChannel(channel); } ERROR1: this.Invoke((Action)(() => { ListViewUtil.ChangeItemText(item, COLUMN_PII, "error:" + strError); // TODO: 把 item 修改为红色背景,表示出错的状态 })); }
// 装入以前的标签信息 // 如果读卡器上有多个标签,则出现对话框让从中选择一个。列表中和右侧 PII 相同的,优先被选定 // parameters: // adjust_right 是否自动调整右侧元素。即,把左侧的锁定状态元素覆盖到右侧。调整前要询问。如果不同意调整,可以放弃,然后改为放一个空白标签并装载保存 int LoadOldChip(bool adjust_right, out string strError) { strError = ""; if (string.IsNullOrEmpty(Program.MainForm.RfidCenterUrl)) { strError = "尚未配置 RFID 中心 URL"; return(-1); } RfidChannel channel = StartRfidChannel( Program.MainForm.RfidCenterUrl, out strError); if (channel == null) { return(-1); } try { ListTagsResult result = channel.Object.ListTags("*"); if (result.Value == -1) { strError = result.ErrorInfo; return(-1); } // 出现对话框让选择一个 SelectTagDialog dialog = new SelectTagDialog(); dialog.Tags = result.Results; dialog.ShowDialog(this); if (dialog.DialogResult == DialogResult.Cancel) { return(0); } // 装载标签详细信息 GetTagInfoResult result1 = channel.Object.GetTagInfo(dialog.SelectedTag.ReaderName, dialog.SelectedTag.UID); return(1); } catch (Exception ex) { strError = "出现异常: " + ex.Message; return(-1); } finally { EndRfidChannel(channel); } }
bool NotifyTag(string reader_name, string uid) { if (_sendKeyEnabled.Value == false) { return(false); } InventoryInfo info = new InventoryInfo { UID = uid }; GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader_name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? // Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); return(false); } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); Element typeOfUsage = chip.FindElement(ElementOID.TypeOfUsage); StringBuilder text = new StringBuilder(); if (pii == null) { text.Append($"uid:{info.UID}"); } else { text.Append($"pii:{pii.Text}"); } if (typeOfUsage != null) { text.Append($",tou:{typeOfUsage.Text}"); } Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"{text}\r"); })); return(true); }
// 装载芯片数据 bool LoadChipData(string uid, ListViewItem item) { InventoryInfo info = new InventoryInfo { UID = uid, }; GetTagInfoResult result = _driver.GetTagInfo(GetCurrentReaderName(), info); if (result.Value == -1) { this.Invoke((Action)(() => { SetItemColor(item, "error"); ListViewUtil.ChangeItemText(item, 1, $"error:{result.ErrorInfo},error_code:{result.ErrorCode}"); })); return(false); } // 刷新 item 行 ItemInfo tag_info = new ItemInfo { OldInfo = result.TagInfo, LogicChip = LogicChipItem.FromTagInfo(result.TagInfo) }; item.Tag = tag_info; tag_info.LogicChip.DSFID = tag_info.OldInfo.DSFID; tag_info.LogicChip.AFI = tag_info.OldInfo.AFI; tag_info.LogicChip.EAS = tag_info.OldInfo.EAS; tag_info.LogicChip.PropertyChanged += LogicChip_PropertyChanged; string pii = tag_info.LogicChip.FindElement(ElementOID.PII)?.Text; this.Invoke((Action)(() => { ListViewUtil.ChangeItemText(item, 1, pii); ListViewUtil.ChangeItemText(item, 0, uid); SetItemColor(item, "normal"); })); // 如果当前打开的 ChipDialog 正好是这个 UID,则更新它 this.Invoke((Action)(() => { SetChipDialogContent(item, uid); })); return(true); }
public GetTagInfoResult GetTagInfo(string reader_name, string uid) { List <GetTagInfoResult> errors = new List <GetTagInfoResult>(); foreach (Reader reader in Program.Rfid.Readers) { if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } InventoryInfo info = new InventoryInfo { UID = uid }; GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); // 继续尝试往后寻找 if (result0.Value == -1 && result0.ErrorCode == "errorFromReader=4") { errors.Add(result0); continue; } if (result0.Value == -1) { return(result0); } // found return(result0); } // 2019/2/13 if (errors.Count > 0) { return(errors[0]); } return(new GetTagInfoResult { ErrorCode = "notFoundReader" }); }
// parameters: // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo public ListTagsResult ListTags(string reader_name, string style) { InventoryResult result = new InventoryResult(); if (Program.MainForm.ErrorState != "normal") { return new ListTagsResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <OneTag> tags = new List <OneTag>(); // uid --> OneTag Hashtable uid_table = new Hashtable(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif if (Reader.MatchReaderName(reader_name, reader.Name) == false) { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, ""); if (inventory_result.Value == -1) { return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo, ErrorCode = inventory_result.ErrorCode }); } foreach (InventoryInfo info in inventory_result.Results) { OneTag tag = null; if (uid_table.ContainsKey(info.UID)) { // 重复出现的,追加 读卡器名字 tag = (OneTag)uid_table[info.UID]; tag.ReaderName += "," + reader.Name; } else { // 首次出现 tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID }; uid_table[info.UID] = tag; tags.Add(tag); } if (StringUtil.IsInList("getTagInfo", style) && tag.TagInfo == null) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }
public GetTagInfoResult GetTagInfo(string reader_name, string uid) { if (Program.MainForm.ErrorState != "normal") { return new GetTagInfoResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <GetTagInfoResult> errors = new List <GetTagInfoResult>(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif if (Reader.MatchReaderName(reader_name, reader.Name) == false) { continue; } InventoryInfo info = new InventoryInfo { UID = uid }; GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); // 继续尝试往后寻找 if (result0.Value == -1 // && result0.ErrorCode == "errorFromReader=4" ) { errors.Add(result0); continue; } if (result0.Value == -1) { return(result0); } // found return(result0); } // 2019/2/13 if (errors.Count > 0) { return(errors[0]); } return(new GetTagInfoResult { ErrorCode = "notFoundReader" }); }
// parameters: // readerNameList list中包含的内容的读卡器名(列表)。注意 list 中包含的标签,可能并不是全部读卡器的标签。对没有包含在其中的标签,本函数需要注意跳过(维持现状),不要当作被删除处理 // 异常: // public static void Refresh(// BaseChannel<IRfid> channel, string readerNameList, List <OneTag> list_param, // delegate_getTagInfo getTagInfo, delegate_notifyChanged notifyChanged, delegate_setError setError) { setError?.Invoke("rfid", null); // 对 list 里面的元素要按照天线号进行过滤 // 注:这样过滤主要是为了防范 shelf.xml 对 M201 这样的没有多天线的配置了多个天线用于多个门,引起这里算法故障(在 Tags 中填充很多重复 UID 的对象) // 由于 RfidCenter 中 ListTags() 对于 M201 这样的读卡器没有严格过滤天线号,所以会有上述问题 // 若加固了 RfidCenter 以后,这一段过滤代码可以省略,以便提高执行速度 List <OneTag> list = new List <OneTag>(); foreach (OneTag tag in list_param) { if (InRange(tag, readerNameList) == false) { continue; } list.Add(tag); } List <TagAndData> new_books = new List <TagAndData>(); List <TagAndData> error_books = new List <TagAndData>(); // 从当前列表中发现已有的图书。用于交叉运算 List <TagAndData> found_books = new List <TagAndData>(); // 即便是发现已经存在 UID 的标签,也要再判断一下 Antenna 是否不同。如果有不同,要进行变化通知 // 从当前列表中发现(除了 UID) 内容有变化的图书。这些图书也会进入 found_books 集合 List <TagAndData> changed_books = new List <TagAndData>(); foreach (OneTag tag in list) { // 检查以前的列表中是否已经有了 var book = FindBookTag(tag.UID); /* * // 2020/4/19 验证性做法:从一个读卡器变动到另一个读卡器,第一种顺序,瞬间集合里面可能会有相同 UID 的两个对象 * // 用 Test_transfer_test_1() 单元测试 * // 如果找到的对象是属于当前读卡器以外的范围,则当作没有找到处理 * if (book != null && InRange(book.OneTag, readerNameList) == false) * book = null; */ if (book != null) { found_books.Add(book); if (book.OneTag.AntennaID != tag.AntennaID || book.OneTag.ReaderName != tag.ReaderName) { var onetag = book.OneTag; // 修改 AntennaID onetag.AntennaID = tag.AntennaID; onetag.ReaderName = tag.ReaderName; if (onetag.TagInfo != null) { /* * // TODO: 这里还有个做法,就是干脆把 .TagInfo 设置为 null。这会导致重新获取 TagInfo(所谓两阶段) * onetag.TagInfo = null; * ClearTagTable(onetag.UID); */ onetag.TagInfo.AntennaID = tag.AntennaID; onetag.TagInfo.ReaderName = tag.ReaderName; // 只清理缓存 // _tagTable.Remove(onetag.UID); } changed_books.Add(book); } if (string.IsNullOrEmpty(book.Error) == false) { error_books.Add(book); } continue; } // ISO15693 的则先添加到 _books 中。等类型判断完成,有可能还要调整到 _patrons 中 book = new TagAndData { OneTag = tag }; new_books.Add(book); // 2020/4/19 // 对于新加入的标签,只清理缓存。防止以前残留的 cache 信息污染 // _tagTable.Remove(tag.UID); } List <TagAndData> remove_books = new List <TagAndData>(); // 交叉运算 // 注意对那些在 readerNameList 以外的标签不要当作 removed 处理 foreach (TagAndData book in _tags) { if (InRange(book.OneTag, readerNameList) == false) { continue; } if (found_books.IndexOf(book) == -1) { remove_books.Add(book); } } bool array_changed = false; // 兑现添加 lock (_sync_tags) { foreach (TagAndData book in new_books) { if (_tags.IndexOf(book) == -1) { _tags.Add(book); array_changed = true; } } // 兑现删除 foreach (TagAndData book in remove_books) { _tags.Remove(book); array_changed = true; } } // 通知一次变化 if (array_changed || changed_books.Count > 0 || new_books.Count > 0 || remove_books.Count > 0) { notifyChanged?.Invoke(new_books, changed_books, remove_books); } #if NO List <TagAndData> news = new List <TagAndData>(); news.AddRange(_tags); new_books = new List <TagAndData>(); remove_books = new List <TagAndData>(); // .TagInfo 是否发生过填充 bool taginfo_changed = false; { List <TagAndData> update_books = new List <TagAndData>(); // 逐个获得新发现的 ISO15693 标签的详细数据,用于判断图书/读者类型 foreach (TagAndData data in news) { OneTag tag = data.OneTag; if (tag == null) { continue; } if (tag.TagInfo != null && data.Error == null) { continue; } if (tag.Protocol == InventoryInfo.ISO14443A) { continue; } if (getTagInfo != null) { // 自动重试一次 GetTagInfoResult gettaginfo_result = null; for (int i = 0; i < 2; i++) { // gettaginfo_result = GetTagInfo(channel, tag.ReaderName, tag.UID, tag.AntennaID); gettaginfo_result = GetTagInfo(getTagInfo, tag.ReaderName, tag.UID, tag.AntennaID); if (gettaginfo_result.Value != -1) { break; } } if (gettaginfo_result.Value == -1) { setError?.Invoke("rfid", gettaginfo_result.ErrorInfo); // TODO: 是否直接在标签上显示错误文字? data.Error = gettaginfo_result.ErrorInfo; update_books.Add(data); continue; } else { if (string.IsNullOrEmpty(data.Error) == false) { data.Error = null; update_books.Add(data); } } TagInfo info = gettaginfo_result.TagInfo; // 记下来。避免以后重复再次去获取了 if (tag.TagInfo == null && info != null) { tag.TagInfo = info; taginfo_changed = true; { if (update_books.IndexOf(data) == -1) { update_books.Add(data); } } } } } // end of foreach array_changed = false; // 再次兑现添加和删除 // 兑现添加 lock (_sync_tags) { foreach (TagAndData book in new_books) { _tags.Add(book); array_changed = true; } // 兑现删除 foreach (TagAndData book in remove_books) { _tags.Remove(book); array_changed = true; } } // 再次通知变化 if (array_changed == true || taginfo_changed == true || new_books.Count > 0 || update_books.Count > 0 || remove_books.Count > 0) { notifyChanged?.Invoke(new_books, update_books, remove_books); } } #endif }
// parameters: // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo public ListTagsResult ListTags(string reader_name, string style) { InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); foreach (Reader reader in Program.Rfid.Readers) { if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, ""); if (inventory_result.Value == -1) { return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo }); } foreach (InventoryInfo info in inventory_result.Results) { var tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID }; tags.Add(tag); if (StringUtil.IsInList("getTagInfo", style)) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }
// 增加了无标签时延迟等待功能。敏捷响应 public ListTagsResult ListTags(string reader_name, string style) { if (Program.Rfid.Pause) { return new ListTagsResult { Value = -1, ErrorInfo = "RFID 功能处于暂停状态", ErrorCode = "paused" } } ; Program.Rfid.IncApiCount(); try { if (Program.Rfid.Pause) { return new ListTagsResult { Value = -1, ErrorInfo = "RFID 功能处于暂停状态", ErrorCode = "paused" } } ; string session_id = StringUtil.GetParameterByPrefix(style, "session"); TimeSpan length = TimeSpan.FromSeconds(2); ListTagsResult result = null; string current_uids = ""; DateTime start = DateTime.Now; while (DateTime.Now - start < length || result == null) { result = _listTags(reader_name, style); if (result != null && result.Results != null) { current_uids = BuildUids(result.Results); } else { current_uids = ""; } // TODO: 这里的比较应该按照 Session 来进行 // 只要本次和上次 tag 数不同,立刻就返回 if (CompareLastUids(session_id, current_uids)) { SetLastUids(session_id, current_uids); return(result); } if (result.Value == -1) { return(result); } /* * // TODO: 如果本次和上次都是 2,是否立即返回?可否先对比一下 uid,有差别再返回? * if (result.Results != null * && result.Results.Count > 0) * { * SetLastUids(current_uids); * return result; * } */ Thread.Sleep(10); } SetLastUids(session_id, current_uids); return(result); } catch (Exception ex) { return(new ListTagsResult { Value = -1, ErrorInfo = $"ListTags() 出现异常:{ex.Message}" }); } finally { Program.Rfid.DecApiCount(); } } // parameters: // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo ListTagsResult _listTags(string reader_name, string style) { InventoryResult result = new InventoryResult(); if (Program.MainForm.ErrorState != "normal") { return new ListTagsResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <OneTag> tags = new List <OneTag>(); // uid --> OneTag Hashtable uid_table = new Hashtable(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif if (Reader.MatchReaderName(reader_name, reader.Name) == false) { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, ""); if (inventory_result.Value == -1) { return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo, ErrorCode = inventory_result.ErrorCode }); } foreach (InventoryInfo info in inventory_result.Results) { OneTag tag = null; if (uid_table.ContainsKey(info.UID)) { // 重复出现的,追加 读卡器名字 tag = (OneTag)uid_table[info.UID]; tag.ReaderName += "," + reader.Name; } else { // 首次出现 tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID }; uid_table[info.UID] = tag; tags.Add(tag); } if (StringUtil.IsInList("getTagInfo", style) && tag.TagInfo == null) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }
// 增加了无标签时延迟等待功能。敏捷响应 // parameters: // style 风格。逗号间隔的字符串内容 // session:会话ID // dont_delay 不根据 session 来进行探测、延迟。也就是说确保要做一次 invetnory 并且立即返回 public ListTagsResult ListTags(string reader_name, string style) { if (Program.Rfid.Pause) { return new ListTagsResult { Value = -1, ErrorInfo = "RFID 功能处于暂停状态", ErrorCode = "paused" } } ; string lockNameList = StringUtil.GetParameterByPrefix(style, "getLockState"); if (lockNameList != null) { lockNameList = StringUtil.UnescapeString(lockNameList); } bool output_time = false; Program.Rfid.IncApiCount(); try { if (Program.Rfid.Pause) { return new ListTagsResult { Value = -1, ErrorInfo = "RFID 功能处于暂停状态", ErrorCode = "paused" } } ; // 2019/12/15 bool dont_delay = StringUtil.IsInList("dont_delay", style); string session_id = StringUtil.GetParameterByPrefix(style, "session"); if (output_time) { Program.MainForm.OutputHistory($"session start: {session_id}, reader_name={reader_name}, style={style}"); } TimeSpan length = TimeSpan.FromSeconds(2); ListTagsResult result = null; GetLockStateResult lock_result = null; string current_uids = ""; DateTime start = DateTime.Now; while (DateTime.Now - start < length || result == null) { Stopwatch watch = null; // 执行 inventory if (string.IsNullOrEmpty(reader_name) == false) { if (output_time) { watch = new Stopwatch(); } else { watch = null; } watch?.Start(); result = _listTags(reader_name, style); // testing //if (reader_name.StartsWith("M201")) // Thread.Sleep(5000); watch?.Stop(); if (output_time) { Program.MainForm.OutputHistory($"{session_id} inventory time:{watch.Elapsed.TotalSeconds}, count:{result.Results?.Count}"); } } else { if (output_time) { Program.MainForm.OutputHistory($"{session_id} inventory skipped"); } result = new ListTagsResult(); } // 执行门锁状态获取 // 目前是 1:1 次数分配 if (lockNameList != null) { if (output_time) { watch = new Stopwatch(); } else { watch = null; } watch?.Start(); lock_result = GetShelfLockState(lockNameList); watch?.Stop(); if (output_time) { Program.MainForm.OutputHistory($"{session_id} getLockState time:{watch.Elapsed.TotalSeconds}, count:{lock_result.States?.Count}"); } // 从此开始 result.GetLockStateResult 就有值了 result.GetLockStateResult = lock_result; } else { if (output_time) { Program.MainForm.OutputHistory($"{session_id} getLockState skipped"); } } // 判断 inventory 结果 if (string.IsNullOrEmpty(reader_name) == false) { // 立即返回 if (dont_delay) { return(result); } if (result != null && result.Results != null) { current_uids = BuildUids(result.Results); } else { current_uids = ""; } // TODO: 这里的比较应该按照 Session 来进行 // 只要本次和上次 tag 数不同,立刻就返回 if (CompareLastUids(session_id, current_uids)) { SetLastUids(session_id, current_uids); return(result); } if (result.Value == -1) { return(result); } } // 判断门锁状态 if (lockNameList != null) { // 这里的疑问是,如果 _listTags 没有出错,是否应该坚持返回正确结果? if (lock_result.Value != -1) { string current_states = BuildStateString(lock_result.States); if (CompareLastUids(session_id + "_lock", current_states)) { SetLastUids(session_id + "_lock", current_states); return(result); } } } /* * // TODO: 如果本次和上次都是 2,是否立即返回?可否先对比一下 uid,有差别再返回? * if (result.Results != null * && result.Results.Count > 0) * { * SetLastUids(current_uids); * return result; * } */ Thread.Sleep(10); // 10? 200? } SetLastUids(session_id, current_uids); return(result); } catch (Exception ex) { return(new ListTagsResult { Value = -1, // TODO: 如何返回异常信息? ErrorInfo = $"ListTags() 出现异常:{ExceptionUtil.GetDebugText(ex)}" }); } finally { Program.Rfid.DecApiCount(); } } //static uint _currenAntenna = 1; //DateTime _lastTime; // parameters: // reader_name_list 读卡器名字列表。形态为 "*" 或 "name1,name2" 或 "name1:1|2|3|4,name2" // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo ListTagsResult _listTags(string reader_name_list, string style) { InventoryResult result = new InventoryResult(); if (Program.MainForm.ErrorState != "normal") { return new ListTagsResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <OneTag> tags = new List <OneTag>(); // uid --> OneTag Hashtable uid_table = new Hashtable(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif // 顺便要从 reader_name_list 中解析出天线部分 if (Reader.MatchReaderName(reader_name_list, reader.Name, out string antenna_list) == false) { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, antenna_list, style // "" ); if (inventory_result.Value == -1) { return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo, ErrorCode = inventory_result.ErrorCode }); } foreach (InventoryInfo info in inventory_result.Results) { OneTag tag = null; if (uid_table.ContainsKey(info.UID)) { // 重复出现的,追加 读卡器名字 tag = (OneTag)uid_table[info.UID]; tag.ReaderName += "," + reader.Name; } else { // 首次出现 tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID, AntennaID = info.AntennaID, // 2019/9/25 // InventoryInfo = info // 有些冗余的字段 }; /* * // testing * tag.AntennaID = _currenAntenna; * if (DateTime.Now - _lastTime > TimeSpan.FromSeconds(5)) * { * _currenAntenna++; * if (_currenAntenna > 50) * _currenAntenna = 1; * _lastTime = DateTime.Now; * } */ uid_table[info.UID] = tag; tags.Add(tag); } if (StringUtil.IsInList("getTagInfo", style) && tag.TagInfo == null) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }
// parameters: // one_reader_name 不能用通配符 // tag_type 如果 uid 为空,则 tag_type 应为 RFIDLIB.rfidlib_def.RFID_ISO15693_PICC_ICODE_SLI_ID // result.Value // -1 // 0 public GetTagInfoResult GetTagInfo(// byte[] uid, UInt32 tag_type string one_reader_name, InventoryInfo info, string style = "") { NormalResult result = GetReader(one_reader_name, out Reader reader); if (result.Value == -1) { return(new GetTagInfoResult(result)); } bool quick = StringUtil.IsInList("quick", style); // 锁定一个读卡器 LockReader(reader); try { #if DEBUG if (info != null) { Debug.Assert(info.UID.Length >= 8 || info.UID.Length == 0); } #endif // 2019/9/27 // 选择天线 int antenna_id = -1; // -1 表示尚未使用 if (info != null && reader.AntennaCount > 1) { antenna_id = (int)info.AntennaID; /* * var hr = rfidlib_reader.RDR_SetAcessAntenna(reader.ReaderHandle, * (byte)info.AntennaID); * if (hr != 0) * { * return new GetTagInfoResult * { * Value = -1, * ErrorInfo = $"4 RDR_SetAcessAntenna() error. hr:{hr},reader_name:{reader.Name},antenna_id:{info.AntennaID}", * ErrorCode = GetErrorCode(hr, reader.ReaderHandle) * }; * } */ } // 2019/11/20 if (info != null && info.UID == "00000000") { return(new GetTagInfoResult()); } var tagInfo = FindTagInfo(info?.UID, reader.Name); if (tagInfo == null) { return new GetTagInfoResult { Value = -1, ErrorInfo = "connectTag Error" } } ; #if NO UIntPtr hTag = _connectTag( reader.ReaderHandle, info?.UID, info == null ? RFIDLIB.rfidlib_def.RFID_ISO15693_PICC_ICODE_SLI_ID : info.TagType); if (hTag == UIntPtr.Zero) { return new GetTagInfoResult { Value = -1, ErrorInfo = "connectTag Error" } } ; #endif try { #if NO int iret; Byte[] uid = new Byte[8]; if (info != null && string.IsNullOrEmpty(info.UID) == false) { uid = Element.FromHexString(info.UID); //Debug.Assert(info.UID.Length >= 8); //Array.Copy(info.UID, uid, uid.Length); } Byte dsfid, afi, icref; UInt32 blkSize, blkNum; dsfid = afi = icref = 0; blkSize = blkNum = 0; iret = RFIDLIB.rfidlib_aip_iso15693.ISO15693_GetSystemInfo( reader.ReaderHandle, hTag, uid, ref dsfid, ref afi, ref blkSize, ref blkNum, ref icref); if (iret != 0) { return new GetTagInfoResult { Value = -1, ErrorInfo = $"ISO15693_GetSystemInfo() error 2. iret:{iret},reader_name:{one_reader_name},uid:{Element.GetHexString(uid)},antenna_id:{antenna_id}", ErrorCode = GetErrorCode(iret, reader.ReaderHandle) } } ; ReadBlocksResult result0 = ReadBlocks( reader.ReaderHandle, hTag, 0, blkNum, blkSize, true); if (result0.Value == -1) { return new GetTagInfoResult { Value = -1, ErrorInfo = $"{result0.ErrorInfo},antenna_id:{antenna_id}", ErrorCode = result0.ErrorCode } } ; NormalResult eas_result = new NormalResult(); if (quick == false) { eas_result = CheckEAS(reader.ReaderHandle, hTag); if (eas_result.Value == -1) { return new GetTagInfoResult { Value = -1, ErrorInfo = eas_result.ErrorInfo, ErrorCode = eas_result.ErrorCode } } ; } GetTagInfoResult result1 = new GetTagInfoResult { TagInfo = new TagInfo { // 这里返回真正 GetTagInfo 成功的那个 ReaderName。而 Inventory 可能返回类似 reader1,reader2 这样的字符串 ReaderName = one_reader_name, // 2019/2/27 UID = Element.GetHexString(uid), AFI = afi, DSFID = dsfid, BlockSize = blkSize, MaxBlockCount = blkNum, IcRef = icref, LockStatus = result0.LockStatus, // TagInfo.GetLockString(block_status), Bytes = result0.Bytes, EAS = eas_result.Value == 1, // AntennaID = info == null ? 0 : info.AntennaID // 2019/11/20 AntennaID = (uint)(antenna_id == -1 ? 0 : antenna_id), } }; return(result1); #endif return(new GetTagInfoResult { TagInfo = tagInfo }); } finally { #if NO _disconnectTag(reader.ReaderHandle, ref hTag); if (quick == false) { // 2019/11/18 尝试关闭射频 RFIDLIB.rfidlib_reader.RDR_CloseRFTransmitter(reader.ReaderHandle); } #endif } } finally { UnlockReader(reader); } }
private void ToolStripMenuItem_testWriteContentToNewChip_Click(object sender, EventArgs e) { #if NO // 准备好一个芯片内容 byte[] data = Element.FromHexString( @"91 00 05 1c be 99 1a 14 02 01 d0 14 02 04 b3 46 07 44 1c b6 e2 e3 35 d6 83 02 07 ac c0 9e ba a0 6f 6b 00 00" ); // 测试 BlockRange.GetBlockRanges() List <BlockRange> ranges = BlockRange.GetBlockRanges( data, "ll....lll", 4); Debug.Assert(ranges[0].BlockCount == 2); Debug.Assert(ranges[0].Locked == true); Debug.Assert(ranges[0].Bytes.SequenceEqual( Element.FromHexString( @"91 00 05 1c be 99 1a 14" ) )); Debug.Assert(ranges[1].BlockCount == 4); Debug.Assert(ranges[1].Locked == false); Debug.Assert(ranges[1].Bytes.SequenceEqual( Element.FromHexString( @"02 01 d0 14 02 04 b3 46 07 44 1c b6 e2 e3 35 d6" ) )); Debug.Assert(ranges[2].BlockCount == 3); Debug.Assert(ranges[2].Locked == true); Debug.Assert(ranges[2].Bytes.SequenceEqual( Element.FromHexString( @"83 02 07 ac c0 9e ba a0 6f 6b 00 00" ) )); #endif GetTagInfoResult result = _driver.GetTagInfo(GetCurrentReaderName(), null); MessageBox.Show(this, "初始芯片内容: " + result.ToString()); TagInfo new_chip = result.TagInfo.Clone(); new_chip.Bytes = Element.FromHexString( @"91 00 05 1c be 99 1a 14 02 01 d0 14 02 04 b3 46 07 44 1c b6 e2 e3 35 d6 83 02 07 ac c0 9e ba a0 6f 6b 00 00"); new_chip.LockStatus = "ww....www"; NormalResult write_result = _driver.WriteTagInfo(GetCurrentReaderName(), result.TagInfo, new_chip); MessageBox.Show(this, write_result.ToString()); }
// parameters: // reader_name_list 读卡器名字列表。形态为 "*" 或 "name1,name2" 或 "name1:1|2|3|4,name2" // style 如果为 "getTagInfo",表示要在结果中返回 TagInfo ListTagsResult _listTags(string reader_name_list, string style) { InventoryResult result = new InventoryResult(); if (Program.MainForm.ErrorState != "normal") { return new ListTagsResult { Value = -1, ErrorInfo = $"{Program.MainForm.ErrorStateInfo}", ErrorCode = $"state:{Program.MainForm.ErrorState}" } } ; List <OneTag> tags = new List <OneTag>(); // uid --> OneTag Hashtable uid_table = new Hashtable(); foreach (Reader reader in Program.Rfid.Readers) { #if NO if (reader_name == "*" || reader.Name == reader_name) { } else { continue; } #endif // 顺便要从 reader_name_list 中解析出天线部分 if (Reader.MatchReaderName(reader_name_list, reader.Name, out string antenna_list) == false) { continue; } InventoryResult inventory_result = Program.Rfid.Inventory(reader.Name, antenna_list, style // "" ); /* * // testing * inventory_result.Value = -1; * inventory_result.ErrorInfo = "模拟 inventory 出错"; * inventory_result.ErrorCode = "test"; */ if (inventory_result.Value == -1) { // TODO: 统计单位时间内出错的总数,如果超过一定限度则重新初始化全部读卡器 _ = _compactLog.Add("inventory 出错: {0}", new object[] { inventory_result.ErrorInfo }); _inventoryErrorCount++; // 每隔一段时间写入日志一次 if (DateTime.Now - _lastCompactTime > _compactLength) { _compactLog?.WriteToLog((text) => { Log.Logger.Error(text); Program.MainForm.OutputHistory(text, 2); }); _lastCompactTime = DateTime.Now; if (_inventoryErrorCount > 10) { // 发出信号,重启 Program.MainForm.RestartRfidDriver($"因最近阶段内 inventory 出错次数为 {_inventoryErrorCount}"); _inventoryErrorCount = 0; } } return(new ListTagsResult { Value = -1, ErrorInfo = inventory_result.ErrorInfo, ErrorCode = inventory_result.ErrorCode }); } foreach (InventoryInfo info in inventory_result.Results) { OneTag tag = null; if (uid_table.ContainsKey(info.UID)) { // 重复出现的,追加 读卡器名字 tag = (OneTag)uid_table[info.UID]; tag.ReaderName += "," + reader.Name; } else { // 首次出现 tag = new OneTag { Protocol = info.Protocol, ReaderName = reader.Name, UID = info.UID, DSFID = info.DsfID, AntennaID = info.AntennaID, // 2019/9/25 // InventoryInfo = info // 有些冗余的字段 }; /* * // testing * tag.AntennaID = _currenAntenna; * if (DateTime.Now - _lastTime > TimeSpan.FromSeconds(5)) * { * _currenAntenna++; * if (_currenAntenna > 50) * _currenAntenna = 1; * _lastTime = DateTime.Now; * } */ uid_table[info.UID] = tag; tags.Add(tag); } if (StringUtil.IsInList("getTagInfo", style) && tag.TagInfo == null) { // TODO: 这里要利用 Hashtable 缓存 GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { tag.TagInfo = null; // TODO: 如何报错?写入操作历史? // $"读取标签{info.UID}信息时出错:{result0.ToString()}" } else { tag.TagInfo = result0.TagInfo; } } #if NO GetTagInfoResult result0 = Program.Rfid.GetTagInfo(reader.Name, info); if (result0.Value == -1) { // TODO: 如何报错?写入操作历史? Program.MainForm.OutputText($"读取标签{info.UID}信息时出错:{result0.ToString()}", 2); continue; } LogicChip chip = LogicChip.From(result0.TagInfo.Bytes, (int)result0.TagInfo.BlockSize, "" // result0.TagInfo.LockStatus ); Element pii = chip.FindElement(ElementOID.PII); if (pii == null) { Program.MainForm.Invoke((Action)(() => { // 发送 UID SendKeys.SendWait($"uid:{info.UID}\r"); })); } else { Program.MainForm.Invoke((Action)(() => { // 发送 PII SendKeys.SendWait($"pii:{pii.Text}\r"); })); } #endif } } return(new ListTagsResult { Results = tags }); #if NO InventoryResult result = new InventoryResult(); List <OneTag> tags = new List <OneTag>(); _lockTagList.EnterReadLock(); try { foreach (OneTag tag in _tagList) { if (reader_name == "*" || tag.ReaderName == reader_name) { tags.Add(tag); } } return(new ListTagsResult { Results = tags }); } finally { _lockTagList.ExitReadLock(); } #endif }