实验1——EPC C1G2标准下的标签状态转换仿真 (4学时)
实验说明:
- 利用Python或Matlab模拟C1G2标签的状态转换模型;
- 程序应能显示标签当前的状态,并能通过键入的不同指令完成状态的转换。
import random
import time
#实验一:C1G2状态机转换
class Reader():
def __init__(self, Ack, command, passwd, handle_bs):
self.ack = Ack
self.command = command
self.pwd = passwd
self.handle = handle_bs
reader = Reader(1, '', 0, '')
#假设reader的ack为0时,阅读器没有收到标签的RN16(标签不会会收到ack确认)
# ack不为0时,阅读器收到标签的RN16(标签会收到ack确认)
class RFID_tag():
def __init__(self, State, Slot, rn16, Pwd, handle_bs, Energy_RFID, EPC, PC ,CRC):
self.state = State
self.slot = Slot
self.RN16 = rn16
self.pwd = Pwd
self.handle = handle_bs
self.energy = Energy_RFID
self.epc = EPC
self.pc = PC
self.crc = CRC
def setRN16(TAG):
s = ''
TAG.RN16 = s.join(random.choice("0123456789") for i in range(16))
#self_RFID.handle = str.join(random.choice("0123456789") for i in range(16))
tag = RFID_tag('', 150, '', 1000, 8430311392384815, 0, 1001, 1010, 1100)
while True:
if reader.command == '': # 输入命令
reader.command = input('请输入命令:')
if reader.command == "select" and tag.energy != 0: # 标签激活且命令为Select则进入就绪态
tag.state = 'Ready'
elif reader.command == "cw" and tag.state == '': # cw是激活命令,激活未激活的标签进入就绪态。
tag.energy = 7
tag.state = 'Ready'
print(tag.state, "Tag已激活")
print("标签Tag进入就绪态")
elif reader.command == "query" and tag.state == 'Ready': # 就绪->仲裁或回复(query)
tag.slot = random.randint(0, 15)
if tag.slot != 0: # slot!=0 : 就绪->仲裁
print("生成的随机数不为0")
tag.state = 'Arbitrate'
arbitrate_signal = 1
print(tag.state, "Tag进入仲裁态")
print('等待slot变为0:', tag.slot, end=' ')
for i in range(0, tag.slot):
tag.slot = tag.slot - 1
print(tag.slot, end=' ')
time.sleep(0.5)
print("此时随机数变为0")
tag.state = 'Reply'
print(tag.state, "Tag进入回复态")
tag.slot = random.randint(1, 15)
reader.command = ''
if tag.slot == 0: # slot=0 : 就绪->回复
print("生成的随机数为0")
tag.state = 'Reply'
print(tag.state, "Tag进入回复态")
tag.slot = random.randint(1, 15)
reader.command = ''
elif tag.slot != 0 and tag.state == 'Arbitrate' and arbitrate_signal == 1 : #仲裁->回复
print('请等待:', tag.slot, end=' ')
for i in range(0, tag.slot):
tag.slot = tag.slot - 1
print(tag.slot, end=' ')
time.sleep(0.5)
print("此时随机数变为0")
tag.state = 'Reply'
print(tag.state, "Tag进入回复态")
tag.slot = random.randint(1, 15)
reader.command = ''
elif tag.state == 'Reply': # 回复态
if reader.command == 'select':
tag.state = 'Ready'
if reader.command == '':
pass
else: # 回复态->确认态或仲裁态
tag.setRN16()
print('标签发送RN16', tag.RN16)
if reader.ack != 0: # 回复态->确认态。 标签会收到ack确认
reader.ack = tag.RN16
time.sleep(1)
print('阅读器成功接收RN16,并发送确认ACK', reader.ack)
time.sleep(1)
print('标签发送EPC', tag.epc)
print('标签发送PC', tag.pc)
print('标签发送CRC', tag.crc)
time.sleep(1)
tag.state = 'acknowledged'
print(tag.state, "Tag进入确认态")
reader.command = ''
if reader.ack == 0: # 回复态->仲裁态
tag.state = 'Arbitrate'
arbitrate_signal = 1
print(tag.state, "响应超时,阅读器接收RN16失败,Tag进入仲裁态")
elif tag.state == 'acknowledged': # 确认态
if reader.command == 'select' or reader.command == 'QueryRep' or reader.command == 'QueryAdjust':
tag.state = 'Ready'
if reader.command == '':
pass
else:
print('阅读器发送Req_RN和RN16', reader.command, reader.ack)
time.sleep(1)
#句柄就是新的RN16,此处句柄要生成一个新的16位随机数
print("标签Tag返回句柄", tag.handle)
time.sleep(1)
if tag.pwd * 1 == 0: # 确认态->安全态(密码为0)
tag.state = 'secured'
print(tag.state, "密码功能未启用,Tag进入安全态")
reader.command = ''
else: # 确认态->开放态
tag.state = 'open'
print(tag.state, "密码功能启用,Tag进入开放态")
reader.command = ''
elif tag.state == 'open': # 开放态
if reader.command == 'select' or reader.command == 'QueryRep' or reader.command == 'QueryAdjust':
tag.state = 'Ready'
if reader.command == '':
pass
else:
print('请输入正确的句柄:')
reader.handle = int(input())
print('请输入正确的密码:')
reader.pwd = int(input())
if reader.handle == tag.handle and reader.pwd == tag.pwd: # 开放->安全
tag.state = 'secured'
print(tag.state, "句柄和密码均正确,进入安全态")
reader.command = ''
else: # 若没有收到其他命令,则tag一直处于开放态直到能量耗尽
print("句柄和密码不正确!")
tag.energy = tag.energy - 1
reader.command = ''
if tag.energy == 0:
tag.state = ''
reader.command = ''
print("能量耗尽")
elif tag.state == 'secured': # 安全态->杀死态
if reader.command == 'select' or reader.command == 'QueryRep' or reader.command == 'QueryAdjust':
tag.state = 'Ready'
if reader.command == '':
pass
else:
if reader.command == 'kill':
print("(提示:即将杀死标签)")
if tag.pwd * 1 != 0: # 密码不为0,验证密码和句柄
print('请输入句柄:')
reader.handle = int(input())
print('请输入密码:')
reader.pwd = int(input())
if reader.handle == tag.handle and reader.pwd == tag.pwd:
tag.state = 'killed'
print(tag.state, "句柄和密码均正确,杀死标签(杀死态)")
break
else:
print("句柄和密码不正确!")
reader.command = ''
else: # 密码为0,只用验证句柄
print('请输入句柄:')
reader.handle = int(input())
if reader.handle == tag.handle:
tag.state = 'killed'
print(tag.state, "句柄正确,杀死标签(杀死态)")
break
else:
print("句柄不正确!")
reader.command = ''
else:
reader.command = ''
if tag.state == 'Ready' and reader.command != "cw": # 进入就绪态。
print(tag.state, "进入就绪态")
time.sleep(1)
reader.command = ''
运行结果: