重构各页面代码,从h文件改为cpp文件;
添加硬件接口并添加,readerAPI使用硬件接口获取invenory信息和connect; 完成开卡初始页面,获取卡号和学号。
This commit is contained in:
parent
f229cd4a28
commit
4b8460f4ce
@ -9,18 +9,26 @@ CONFIG += c++17
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
VCD.cpp \
|
||||
VCDOurs.cpp \
|
||||
databaseAPI.cpp \
|
||||
deviceAPI.cpp \
|
||||
main.cpp \
|
||||
mainwindow.cpp
|
||||
mainwindow.cpp \
|
||||
newCardPage.cpp \
|
||||
quitAppPage.cpp \
|
||||
readerAPI.cpp \
|
||||
settingPage.cpp
|
||||
|
||||
HEADERS += \
|
||||
HF15693.h \
|
||||
HLog.h \
|
||||
VCD.h \
|
||||
VCDOurs.h \
|
||||
databaseAPI.h \
|
||||
deviceAPI.h \
|
||||
mainwindow.h \
|
||||
newCardPage.h \
|
||||
quitAppPage.h \
|
||||
readerAPI.h \
|
||||
settingPage.h
|
||||
readerAPI.h
|
||||
|
||||
FORMS += \
|
||||
mainwindow.ui
|
||||
|
63
HLog.h
Normal file
63
HLog.h
Normal file
@ -0,0 +1,63 @@
|
||||
//#pragma once
|
||||
#ifndef _H_LOG_H_
|
||||
#define _H_LOG_H_
|
||||
|
||||
#include <stdio.h>
|
||||
typedef unsigned char uchar_t;
|
||||
|
||||
class CHLog
|
||||
{
|
||||
public:
|
||||
CHLog(void)
|
||||
{
|
||||
m_fp = fopen( "hfsim.log", "w");
|
||||
}
|
||||
~CHLog(void)
|
||||
{
|
||||
if( m_fp )
|
||||
{
|
||||
fclose( m_fp );
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
void logstr( char *str )
|
||||
{
|
||||
if( m_fp )
|
||||
{
|
||||
fprintf( m_fp, "%s\n", str );
|
||||
}
|
||||
}
|
||||
|
||||
void logDIM( int len, uchar_t aucDat[] )
|
||||
{
|
||||
int n = len/16;
|
||||
int k = 0;
|
||||
|
||||
if( m_fp )
|
||||
{
|
||||
fprintf( m_fp, "hex----------------\n");
|
||||
for( int i = 0; i < n; i++ )
|
||||
{
|
||||
for( int j = 0; j < 16; j++ )
|
||||
{
|
||||
fprintf( m_fp, "%02x ", aucDat[k++]);
|
||||
}
|
||||
fprintf( m_fp, "\n" );
|
||||
}
|
||||
|
||||
for( int j = 0; j < len%16; j++ )
|
||||
{
|
||||
fprintf( m_fp, "%02x ", aucDat[k++]);
|
||||
}
|
||||
fprintf( m_fp, "\n" );
|
||||
fprintf( m_fp, "hex----------------\n");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
FILE *m_fp;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
56
VCD.cpp
Normal file
56
VCD.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include "VCD.h"
|
||||
|
||||
#define POLYNOMIAL 0x8408 // x^16 + x^12 + x^5 + 1
|
||||
#define PRESET_VALUE 0xFFFF
|
||||
#define CHECK_VALUE 0xF0B8
|
||||
#define CALC_CRC 1
|
||||
#define CHECK_CRC 0
|
||||
|
||||
void CVCD::CRC16( int buflen, uchar_t buf[], uchar_t *pucCRCL, uchar_t *pucCRCH )
|
||||
{
|
||||
unsigned int current_crc_value;
|
||||
unsigned char *array_of_databytes;
|
||||
int number_of_databytes;
|
||||
int i, j;
|
||||
|
||||
number_of_databytes = buflen;
|
||||
array_of_databytes = buf;
|
||||
current_crc_value = PRESET_VALUE;
|
||||
for (i = 0; i < number_of_databytes; i++)
|
||||
{
|
||||
current_crc_value = current_crc_value ^ ((unsigned int)array_of_databytes[i]);
|
||||
for (j = 0; j < 8; j++)
|
||||
{
|
||||
if (current_crc_value & 0x0001)
|
||||
{
|
||||
current_crc_value = (current_crc_value >> 1) ^ POLYNOMIAL;
|
||||
}
|
||||
else
|
||||
{
|
||||
current_crc_value = (current_crc_value >> 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
current_crc_value = ~current_crc_value;
|
||||
*pucCRCL = current_crc_value & 0xFF;
|
||||
*pucCRCH = (current_crc_value >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
void CVCD::ISO15693_getCRC16( int buflen, uchar_t buf[], uchar_t *pucCRCL, uchar_t *pucCRCH )
|
||||
{
|
||||
CRC16( buflen, buf, pucCRCL, pucCRCH );
|
||||
}
|
||||
|
||||
bool CVCD::ISO15693_checkCRC16( int buflen, uchar_t buf[] )
|
||||
{
|
||||
uchar_t ucCRCL, ucCRCH;
|
||||
CRC16( buflen-2, buf, &ucCRCL, &ucCRCH );
|
||||
if( ucCRCL == buf[buflen-2] && ucCRCH == buf[buflen-1] )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
438
VCD.h
Normal file
438
VCD.h
Normal 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; // 0:16 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
|
493
VCDOurs.cpp
Normal file
493
VCDOurs.cpp
Normal file
@ -0,0 +1,493 @@
|
||||
#include <cstdlib>
|
||||
#include "VCDOurs.h"
|
||||
|
||||
CVCDOurs::CVCDOurs(void)
|
||||
{
|
||||
m_bComOpened = false;
|
||||
}
|
||||
|
||||
|
||||
CVCDOurs::~CVCDOurs(void)
|
||||
{
|
||||
if( m_bComOpened )
|
||||
{
|
||||
t15portClose();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// 使用串口和建立连接
|
||||
int CVCDOurs::connectReaderByCOM( int comno )
|
||||
{
|
||||
if(t15portOpen(comno))
|
||||
{
|
||||
t15bSubCarrier=m_ucSubCarrier;
|
||||
t15bDataCoding=m_ucDataCoding;
|
||||
t15bFullPower=1;
|
||||
t15bDataRate=m_ucDataRate;
|
||||
|
||||
m_bComOpened = true;
|
||||
if( t15setProtocol() == 0 )
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CVCDOurs::disconnectReaderByCOM( )
|
||||
{
|
||||
if( m_bComOpened )
|
||||
{
|
||||
t15portClose( );
|
||||
}
|
||||
}
|
||||
|
||||
int CVCDOurs::inventory(
|
||||
bool bAFIUsed,
|
||||
uchar_t ucAFI,
|
||||
int nViccNum, // 应用层的接收的UID数量;
|
||||
uchar_t aucDSFID[],
|
||||
uchar_t aucUID[][8] )
|
||||
{
|
||||
t15bInventory=1;
|
||||
|
||||
// t15bAddress & t15bSelect在inventory=1的情况下,表示: AFI 和 NBSlots
|
||||
// 而NBSlots为16,取值为0.
|
||||
t15bAddress=0; // 本来就没有用
|
||||
t15bOption=0; // 没用用.
|
||||
|
||||
if( bAFIUsed )
|
||||
{
|
||||
t15bSelect=1; // 此处的含义是没有AFI,其实可以有!
|
||||
sprintf( t15AFI, "%02x", ucAFI );
|
||||
}
|
||||
|
||||
char* strUID[16];
|
||||
for( int i = 0; i < 16; i++ )
|
||||
{
|
||||
strUID[i] = new char[50];
|
||||
}
|
||||
int n = doInventory( strUID );
|
||||
n = ( n >= nViccNum ) ? nViccNum : n;
|
||||
// 开始解析.
|
||||
for( int i = 0; i < n; i++ )
|
||||
{
|
||||
StringToHex( strUID[i], aucUID[i] );
|
||||
}
|
||||
|
||||
for( int i = 0; i < 16; i++ )
|
||||
{
|
||||
delete []strUID[i];
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
// Ours
|
||||
// 1. 执行inventory时,因为:t15bSelect=0,因此没有AFI flag.
|
||||
// 2. 没有处理返回的DSFID.
|
||||
//
|
||||
int CVCDOurs::inventory( char *pTagUID[] )
|
||||
{
|
||||
t15bInventory=1;
|
||||
// t15bAddress & t15bSelect在inventory=1的情况下,表示: AFI 和 NBSlots
|
||||
// 而NBSlots为16,取值为0.
|
||||
t15bAddress=0; // 本来就没有用
|
||||
t15bSelect=0; // 此处的含义是没有AFI,其实可以有!
|
||||
t15bOption=0; // 没用用.
|
||||
|
||||
return doInventory( pTagUID );
|
||||
}
|
||||
|
||||
int CVCDOurs::doInventory( char *pTagUID[] )
|
||||
{
|
||||
// 对返回的UID
|
||||
// 每个[],一个UID
|
||||
// []表示分配的slot数
|
||||
// [z,40]中, 'z'表示发生了冲突
|
||||
// 返回的序列是防冲突过程中的全部序列。
|
||||
//
|
||||
char cmdsend[CMD_LEN],reply[CMD_LEN]/*="23[,40][2343334239,55][,49][abcderfdsdfs0d,30]"*/;
|
||||
|
||||
t15execute(INVENTORY,cmdsend,reply);
|
||||
|
||||
int k = 0;
|
||||
char *p,*q,tstr[50]={0};
|
||||
p=reply;
|
||||
|
||||
while (1)
|
||||
{
|
||||
p = strchr(p,'[');
|
||||
|
||||
if (NULL == p)
|
||||
break ;
|
||||
|
||||
q = strchr(p+1,',');
|
||||
|
||||
if (NULL == q)
|
||||
break ;
|
||||
|
||||
// 'z'表示冲突
|
||||
if (q != (p+1) && *(p+1) != 'z' )
|
||||
{
|
||||
t15changeByteOrder(tstr,p+1,q-p-1); //返回的数据是低字节在前,调整字节序
|
||||
strcpy( pTagUID[k++], tstr );
|
||||
|
||||
// 获取某个Tag的详细信息:call GetSystemInfo().
|
||||
setVICCStr( pTagUID[k-1] );
|
||||
}
|
||||
|
||||
p = q+1;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
//已经通过UID,获得了VICC的信息.
|
||||
int CVCDOurs::getSystemInfo(
|
||||
uchar_t *pucUID,
|
||||
uchar_t *pinfoFlag,
|
||||
uchar_t *pDSFID, uchar_t *pAFI, uchar_t *pBlockNum, uchar_t *pBlockSize, uchar_t *pICRef
|
||||
)
|
||||
{
|
||||
char str[100];
|
||||
|
||||
t15bOption = 0;
|
||||
t15bInventory = 0;
|
||||
if( pucUID )
|
||||
{
|
||||
t15bAddress=1;
|
||||
t15bSelect = 0;
|
||||
HexToString( pucUID, 8, str );
|
||||
t15changeByteOrder( t15UID, str, 16 );
|
||||
t15UID[16]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t15bAddress=0;
|
||||
t15bSelect =1;
|
||||
}
|
||||
|
||||
//执行命令
|
||||
char cmdstr[CMD_LEN] = {0},reply[CMD_LEN] = {0};
|
||||
|
||||
if (!t15execute(T15SYSTEM_INFO,cmdstr,reply))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// 开始解释数据.
|
||||
char *p;
|
||||
char tflag[5], iflag, rflag;
|
||||
{
|
||||
if (! (p = strchr (reply, '[') ) )
|
||||
return 0;
|
||||
|
||||
p++;
|
||||
|
||||
if (*p && (*p == ']' || *p == 'z' || *p == 'Z') )
|
||||
return 0;
|
||||
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
rflag=(char)strtol(tflag,NULL,16);
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
|
||||
if( rflag != 0x00) //Err-Flag is set
|
||||
{
|
||||
return rflag;
|
||||
}
|
||||
else
|
||||
{
|
||||
iflag=(char)strtol(tflag,NULL,16);
|
||||
*pinfoFlag = iflag;
|
||||
|
||||
p += 16;
|
||||
if( iflag & 0x01 )
|
||||
{
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
*pDSFID =(char)strtol(tflag,NULL,16);
|
||||
}
|
||||
if( iflag & 0x02 )
|
||||
{
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
*pAFI =(char)strtol(tflag,NULL,16);
|
||||
}
|
||||
if( iflag & 0x04 )
|
||||
{
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
*pBlockNum =(char)strtol(tflag,NULL,16);
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
*pBlockSize = ((char)strtol(tflag,NULL,16))&0x1F;
|
||||
}
|
||||
if( iflag & 0x08 )
|
||||
{
|
||||
tflag[0]=*p++;
|
||||
tflag[1]=*p++;
|
||||
tflag[2]='\0';
|
||||
*pICRef = ((char)strtol(tflag,NULL,16))&0x1F;
|
||||
}
|
||||
}
|
||||
}
|
||||
return rflag;
|
||||
}
|
||||
|
||||
|
||||
// VCD不处理一些参数的合法性判断,比如nFirstBlock等
|
||||
// 因为:1. VCD没有必要保留;2.射频场中可能存在不同的VICC,从而导致参数不同;
|
||||
// 3. 不要说VCD知道每个UID的参数,所以判断。虽然可以,但不合理,即使pucUID=NULL,即处理SELECT模式的VICC时,虽然
|
||||
// VCD的确知道是哪个VICC。这个任务应该交给VICC,VICC会返回错误通知用户;
|
||||
// 用户可以在inventory后,使用get system info获取需要的信息;
|
||||
|
||||
int CVCDOurs::readBlocks( int nFirstBlock, int nBlockNum, uchar_t *pDat, uchar_t *pSecurity, uchar_t *pucUID )
|
||||
{
|
||||
// m_nBlockNum想表示 VICC 的可用block数。
|
||||
// 可以不做这种判断,毕竟,m_nBlockNum不是VCD的参数,而是VICC的属性,应该由VICC判断并返回.
|
||||
char str[100];
|
||||
|
||||
t15bOption = 0;
|
||||
t15bInventory = 0;
|
||||
if( pucUID )
|
||||
{
|
||||
t15bSelect = 0;
|
||||
t15bAddress=1;
|
||||
HexToString( pucUID, 8, str );
|
||||
t15changeByteOrder( t15UID, str, 16 );
|
||||
t15UID[16]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t15bSelect = 1;
|
||||
t15bAddress =0;
|
||||
}
|
||||
|
||||
sprintf( t15FirstBN, "%02d", nFirstBlock );
|
||||
sprintf( t15NumBl, "%02d", nBlockNum - 1 );
|
||||
|
||||
//执行命令
|
||||
char cmdstr[CMD_LEN] = {0},reply[CMD_LEN] = {0};
|
||||
|
||||
int cmdno = ( nBlockNum == 1 )?READ_SB:READ_MB;
|
||||
if (!t15execute(cmdno,cmdstr,reply))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//处理返回数据
|
||||
char *p,*q,tstr[CMD_LEN];
|
||||
p=strchr(reply,'[')+1;
|
||||
|
||||
if(NULL == p)
|
||||
return 0;
|
||||
|
||||
q=strchr(p,']');
|
||||
|
||||
if(NULL == q)
|
||||
return 0;
|
||||
|
||||
*q=0;
|
||||
|
||||
// if('z' == *p )
|
||||
// 2023/7/4,修改:
|
||||
// 返回的reply,出现过如下的值: “[]”
|
||||
// 此时*q=0,导致']'被0替换;
|
||||
// 后续代码 tf[0/1] = *p++,导致 p > q;
|
||||
// 再调用t15changeByteOrder()时,q-p = -2 < 0;
|
||||
// 而:t15changeByteOrder()函数定义如下:
|
||||
/*
|
||||
HF15693_API void t15changeByteOrder(char *pout, const char *pin,int lenbytes)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < lenbytes; i += 2)
|
||||
{
|
||||
pout[lenbytes-2-i] = pin[i];
|
||||
pout[lenbytes-1-i] = pin[i+1];
|
||||
}
|
||||
pout[lenbytes] = 0;
|
||||
}
|
||||
*/
|
||||
// 在 lenbytes =-2 < 0的情况下,直接访问了pout[-2],导致程序直接崩溃!
|
||||
|
||||
// 修改如下:
|
||||
if('z' == *p || p == q )
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
// 同时放开该判断!
|
||||
if(2 < q-p)
|
||||
{
|
||||
char tf[3];
|
||||
tf[0]=*p++;
|
||||
tf[1]=*p++;
|
||||
tf[2]=0;
|
||||
int tfi=strtoul(tf,NULL,10);
|
||||
|
||||
// 因为代码:*q = 0,导致tf是空串;
|
||||
// 因此tfi=0, 所以下述语句起不到判断作用;
|
||||
if(OP_RESPONSE_FLAG_ERROR & tfi) //检查标志位,是否发生错误
|
||||
return 0;
|
||||
|
||||
if(READ_SB == cmdno)
|
||||
{
|
||||
t15changeByteOrder(tstr,p,q-p);
|
||||
}
|
||||
else
|
||||
{
|
||||
int i=strtoul(t15NumBl,NULL,10)+1;
|
||||
t15changeByteOrder_MB(tstr,p,i);
|
||||
}
|
||||
|
||||
StringToHex( tstr, pDat );
|
||||
return strlen( tstr )/2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CVCDOurs::getValueFromChar( char c )
|
||||
{
|
||||
if( c >= '0' && c <= '9' )
|
||||
{
|
||||
return c-'0';
|
||||
}
|
||||
else if( c >= 'a' && c <= 'f' )
|
||||
{
|
||||
return c-'a' + 10;
|
||||
}
|
||||
else if( c >= 'A' && c <= 'F' )
|
||||
{
|
||||
return c - 'A' + 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
// 返回UID的字节长度
|
||||
// 如果不是偶数,把str最后一个字符丢弃
|
||||
int CVCDOurs::StringToHex( char *str, uchar_t aucUID[] )
|
||||
{
|
||||
int k = 0;
|
||||
int t1, t2;
|
||||
|
||||
int len = strlen( str )/2;
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
t1 = getValueFromChar(str[k++]);
|
||||
t2 = getValueFromChar(str[k++]);
|
||||
aucUID[i] = ( t1 << 4 ) + t2;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
void CVCDOurs::HexToString( uchar_t aucDat[], int len, char *str )
|
||||
{
|
||||
int k = 0;
|
||||
int t;
|
||||
for( int i = 0; i < len; i++ )
|
||||
{
|
||||
t = aucDat[i] >> 4;
|
||||
if( t <= 9 )
|
||||
{
|
||||
str[k++] = t + '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
str[k++] = t - 10 + 'A';
|
||||
}
|
||||
|
||||
t = aucDat[i] & 0x0F;
|
||||
if( t <= 9 )
|
||||
{
|
||||
str[k++] = t + '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
str[k++] = t - 10 + 'A';
|
||||
}
|
||||
}
|
||||
str[k] = '\0';
|
||||
}
|
||||
int CVCDOurs::writeBlocks( int nFirstBlock, int nBlockNum, uchar_t *pDat, uchar_t *pucUID )
|
||||
{
|
||||
int k = 0;
|
||||
for( int i = 0; i < nBlockNum; i++ )
|
||||
{
|
||||
k += writeBlock( nFirstBlock + i, pDat+i*8, pucUID );
|
||||
}
|
||||
return k;
|
||||
}
|
||||
int CVCDOurs::writeBlock( int nFirstBlock, uchar_t *pDat, uchar_t *pucUID )
|
||||
{
|
||||
char str[100];
|
||||
|
||||
t15bOption = 0;
|
||||
t15bInventory = 0;
|
||||
t15bSelect = 0;
|
||||
if( pucUID )
|
||||
{
|
||||
t15bAddress = 1;
|
||||
HexToString( pucUID, 8, str );
|
||||
t15changeByteOrder( t15UID, str, 16 );
|
||||
t15UID[16]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
t15bAddress = 0;
|
||||
}
|
||||
|
||||
sprintf( t15FirstBN, "%02d", nFirstBlock );
|
||||
sprintf( t15NumBl, "00" );
|
||||
|
||||
// 此处4是blocksize.
|
||||
HexToString( pDat, 4, str );
|
||||
t15changeByteOrder( t15Data, str, 8 );
|
||||
t15Data[8]=0;
|
||||
strcpy( str, t15Data );
|
||||
|
||||
char cmdstr[CMD_LEN] = {0}, reply[CMD_LEN] = {0};
|
||||
|
||||
if (!t15execute(WRITE_SB,cmdstr,reply))
|
||||
{
|
||||
// MessageBox("执行错误,可能参数错误", 0, MB_ICONSTOP);
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
char *p,*e;
|
||||
|
||||
if (! (p = strchr (reply, '[') ) )
|
||||
return 0;
|
||||
|
||||
p++;
|
||||
|
||||
//if (*p && (*p == ']' || *p == 'z' || *p == 'Z') ) return 2;
|
||||
if (! (e = strchr(p, ']')))
|
||||
return 0;
|
||||
|
||||
if (e == p)
|
||||
return 0;
|
||||
|
||||
// if( 2 <= e-p)
|
||||
{
|
||||
char tf[3];
|
||||
tf[0] = *p++;
|
||||
tf[1] = *p++;
|
||||
tf[2] = '\0';
|
||||
|
||||
char tfi=(char)strtol(tf,NULL,16);//
|
||||
|
||||
if (OP_RESPONSE_FLAG_ERROR & tfi)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
}
|
146
VCDOurs.h
Normal file
146
VCDOurs.h
Normal file
@ -0,0 +1,146 @@
|
||||
//#pragma once
|
||||
|
||||
#ifndef _VCD_OURS_H_
|
||||
#define _VCD_OURS_H_
|
||||
|
||||
#include "VCD.h"
|
||||
|
||||
#include "HF15693.h"
|
||||
|
||||
class CVCDOurs :
|
||||
public CVCD
|
||||
{
|
||||
public:
|
||||
CVCDOurs(void);
|
||||
~CVCDOurs(void);
|
||||
|
||||
public:
|
||||
virtual int connectReaderByCOM( int comno );
|
||||
virtual void disconnectReaderByCOM( );
|
||||
public:
|
||||
int inventory( char *pTagUID[] );
|
||||
|
||||
// 执行inventory!
|
||||
// ours reader: 支持AFI
|
||||
// 但:不返回DSFID.
|
||||
//
|
||||
virtual int inventory(
|
||||
bool bAFIUsed,
|
||||
uchar_t ucAFI,
|
||||
int nViccNum, // 应用层的接收的UID数量;
|
||||
uchar_t aucDSFID[],
|
||||
uchar_t aucUID[][8] );
|
||||
|
||||
// 通过该命令,或者VICC信息
|
||||
//
|
||||
virtual int getSystemInfo(
|
||||
uchar_t *pucUID,
|
||||
uchar_t *pinfoFlag,
|
||||
uchar_t *pDSFID, uchar_t *pAFI, uchar_t *pBlockNum, uchar_t *pBlockSize, uchar_t *pICRef
|
||||
);
|
||||
//------------------------------------------
|
||||
// 操作
|
||||
// 操作类命令,寻址模式只能:地址,或者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.
|
||||
)
|
||||
{
|
||||
// 没有处理optional-flag
|
||||
//
|
||||
t15bOption = optional_flag;
|
||||
return readBlocks( ucBlkno, 1, buf, pucSecurity, pucUID );
|
||||
}
|
||||
|
||||
// 0x21
|
||||
virtual int writeSingleBlock(
|
||||
uchar_t *pucUID, // NULL表示select模式
|
||||
uchar_t ucBlkno, //
|
||||
uchar_t ucBlksize,
|
||||
uchar_t buf[] )
|
||||
{
|
||||
return writeBlocks( ucBlkno, 1, buf, pucUID );
|
||||
}
|
||||
// 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.
|
||||
)
|
||||
{
|
||||
t15bOption = optional_flag;
|
||||
return readBlocks( ucBlkno, blocknum+1, buf, aucSecurity, pucUID );
|
||||
}
|
||||
|
||||
// 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 writeBlocks( ucBlkno, blocknum, buf, pucUID );
|
||||
}
|
||||
// 返回UID的长度
|
||||
int StringToHex( char *str, uchar_t aucUID[] );
|
||||
bool opened( )
|
||||
{
|
||||
return m_bComOpened;
|
||||
}
|
||||
|
||||
protected:
|
||||
int doInventory( char *pTagUID[] );
|
||||
// CMD: 0x2B
|
||||
//
|
||||
protected:
|
||||
void HexToString( uchar_t aucDat[], int len, char *str );
|
||||
int getValueFromChar( char c );
|
||||
|
||||
// 数据保存方式:
|
||||
// block从 L->H
|
||||
// 每个block中,从byte 0 - byte N-1
|
||||
// 返回:<0 失败
|
||||
// block序号,从0开始.
|
||||
// pTagUID = NULL,表示采用select模式。
|
||||
// nBlockNum: 1...
|
||||
int readBlocks( int nFirstBlock, int nBlockNum, uchar_t *pDat, uchar_t *pSecurity, uchar_t *pucTagUID = NULL );
|
||||
int writeBlocks( int nFirstBlock, int nBlockNum, uchar_t *pDat,uchar_t *pucTagUID = NULL );
|
||||
|
||||
// nxp dosn't support write multiblocks;
|
||||
int writeBlock( int nFirstBlock, uchar_t *pDat,uchar_t *pucTagUID = NULL );
|
||||
|
||||
|
||||
int getVICCstr( char *szUID )
|
||||
{
|
||||
uchar_t aucUID[8];
|
||||
if( StringToHex( szUID, aucUID ))
|
||||
{
|
||||
return getVICC( aucUID );
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool setVICCStr( char *szUID )
|
||||
{
|
||||
uchar_t aucUID[8];
|
||||
if( StringToHex( szUID, aucUID ))
|
||||
{
|
||||
return setVICC( aucUID );
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected:
|
||||
bool m_bComOpened;
|
||||
};
|
||||
|
||||
#endif;
|
64
databaseAPI.cpp
Normal file
64
databaseAPI.cpp
Normal file
@ -0,0 +1,64 @@
|
||||
#include "databaseAPI.h"
|
||||
|
||||
Database::Database(QSqlDatabase database)
|
||||
{
|
||||
db = database;
|
||||
db.setDatabaseName(databaseName);
|
||||
db.setUserName(userName);
|
||||
}
|
||||
|
||||
Database::Database(QSqlDatabase database, QString hostName, int port, QString password)
|
||||
{
|
||||
db = database;
|
||||
db.setDatabaseName(databaseName);
|
||||
db.setUserName(userName);
|
||||
db.setHostName(hostName);
|
||||
db.setPort(port);
|
||||
db.setPassword(password);
|
||||
}
|
||||
|
||||
QSqlDatabase Database::getDatabase()
|
||||
{
|
||||
return db;
|
||||
}
|
||||
|
||||
void Database::setHostName(QString hostName)
|
||||
{
|
||||
db.setHostName(hostName);
|
||||
}
|
||||
|
||||
QString Database::getHostName()
|
||||
{
|
||||
return db.hostName();
|
||||
}
|
||||
|
||||
void Database::setPort(int port)
|
||||
{
|
||||
db.setPort(port);
|
||||
}
|
||||
|
||||
int Database::getPort()
|
||||
{
|
||||
return db.port();
|
||||
}
|
||||
|
||||
void Database::setPassword(QString password)
|
||||
{
|
||||
db.setPassword(password);
|
||||
}
|
||||
|
||||
bool Database::is_connected()
|
||||
{
|
||||
return connected;
|
||||
}
|
||||
|
||||
bool Database::open()
|
||||
{
|
||||
connected = db.open();
|
||||
return connected;
|
||||
}
|
||||
|
||||
Database::~Database()
|
||||
{
|
||||
db.close();
|
||||
}
|
@ -15,68 +15,17 @@ private:
|
||||
QString userName = QString("cardManageSystem");
|
||||
|
||||
public:
|
||||
Database(QSqlDatabase database)
|
||||
{
|
||||
db = database;
|
||||
db.setDatabaseName(databaseName);
|
||||
db.setUserName(userName);
|
||||
}
|
||||
|
||||
Database(QSqlDatabase database, QString hostName, int port, QString password)
|
||||
{
|
||||
db = database;
|
||||
db.setDatabaseName(databaseName);
|
||||
db.setUserName(userName);
|
||||
db.setHostName(hostName);
|
||||
db.setPort(port);
|
||||
db.setPassword(password);
|
||||
}
|
||||
|
||||
QSqlDatabase getDatabase()
|
||||
{
|
||||
return db;
|
||||
}
|
||||
|
||||
void setHostName(QString hostName)
|
||||
{
|
||||
db.setHostName(hostName);
|
||||
}
|
||||
|
||||
QString getHostName()
|
||||
{
|
||||
return db.hostName();
|
||||
}
|
||||
|
||||
void setPort(int port)
|
||||
{
|
||||
db.setPort(port);
|
||||
}
|
||||
|
||||
int getPort()
|
||||
{
|
||||
return db.port();
|
||||
}
|
||||
|
||||
void setPassword(QString password)
|
||||
{
|
||||
db.setPassword(password);
|
||||
}
|
||||
|
||||
bool is_connected()
|
||||
{
|
||||
return connected;
|
||||
}
|
||||
|
||||
bool open()
|
||||
{
|
||||
connected = db.open();
|
||||
return connected;
|
||||
}
|
||||
|
||||
~Database()
|
||||
{
|
||||
db.close();
|
||||
}
|
||||
Database(QSqlDatabase database);
|
||||
Database(QSqlDatabase database, QString hostName, int port, QString password);
|
||||
QSqlDatabase getDatabase();
|
||||
void setHostName(QString hostName);
|
||||
QString getHostName();
|
||||
void setPort(int port);
|
||||
int getPort();
|
||||
void setPassword(QString password);
|
||||
bool is_connected();
|
||||
bool open();
|
||||
~Database();
|
||||
};
|
||||
|
||||
|
||||
|
41
deviceAPI.cpp
Normal file
41
deviceAPI.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include "deviceAPI.h"
|
||||
|
||||
bool Device::is_connected()
|
||||
{
|
||||
return connected;
|
||||
}
|
||||
|
||||
|
||||
bool Device::is_depositAllowed()
|
||||
{
|
||||
return depositAllowed;
|
||||
}
|
||||
|
||||
|
||||
void Device::setDevice(QString name, Database *db)
|
||||
{
|
||||
QSqlQuery query(db->getDatabase());
|
||||
QString sql = QString("select * from device where `name` = '%1';").arg(name);
|
||||
query.exec(sql);
|
||||
if (query.next())
|
||||
{
|
||||
connected = true;
|
||||
this->name = name;
|
||||
depositAllowed = query.value(2).toBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
connected = false;
|
||||
depositAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QString Device::getName()
|
||||
{
|
||||
if (connected) {
|
||||
if (depositAllowed) return name + QString("(可充值)");
|
||||
else return name + QString("(仅可消费)");
|
||||
}
|
||||
else return QString("未指定设备名");
|
||||
}
|
40
deviceAPI.h
40
deviceAPI.h
@ -13,42 +13,10 @@ private:
|
||||
QString name = QString("未指定设备名");
|
||||
|
||||
public:
|
||||
bool is_connected()
|
||||
{
|
||||
return connected;
|
||||
}
|
||||
|
||||
bool is_depositAllowed()
|
||||
{
|
||||
return depositAllowed;
|
||||
}
|
||||
|
||||
void setDevice(QString name, Database *db)
|
||||
{
|
||||
QSqlQuery query(db->getDatabase());
|
||||
QString sql = QString("select * from device where `name` = '%1';").arg(name);
|
||||
query.exec(sql);
|
||||
if (query.next())
|
||||
{
|
||||
connected = true;
|
||||
this->name = name;
|
||||
depositAllowed = query.value(2).toBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
connected = false;
|
||||
depositAllowed = false;
|
||||
}
|
||||
}
|
||||
|
||||
QString getName()
|
||||
{
|
||||
if (connected) {
|
||||
if (depositAllowed) return name + QString("(可充值)");
|
||||
else return name + QString("(仅可消费)");
|
||||
}
|
||||
else return QString("未指定设备名");
|
||||
}
|
||||
bool is_connected();
|
||||
bool is_depositAllowed();
|
||||
void setDevice(QString name, Database *db);
|
||||
QString getName();
|
||||
};
|
||||
|
||||
#endif // DEVICEAPI_H
|
||||
|
@ -1,8 +1,8 @@
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
#include "settingPage.h"
|
||||
#include "quitAppPage.h"
|
||||
#include "newCardPage.h"
|
||||
#include "settingPage.cpp"
|
||||
#include "quitAppPage.cpp"
|
||||
#include "newCardPage.cpp"
|
||||
|
||||
MainWindow::MainWindow(QWidget *parent)
|
||||
: QMainWindow(parent)
|
||||
@ -36,6 +36,12 @@ MainWindow::MainWindow(QWidget *parent)
|
||||
deviceLabel = new QLabel(device.getName());
|
||||
ui->statusBar->addWidget(deviceLabel);
|
||||
|
||||
|
||||
// 清空部分输入框
|
||||
ui->userIdBox->clear();
|
||||
|
||||
|
||||
// 设置启动页面
|
||||
ui->stackedWidget->setCurrentWidget(ui->settingPage);
|
||||
}
|
||||
|
||||
|
@ -277,7 +277,7 @@
|
||||
</property>
|
||||
<layout class="QGridLayout" name="gridLayout_2">
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="spinBox">
|
||||
<widget class="QSpinBox" name="userIdBox">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
@ -290,6 +290,12 @@
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1000</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
|
@ -1,6 +1,3 @@
|
||||
#ifndef NEWCARDPAGE_H
|
||||
#define NEWCARDPAGE_H
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
@ -14,7 +11,10 @@ void MainWindow::on_NewCardAction_triggered()
|
||||
if (!ready())
|
||||
{
|
||||
QMessageBox::warning(this, QString("提示"), QString("读卡器或数据库未连接,请设置。"));
|
||||
ui->stackedWidget->setCurrentWidget(ui->settingPage);
|
||||
if (ui->stackedWidget->currentWidget() != ui->settingPage)
|
||||
{
|
||||
ui->stackedWidget->setCurrentWidget(ui->settingPage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -28,8 +28,7 @@ void MainWindow::on_NewCardAction_triggered()
|
||||
*/
|
||||
void MainWindow::on_inventoryButton_clicked()
|
||||
{
|
||||
|
||||
QStringList cardIdList = reader.inventory(10); // 最多显示10张卡
|
||||
ui->cardIdBox->clear();
|
||||
ui->cardIdBox->addItems(cardIdList);
|
||||
}
|
||||
|
||||
|
||||
#endif // NEWCARDPAGE_H
|
@ -1,6 +1,3 @@
|
||||
#ifndef QUITAPPPAGE_H
|
||||
#define QUITAPPPAGE_H
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
@ -23,6 +20,3 @@ void MainWindow::on_confirmQuitButton_clicked()
|
||||
{
|
||||
this->close();
|
||||
}
|
||||
|
||||
|
||||
#endif // QUITAPPPAGE_H
|
46
readerAPI.cpp
Normal file
46
readerAPI.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
#include "readerAPI.h"
|
||||
|
||||
|
||||
bool Reader::is_connected()
|
||||
{
|
||||
return comNumber > 0;
|
||||
}
|
||||
|
||||
|
||||
bool Reader::connect()
|
||||
{
|
||||
if (CVCDOurs::connectReaderByCOM(comNumber))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
comNumber = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Reader::setComNumber(int comNumber)
|
||||
{
|
||||
this->comNumber = comNumber;
|
||||
}
|
||||
|
||||
int Reader::getComNumber()
|
||||
{
|
||||
return comNumber;
|
||||
}
|
||||
|
||||
QStringList Reader::inventory(int maxViccNum)
|
||||
{
|
||||
uchar_t (*aucUID)[8] = (uchar_t (*)[8])malloc(maxViccNum * sizeof(*aucUID));;
|
||||
int receivedViccNum = CVCDOurs::inventory(false, '\0', maxViccNum, nullptr, aucUID);
|
||||
QStringList uidList;
|
||||
for (int i = 0; i < receivedViccNum; ++i)
|
||||
{
|
||||
char uidStr[8];
|
||||
CVCDOurs::HexToString(aucUID[i], 8, uidStr);
|
||||
uidList.push_back(QString::fromStdString(uidStr));
|
||||
}
|
||||
free(aucUID);
|
||||
return uidList;
|
||||
}
|
41
readerAPI.h
41
readerAPI.h
@ -2,42 +2,25 @@
|
||||
#define READERAPI_H
|
||||
|
||||
#include <HF15693.h>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <VCDOurs.h>
|
||||
|
||||
typedef unsigned char uchar_t;
|
||||
|
||||
class Reader
|
||||
class Reader : private CVCDOurs
|
||||
{
|
||||
private:
|
||||
int comNumber = -1; // com口号,若未连接为-1
|
||||
|
||||
public:
|
||||
bool is_connected()
|
||||
{
|
||||
return comNumber > 0;
|
||||
}
|
||||
|
||||
bool connectReader()
|
||||
{
|
||||
if (t15portOpen(comNumber))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
comNumber = -1;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void setComNumber(int comNumber)
|
||||
{
|
||||
this->comNumber = comNumber;
|
||||
}
|
||||
|
||||
int getComNumber()
|
||||
{
|
||||
return comNumber;
|
||||
}
|
||||
bool is_connected();
|
||||
bool connect();
|
||||
void setComNumber(int comNumber);
|
||||
int getComNumber();
|
||||
QStringList inventory(int maxViccNum);
|
||||
};
|
||||
|
||||
|
||||
#endif // READERAPI_H
|
||||
|
@ -1,6 +1,3 @@
|
||||
#ifndef SETTINGPAGE_H
|
||||
#define SETTINGPAGE_H
|
||||
|
||||
#include "mainwindow.h"
|
||||
#include "ui_mainwindow.h"
|
||||
|
||||
@ -45,7 +42,7 @@ void MainWindow::on_connectReaderButton_clicked()
|
||||
{
|
||||
int comNumber = ui->comNumberBox->value();
|
||||
reader.setComNumber(comNumber);
|
||||
bool connectSuccess = reader.connectReader();
|
||||
bool connectSuccess = reader.connect();
|
||||
|
||||
if (!connectSuccess) {
|
||||
QString warningMessage = QString("COM") + QString::number(comNumber);
|
||||
@ -105,6 +102,3 @@ bool MainWindow::ready()
|
||||
if (!device.is_connected()) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
#endif // SETTINGPAGE_H
|
Loading…
x
Reference in New Issue
Block a user