EPC C1G2标准下的标签状态转换仿真

原理:
在这里插入图片描述

通过python实现:

import random
import time
import threading


class Reader_king():
    def __init__(self, ack1, command, passwd, handle_back):
        self.ack = ack1
        self.command = command
        self.pwd = passwd
        self.handle = handle_back

    def printinfo(self_RFID):
        print("ack:", self_RFID.ack)
        print("命令:", self_RFID.command)
        print("密码:", self_RFID.pwd)
        print("句柄:", self_RFID.handle)


class RFID_king():
    def __init__(self, state, Q, RN16, passwd, handle_back, energy_RFID, epc):
        self.state = state
        self.Q = Q
        self.RN16 = RN16
        self.pwd = passwd
        self.handle = handle_back
        self.energy = energy_RFID
        self.epc = epc

    def setRN16(self_RFID):
        str = ''
        a = str.join(random.choice("0123456789") for i in range(16))
        #print(a)
        self_RFID.RN16 = a


reader = Reader_king(0, '', 0, '')

rfid = RFID_king('', 100, '', 000, 11101, 0, 1001)


exitFlag = 0


class myThread_king(threading.Thread):
    def __init__(self_RFID, threadID, name, counter):
        threading.Thread.__init__(self_RFID)
        self_RFID.threadID = threadID
        self_RFID.name = name
        self_RFID.counter = counter

    def run(self_RFID):
        start = time.time()
        global x
        global e
        start = time.time()
        print('请输入Req_RN命令:')
        x = input()
        e = time.time() - start


while 1:
    if reader.command == '' or reader.command == 'CW':  # 输入命令
        reader.command = input('请输入命令:')

    if reader.command == "Select" and rfid.energy != 0:  # 标签激活且命令为Select则进入就绪态
        rfid.state = 'ready'

    elif reader.command == "CW" and rfid.state == '':  # 激活未激活的标签进入就绪态
        rfid.energy = 10
        rfid.state = 'ready'
        print(rfid.state, "标签已激活")
        print("进入就绪态")

    elif reader.command == "query" and rfid.state == 'ready':  # 就绪->仲裁(query)
        rfid.Q = random.randint(0, 10)
        rfid.state = 'arbitrate'
        print(rfid.state, "进入仲裁态")
        reader.command = ''

    elif rfid.Q == 0 and rfid.state == 'arbitrate' and reader.command == "query":  # 仲裁->回复(query,Q=0)
        rfid.state = 'reply'
        print(rfid.state, "进入回复态")
        rfid.Q = random.randint(1, 10)
        reader.command = ''

    elif rfid.Q != 0 and rfid.state == 'arbitrate' and reader.command == "query":  # 仲裁->回复(query,Q=0)
        print('请等待:', rfid.Q, end=' ')
        for i in range(0, rfid.Q):
            rfid.Q = rfid.Q - 1
            print(rfid.Q, end=' ')
            time.sleep(0.5)
        print('\n')
        rfid.state = 'reply'
        print(rfid.state, "进入回复态")
        rfid.Q = random.randint(1, 10)
        reader.command = ''

    elif rfid.state == 'reply':  # 回复态
        if reader.command == 'Select':
            rfid.state = 'ready'
        if reader.command == '':
            pass
        else:
            rfid.setRN16()
            print('标签发送RN16', rfid.RN16)
            reader.ack = rfid.RN16
            time.sleep(1)
            print('阅读器发送ACK', reader.ack)
            time.sleep(1)
            print('标签发送EPC', rfid.epc)
            time.sleep(1)
            rfid.state = 'acknowledged'
            print(rfid.state, "进入确认态")
            reader.command = ''

    elif rfid.state == 'acknowledged':  # 确认态
        if reader.command == 'Select':
            rfid.state = 'ready'
        if reader.command == 'QueryRep':
            rfid.state = 'ready'
        if reader.command == 'QueryAdjust':
            rfid.state = 'ready'
        if reader.command == '':
            pass
        else:
            thread1 = myThread_king(1, "Thread-1", 1)
            # 开启新线程
            e = 20
            x = ''
            thread1.start()
            thread1.join(20)
            reader.command = x
            if e < 20:
                print('阅读器发送Req_RN和RN16', reader.command, reader.ack)
                time.sleep(1)
                print("标签返回句柄", rfid.handle)
                time.sleep(1)
                if rfid.pwd * 1 == 0:
                    rfid.state = 'secured'
                    print(rfid.state, "密码功能未启用,进入安全态")
                    reader.command = ''
                else:
                    rfid.state = 'open'
                    print(rfid.state, "密码功能启用,进入开放态")
                    reader.command = ''
            else:
                rfid.state = 'arbitrate'
                print(rfid.state, "响应超时,进入仲裁态")

    elif rfid.state == 'open':  # 开放态
        if reader.command == 'Select':
            rfid.state = 'ready'
        if reader.command == 'QueryRep':
            rfid.state = 'ready'
        if reader.command == 'QueryAdjust':
            rfid.state = 'ready'
        if reader.command == '':
            pass
        else:
            print('请输入句柄')
            reader.handle = int(input())
            print('请输入密码')
            reader.pwd = int(input())
            if reader.handle == rfid.handle and reader.pwd == rfid.pwd:
                rfid.state = 'secured'
                print(rfid.state, "组合正确,进入安全态")
                reader.command = ''
            else:
                print("组合不正确!")
                rfid.energy = rfid.energy - 1
                reader.command = ''
            if rfid.energy == 0:
                rfid.state = ''
                reader.command = ''
                print("能量耗尽")

    elif rfid.state == 'secured':  # 安全态
        if reader.command == 'Select':
            rfid.state = 'ready'
        if reader.command == 'QueryRep':
            rfid.state = 'ready'
        if reader.command == 'QueryAdjust':
            rfid.state = 'ready'
        if reader.command == '':
            pass
        if reader.command == 'kill':
            if rfid.pwd * 1 != 0:
                print('请输入句柄')
                reader.handle = int(input())
                print('请输入密码')
                reader.pwd = int(input())
                if reader.handle == rfid.handle and reader.pwd == rfid.pwd:
                    rfid.state = 'killed'
                    print(rfid.state, "组合正确,杀死标签")
                    break
                else:
                    print("组合不正确!")
                    reader.command = ''
            else:
                print('请输入句柄')
                reader.handle = int(input())
                if reader.handle == rfid.handle:
                    rfid.state = 'killed'
                    print(rfid.state, "句柄正确,杀死标签")
                    break
                else:
                    print("组合不正确!")
                    reader.command = ''

    else:
        print('命令无效')
        reader.command = ''

    if rfid.state == 'ready' and reader.command != "CW":
        print(rfid.state, "进入就绪态")
        time.sleep(1)
        reader.command = ''

