/// <summary> /// 设置读写器询查时间。读写器将会把询查命令最大响应时间改为用户给定的值 /// (3*100ms~255*100ms),以后将使用此项新的询查命令最大响应时间。出厂时 /// 缺省值是0x0a(对应的时间为10*100ms)。用户修改范围是0x03~0xff(对应时 /// 间是3*100ms~255*100ms)。注意,实际的响应时间可能会比设定值大0~75ms。 /// 当用户写入的值是0x00~0x02 时,读写器将会自动恢复成缺省值 0x0a(对应的 /// 时间为10*100ms)。 /// </summary> /// <param name="scanTime">询查时间,范围是0x03~0xff(对应时间是3*100ms~255*100ms)</param> /// <returns></returns> public async Task <InfoBase> SetInventoryTimeAsync(byte scanTime) { byte[] frame = CreateSetInventoryTimeFrame(scanTime); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 该命令用来控制LED灯和蜂鸣器按一定规律闪烁和鸣叫。 /// </summary> /// <param name="activeT">LED灯亮和蜂鸣器鸣叫时间(ActiveT*50ms),默认值为零。0 小于等于 ActiveT 小于等于 255。</param> /// <param name="silentT">LED灯和蜂鸣器静默时间(SilentT *50ms),默认值为零。0 小于等于 SilentT 小于等于 255。</param> /// <param name="times">LED灯亮和蜂鸣器鸣叫次数(0 小于等于 Times 小于等于 255) 默认值为零。</param> /// <returns></returns> public async Task <InfoBase> BuzzerAndLEDControlAsync(byte activeT, byte silentT, byte times) { byte[] frame = CreateBuzzerAndLEDControlFrame(activeT, silentT, times); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机执行该命令可以将处于Quiet状态的电子标签设置为返回“Ready状态”。 /// 该命令可以在address mode和non-address mode下运行。 /// </summary> /// <returns></returns> public async Task <InfoBase> ResetToReadyAsync() { byte[] frame = CreateResetToReadyFrame(); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机发送该命令读取电子标签中指定块的数据(4或8个字节)和安全状态信息。 /// 该命令可以在address mode和select mode下运行。 /// </summary> /// <param name="blockLen">卡的数据块所占空间的字节数,4或8</param> /// <param name="blockNum">绝对块号</param> /// <returns></returns> public async Task <ReadSingleBlockInfo> ReadSingleBlockAsync(I15693BlockLen blockLen, byte blockNum) { byte[] frame = CreateReadSingleBlockFrame(blockLen, blockNum); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { ReadSingleBlockInfo ib = new ReadSingleBlockInfo(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } ReadSingleBlockInfo info = HandleReadSingleBlockFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机执行该命令以获得电子标签的详细信息,这其中包括Information Flag,UID,DSFID,AFI,Memory,IC reference的信息。 /// </summary> /// <returns></returns> public async Task <GetSystemInformationInfo> GetSystemInformationAsync() { byte[] frame = CreateGetSystemInformationFrame(); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { GetSystemInformationInfo gii = new GetSystemInformationInfo(); gii.SendByte = frame; gii.ReturnValue = cri.ReturnValue; gii.ExceptionMessage = cri.ExceptionMessage; return(gii); } GetSystemInformationInfo info = HandleGetSystemInformationFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令用来选择频段及各频段中的上限频率,下限频率。上限频率必须大于或等于下限频率。 /// </summary> /// <param name="minFre">一个字节,Bit7-Bit6用于频段设置用;Bit5-Bit0表示读写器工作的最大频率</param> /// <param name="maxFre">一个字节,Bit7-Bit6用于频段设置用;Bit5-Bit0表示读写器工作的最小频率。最小频率必须小于等于最大频率。</param> /// <returns></returns> public async Task <InfoBase> SetFrequencyAsync(byte minFre, byte maxFre) { byte[] frame = CreateSetFrequencyFrame(minFre, maxFre); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机执行该命令锁定电子标签的数据保存格式识别码(DSFID=Data Storage Format IDentifier),DSFID一旦被锁定将不能再更改。 /// 此命令为写类型命令,不同厂商的电子标签的响应机制会有所不同,它们可分为A类和B类两大类。 /// 该命令可以在address mode和select mode下运行。 /// </summary> /// <param name="type">卡类型,A类或B类</param> /// <returns></returns> public async Task <InfoBase> LockDSFIDAsync(I15693CardType type) { byte[] frame = CreateLockDSFIDFrame(type); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令不能测试标签是否支持读保护锁定命令,只能测试标签是否被读保护锁定。对于不支持读保护锁定的电子标签,一致认为没有被锁定。 /// 这个命令只能对单张电子标签进行操作,确保天线有效范围内只存在一张电子标签。仅对NXP的UCODE EPC G2X标签有效。 /// </summary> /// <returns></returns> public async Task <CheckReadProtectedInfo> CheckReadProtectedAsync() { byte[] frame = CreateCheckReadProtectedFrame(); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { CheckReadProtectedInfo crpi = new CheckReadProtectedInfo(); crpi.SendByte = frame; crpi.ReturnValue = cri.ReturnValue; crpi.ExceptionMessage = cri.ExceptionMessage; return(crpi); } CheckReadProtectedInfo info = HandelCheckReadProtectedFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令可以为有效范围内的电子标签设定读保护。这个命令与前面一个命令的区别是,当有效范围内存在多张标签的时候,无法知道这个命令操作的是哪一张电子标签。 /// </summary> /// <param name="Pwd">4个字节的访问密码。32位的访问密码的最高位在Pwd的第一字节(从左往右)的最高位,访问密码最低位在Pwd第四字节的最低位,Pwd的前两个字节放置访问密码的高字。待设定读保护的电子标签访问密码必须不为0,访问密码为0 的电子标签是无法设置读保护的,在命令中,必须给出正确的访问密码。</param> /// <returns></returns> public async Task <InfoBase> SetMultiReadProtectAsync(byte[] Pwd) { byte[] frame = CreateSetMultiReadProtectFrame(Pwd); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 防冲突操作,必须在Request命令后立即执行。如果事先知道所需要 /// 操作的电子标签的序列号,可以越过此调用,在Request命令后直接 /// 调用Select 即可。 /// </summary> /// <param name="ml"> /// ml=MultiLable.AllowOne 不允许多张电子标签进入感应场 /// m1=MultiLable.AllowMulti 允许多张电子标签进入感应场 /// </param> /// <returns></returns> public async Task <AnticollInfo> Anticoll2Async(MultiLable ml) { byte[] frame = CreateAnticoll2Frame(ml); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { AnticollInfo ai = new AnticollInfo(); ai.SendByte = frame; ai.ReturnValue = cri.ReturnValue; ai.ExceptionMessage = cri.ExceptionMessage; return(ai); } AnticollInfo info = HandleAnticollFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// UtraLight标签防冲突操作,返回一张标签的UID。 /// </summary> /// <returns></returns> public async Task <ULAnticollInfo> ULAnticollAsync() { byte[] frame = CreateULAnticollFrame(); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { ULAnticollInfo uai = new ULAnticollInfo(); uai.SendByte = frame; uai.ReturnValue = cri.ReturnValue; uai.ExceptionMessage = cri.ExceptionMessage; return(uai); } ULAnticollInfo info = HandleULAnticollFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令向电子标签写入EPC号。写入的时候,天线有效范围内只能有一张电子标签。 /// </summary> /// <param name="ENum">1个字节。要写入的EPC的长度,以字为单位。可以为0,但不能超过15,否则返回参数错误信息。</param> /// <param name="Pwd">4个字节的访问密码。32位的访问密码的最高位在Pwd的第一字节(从左往右)的最高位,访问密码最低位在Pwd第四字节的最低位,Pwd的前两个字节放置访问密码的高字。在本命令中,当EPC区设置为密码锁、且标签访问密码为非0的时候,才需要使用访问密码。在其他情况下,Pwd为零或正确的访问密码。</param> /// <param name="WEPC">要写入的EPC号,长度必须和ENum说明的一样。WEPC最小0个字,最多15个字,否则返回参数错误信息。</param> /// <returns></returns> public async Task <InfoBase> WriteEPCAsync(byte ENum, byte[] Pwd, byte[] WEPC) { byte[] frame = CreateWriteEPCFrame(ENum, Pwd, WEPC); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 读被访问的值块,检查数据的结构,减去传输的值,然后将结果 /// 存在标签的内部寄存器中。值块有标准的格式。 /// </summary> /// <param name="blockNum">要操作的值块的绝对块号</param> /// <param name="data">要减少的值,低字节在前</param> /// <returns></returns> public async Task <InfoBase> DecrementAsync(byte blockNum, byte[] data) { byte[] frame = CreateDecrementFrame(blockNum, data); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 对标签数据区进行读写加减等操作前,必须对电子标签进行证实操作。 /// 该操作将进行标签中指定扇区的密钥与读写器密钥存储区中对应位置 /// 储存的密钥的匹配检查,若匹配,则证实成功 /// </summary> /// <param name="keyType">ISO 14443A:密钥类型,KeyA 或 KeyB</param> /// <param name="sectorNum">待证实的电子标签的扇区号,必须小于16。</param> /// <returns></returns> public async Task <InfoBase> AuthenticationAsync(KeyType keyType, byte sectorNum) { byte[] frame = CreateAuthenticationFrame(keyType, sectorNum); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 读取标签指定块的16个字节 /// </summary> /// <param name="blockNum">待读取的数据块的绝对块号</param> /// <returns></returns> public async Task <ReadInfo> ReadAsync(byte blockNum) { byte[] frame = CreateReadFrame(blockNum); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { ReadInfo ri = new ReadInfo(); ri.SendByte = frame; ri.ReturnValue = cri.ReturnValue; ri.ExceptionMessage = cri.ExceptionMessage; return(ri); } ReadInfo info = HandleReadFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机发送该命令将给定数据(4或8个字节)写入电子标签的指定数据块中。。 /// 上位机可指定的块的范围和每个块的大小会因电子标签的生产厂商的不同而有所差异。 /// 此命令为写类型命令,不同厂商的电子标签的响应机制会有所不同,它们可分为A类和B类两大类。 /// 该命令可以在address mode和select mode下运行。 /// </summary> /// <param name="type">卡类型,A类或B类</param> /// <param name="blockLen">卡的数据块所占空间的字节数,4或8</param> /// <param name="blockNum">绝对块号</param> /// <param name="data">写入的数据</param> /// <returns></returns> public async Task <InfoBase> WriteSingleBlockAsync(I15693CardType type, I15693BlockLen blockLen, byte blockNum, byte[] data) { byte[] frame = CreateWriteSingleBlockFrame(type, blockLen, blockNum, data); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 带AFI的Inventory。 /// AFI相符的电子标签才能响应,但只是返回一张电子标签的UID,并让这张电子标签进入Quiet状态 /// </summary> /// <param name="afi">类型识别码</param> /// <returns></returns> public async Task <InventoryInfo> InventoryWithAFIAsync(byte afi) { byte[] frame = CreateInventoryWithAFIFrame(afi); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InventoryInfo ii = new InventoryInfo(); ii.SendByte = frame; ii.ReturnValue = cri.ReturnValue; ii.ExceptionMessage = cri.ExceptionMessage; return(ii); } InventoryInfo info = HandleInventoryFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 不带AFI的Inventory-scan。 /// 新询查命令:在运行询查命令前,读写器会自动运行“Close RF”和“Open RF”。 /// 这样,处于感应场内的符合协议的所有电子标签均能响应,读写器会把在 /// InventoryScanTime溢出前得到的UID全部返回。 /// 继续询查命令:读写器不会对感应场进行操作,只有新进入感应场的电子标签或 /// 前面的询查命令没有得到UID的电子标签才会响应,读写器会把在 /// InventoryScanTime溢出前得到的UID返回 /// </summary> /// <param name="mode">0x06:新询查命令,0x02:继续询查命令</param> /// <returns></returns> public async Task <InventoryScanInfo> InventoryScanWithoutAFIAsync(InventoryScanWithoutAFIMode mode) { byte[] frame = CreateInventoryScanWithoutAFIFrame(mode); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InventoryScanInfo isi = new InventoryScanInfo(); isi.SendByte = frame; isi.ReturnValue = cri.ReturnValue; isi.ExceptionMessage = cri.ExceptionMessage; return(isi); } InventoryScanInfo info = HandleInventoryScanFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 将数据写入指定地址开始的读写器内部EEPROM。 /// 地址0x00~0x0F为只读区域,不能写入,0x10~0x2F为初始化数据区, /// 不要改写,0x80-0x1FF 为读写器密钥存储区,不能用该命令写入。 /// </summary> /// <param name="start">写操作的起始地址,范围0x30~0x7E;</param> /// <param name="len">写入的数据长度,必须小于20个字节;</param> /// <param name="data">要写入的数据,低字节在前。</param> /// <returns></returns> public async Task <InfoBase> WriteE2Async(byte start, byte len, byte[] data) { byte[] frame = CreateWriteE2Frame(start, len, data); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 将指定地址开始的读写器内部EEPROM的数据读出。该起始地址必须 /// 小于0x80。从0x80地址开始是读写器密钥存储区,内容不能被读出。 /// </summary> /// <param name="start">读操作的起始地址,必须小于0x80</param> /// <param name="len">被读的数据长度(小于20个字节)</param> /// <returns></returns> public async Task <ReadE2Info> ReadE2Async(byte start, byte len) { byte[] frame = CreateReadE2Frame(start, len); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { ReadE2Info rei = new ReadE2Info(); rei.SendByte = frame; rei.ReturnValue = cri.ReturnValue; rei.ExceptionMessage = cri.ExceptionMessage; return(rei); } ReadE2Info info = HandleReadE2Frame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 选择指定UID的电子标签,返回该标签的容量标志。 /// </summary> /// <param name="UID">指定的UID</param> /// <returns></returns> public async Task <SelectInfo> SelectAsync(byte[] UID) { byte[] frame = CreateSelectFrame(UID); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { SelectInfo si = new SelectInfo(); si.SendByte = frame; si.ReturnValue = cri.ReturnValue; si.ExceptionMessage = cri.ExceptionMessage; return(si); } SelectInfo info = HandleSelectFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机发送该命令设置读写器地址为用户给定的值,该值将被写入EEPROM, /// 以后将使用此项新的读写器地址。出厂时缺省值是0x00。 /// 允许用户的修改范围是0x00~0xfe。当用户写入的值是0xff时, /// 读写器将会自动恢复成缺省值0x00。 /// </summary> /// <param name="addr">新的读写器地址</param> /// <returns></returns> public async Task <InfoBase> WriteComAdrAsync(byte addr) { byte[] frame = CreateWriteComAdrFrame(addr); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; Com_adr = addr; return(info); }
/// <summary> /// 此命令可以擦除标签的保留区、EPC存储区、TID存储区或用户存储区的若干字。 /// </summary> /// <param name="ENum">EPC号长度。以字为单位。EPC的长度在15个字以内,可以为0,否则返回参数错误信息。</param> /// <param name="EPC">要写入数据的标签的EPC号。长度根据所给的EPC号决定,EPC号以字为单位,且必须是整数个长度。高字在前,每个字的高字节在前。这里要求给出的是完整的EPC号。</param> /// <param name="Mem">1个字节,选择要读取的存储区。0x00:保留区;0x01:EPC区;0x02:TID存储区;0x03:用户存储区。其他值保留,若命令中出现了其它值,则返回参数错误信息。</param> /// <param name="WordPtr">1个字节,指定要擦除的字起始地址。0x00 表示从第一个字(第一个16位存储体)开始擦除,0x01表示从第2个字开始擦除,依次类推。当擦除EPC区时,WordPtr必须大于等于0x01,若小于0x01,则返回参数错误消息。</param> /// <param name="Num">1个字节,指定要擦除的字的个数。从WordPtr指定的地址开始擦除,擦除Num指定个数的字。若Num为0x00,则返回参数错误信息。</param> /// <param name="Pwd">4个字节的访问密码。32位的访问密码的最高位在Pwd的第一字节(从左往右)的最高位,访问密码最低位在Pwd第四字节的最低位,Pwd的前两个字节放置访问密码的高字。当进行擦除操作时,并且相应存储区设置为密码锁的时候,才必须使用正确的访问密码。其它情况下,Pwd为零或正确的访问密码。</param> /// <param name="MaskAdr">一个字节,掩模EPC号的起始字节地址。0x00表示从EPC号的最高字节开始掩模,0x01表示从EPC号的第二字节开始掩模,以此类推。</param> /// <param name="MaskLen">一个字节,掩模的字节数。掩模起始字节地址+掩模字节数不能大于EPC号字节长度,否则返回参数错误信息。</param> /// <returns></returns> public async Task <InfoBase> EraseCardAsync(byte ENum, byte[] EPC, MemoryArea Mem, byte WordPtr, byte Num, byte[] Pwd, byte MaskAdr, byte MaskLen) { byte[] frame = CreateEraseCardFrame(ENum, EPC, Mem, WordPtr, Num, Pwd, MaskAdr, MaskLen); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令可以设定保留区为无保护下的可读可写、永远可读可写、带密码可读可 /// 写、永远不可读不可写;可以分别设定EPC存储区、用户存储区为无保护下的可 /// 写、永远可写、带密码可写、永远不可写;TID存储区是只读的,永远都不可写。 /// EPC存储区、TID存储区和用户存储区是永远可读的。 /// 标签的保留区一旦设置为永远可读写或永远不可读写,则以后不能再更改其读写 /// 保护设定。标签的EPC存储区、TID存储区或用户存储区若是设置为永远可写或永 /// 远不可写,则以后不能再更改其读写保护设定。如果强行发命令欲改变以上几种 /// 状态,则电子标签将返回错误代码。 /// 在把某个存储区设置为带密码可读写、带密码可写或把带密码锁状态设置为其它 /// 非密码锁状态时,必须给出访问密码,所以,在进行此操作前,必须确保电子标 /// 签已设置了访问密码。 /// </summary> /// <param name="ENum">EPC号长度,以字为单位。EPC的长度在15个字以内,可以为0,否则返回参数错误信息。</param> /// <param name="EPC">要写入数据的标签的EPC号。长度由所给的EPC号决定,EPC号以字为单位,且必须是整数个长度。高字在前,每个字的高字节在前。这里要求给出的是完整的EPC号。</param> /// <param name="Select">一个字节。定义如下: /// Select为0x00时,控制Kill密码读写保护设定。 /// Select为0x01时,控制访问密码读写保护设定。 /// Select为0x02时,控制EPC存储区读写保护设定。 /// Select为0x03时,控制TID存储区读写保护设定。 /// Select为0x04时,控制用户存储区读写保护设定。 /// 其它值保留,若读写器接收到了其他值,将返回参数出错的消息,并且不执行命令。</param> /// <param name="SetProtect">SetProtect的值根据Select的值而确定。 /// 当Select为0x00或0x01,即当设置Kill密码区或访问密码区的时候,SetProtect的值代表的意义如下: /// 0x00:设置为无保护下的可读可写 /// 0x01:设置为永远可读可写 /// 0x02:设置为带密码可读可写 /// 0x03:设置为永远不可读不可写 /// 当Select与SetProtect出现了其他值的时候,将返回参数出错的消息,并且不执行命令。</param> /// <param name="Pwd">4个字节的访问密码。32位的访问密码的最高位在Pwd的第一字节(从左往右)的最高位,访问密码最低位在Pwd第四字节的最低位,Pwd的前两个字节放置访问密码的高字。必须给出正确的访问密码。</param> /// <param name="MaskAdr">一个字节,掩模EPC号的起始字节地址。0x00表示从EPC号的最高字节开始掩模,0x01表示从EPC号的第二字节开始掩模,以此类推。</param> /// <param name="MaskLen">一个字节,掩模的字节数。掩模起始字节地址+掩模字节数不能大于EPC号字节长度,否则返回参数错误信息。</param> /// <returns></returns> public async Task <InfoBase> SetCardProtectAsync(byte ENum, byte[] EPC, ProtectArea Select, byte SetProtect, byte[] Pwd, byte MaskAdr, byte MaskLen) { byte[] frame = CreateSetCardProtectFrame(ENum, EPC, Select, SetProtect, Pwd, MaskAdr, MaskLen); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令读取标签的保留区、EPC存储区、TID存储区或用户存储区中的数据。从指定的地址开始读,以字为单位。 /// </summary> /// <param name="ENum">EPC号长度,以字为单位。EPC的长度在15个字以内,可以为0。超出范围,将返回参数错误信息。</param> /// <param name="EPC">要读取数据的标签的EPC号。长度根据所给的EPC号决定,EPC号以字为单位,且必须是整数个长度。高字在前,每个字的高字节在前。这里要求给出的是完整的EPC号。</param> /// <param name="Mem">一个字节。选择要读取的存储区。0x00:保留区;0x01:EPC存储区;0x02:TID存储区;0x03:用户存储区。其他值保留。若命令中出现了其它值,将返回参数出错的消息。</param> /// <param name="WordPtr">一个字节。指定要读取的字起始地址。0x00 表示从第一个字(第一个16位存储区)开始读,0x01表示从第2个字开始读,依次类推。</param> /// <param name="Num">一个字节。要读取的字的个数。不能设置为0x00,否则将返回参数错误信息。Num不能超过120,即最多读取120个字。若Num设置为0或者超过了120,将返回参数出错的消息。</param> /// <param name="Pwd">四个字节,这四个字节是访问密码。32位的访问密码的最高位在Pwd的第一字节(从左往右)的最高位,访问密码最低位在Pwd第四字节的最低位,Pwd的前两个字节放置访问密码的高字。只有当读保留区,并且相应存储区设置为密码锁、且标签的访问密码为非0的时候,才需要使用正确的访问密码。在其他情况下,Pwd为零或正确的访问密码。</param> /// <param name="MaskAdr">一个字节,掩模EPC号的起始字节地址。0x00表示从EPC号的最高字节开始掩模,0x01表示从EPC号的第二字节开始掩模,以此类推。</param> /// <param name="MaskLen">一个字节,掩模的字节数。掩模起始字节地址+掩模字节数不能大于EPC号字节长度,否则返回参数错误信息。</param> /// <returns></returns> public async Task <ReadCardInfo> ReadCardAsync(byte ENum, byte[] EPC, MemoryArea Mem, byte WordPtr, byte Num, byte[] Pwd, byte MaskAdr, byte MaskLen) { byte[] frame = CreateReadCardFrame(ENum, EPC, Mem, WordPtr, Num, Pwd, MaskAdr, MaskLen); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { ReadCardInfo rci = new ReadCardInfo(); rci.SendByte = frame; rci.ReturnValue = cri.ReturnValue; rci.ExceptionMessage = cri.ExceptionMessage; return(rci); } ReadCardInfo info = HandleReadCardFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 这个命令每次永久锁定user区中的32bits数据,锁定后,这32bits数据只能读,不能被再次写,也不能被擦除。这个命令仅对NXP UCODE EPC G2电子标签有效。 /// </summary> /// <param name="ENum">EPC号长度。以字为单位。EPC的长度在15个字以内,可以为0,否则返回参数错误信息。</param> /// <param name="EPC">要写入数据的标签的EPC号。长度由所给的EPC号决定,EPC号以字为单位,且必须是整数个长度。高字在前,每个字的高字节在前。这里要求给出的是完整的EPC号。</param> /// <param name="Pwd">4个字节的访问密码。32位的访问密码的最高位在Pwd的第一字节(从左往右)的最高位,访问密码最低位在Pwd第四字节的最低位,Pwd的前两个字节放置访问密码的高字。User区块锁操作时必须给出正确的访问密码。</param> /// <param name="WrdPointer">要锁定的字地址。一次会锁定2个字</param> /// <param name="MaskAdr">一个字节,掩模EPC号的起始字节地址。0x00表示从EPC号的最高字节开始掩模,0x01表示从EPC号的第二字节开始掩模,以此类推</param> /// <param name="MaskLen">一个字节,掩模的字节数。掩模起始字节地址+掩模字节数不能大于EPC号字节长度,否则返回参数错误信息。</param> /// <returns></returns> public async Task <InfoBase> LockUserBlockAsync(byte ENum, byte[] EPC, byte[] Pwd, byte WrdPointer, byte MaskAdr, byte MaskLen) { byte[] frame = CreateLockUserBlockFrame(ENum, EPC, Pwd, WrdPointer, MaskAdr, MaskLen); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 上位机发送该命令以控制读写器LED的状态(LED的亮灭持续时间以及闪烁次数)。 /// </summary> /// <param name="duration">持续时间 *50ms</param> /// <param name="interval">时间间隔 *50ms</param> /// <param name="repeat">重复次数</param> /// <returns></returns> public async Task <InfoBase> BeepAsync(byte duration, byte interval, byte repeat) { byte[] frame = CreateBeepFrame(duration, interval, repeat); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } //读写器让蜂鸣器发声是需要占用 MCU 资源的,鸣叫花掉多少时间这里 //就需要休眠多少时间,之后读写器才可以接收后续指令 Thread.Sleep((duration * 50 + interval * 50) * repeat); InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 对标签内的某一值块进行加、减或备份,支持自动传送,传送的目的 /// 块与该值块必须在同一个扇区。 /// </summary> /// <param name="oper">为0xC0进行减操作,为0xC1进行加操作,为0xC2进行备份操作</param> /// <param name="sourceBlockNum">执行值操作的源值块的绝对块号,取值范围0-63;</param> /// <param name="value">当进行加、减操作时,为加数或减数;当进行恢复操作时该值为空值</param> /// <param name="destBlockNum">执行操作后保存操作结果的目的值块的绝对块号,取值范围0-63</param> /// <returns></returns> public async Task <InfoBase> ValueAsync(OperCode oper, byte sourceBlockNum, byte[] value, byte destBlockNum) { byte[] frame = CreateValueFrame(oper, sourceBlockNum, value, destBlockNum); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }
/// <summary> /// 对写入标签的数据进行检查。 /// 先进行Request/select/ Authentication操作,然后进行指定的数据块的 /// 内容与命令中给出的数据的比较,数据不符返回Error code 0x2C,其它 /// 情况返回相应的值。此过程中采用的证实过程参考前面的Authentication操作介绍。 /// </summary> /// <param name="UID">电子标签的序列号</param> /// <param name="keyType">上次写的证实模式:密钥类型,KeyA 或 KeyB</param> /// <param name="sectorNum">所要检查的数据块的绝对块号</param> /// <param name="data">所要检查的16字节的数据,低字节在前。</param> /// <returns></returns> public async Task <InfoBase> CheckWriteAsync(byte[] UID, KeyType keyType, byte sectorNum, byte[] data) { byte[] frame = CreateCheckWriteFrame(UID, keyType, sectorNum, data); CommunicationReturnInfo cri = await com.SendAsync(frame); if (cri.ReturnValue != ReturnMessage.Success) { InfoBase ib = new InfoBase(); ib.SendByte = frame; ib.ReturnValue = cri.ReturnValue; ib.ExceptionMessage = cri.ExceptionMessage; return(ib); } InfoBase info = HandleBaseFrame(cri.RecvByte); info.SendByte = frame; return(info); }