// parameters: // one_reader_name 不能用通配符 // style randomizeEasAfiPassword public NormalResult WriteTagInfo(// byte[] uid, UInt32 tag_type string one_reader_name, TagInfo old_tag_info, TagInfo new_tag_info //, // string style ) { StringBuilder debugInfo = new StringBuilder(); debugInfo.AppendLine($"WriteTagInfo() one_reader_name={one_reader_name}"); debugInfo.AppendLine($"old_tag_info={old_tag_info.ToString()}"); debugInfo.AppendLine($"new_tag_info={new_tag_info.ToString()}"); WriteDebugLog(debugInfo.ToString()); // 要确保 new_tag_info.Bytes 包含全部 byte,避免以前标签的内容在保存后出现残留 EnsureBytes(new_tag_info); EnsureBytes(old_tag_info); NormalResult result = GetReader(one_reader_name, out Reader reader); if (result.Value == -1) { return(result); } // 锁定一个读卡器 LockReader(reader); try { // TODO: 选择天线 // 2019/9/27 // 选择天线 if (reader.AntennaCount > 1) { /* * var hr = rfidlib_reader.RDR_SetAcessAntenna(reader.ReaderHandle, * (byte)old_tag_info.AntennaID); * if (hr != 0) * { * return new GetTagInfoResult * { * Value = -1, * ErrorInfo = $"3 RDR_SetAcessAntenna() error. hr:{hr},reader_name:{reader.Name},antenna_id:{old_tag_info.AntennaID}", * ErrorCode = GetErrorCode(hr, reader.ReaderHandle) * }; * } */ } var tag = FindTag(old_tag_info.UID, reader.Name); if (tag == null) { return new NormalResult { Value = -1, ErrorInfo = "connectTag Error" } } ; var tagInfo = tag.TagInfo; /* * UInt32 tag_type = RFIDLIB.rfidlib_def.RFID_ISO15693_PICC_ICODE_SLI_ID; * UIntPtr hTag = _connectTag(reader.ReaderHandle, old_tag_info.UID, tag_type); * if (hTag == UIntPtr.Zero) * return new NormalResult { Value = -1, ErrorInfo = "connectTag Error" }; */ try { // TODO: 如果是新标签,第一次执行修改密码命令 // *** 分段写入内容 bytes if (new_tag_info.Bytes != null) { // 写入时候自动跳过锁定的块 List <BlockRange> new_ranges = BlockRange.GetBlockRanges( (int)old_tag_info.BlockSize, new_tag_info.Bytes, old_tag_info.LockStatus, 'l'); // 检查要跳过的块,要对比新旧 bytes 是否完全一致。 // 不一致则说明数据修改过程有问题 { List <BlockRange> compare_ranges = BlockRange.GetBlockRanges( (int)old_tag_info.BlockSize, old_tag_info.Bytes, old_tag_info.LockStatus, 'l'); NormalResult result0 = CompareLockedBytes( compare_ranges, new_ranges); if (result0.Value == -1) { return(result0); } } int current_block_count = 0; foreach (BlockRange range in new_ranges) { if (range.Locked == false) { NormalResult result0 = TagData.WriteBlocks( tagInfo, (uint)current_block_count, (uint)range.BlockCount, range.Bytes); if (result0.Value == -1) { return new NormalResult { Value = -1, ErrorInfo = result0.ErrorInfo, ErrorCode = result0.ErrorCode } } ; } current_block_count += range.BlockCount; } } // *** 兑现锁定 'w' 状态的块 if (new_tag_info.Bytes != null) { List <BlockRange> ranges = BlockRange.GetBlockRanges( (int)old_tag_info.BlockSize, new_tag_info.Bytes, // TODO: 研究一下此参数其实应该允许为 null new_tag_info.LockStatus, 'w'); // 检查,原来的 'l' 状态的块,不应后来被当作 'w' 再次锁定 string error_info = CheckNewlyLockStatus(old_tag_info.LockStatus, new_tag_info.LockStatus); if (string.IsNullOrEmpty(error_info) == false) { return new NormalResult { Value = -1, ErrorInfo = error_info, ErrorCode = "checkTwoLockStatusError" } } ; int current_block_count = 0; foreach (BlockRange range in ranges) { if (range.Locked == true) { string error_code = TagData.LockBlocks( tagInfo, (uint)current_block_count, (uint)range.BlockCount); if (string.IsNullOrEmpty(error_code) == false) { return new NormalResult { Value = -1, ErrorInfo = "LockBlocks error", ErrorCode = error_code } } ; } current_block_count += range.BlockCount; } } // 写入 DSFID if (old_tag_info.DSFID != new_tag_info.DSFID) { tagInfo.DSFID = new_tag_info.DSFID; /* * NormalResult result0 = WriteDSFID(reader.ReaderHandle, hTag, new_tag_info.DSFID); * if (result0.Value == -1) * return result0; */ } // 写入 AFI if (old_tag_info.AFI != new_tag_info.AFI) { tagInfo.AFI = new_tag_info.AFI; /* * NormalResult result0 = WriteAFI(reader.ReaderHandle, hTag, new_tag_info.AFI); * if (result0.Value == -1) * return result0; */ } // 设置 EAS 状态 if (old_tag_info.EAS != new_tag_info.EAS) { tagInfo.EAS = new_tag_info.EAS; /* * NormalResult result0 = EnableEAS(reader.ReaderHandle, hTag, new_tag_info.EAS); * if (result0.Value == -1) * return result0; */ } tag.RefreshInventoryInfo(); return(new NormalResult()); } finally { // _disconnectTag(reader.ReaderHandle, ref hTag); } } finally { UnlockReader(reader); } }
// 根据前端发来的 tagInfo 构造一个 TagData 对象 public TagData Build(TagInfo source, string protocol = InventoryInfo.ISO15693) { // Debug.Assert(false); // testing if (this._readers.Count == 0) { throw new Exception("当前没有任何(模拟的)读卡器,因此无法添加标签信息"); } var tag = TagData.Build(source, protocol); InventoryInfo inventory = tag.InventoryInfo; TagInfo tagInfo = tag.TagInfo; // 自动生成一些成员 // inventory inventory.TagType = 0; // ??? inventory.AipID = 0; // ??? // tagInfo Reader reader = null; if (string.IsNullOrEmpty(tagInfo.ReaderName)) { // 自动取协议合适的第一个读卡器? reader = _readers.Find((r) => { return(StringUtil.IsInList(protocol, r.Protocols) == true); }); if (reader == null) { throw new Exception($"没有找到满足 '{protocol}' 协议的读卡器"); } } else { var result = GetReader(tagInfo.ReaderName, out reader); if (result.Value == -1) { throw new Exception($"读卡器 '{tagInfo.ReaderName}' 没有找到"); } Debug.Assert(reader != null); } // tagInfo.ReaderName; if (string.IsNullOrEmpty(tagInfo.ReaderName)) { Debug.Assert(string.IsNullOrEmpty(reader.Name) == false); tagInfo.ReaderName = reader.Name; } // tagInfo.UID; // 自动发生 // 8 bytes? if (string.IsNullOrEmpty(tagInfo.UID)) { tagInfo.UID = ByteArray.GetHexTimeStampString(Guid.NewGuid().ToByteArray()); } // public byte DSFID { get; set; } // public byte AFI { get; set; } // public byte IcRef { get; set; } // 每个块内包含的字节数 tagInfo.BlockSize = 4; // 设置为默认值 // 块最大总数 tagInfo.MaxBlockCount = 28; // 设置为默认值 // public bool EAS { get; set; } // tagInfo.AntennaID; // 检查是否符合范围。否则设置为第一个天线 if (tagInfo.AntennaID < reader.AntennaStart || tagInfo.AntennaID >= reader.AntennaStart + reader.AntennaCount) { tagInfo.AntennaID = (uint)reader.AntennaStart; } // 锁定状态字符串。表达每个块的锁定状态 // 例如 "ll....lll"。'l' 表示锁定,'.' 表示没有锁定。缺省为 '.'。空字符串表示全部块都没有被锁定 // LockStatus { get; set; } // 芯片全部内容字节 // Bytes { get; set; } tag.RefreshInventoryInfo(); return(tag); }