运行结果:
在这里插入图片描述
结论:
七个状态及状态转移。就绪态:标签在通电前的状态,此时标签不参加询问过程。标签从阅读器发送的查询命令中,选择一个参数生成随机数用于计算发送的时隙。若为0,标签进入回复状态,否则进入仲裁态。
仲裁态:标签参加本轮查询。此时标签时隙不为0,将等待时隙数变为0,然后进入回复状态。
回复态:当标签需要回复EPC码时,首先进入回复态。标签接受到ACK后进入确认态。否则,标签会自动进入仲裁态。
确认态:标签回复EPC码后进入确认态。这是标签进入访问命令的必经状态。如回复态一样,若标签在指定时间内没有接受到阅读器的命令,将会自动返回仲裁态。
开放态:标签进入访问命令时需要互斥使用的状态。若标签没接受阅读器的命令将一直保持在此状态直至没有能量。标签能从开放态进入安全态。
安全态:标签可以使用一个可选的密码功能要求阅读器在执行任何访问命令时都要提供保护的密码。
杀死态:RFID标签中存储特定对象的信息,在不需要该标签将其杀死以保护信息。当标签进入杀死态以后,将不再响应阅读器发出的任何命令。

### EPCC1G2 状态机实现原理 EPCC1G2EPC Class 1 Generation 2标准定义了一种用于无源RFID标签的状态机模型。该状态机描述了标签如何响应来自阅读器的不同命令并改变其内部状态。 #### 状态及其转换条件 标签具有四种主要状态: - **Ready**:初始状态,在此状态下等待接收查询命令。 - **Arbitrate**:当接收到有效的Query或QueryRep命令后进入此状态,准备参与防碰撞算法。 - **Reply**:成功通过仲裁阶段后的状态;在此期间发送应答信号给读卡器。 - **Open/Safe**:完成身份验证过程后达到的安全操作模式。取决于访问权限设置,可进一步细分为开放态(Open)和安全态(Safe)[^3]。 为了使标签能够正确处理各种请求并保持同步通信,必须严格遵循这些状态之间的过渡规则。例如,只有在标签已经回复了自己的唯一识别符(EPC编码),即处于确认态之后,才能执行其他高级别的访问控制指令,如读取、写入数据等。 #### 关键交互流程 1. 标签启动时自动置于`Ready`状态; 2. 接收到来自阅读者的合法询问(`Query`)消息后转入`Arbitrate`状态; 3. 经过竞争解决机制选定特定目标个体,并向后者发出肯定答复(Acknowledgment, ACK),此时标签切换至`Reply`状态; 4. 发送完毕自身的EPC ID 后,依据是否存在有效密钥以及相应的认证结果来决定下一步是停留在`Open`(未加密区域允许自由存取)还是迁移到`Safe`(需额外授权才可修改敏感资料); 5. 不论在哪一种工作模式下,一旦遭遇非法入侵尝试或是超时未得到预期回应都将重置回起点重新开始整个周期循环。 ### 代码示例 下面给出一段简化版的Python伪代码用来模拟上述部分行为逻辑: ```python class EPCCTagStateMachine: def __init__(self): self.state = 'Ready' def on_query_received(self): if self.state == 'Ready': print("Transitioning to Arbitrate state.") self.state = 'Arbitrate' def arbitrate_successfully(self): if self.state == 'Arbitrate': print("Sending EPC code and transitioning to Reply state.") self.send_epc_code() self.state = 'Reply' def send_epc_code(self): # Simulate sending the EPC code here. pass def authenticate_and_transition(self, password='0'*16): if self.state == 'Reply': if all(c=='0' for c in password): new_state = 'Open' else: new_state = 'Safe' print(f"Authenticated successfully; moving into {new_state} state.") self.state = new_state tag_sm = EPCCTagStateMachine() # Example usage of tag state machine transitions tag_sm.on_query_received() # Transition from Ready -> Arbitrate tag_sm.arbitrate_successfully() # Send EPC & transition from Arbitrate -> Reply tag_sm.authenticate_and_transition('0'*16) # Authenticate with default (all zeros) password ``` 这段代码展示了基本的状态转移路径,实际应用中还需要考虑更多细节,比如错误处理、时间限制等因素。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值