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"); })); }
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 修改为红色背景,表示出错的状态 })); }
public static OneTag BuildOne15693Tag(string readerName, uint antennaID, string uid) { OneTag tag = new OneTag(); tag.Protocol = InventoryInfo.ISO15693; tag.ReaderName = readerName; tag.AntennaID = antennaID; tag.UID = uid; return(tag); }
private void listView1_SelectedIndexChanged(object sender, EventArgs e) { if (this.listView1.SelectedItems.Count > 0) { this.SelectedTag = (OneTag)this.listView1.SelectedItems[0].Tag; this.button_OK.Enabled = true; } else { this.SelectedTag = null; this.button_OK.Enabled = false; } }
public static TagInfo BuildOne15693TagInfo(OneTag tag) { TagInfo info = new TagInfo(); info.ReaderName = tag.ReaderName; info.AntennaID = tag.AntennaID; info.UID = tag.UID; // 每个块内包含的字节数 info.BlockSize = 4; // 块最大总数 info.MaxBlockCount = 28; info.Bytes = BuildBytes(4, 28, "0000001"); return(info); }
// 根据读卡器名字和标签 UID 找到已有的 ListViewItem 对象 static ListViewItem FindItem(ListView list, string reader_name, string uid) { foreach (ListViewItem item in list.Items) { OneTag tag = (OneTag)item.Tag; if (tag.ReaderName == reader_name && tag.UID == uid) { return(item); } } return(null); }
private void listView_tags_SelectedIndexChanged(object sender, EventArgs e) { if (this.listView_tags.SelectedItems.Count == 1) { ItemInfo item_info = (ItemInfo)this.listView_tags.SelectedItems[0].Tag; OneTag tag = item_info.OneTag; // var tag_info = tag.TagInfo; this.SelectedTag = tag; this.button_OK.Enabled = true; this.chipEditor1.LogicChipItem = item_info.LogicChipItem; if (string.IsNullOrEmpty(item_info.Xml) == false) { BookItem book_item = new BookItem(); int nRet = book_item.SetData("", item_info.Xml, null, out string strError); if (nRet == -1) { // 如何报错? } else { this.propertyGrid_record.SelectedObject = book_item; } } else { this.propertyGrid_record.SelectedObject = null; } } else { this.chipEditor1.LogicChipItem = null; this.propertyGrid_record.SelectedObject = null; this.SelectedTag = null; this.button_OK.Enabled = false; } }
static bool IsEqual(OneTag tag1, OneTag tag2, bool compare_tagInfo = true) { if (tag1.Protocol != tag2.Protocol) { return(false); } if (tag1.UID != tag2.UID) { return(false); } if (tag1.ReaderName != tag2.ReaderName) { return(false); } if (tag1.AntennaID != tag2.AntennaID) { return(false); } if (tag1.DSFID != tag2.DSFID) { return(false); } if (compare_tagInfo) { if (tag1.TagInfo == null && tag2.TagInfo == null) { } else { if (IsEqual(tag1.TagInfo, tag2.TagInfo) == false) { return(false); } } } return(true); }
bool AddToTagList(string reader_name, string uid, byte dsfid, string protocol) { OneTag tag = FindTag(uid); if (tag != null) { return(false); } _lockTagList.EnterWriteLock(); try { tag = new OneTag { Protocol = protocol, ReaderName = reader_name, UID = uid, LastActive = DateTime.Now, DSFID = dsfid }; tag.LastActive = DateTime.Now; _tagList.Add(tag); } finally { _lockTagList.ExitWriteLock(); } // 触发通知动作 // TODO: 通知以后,最好把标签内容信息给存储起来,这样 Inventory 的时候可以直接使用 if (_sendKeyEnabled.Value == true) { Notify(tag.ReaderName, tag.UID, tag.Protocol); } return(true); }
// TODO: 维持一个 UID --> typeOfUsage 的对照表,加快对图书和读者类型标签的分离判断过程 // UID --> typeOfUsage string // static Hashtable _typeTable = new Hashtable(); // TODO: 可以把 readerNameList 先 Parse 到一个结构来加快 match 速度 static bool InRange(OneTag tag, string readerNameList) { // 匹配读卡器名字 var ret = Reader.MatchReaderName(readerNameList, tag.ReaderName, out string antenna_list); if (ret == false) { return(false); } var list = GetAntennaList(antenna_list); // 2019/12/19 // 如果列表为空,表示不指定天线编号,所以任何 data 都是匹配命中的 // RL8600 默认天线编号为 0;M201 默认天线编号为 1。列表为空的情况表示不指定天线编号有助于处理好这两种不同做法的读写器 if (list.Count == 0) { return(true); } if (list.IndexOf(tag.AntennaID) != -1) { return(true); } return(false); // ret is bug!!! }
// 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 }
// 第一阶段:填充 UID 和 PII // parameters: // new_entities 返回本次新增的部分 Entity。调用前如果为 null,则表示不希望返回信息 // return: // 是否发生了变动 public bool Refresh(List <OneTag> tags, ref List <Entity> new_entities) { bool changed = false; List <Entity> need_delete = new List <Entity>(); foreach (Entity entity in this) { OneTag tag = tags.Find((o) => { if (o.UID == entity.UID) { return(true); } return(false); }); if (tag == null) { // 多出来的,需要删除 need_delete.Add(entity); } else { // 已经存在的 tags.Remove(tag); } } // 删除 foreach (Entity entity in need_delete) { this.Remove(entity); changed = true; } // 新添加 foreach (OneTag tag in tags) { string pii = ""; if (tag.TagInfo != null) { LogicChip chip = LogicChip.From(tag.TagInfo.Bytes, (int)tag.TagInfo.BlockSize, "" // tag.TagInfo.LockStatus ); pii = chip.FindElement(ElementOID.PII)?.Text; } else { // 尝试重新获取一次 } Entity entity = new Entity { TagInfo = tag.TagInfo, UID = tag.UID, PII = pii, Container = this, }; this.Add(entity); changed = true; if (new_entities != null) { new_entities.Add(entity); } } return(changed); }
public static void Refresh(BaseChannel <IRfid> channel, List <OneTag> list, delegate_notifyChanged notifyChanged, delegate_setError setError) { setError?.Invoke("rfid", null); List <TagAndData> new_books = new List <TagAndData>(); List <TagAndData> new_patrons = new List <TagAndData>(); List <TagAndData> error_books = new List <TagAndData>(); List <TagAndData> error_patrons = new List <TagAndData>(); // 从当前列表中发现已有的图书。用于交叉运算 List <TagAndData> found_books = new List <TagAndData>(); // 从当前列表中发现已有的读者。用于交叉运算 List <TagAndData> found_patrons = new List <TagAndData>(); foreach (OneTag tag in list) { // 检查以前的列表中是否已经有了 var book = FindBookTag(tag.UID); if (book != null) { found_books.Add(book); if (string.IsNullOrEmpty(book.Error) == false) { error_books.Add(book); } continue; } var patron = FindPatronTag(tag.UID); if (patron != null) { found_patrons.Add(patron); if (string.IsNullOrEmpty(patron.Error) == false) { error_patrons.Add(patron); } continue; } // ISO14443A 的一律当作读者证卡 if (tag.Protocol == InventoryInfo.ISO14443A) { patron = new TagAndData { OneTag = tag, Type = "patron" }; new_patrons.Add(patron); } else { // 根据缓存的 typeOfUsage 来判断 string typeOfUsage = (string)_typeTable[tag.UID]; if (typeOfUsage != null && typeOfUsage.StartsWith("8")) { patron = new TagAndData { OneTag = tag, Type = "patron" }; new_patrons.Add(patron); found_books.Remove(patron); } else { // ISO15693 的则先添加到 _books 中。等类型判断完成,有可能还要调整到 _patrons 中 book = new TagAndData { OneTag = tag }; new_books.Add(book); } } } List <TagAndData> remove_books = new List <TagAndData>(); List <TagAndData> remove_patrons = new List <TagAndData>(); // 交叉运算 foreach (TagAndData book in _books) { if (found_books.IndexOf(book) == -1) { remove_books.Add(book); } } foreach (TagAndData patron in _patrons) { if (found_patrons.IndexOf(patron) == -1) { remove_patrons.Add(patron); } } bool array_changed = false; // 兑现添加 lock (_sync_books) { foreach (TagAndData book in new_books) { if (_books.IndexOf(book) == -1) { _books.Add(book); array_changed = true; } } // 兑现删除 foreach (TagAndData book in remove_books) { _books.Remove(book); array_changed = true; } } lock (_sync_patrons) { foreach (TagAndData patron in new_patrons) { if (_patrons.IndexOf(patron) == -1) { _patrons.Add(patron); array_changed = true; } } foreach (TagAndData patron in remove_patrons) { _patrons.Remove(patron); array_changed = true; } } // 通知一次变化 if (array_changed || new_books.Count > 0 || remove_books.Count > 0 || new_patrons.Count > 0 || remove_patrons.Count > 0) // 2019/8/15 优化 { notifyChanged(new_books, null, remove_books, new_patrons, null, remove_patrons); } // 需要获得 Tag 详细信息的。注意还应当包含以前出错的 Tag //List<TagAndData> news = new_books; // news.AddRange(error_books); List <TagAndData> news = new List <TagAndData>(); news.AddRange(_books); news.AddRange(new_patrons); new_books = new List <TagAndData>(); remove_books = new List <TagAndData>(); new_patrons = new List <TagAndData>(); remove_patrons = new List <TagAndData>(); // .TagInfo 是否发生过填充 bool taginfo_changed = false; { List <TagAndData> update_books = new List <TagAndData>(); List <TagAndData> update_patrons = 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; } { var gettaginfo_result = GetTagInfo(channel, tag.UID); if (gettaginfo_result.Value == -1) { setError?.Invoke("rfid", gettaginfo_result.ErrorInfo); // TODO: 是否直接在标签上显示错误文字? data.Error = gettaginfo_result.ErrorInfo; if (data.Type == "patron") { update_patrons.Add(data); } else { update_books.Add(data); } continue; } else { if (string.IsNullOrEmpty(data.Error) == false) { data.Error = null; if (data.Type == "patron") { update_patrons.Add(data); } else { update_books.Add(data); } } } TagInfo info = gettaginfo_result.TagInfo; // 记下来。避免以后重复再次去获取了 if (tag.TagInfo == null) { tag.TagInfo = info; taginfo_changed = true; } // 观察 typeOfUsage 元素 var chip = LogicChip.From(info.Bytes, (int)info.BlockSize, ""); string typeOfUsage = chip.FindElement(ElementOID.TypeOfUsage)?.Text; // 分离 ISO15693 图书标签和读者卡标签 if (string.IsNullOrEmpty(data.Type)) { if (typeOfUsage != null && typeOfUsage.StartsWith("8")) { // 需要调整到 _patrons 中 data.Type = "patron"; // 删除列表? 同时添加列表 remove_books.Add(data); update_books.Remove(data); // 容错 new_patrons.Add(data); } else { data.Type = "book"; update_books.Add(data); update_patrons.Remove(data); } // 保存到缓存 if (typeOfUsage != null) { if (_typeTable.Count > 1000) { _typeTable.Clear(); } _typeTable[data.OneTag.UID] = typeOfUsage; } } } } // end of foreach array_changed = false; // 再次兑现添加和删除 // 兑现添加 lock (_sync_books) { foreach (TagAndData book in new_books) { _books.Add(book); array_changed = true; } // 兑现删除 foreach (TagAndData book in remove_books) { _books.Remove(book); array_changed = true; } } lock (_sync_patrons) { foreach (TagAndData patron in new_patrons) { _patrons.Add(patron); array_changed = true; } foreach (TagAndData patron in remove_patrons) { _patrons.Remove(patron); array_changed = true; } } // 再次通知变化 if (array_changed == true || taginfo_changed == true || new_books.Count > 0 || update_books.Count > 0 || remove_books.Count > 0 || new_patrons.Count > 0 || update_patrons.Count > 0 || remove_patrons.Count > 0) // 2019/8/15 优化 { notifyChanged(new_books, update_books, remove_books, new_patrons, update_patrons, remove_patrons); } } }
// 增加了无标签时延迟等待功能。敏捷响应 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 }
// 装入以前的标签信息 // 如果读卡器上有多个标签,则出现对话框让从中选择一个。列表中和右侧 PII 相同的,优先被选定 // parameters: // strStyle 操作方式 // auto_close_dialog 是否要自动关闭选择对话框。条件是选中了 auto_select_pii 事项 // adjust_right 是否自动调整右侧元素。即,把左侧的锁定状态元素覆盖到右侧。调整前要询问。如果不同意调整,可以放弃,然后改为放一个空白标签并装载保存 // saving 是否为了保存而装载?如果是,有些提示要改变 // return: // -1 出错 // 0 放弃装载 // 1 成功装载 int LoadOldChip( string auto_select_pii, string strStyle, #if NO bool auto_close_dialog, bool adjust_right, #endif out string strError) { strError = ""; bool auto_close_dialog = StringUtil.IsInList("auto_close_dialog", strStyle); bool adjust_right = StringUtil.IsInList("adjust_right", strStyle); bool saving = StringUtil.IsInList("saving", strStyle); try { REDO: // 出现对话框让选择一个 // SelectTagDialog dialog = new SelectTagDialog(); RfidToolForm dialog = new RfidToolForm(); dialog.Text = "选择 RFID 标签"; dialog.OkCancelVisible = true; dialog.LayoutVertical = false; dialog.AutoCloseDialog = auto_close_dialog; dialog.SelectedPII = auto_select_pii; dialog.AutoSelectCondition = "auto_or_blankPII"; // 2019/1/30 Program.MainForm.AppInfo.LinkFormState(dialog, "selectTagDialog_formstate"); dialog.ShowDialog(this); if (dialog.DialogResult == DialogResult.Cancel) { strError = "放弃装载 RFID 标签内容"; return(0); } if (auto_close_dialog == false // && string.IsNullOrEmpty(auto_select_pii) == false && dialog.SelectedPII != auto_select_pii && string.IsNullOrEmpty(dialog.SelectedPII) == false ) { string message = $"您所选择的标签其 PII 为 '{dialog.SelectedPII}',和期待的 '{auto_select_pii}' 不吻合。请小心检查是否正确。\r\n\r\n是否重新选择?\r\n\r\n[是]重新选择 RFID 标签;\r\n[否]将这一种不吻合的 RFID 标签装载进来\r\n[取消]放弃装载"; if (saving) { message = $"您所选择的标签其 PII 为 '{dialog.SelectedPII}',和期待的 '{auto_select_pii}' 不吻合。请小心检查是否正确。\r\n\r\n是否重新选择?\r\n\r\n[是]重新选择 RFID 标签;\r\n[否]将信息覆盖保存到这一种不吻合的 RFID 标签中(危险)\r\n[取消]放弃保存"; } DialogResult temp_result = MessageBox.Show(this, message, "EntityEditForm", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (temp_result == DialogResult.Yes) { goto REDO; } if (temp_result == DialogResult.Cancel) { strError = "放弃装载 RFID 标签内容"; return(0); } if (saving == false) { MessageBox.Show(this, "警告:您刚装入了一个可疑的标签,极有可能不是当前册对应的标签。待会儿保存标签内容的时候,有可能会张冠李戴覆盖了它。保存标签内容前,请务必反复仔细检查"); } } var tag_info = dialog.SelectedTag.TagInfo; _tagExisting = dialog.SelectedTag; var chip = LogicChipItem.FromTagInfo(tag_info); this.chipEditor_existing.LogicChipItem = chip; if (adjust_right) { int nRet = Merge(this.chipEditor_existing.LogicChipItem, this.chipEditor_editing.LogicChipItem, out strError); if (nRet == -1) { return(-1); } // 让右侧编辑器感受到 readonly 和 text 的变化 var save = this.chipEditor_editing.LogicChipItem; this.chipEditor_editing.LogicChipItem = null; this.chipEditor_editing.LogicChipItem = save; } return(1); } catch (Exception ex) { strError = "出现异常: " + ex.Message; return(-1); } }
// 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 }
// 增加了无标签时延迟等待功能。敏捷响应 // 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: // 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 }
// 装入以前的标签信息 // 如果读卡器上有多个标签,则出现对话框让从中选择一个。列表中和右侧 PII 相同的,优先被选定 // parameters: // strStyle 操作方式 // auto_close_dialog 是否要自动关闭选择对话框。条件是选中了 auto_select_pii 事项 // adjust_right 是否自动调整右侧元素。即,把左侧的锁定状态元素覆盖到右侧。调整前要询问。如果不同意调整,可以放弃,然后改为放一个空白标签并装载保存 // saving 是否为了保存而装载?如果是,有些提示要改变 // return: // -1 出错 // 0 放弃装载 // 1 成功装载 int LoadOldChip( string auto_select_pii, string strStyle, out string strError) { strError = ""; bool auto_close_dialog = StringUtil.IsInList("auto_close_dialog", strStyle); bool adjust_right = StringUtil.IsInList("adjust_right", strStyle); bool saving = StringUtil.IsInList("saving", strStyle); try { REDO: // 出现对话框让选择一个 // SelectTagDialog dialog = new SelectTagDialog(); using (RfidToolForm dialog = new RfidToolForm()) { dialog.Text = "选择 RFID 读者卡"; dialog.OkCancelVisible = true; dialog.LayoutVertical = false; dialog.AutoCloseDialog = auto_close_dialog; dialog.SelectedPII = auto_select_pii; dialog.AutoSelectCondition = "auto_or_blankPII"; // 2019/1/30 dialog.ProtocolFilter = InventoryInfo.ISO15693; Program.MainForm.AppInfo.LinkFormState(dialog, "selectTagDialog_formstate"); dialog.ShowDialog(this); if (dialog.DialogResult == DialogResult.Cancel) { strError = "放弃装载 RFID 读者卡内容"; return(0); } { var old_chip = LogicChipItem.FromTagInfo(dialog.SelectedTag.TagInfo); // 首先检查 typeOfUsage 是否为 8X if (old_chip.IsBlank() == false && IsPatronUsage(old_chip) == false) { strError = "当前 RFID 标签是图书类型,不是读者卡类型。请小心不要弄混这两种类型"; string message = $"您所选择的 RFID 标签是图书类型,不是读者卡类型。请小心不要弄混这两种类型。\r\n\r\n是否重新选择?\r\n\r\n[是]重新选择 RFID 读者卡;\r\n[否]将这一种不吻合的 RFID 标签装载进来\r\n[取消]放弃装载"; if (saving) { message = $"您所选择的 RFID 标签是图书类型,不是读者卡类型。请小心不要弄混这两种类型。\r\n\r\n是否重新选择?\r\n\r\n[是]重新选择 RFID 读者卡;\r\n[否]将信息覆盖保存到这一种不吻合的 RFID 标签中(危险)\r\n[取消]放弃保存"; } DialogResult temp_result = MessageBox.Show(this, message, "RfidPatronCardDialog", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (temp_result == DialogResult.Yes) { goto REDO; } if (temp_result == DialogResult.Cancel) { strError = "放弃装载 RFID 读者卡内容"; return(0); } if (saving == false) { MessageBox.Show(this, "警告:您刚装入了一个可疑的读者卡,极有可能不是读者卡而是图书 RFID 标签。待会儿保存读者卡内容的时候,有可能会张冠李戴覆盖了它。保存读者卡内容前,请务必反复仔细检查"); } } } if (auto_close_dialog == false // && string.IsNullOrEmpty(auto_select_pii) == false && dialog.SelectedPII != auto_select_pii && string.IsNullOrEmpty(dialog.SelectedPII) == false ) { string message = $"您所选择的读者卡其 PII 为 '{dialog.SelectedPII}',和期待的 '{auto_select_pii}' 不吻合。请小心检查是否正确。\r\n\r\n是否重新选择?\r\n\r\n[是]重新选择 RFID 读者卡;\r\n[否]将这一种不吻合的 RFID 读者卡装载进来\r\n[取消]放弃装载"; if (saving) { message = $"您所选择的读者卡其 PII 为 '{dialog.SelectedPII}',和期待的 '{auto_select_pii}' 不吻合。请小心检查是否正确。\r\n\r\n是否重新选择?\r\n\r\n[是]重新选择 RFID 读者卡;\r\n[否]将信息覆盖保存到这一种不吻合的 RFID 读者卡中(危险)\r\n[取消]放弃保存"; } DialogResult temp_result = MessageBox.Show(this, message, "RfidPatronCardDialog", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1); if (temp_result == DialogResult.Yes) { goto REDO; } if (temp_result == DialogResult.Cancel) { strError = "放弃装载 RFID 读者卡内容"; return(0); } if (saving == false) { MessageBox.Show(this, "警告:您刚装入了一个可疑的读者卡,极有可能不是当前读者记录对应的读者卡。待会儿保存读者卡内容的时候,有可能会张冠李戴覆盖了它。保存读者卡内容前,请务必反复仔细检查"); } } var tag_info = dialog.SelectedTag.TagInfo; _tagExisting = dialog.SelectedTag; var chip = LogicChipItem.FromTagInfo(tag_info); this.chipEditor_existing.LogicChipItem = chip; if (adjust_right) { int nRet = Merge(this.chipEditor_existing.LogicChipItem, this.chipEditor_editing.LogicChipItem, out strError); if (nRet == -1) { return(-1); } // 让右侧编辑器感受到 readonly 和 text 的变化 var save = this.chipEditor_editing.LogicChipItem; this.chipEditor_editing.LogicChipItem = null; this.chipEditor_editing.LogicChipItem = save; } return(1); } } catch (Exception ex) { strError = "出现异常: " + ex.Message; return(-1); } }
// 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 }