#include "userlock.h"

userlock::userlock(QSerialPort *serial, QObject *parent)
{
    this->devserial = serial;
}

quint16 userlock::Modbus_Crc(QByteArray &data, quint8 count)
{
    quint16 crc,carry_flag,a;
    crc = 0xffff;
    for (quint8 i = 0; i < count; i++)
    {
        crc=crc ^ (quint8)(data.at(i));
        for (quint8 j = 0; j < 8; j++)
        {
            a = crc;
            carry_flag = a & 0x0001;
            crc = crc >> 1;
            if (carry_flag == 1)
            {
                crc = crc ^ 0xA001;
            }
        }
    }
    return crc;
}

// 发送数据给下位机
void userlock::sendData(QByteArray &sendData)
{
    // qDebug() << "sendData: " << sendData.toHex();
    quint16 crc = Modbus_Crc(sendData, sendData.size());
    // 输出CRC16校验和
    // qDebug() << "CRC16:" << QString::number(crc, 16).toUpper();
    sendData.append((quint8)crc);
    sendData.append((quint8)(crc >> 8));
    sendData.prepend(0x68);
    sendData.append(0x16);

    // qDebug() << "QByteArray: " << sendData.toHex();
    // 发送数据帧
    devserial->clear(QSerialPort::AllDirections);
    devserial->write(sendData);
    devserial->waitForBytesWritten(1000);
}

// 读取下位机发来数据
bool userlock::readData(QByteArray *data, quint16 timeout)
{
    if(!devserial->waitForReadyRead(timeout))
    {
        return false;
    }
    msleep(100);
    *data = devserial->readAll();

    qDebug() << "readData: " << data->toHex();
    quint8 head = data->at(0);
    quint8 end = data->at(data->size() - 1);
    if(head == 0x68 && end == 0x16)
    {
        quint16 crc1 = Modbus_Crc(*(data + 1), data->size() - 3);
        quint16 crc2 = quint8(data->at(data->size() - 2));
        crc2 <<= 8;
        crc2 += quint8(data->at(data->size() - 3));
        if(crc1 == crc2)
        {
            return true;
        }
    }
    return false;
}

bool userlock::readLockStat(void)
{
    quint8 dataArray[] = {0x01, 0x02, 0x00};
    QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
    this->sendData(ba);

    QByteArray data;
    if(true == readData(&data, 1000))
    {
        workstat = lockWorkStat::open;
        return true;
    }
    return false;
}

bool userlock::openLock(void)
{
    quint8 dataArray[] = {0x01, 0x03, 0x00};
    QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
    this->sendData(ba);

    QByteArray data;
    if(true == readData(&data, 1000))
    {
        if(data.at(2) == 0x83
            && data.at(3) == 0x01
            && data.at(4) == 0x01)
        {
            return true;
        }
        else{
            return false;
        }
    }
}

bool userlock::closeLock(void)
{
    quint8 dataArray[] = {0x04, 0x00, 0x21};
    QByteArray ba(reinterpret_cast<char*>(dataArray), sizeof(dataArray));
    this->sendData(ba);

    QByteArray data;
    if(true == readData(&data, 1000))
    {

    }
}

bool userlock::checkLock(void)
{

}

