重构各页面代码,从h文件改为cpp文件;

添加硬件接口并添加,readerAPI使用硬件接口获取invenory信息和connect;
完成开卡初始页面,获取卡号和学号。
This commit is contained in:
2024-07-29 11:24:26 +08:00
parent f229cd4a28
commit 4b8460f4ce
17 changed files with 1411 additions and 157 deletions

438
VCD.h Normal file
View File

@@ -0,0 +1,438 @@
//-----------------------------------------
// 关于类说明
// 类 CVCD 用于 描述 VCD
// 应用软件调用类的成员函数可以对VICC进行访问
//
// 派生类CVCD_Sim 用软件仿真VCD通过transponderEnter函数仿真VICC进入了射频场
// class CVCD_Sim : public CVCD
//
// 派生类CVCD_Ours 封装了Ours的reader.
// class CVCD_Ours : public CVCD
//
//
//#pragma once
#ifndef _VCD_H_
#define _VCD_H_
#include "HLog.h"
#include <cstring>
//
// 并部分实现函数的部分功能
// 比如select request寻址模式一定是address mode
//
// 有些命令,可以由用户确定寻址模式
// 00: 所有的卡都应答
// 01: 被选择卡应答
// 02: 特定地址的卡应答
// else: 不支持;
//
//---------------------------------------------------
// 下面定义了reader成员函数的返回结果
//
// 比如一个addressed的命令收到多个应答或者没有应答
// 注意此处没有应答不指VICC没有影带有些场景VICC不应答也是正确的
// 比如stay quiet收不到任何响应其实是正确的。
// 此处没有应答指VICC应该应答而没有应答
//
#define ISO15693_READER_OK 0xA0
#define ISO15693_READER_ER_LESS_ANSWER 0xA1 // 没有应答
#define ISO15693_READER_ER_MORE_ANSWERS 0xA2 // 收到多个应答
#define ISO15693_READER_ER_FRAME 0xA3 // 收到frame格式错可能发生了冲突软件表示frame错误.
// 副载波0: for single subcarrier / 1: for double subcarrier
#define ISO15693_REQ_FLAG_SUB_CARRIER_S 0
#define ISO15693_REQ_FLAG_SUB_CARRIER_D 1
// 速率, 0: for low data rate / 1: for high data rate
#define ISO15693_REQ_FLAG_DATA_RATE_H 0
#define ISO15693_REQ_FLAG_DATA_RATE_H 1
// 编码方式0: for 1/4 / 1 for 1/256;
#define ISO15693_CODING_1_FROM_4 0
#define ISO15693_CODING_1_FROM_256 1
#define ISO15693_RSP_ERR_NO 0
#define MAX_TRANSPONDERS 16
#define MAX_PKT_LEN 1024
// 寻址模式
// 除inventory命令外其他都涉及到寻址模式.
#define ISO15693_INVENTORY_NO_VICC 0x00
#define ISO15693_INVENTORY_ONE_VICC 0x01
#define ISO15693_INVENTORY_MORE_VICCS 0x02
// VCD的射频场最多支持的VICC数
// 定义为16个是因为inventory采用16slots的情况下最多一次可以清晰收到16个VICC的应答。
// 如果发生了碰撞,或者访问清晰收到的,或者继续寻找碰撞的。
#define MAX_NUM_VICCS 16
typedef unsigned char uchar_t;
typedef enum
{
mode_all,
mode_select,
mode_addressed
}ISO15693_MODE_E;
// VICC的部分信息.
typedef struct tag_VICCInfo
{
uchar_t aucUID[8];
uchar_t ucValid; // 0 for unvalid, 1 for valid.
uchar_t ucDSFID;
uchar_t ucAFI;
uchar_t ucBlockNum;
uchar_t ucBlockSize;
uchar_t ucICRef;
}VICCInfo;
class CVCD
{
public:
CVCD(void)
{
m_ucSubCarrier = ISO15693_REQ_FLAG_SUB_CARRIER_D; // 默认双载波
m_ucDataRate = ISO15693_REQ_FLAG_DATA_RATE_H; // 默认高速率
m_ucDataCoding = ISO15693_CODING_1_FROM_4;
m_ucSlots = 16;
m_pLog = NULL;
for( int i = 0; i < MAX_NUM_VICCS; i++ )
{
m_astVICCs[i].ucValid = 0;
}
}
virtual ~CVCD(void)
{
}
public:
// 正式执行inventory前设置这些参数
int set( uchar_t ucSubCarrier, uchar_t ucDataRate, uchar_t ucSlots )
{
m_ucSubCarrier = ucSubCarrier;
m_ucDataRate = ucDataRate;
m_ucSlots = ucSlots;
}
int setSubCarrier( uchar_t ucSubCarrier )
{
m_ucSubCarrier = ucSubCarrier;
}
int setDataRate( uchar_t ucDataRate )
{
m_ucDataRate = ucDataRate;
}
int setSlots( uchar_t ucSlots )
{
m_ucSlots = ucSlots;
}
void setDataCoding_1from4()
{
m_ucDataCoding = ISO15693_CODING_1_FROM_4;
}
void setDataCoding_1from256()
{
m_ucDataCoding = ISO15693_CODING_1_FROM_256;
}
void setLog( CHLog *plog )
{
m_pLog = plog;
}
// 如何设置和VCD/Reader的连接
// 串口.
virtual int connectReader()
{
return 1;
}
virtual int disconnectReader( )
{
return 1;
}
/*
virtual int connectReaderByCOM( int comno )
{
return 1;
}
*/
// 在执行了inventory后用户可以获得芯片的信息。
// 其中获得的blocksize和blocknum在readblocks()和write block()时,有用.
VICCInfo getVICCInfo( uchar_t aucUID[8] )
{
VICCInfo vicc;
memset( (uchar_t *)&vicc, 0x00, sizeof(vicc));
int k = getVICC( aucUID );
if( k != -1 )
{
return m_astVICCs[k];
}
return vicc;
}
public:
// 协议命令
// 返回:>0表示读到的Transponder数量;
//
virtual int inventory(
bool bAFIUsed,
uchar_t ucAFI,
int nViccNum, // 应用层可以接收的UID数量;
uchar_t aucDSFID[],
uchar_t aucUID[][8] )
{
m_bAFIUsed = bAFIUsed;
if( m_bAFIUsed )
{
m_ucAFI = ucAFI;
}
return ISO15693_RSP_ERR_NO;
}
//------------------------------------------
// 状态转换
// stayquiet
// cmd=0x02;
// 寻址方式:只能是地址模式, UID必须;
virtual int stayQuiet( uchar_t *pucUID )
{
return ISO15693_RSP_ERR_NO;
}
// select命令
// cmd=0x25
// 寻址方式一定是地址模式, UID必须;
virtual int select( uchar_t *pucUID )
{
return ISO15693_RSP_ERR_NO;
}
// reset to ready
// cmd=0x26
// 可以使地址模式,也可以是选择模式
virtual int resetToReady( uchar_t *pucUID )
{
return ISO15693_RSP_ERR_NO;
}
//------------------------------------------
// 操作
// 操作类命令寻址模式只能地址或者select
//
// 0x20
virtual int readSingleBlock(
uchar_t *pucUID, // NULL表示select模式
uchar_t optional_flag, // optional bit = 1, 要求返回block的安全状态
uchar_t ucBlkno, // blockno
uchar_t buf[], // 返回读取的数据
uchar_t *pucSecurity // 如果optional_flag = 1, 返回该block的安全状态1表示locked.
)
{
return ISO15693_RSP_ERR_NO;
}
// 0x21
virtual int writeSingleBlock(
uchar_t *pucUID, // NULL表示select模式
uchar_t ucBlkno, //
uchar_t ucBlksize,
uchar_t buf[] )
{
return ISO15693_RSP_ERR_NO;
}
// 0x22
virtual int lockBlock(
uchar_t *pucUID, // NULL表示select模式
int blockno )
{
return ISO15693_RSP_ERR_NO;
}
// 0x23
virtual int readMultipleBlocks(
uchar_t *pucUID, // NULL表示select模式
uchar_t optional_flag, // optional bit = 1, 要求返回block的安全状态
uchar_t ucBlkno, // 开始block no
uchar_t blocknum, // 实际读的block是blocknum+1;
uchar_t buf[], // 返回读取的数据
uchar_t aucSecurity[] // 如果optional_flag = 1, 返回该block的安全状态1表示locked.
)
{
return ISO15693_RSP_ERR_NO;
}
// 0x24
virtual int writeMultipleBlocks(
uchar_t *pucUID, // NULL表示select模式
uchar_t ucBlkno, // 开始block no
uchar_t blocknum, // 实际写的block是blocknum+1;
uchar_t ucBlksize,
uchar_t buf[] )
{
return ISO15693_RSP_ERR_NO;
}
//----------------------------------------------------------
// AFI & DSFID
//
// CMD: 0x27
// optional 不处理.
virtual int writeAFI(
uchar_t *pucUID, // NULL表示select模式
uchar_t ucAFI )
{
return ISO15693_RSP_ERR_NO;
}
//
// CMD: 0x28
// optional 不处理.
virtual int lockAFI(
uchar_t *pucUID // NULL表示select模式
)
{
return ISO15693_RSP_ERR_NO;
}
//
// CMD: 0x29
// optional 不处理.
virtual int writeDSFID(
uchar_t *pucUID, // NULL表示select模式
uchar_t ucDSFID )
{
return ISO15693_RSP_ERR_NO;
}
//
// CMD: 0x2A
// optional 不处理.
virtual int lockDSFID(
uchar_t *pucUID // NULL表示select模式
)
{
return ISO15693_RSP_ERR_NO;
}
// CMD: 0x2B
//
virtual int getSystemInfo(
uchar_t *pucUID,
uchar_t *pinfoFlag,
uchar_t *pDSFID, uchar_t *pAFI, uchar_t *pBlockNum, uchar_t *pBlockSize, uchar_t *pICRef
)
{
return ISO15693_RSP_ERR_NO;
}
protected:
void CRC16( int buflen, uchar_t buf[], uchar_t *pucCRCL, uchar_t *pucCRCH );
bool ISO15693_checkCRC16( int buflen, uchar_t buf[] );
void ISO15693_getCRC16( int buflen, uchar_t buf[], uchar_t *pucCRCL, uchar_t *pucCRCH );
/**
* 在inventory后获取某个VICC的systeminfo
* 生成CVICC.
* 其中blocksize & blocknum 用于以后执行read,write命令用。
* 输入pucUID. 8字节的UID.
*/
virtual bool setVICC( uchar_t aucUID[8] )
{
uchar_t infoFlag;
uchar_t ucDSFID, ucAFI, ucBlockNum, ucBlockSize;
uchar_t ucICRef;
if( getSystemInfo( aucUID, &infoFlag, &ucDSFID, &ucAFI, &ucBlockNum, &ucBlockSize, &ucICRef ) != ISO15693_RSP_ERR_NO )
{
return false;
}
// OK.
for( int i = 0; i < MAX_NUM_VICCS; i++ )
{
if( m_astVICCs[i].ucValid == 0 )
{
m_astVICCs[i].ucValid = 1;
if( infoFlag & (1 << 0) )
{
m_astVICCs[i].ucDSFID = ucDSFID;
}
else if( infoFlag & ( 1 << 1 ))
{
m_astVICCs[i].ucAFI = ucAFI;
}
else if( infoFlag & ( 1 << 2 ) )
{
m_astVICCs[i].ucBlockNum = ucBlockNum;
m_astVICCs[i].ucBlockSize = ucBlockSize;
}
else if( infoFlag & ( 1 << 3 ))
{
m_astVICCs[i].ucICRef = ucICRef;
}
memcpy( m_astVICCs[i].aucUID, aucUID, 8 );
return true;
}
}
return false;
}
int getVICC( uchar_t aucUID[8] )
{
for( int i = 0; i < MAX_NUM_VICCS; i++ )
{
if( memcmp(m_astVICCs[i].aucUID, aucUID, 8 ) == 0 )
{
return i;
}
}
return -1;
}
protected:
void log( char *str )
{
if( m_pLog )
{
m_pLog->logstr( str );
}
}
void logDIM( int len, uchar_t aucDat[] )
{
if( m_pLog )
{
m_pLog->logDIM( len, aucDat );
}
}
protected:
// 全局性配置
// VCD自己的选择
uchar_t m_ucDataCoding; // 编码方式0: for 1/4 / 1 for 1/256;
uchar_t m_ucSlots; // 016 slots or 1 slots;
// VCD对VICC的要求
uchar_t m_ucSubCarrier; // 副载波0: for single subcarrier / 1: for double subcarrier
uchar_t m_ucDataRate; // 速率, 0: for low data rate / 1: for high data rate
// 执行防碰撞循环时可能多次发送inventory request每个都涉及是否使用AFI
// 因此设置为成员变量;
//
uchar_t m_ucAFI;
bool m_bAFIUsed;
// 记录日志.
CHLog* m_pLog;
// 通过inventory命令后发现的viccs.
VICCInfo m_astVICCs[MAX_NUM_VICCS];
};
#endif