640 lines
19 KiB
C++
640 lines
19 KiB
C++
#include "rfidfunction.h"
|
||
#include "sm3.h"
|
||
#include "sm4.h"
|
||
#include <QTime>
|
||
#include <QCoreApplication>
|
||
|
||
|
||
// 计算校验和并输出
|
||
void RFIDFunction::CheckSumOut(unsigned char* buf, unsigned char len)
|
||
{
|
||
unsigned char i;
|
||
unsigned char checksum;
|
||
checksum = 0;
|
||
for (i = 0; i < (len - 1); i++)
|
||
{
|
||
checksum ^= buf[i]; // 逐位异或计算校验和
|
||
}
|
||
buf[len - 1] = (unsigned char)~checksum; // 取反作为校验和
|
||
}
|
||
|
||
// 检查输入的校验和是否正确
|
||
bool RFIDFunction::CheckSumIn(unsigned char* buf, unsigned char len)
|
||
{
|
||
unsigned char i;
|
||
unsigned char checksum;
|
||
checksum = 0;
|
||
for (i = 0; i < (len - 1); i++)
|
||
{
|
||
checksum ^= buf[i]; // 逐位异或计算校验和
|
||
}
|
||
if (buf[len - 1] == (unsigned char)~checksum) // 比较校验和
|
||
{
|
||
return true; // 校验和正确
|
||
}
|
||
return false; // 校验和错误
|
||
}
|
||
|
||
// 将十六进制字符串转换为字节数组
|
||
void hexStrToByte(const QByteArray& hexIn, unsigned char* dest)
|
||
{
|
||
int sourceLen = hexIn.size();
|
||
unsigned char* source = (unsigned char*)hexIn.constData();
|
||
short i;
|
||
unsigned char highByte, lowByte;
|
||
|
||
for (i = 0; i < sourceLen; i += 2)
|
||
{
|
||
highByte = toupper(source[i]); // 高位
|
||
lowByte = toupper(source[i + 1]); // 低位
|
||
|
||
if (highByte > 0x39)
|
||
{
|
||
highByte -= 0x37; // A-F转换
|
||
}
|
||
else
|
||
{
|
||
highByte -= 0x30; // 0-9转换
|
||
}
|
||
|
||
if (lowByte > 0x39)
|
||
{
|
||
lowByte -= 0x37; // A-F转换
|
||
}
|
||
else
|
||
{
|
||
lowByte -= 0x30; // 0-9转换
|
||
}
|
||
dest[i / 2] = (highByte << 4) | lowByte; // 合并高低位
|
||
}
|
||
return;
|
||
}
|
||
|
||
// 检测输入的字符是否是有效的16进制字符
|
||
bool isValidHex(const QByteArray& input)
|
||
{
|
||
int length = input.size(); // 获取输入的长度
|
||
for (int i = 0; i < length; ++i) // 使用传统的for循环
|
||
{
|
||
char c = input[i]; // 获取当前字符
|
||
// 检查字符是否在0-9, A-F, a-f范围内
|
||
if (!((c >= '0' && c <= '9') ||
|
||
(c >= 'A' && c <= 'F') ||
|
||
(c >= 'a' && c <= 'f')))
|
||
{
|
||
return false; // 如果有无效字符,返回false
|
||
}
|
||
}
|
||
return true; // 所有字符均有效,返回true
|
||
}
|
||
|
||
|
||
void sleepMs(unsigned int msec)
|
||
{
|
||
QTime dieTime = QTime::currentTime().addMSecs(msec);
|
||
|
||
while( QTime::currentTime() < dieTime )
|
||
|
||
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
|
||
}
|
||
|
||
|
||
RFIDFunction::RFIDFunction(QObject *parent)
|
||
: QObject(parent),m_SerialPort(NULL)
|
||
{
|
||
m_SerialSate = initSerialPortAndOpen("COM3"); // 初始化串口
|
||
}
|
||
|
||
RFIDFunction::~RFIDFunction()
|
||
{
|
||
m_SerialPort->deleteLater();
|
||
}
|
||
|
||
/***
|
||
* @描述 : 创建读写卡的密码(Key_A和Key_B)
|
||
* @入参 : info 生成密码的数据
|
||
* @输出 : 无
|
||
* @返回 : 密钥的原始数据
|
||
*/
|
||
const QByteArray RFIDFunction::createPassword(const QByteArray& info)
|
||
{
|
||
if (info.isEmpty())
|
||
{
|
||
return ""; // 如果输入为空,返回空
|
||
}
|
||
int inputSize = info.size();
|
||
if (inputSize > 8192)
|
||
{
|
||
return ""; // 如果输入大小超过限制,返回空
|
||
}
|
||
//先用SM3对原始数据进行哈希生成
|
||
unsigned char hashDataOrigin[32] = { 0 };
|
||
SM3::sm3Hash((unsigned char*)info.data(), inputSize, hashDataOrigin); // 生成哈希
|
||
|
||
//接着使用哈希生成SM4加密密钥
|
||
unsigned char sm4Key[16] = { 0 };
|
||
unsigned char sm4IV[16] = { 0 };
|
||
int index_1 = 0;
|
||
int index_2 = 0;
|
||
for (int i = 0; i < 32; i++)
|
||
{
|
||
if (i % 2 == 0)
|
||
{
|
||
sm4Key[index_1++] = hashDataOrigin[i]; // 偶数位作为SM4密钥
|
||
}
|
||
else
|
||
{
|
||
sm4IV[index_2++] = hashDataOrigin[i]; // 奇数位作为SM4初始向量
|
||
}
|
||
}
|
||
|
||
//再用SM4对原始数据进行加密
|
||
unsigned char out[8192] = {0};
|
||
sm4_context sm4Ctx;
|
||
SM4::sm4_setkey_enc(&sm4Ctx, sm4Key); // 设置SM4加密密钥
|
||
SM4::sm4_crypt_cbc(&sm4Ctx, SM4_ENCRYPT, inputSize, sm4IV, (unsigned char*)info.data(), out); // 执行SM4加密
|
||
|
||
//最后再用SM3对加密后的数据取哈希
|
||
unsigned char hashEncrypted[32] = { 0 };
|
||
SM3::sm3Hash(out, inputSize, hashEncrypted); // 生成加密数据的哈希
|
||
index_1 = 0;
|
||
char key[16] = { 0 };
|
||
for (int i = 0; i < 32; i++)
|
||
{
|
||
if (i % 2 != 0)//取哈希的奇数位作为最终的密码
|
||
{
|
||
key[index_1++] = hashEncrypted[i];
|
||
}
|
||
}
|
||
return QByteArray(key,16).toHex(); // 返回最终的密码
|
||
}
|
||
|
||
|
||
bool RFIDFunction::getSerialState()
|
||
{
|
||
return m_SerialSate; // 返回串口状态
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::initSerialPortAndOpen(const QString& portName,
|
||
BaudRateType baudRate,
|
||
DataBitsType setDataBits,
|
||
StopBitsType stopBits,
|
||
ParityType parity)
|
||
{
|
||
m_SerialPort = new Posix_QextSerialPort("/dev/ttyO3",QextSerialBase::Polling); // 创建串口对象
|
||
m_SerialPort->setPortName(portName); // 设置串口名称
|
||
m_SerialPort->setBaudRate((BaudRateType)baudRate); // 设置波特率
|
||
m_SerialPort->setDataBits(setDataBits); // 设置数据位
|
||
m_SerialPort->setStopBits(stopBits); // 设置停止位
|
||
m_SerialPort->setParity(parity); // 设置校验位
|
||
m_SerialPort->setFlowControl(FLOW_OFF);
|
||
if (m_SerialPort->open(QIODevice::ReadWrite)) // 打开串口
|
||
{
|
||
return Serial_Error; // 打开失败,返回串口错误
|
||
}
|
||
|
||
return No_Error; // 打开成功,返回无错误
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::setOriginPassword(const QByteArray& psw)
|
||
{
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x03; // 命令头
|
||
com[1] = 0x0B; // 数据长度
|
||
com[2] = 0xC4; // 命令类型
|
||
com[3] = 0x20; // 额外数据
|
||
unsigned char hexOut[32] = { 0 }; // 存储转换后的十六进制数据
|
||
hexStrToByte(psw, hexOut); // 将密码转换为字节数组
|
||
memcpy(com + 4, hexOut, 6); // 将密码添加到命令中
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
|
||
//QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x03) && (revData[1] == 0x08) && (revData[2] == 0xC4) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::setWriteAndReadPassword(const QByteArray& writePassword, const QByteArray& readPassword, KeyFunction keyFunc)
|
||
{
|
||
if (writePassword.isEmpty() || readPassword.isEmpty())
|
||
{
|
||
return Data_Is_Empty_Error; // 如果密码为空,返回错误
|
||
}
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x03; // 命令头
|
||
com[1] = 0x15; // 数据长度
|
||
com[2] = 0xC3; // 命令类型
|
||
com[3] = 0x20; // 额外数据
|
||
unsigned char hexOut[32] = { 0 }; // 存储转换后的十六进制数据
|
||
hexStrToByte(writePassword.toHex(), hexOut); // 将写密码转换为字节数组
|
||
memcpy(com + 4, hexOut, 6); // 将写密码添加到命令中
|
||
switch (keyFunc) // 根据密钥功能设置命令
|
||
{
|
||
case RFIDFunction::KeyA_Same_KeyB:
|
||
/*
|
||
* 控制如下:KEYA,KEYB 可以用来读 、写 、增值 、减值 、更改扇区密钥
|
||
*/
|
||
com[10] = 0xFF; // 设置KEYA和KEYB相同
|
||
com[11] = 0x07; // 设置权限
|
||
com[12] = 0x80; // 设置操作
|
||
com[13] = 0x69; // 设置结束标志
|
||
break;
|
||
case RFIDFunction::KeyB_Control_KeyA:
|
||
/*
|
||
控制如下:KEYA 可以读数据块 、减值 、查询余额
|
||
KEYB 可以读写数据块 、增值 、减值 、查询余额
|
||
KEYA 、KEYB 不可读,KEYA,KEYB 由 KEYB 修改
|
||
*/
|
||
com[10] = 0x08; // 设置KEYB控制KEYA
|
||
com[11] = 0x77; // 设置权限
|
||
com[12] = 0x8F; // 设置操作
|
||
com[13] = 0x69; // 设置结束标志
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
memset(hexOut, 0, 32); // 清空hexOut
|
||
hexStrToByte(readPassword.toHex(), hexOut); // 将读密码转换为字节数组
|
||
memcpy(com + 14, hexOut, 6); // 将读密码添加到命令中
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
|
||
QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
|
||
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x03) && (revData[1] == 0x08) && (revData[2] == 0xC3) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::setEncryptedBlock(KeyType type, ControlBlock block)
|
||
{
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x01; // 命令头
|
||
com[1] = 0x08; // 数据长度
|
||
switch (type)//只有两种密码,A和B
|
||
{
|
||
case RFIDFunction::KEY_A:
|
||
com[2] = 0xA5; // 设置为KEY_A
|
||
break;
|
||
case RFIDFunction::KEY_B:
|
||
com[2] = 0x5A; // 设置为KEY_B
|
||
break;
|
||
default:
|
||
com[2] = 0xA5; // 默认设置为KEY_A
|
||
break;
|
||
}
|
||
com[3] = 0x20; // 额外数据
|
||
memcpy(com + 4, &block, 1); // 将加密块添加到命令中
|
||
|
||
com[5] = 0x01;//蜂鸣器开 0x00不开
|
||
com[6] = 0x00;//保留
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
|
||
QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
|
||
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x01) && (revData[1] == 0x08) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::writeDataToBlock(KeyType type, DataBlock block, const QByteArray& data)
|
||
{
|
||
if (data.isEmpty())
|
||
{
|
||
return Data_Is_Empty_Error; // 如果数据为空,返回错误
|
||
}
|
||
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x01; // 命令头
|
||
com[1] = 0x17; // 数据长度
|
||
switch (type)//只有两种密码,A和B
|
||
{
|
||
case RFIDFunction::KEY_A:
|
||
com[2] = 0xA4; // 设置为KEY_A
|
||
break;
|
||
case RFIDFunction::KEY_B:
|
||
com[2] = 0x5B; // 设置为KEY_B
|
||
break;
|
||
default:
|
||
com[2] = 0xA4; // 默认设置为KEY_A
|
||
break;
|
||
}
|
||
com[3] = 0x20; // 额外数据
|
||
memcpy(com + 4, &block, 1); // 将数据块添加到命令中
|
||
|
||
com[5] = 0x01;//蜂鸣器开 0x00不开
|
||
unsigned char hexOut[32] = { 0 }; // 存储转换后的十六进制数据
|
||
memset(hexOut, 0, 32); // 清空hexOut
|
||
if (!isValidHex(data)) // 检查数据是否合法
|
||
{
|
||
return Data_Is_Illegal_Error; // 数据非法
|
||
}
|
||
hexStrToByte(data, hexOut); // 将数据转换为字节数组
|
||
memcpy(com + 6, hexOut, 16); // 将数据添加到命令中
|
||
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x01) && (revData[1] == 0x08) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::readDataFromBlock(KeyType type, DataBlock block, QByteArray& data)
|
||
{
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x01; // 命令头
|
||
com[1] = 0x08; // 数据长度
|
||
switch (type)//只有两种密码,A和B
|
||
{
|
||
case RFIDFunction::KEY_A:
|
||
com[2] = 0xA3; // 设置为KEY_A
|
||
break;
|
||
case RFIDFunction::KEY_B:
|
||
com[2] = 0x5C; // 设置为KEY_B
|
||
break;
|
||
default:
|
||
com[2] = 0xA3; // 默认设置为KEY_A
|
||
break;
|
||
}
|
||
com[3] = 0x20; // 额外数据
|
||
|
||
memcpy(com + 4, &block, 1); // 将数据块添加到命令中
|
||
|
||
com[5] = 0x01;//蜂鸣器开 0x00不开
|
||
com[6] = 0x00;//保留
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
//QByteArray AAA = readData.toHex(); // 转换为十六进制字符串
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x01) && (revData[1] == 0x16) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
data = QByteArray::fromHex(readData.mid(3,16));
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|
||
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::setWorkMode(WorkMode mode, DataBlock block, UploadMode uploadMode)
|
||
{
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x03; // 命令头
|
||
com[1] = 0x08; // 数据长度
|
||
com[2] = 0xC1; // 工作模式
|
||
com[3] = 0x20; // 设备号数据
|
||
|
||
memcpy(com + 4, &mode, 1); // 将工作模式添加到命令中
|
||
switch (mode)
|
||
{
|
||
case RFIDFunction::Command_Mode:
|
||
com[5] = 0x00;
|
||
com[6] = 0x00;
|
||
break;
|
||
case RFIDFunction::Auto_Read_Card_Num_Mode:
|
||
com[5] = 0x00;
|
||
com[6] = uploadMode;
|
||
break;
|
||
case RFIDFunction::Auto_Read_Data_Mode:
|
||
case RFIDFunction::Auto_Read_Card_Num_Data_Mode:
|
||
default:
|
||
com[5] = block;
|
||
com[6] = uploadMode;
|
||
break;
|
||
}
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
QByteArray AAA = readData.toHex(); // 转换为十六进制字符串
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x03) && (revData[1] == 0x08) && (revData[2] == com[2]) && (revData[3] == 0x20)) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|
||
|
||
RFIDFunction::ErrorCode RFIDFunction::getReaderAddress(QByteArray& psw)
|
||
{
|
||
unsigned char com[32] = { 0 }; // 命令数组
|
||
com[0] = 0x02; // 命令头
|
||
com[1] = 0x08; // 数据长度
|
||
com[2] = 0xB0; // 命令类型
|
||
com[3] = 0x00; // 额外数据
|
||
com[4] = 0x00; // 额外数据
|
||
com[5] = 0x00; // 额外数据
|
||
com[6] = 0x00; // 额外数据
|
||
|
||
CheckSumOut(com, com[1]); // 计算校验和
|
||
|
||
QByteArray AAA = QByteArray((char*)com, com[1]).toHex(); // 转换为十六进制字符串
|
||
if (m_SerialPort->isOpen()) // 检查串口是否打开
|
||
{
|
||
qint64 len = m_SerialPort->write(QByteArray((char*)com, com[1])); // 发送命令
|
||
if (len != com[1]) // 检查发送长度
|
||
{
|
||
return Send_Data_Error; // 发送错误
|
||
}
|
||
// 等待请求完成
|
||
sleepMs(200);
|
||
|
||
QByteArray readData = m_SerialPort->readAll(); // 读取返回数据
|
||
unsigned char revData[32] = { 0 }; // 存储返回数据
|
||
memcpy(revData, readData.data(), readData.size()); // 复制返回数据
|
||
if ((revData[0] == 0x02) && (revData[1] == 0x08) && (revData[2] == com[2])) //判断是否为写数据返回的数据包
|
||
{
|
||
bool status = CheckSumIn(revData, revData[1]); //计算校验和
|
||
if (status)
|
||
{
|
||
if (revData[4] == 0x00) //写数据块成功
|
||
{
|
||
psw = QByteArray::fromHex(QByteArray(revData[5], 1));
|
||
return No_Error; // 返回无错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Check_Error; // 校验和错误
|
||
}
|
||
}
|
||
else
|
||
{
|
||
return Received_Data_Error; // 返回数据错误
|
||
}
|
||
}
|
||
return Serial_Error; // 串口错误
|
||
}
|