Exemple #1
0
        // 从缓存中获取标签信息
        static GetTagInfoResult GetTagInfo(delegate_getTagInfo getTagInfo,
                                           string reader_name,
                                           string uid,
                                           uint antenna)
        {
            //if (channel.Started == false)
            //    return new GetTagInfoResult { Value = -1, ErrorInfo = "RFID 通道尚未启动" };

            TagInfo info = (TagInfo)_tagTable[uid];

            if (info == null)
            {
                var result = getTagInfo(reader_name, uid, antenna);
                if (result.Value == -1)
                {
                    return(result);
                }
                info = result.TagInfo;
                if (info != null)
                {
                    if (_tagTable.Count > 1000)
                    {
                        _tagTable.Clear();
                    }
                    _tagTable[uid] = info;
                }
            }

            return(new GetTagInfoResult {
                TagInfo = info
            });
        }
Exemple #2
0
        /*
         * public static int TagTableCount
         * {
         *  get
         *  {
         *      return _tagTable.Count;
         *  }
         * }
         */

        // 获取标签信息
        static GetTagInfoResult GetTagInfo(delegate_getTagInfo getTagInfo,
                                           string reader_name,
                                           string uid,
                                           uint antenna)
        {
            var result = getTagInfo(reader_name, uid, antenna);

            if (result.Value == -1)
            {
                return(result);
            }
            var info = result.TagInfo;

            return(new GetTagInfoResult {
                TagInfo = info
            });
        }
Exemple #3
0
        // 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);
            }

            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);
                }
            }
        }