#include "machine.h"
#include <QTime>
#include <QApplication>

/*
Machine的dll如果是Release版本的在应用程序中只能在Release下调用，
否则调用不成功（连接不上）,Machine的dll如果是Debug版本,
应用程序中在Debug下调用成功；
*/

//------------------------------------------

QByteArray g_receiveBuff;
DataExFuns g_exfuns = {NULL,NULL,NULL,NULL,NULL};

// 发送数据
int operatorSendData(u8 * pDatBuf, int len)
{
    if (pDatBuf != NULL && len != 0)
    {
        // 不准备通过该函数发送数据
    }
    return 0;
}

// 得到发送缓冲区空闲长度
int operatorGetSdFreeLen(void)
{
    return 0;  // 认没有空间
}

// 接收数据
int operatorGetData(u8 * pDat, int expectLen)
{
    int len = g_receiveBuff.size();
    if (len > expectLen)
    {
        len = expectLen;
    }

    //if (len != 0 && pDat != NULL)
    if (len == expectLen && pDat != NULL)  //使len等于expectLen(串口下接收数据暴露的问题)
    {
        memcpy(pDat, g_receiveBuff.data(), len);
        g_receiveBuff.remove(0, len);
    }
    else
    {
        len = 0;
    }

    return len;
}

// 已接收数据长度
int operatorGetRsLen(void)
{
    return g_receiveBuff.size();
}

void delayMs(u32 ms)
{
    QDateTime oldTime, curTime;
    oldTime = QDateTime::currentDateTime();
    while(1)
    {
        curTime = QDateTime::currentDateTime();
        if(oldTime.msecsTo(curTime) > ms)
        {
            break;
        }
    }
}

void initDataExFuns(void)
{
    g_exfuns.sendCommData = operatorSendData;
    g_exfuns.getCommData = operatorGetData;
    g_exfuns.getRsvLen = operatorGetRsLen;
    g_exfuns.getTrsFreeLen = operatorGetSdFreeLen;

    g_exfuns.delay = delayMs;
}

//------------------------------------------


Machine::Machine(QObject *parent) :
    QObject(parent),
    m_pTcpThread(NULL),
    m_pTcpClient(NULL),
    m_pComThread(NULL),
    m_pComPort(NULL),
    m_startComm(0)
{
    memset(&m_mcStatus, 0, sizeof(MCStatus));           // 机器状态
    memset(&m_mcPara, 0, sizeof(ParaStruct));           // 机器参数信息
    memset(&m_wkPara, 0, sizeof(ParaStruct));           // 工作参数信息
    memset(&m_mcPrePara, 0, sizeof(ParaStruct));           // 机器预留参数信息
    memset(&m_wkPrePara, 0, sizeof(ParaStruct));           // 工作预留参数信息
    memset(&m_frameAnglePara, 0, sizeof(EmbMvAng)); //动框角度参数
    memset(&m_mcInfo,0,sizeof(MCInfo));                 // 机器信息
    memset(&m_ds16Head,0,sizeof(DataDs16FileHead));   // 文件头
    memset(&m_lotData,0,sizeof(McLotData));                // 物联数据
    memset(&m_exboardInfo,0,sizeof(ExBoardInfo));        // 外围板信息

    memset(&m_sensorsStaDat, 0, sizeof(SensorsBitmap));        // 传感器信号状态位图
    memset(&m_sensorEnBmp, 0, sizeof(SensorsBitmap));        // 传感器信号有效位图

    memset(&m_transCtrl, 0, sizeof(FileTransCtrl));     // 文件传输信息

    m_pSendTimer = new QTimer(this);
    m_pSendTimer->setInterval(100);    // 设置定时间隔100毫秒
    connect(m_pSendTimer, SIGNAL(timeout()), this, SLOT(onSendTimer()));
    m_transCtrl.pFileHead = new DataDs16FileHead;
    m_transCtrl.pAppHead  = new AppFileHead;
    m_transCtrl.pBoardHead  = new BoardFileHead;
    m_transCtrl.pDatBuff  = new u8[MAX_FILE_SIZE];
    m_startComm = 0;
    m_connected = 0;
    m_statusEn = 0;
    m_mcParaEn = 0;
    m_wkParaEn = 0;
    m_mcPreParaEn = 0;
    m_wkPreParaEn = 0;
    m_frameAngleParaEn = 0;
    m_sensorStaEn = 0;
    m_sensorBmpEn = 0;

    m_statusToggle = 0;
    m_fileTransEn = 0;
    m_transBreak = 0;
    m_totalSendNum = 0;
    m_totalPacketNum = 0;
    m_connectMode = 0;

    initDataExFuns();
}

Machine::~Machine()
{
    if (m_startComm != 0)
    {
        if(m_connectMode == USE_TCP_COMM)
        {
            m_pTcpThread->quit();
            m_pTcpThread->wait();
        }
        else if(m_connectMode == USE_SERIAL_COMM)
        {
            m_pComThread->quit();
            m_pComThread->wait();
        }
    }
    if (m_transCtrl.pFileHead != NULL)
    {
        delete []m_transCtrl.pFileHead;
        m_transCtrl.pFileHead = NULL;
    }
    if (m_transCtrl.pDatBuff != NULL)
    {
        delete []m_transCtrl.pDatBuff;
        m_transCtrl.pDatBuff = NULL;
    }

    if(m_connectMode == USE_TCP_COMM)
    {
        if(m_pTcpThread != NULL)
        {
            delete m_pTcpThread;
        }
    }
    else if(m_connectMode == USE_SERIAL_COMM)
    {
        if(m_pComThread != NULL)
        {
            delete m_pComThread;
        }
    }
}

//初始化通讯连接方式
void Machine::initConnectMode(s16 val)
{
    m_connectMode = val;
    if(m_connectMode == USE_TCP_COMM)//网口
    {
        m_pTcpThread = new QThread();
        m_pTcpClient = new TcpClient();
    }
    else if(m_connectMode == USE_SERIAL_COMM)//串口
    {
        m_pComThread = new QThread();
        m_pComPort = new ComPort();
        connect(m_pComPort, SIGNAL(siSerialPortOpenState(int)), this, SLOT(slIfOpenSerialPort(int)) );
    }
}

void Machine::setConfigFileName(QString configfilename)
{
    m_configFileName = configfilename;
    if(m_connectMode == USE_TCP_COMM)//网口
    {
        m_pTcpClient->setConfigFileName(m_configFileName);
    }
}

//设置串口名称
void Machine::setComportName(QString portName)
{
    if(m_pComPort == NULL)
    {
        return;
    }

    if(m_connectMode == USE_SERIAL_COMM)//串口
    {
        m_pComPort->setComPortName(portName);
    }
}

QString Machine::getConfigFileName()
{
    return m_configFileName;
}

int Machine::startCommunication()
{
    if (m_startComm == 0)
    {
        //   qDebug() << "Machine " << QThread::currentThread();

        if(m_connectMode == USE_TCP_COMM)//网口
        {
            if (m_configFileName.isEmpty())
            {
                qDebug() << "mast call SetConfigFileName first ";
            }

            m_pTcpClient->moveToThread(m_pTcpThread);     // 移动对象到线程中

            //    connect(qApp, SIGNAL(finished()), m_pTcpThread, SLOT(finished()));

            connect(m_pTcpThread, SIGNAL(started()), m_pTcpClient, SLOT(connectToServer()) );
            connect(m_pTcpThread, SIGNAL(finished()), m_pTcpClient, SLOT(deleteLater()) );  // 退出删除对象

            connect(m_pTcpClient, SIGNAL(siConnectSta(int)),
                    this, SLOT(slotConnectSta(int)), Qt::AutoConnection);             // 连接状态改变
            connect(m_pTcpClient, SIGNAL(siConnectErr(QString)),
                    this, SLOT(slotConnectErr(QString)), Qt::AutoConnection);         // 接收到通讯错误
            connect(m_pTcpClient, SIGNAL(siReceiveData(QByteArray)),
                    this, SLOT(slotReceiveData(QByteArray)), Qt::AutoConnection);     // 接收到数据
            connect(this, SIGNAL(siSendData(QByteArray)),
                    m_pTcpClient, SLOT(slotSendData(QByteArray)), Qt::AutoConnection); // 发送数据的槽

            m_pTcpThread->start();    // 启动线程
        }

        if(m_connectMode == USE_SERIAL_COMM)//串口
        {
            m_pComPort->moveToThread(m_pComThread);

            connect(m_pComThread, SIGNAL(started()), m_pComPort, SLOT(initComm()) );
            connect(m_pComThread, SIGNAL(finished()), m_pComPort, SLOT(deleteLater()) );  // 退出删除对象

            connect(m_pComPort, SIGNAL(siReceiveData(QByteArray)),
                    this, SLOT(slotReceiveData(QByteArray)), Qt::QueuedConnection);       // 接收到数据
            connect(this, SIGNAL(siSendData(QByteArray)),
                    m_pComPort, SLOT(slotSendData(QByteArray)), Qt::QueuedConnection); // 发送数据的槽

            m_pComThread->start();  // 启动线程
        }
        m_startComm = 1;
    }
    return m_startComm;
}

// 连接状态改变的槽函数
void Machine::slotConnectSta(int sta)
{
    //    qDebug() << "SlotConnectSta" << sta;
    m_connected = sta;
}

// 接收到通讯错误槽函数
void Machine::slotConnectErr(QString errinfo)
{
    if(errinfo.length() <= 0){}
    //qDebug() << "SlotConnectErr" << errinfo;
}

void Machine::setMcStatusAsMc(u8 * buff, u16 len, int toggle)
{
    //memcpy(&m_mcStatus, buff, sizeof(MCStatus));
    memcpy(&m_mcStatus, buff, len);
    m_statusEn = 1;
    emit(siStatusChange(toggle));
}

// 接收到数据的槽函数
void Machine::slotReceiveData(QByteArray dat)
{
    int rslt;
    DataPacket packet;
    OperPacket * operpkt = (OperPacket *)(&packet);

    //    qDebug() << "SlotReceiveData size=" << dat.size();

    g_receiveBuff.append(dat);
    //qDebug()<<"append dat size"<<dat.size();
    do
    {
        rslt = getANormalPacket(&g_exfuns, &packet);
        // 分析数据包，并执行
        if (rslt > 0)	// 收到数据包
        {
            //qDebug()<<"getANormalPacket rslt="<<rslt<<operpkt->packet.fldp.cmd;
            switch(operpkt->packet.fldp.cmd)	// 先按固定长度解析
            {
            case DCMD_REQUEST_DAT:          	// 请求文件数据
            {
               if (m_transCtrl.transActive == TRANS_ACTIVE)
                {
                    if (1   &&
                            m_transCtrl.transflag == TRANS_REQUEST &&       // 请求传输数据模式
                            m_transCtrl.fileType    == operpkt->dRequestDatBlock.fileType &&
                            m_transCtrl.fileIdx     == operpkt->dRequestDatBlock.fileIdx &&
                            m_transCtrl.fileId      == operpkt->dRequestDatBlock.fileId &&
                            1   )
                    {
                        qDebug("in request mode, send block idx=%d", operpkt->dRequestDatBlock.datBlockIdx);
                        transFileData(m_transCtrl, operpkt->dRequestDatBlock.datBlockIdx);
                    }
                }
                break;
            }
            case DCMD_SEND_MC_INFO:         	// 发送机器信息
            {
                memcpy(&m_mcInfo, operpkt->dSendMcInfo.exData, sizeof(MCInfo));
                emit(siMcInfoChange( ));
                break;
            }

            case DCMD_SEND_DEBUG_INFO:         	// 发送调试信息
            {
                memcpy(&m_debugInfo, operpkt->sendDebugInfo.exData, sizeof(DebugInfo));
                emit(siDebugInfo( ));
                break;
            }

            case DCMD_SEND_BOARDVER:        // 发送外围板程序版本
            {
                if (operpkt->sendBoardVer.protocolType == BN_PROTOCOL_HEAD) // 机头板
                {
                    memcpy(&m_exboardInfo.headInfo[operpkt->sendBoardVer.nodeId - 1].softwareVerStr,
                            operpkt->sendBoardVer.ver, BOARD_VER_LEN*sizeof(char)); //复制版本

                    memcpy(&m_exboardInfo.headInfo[operpkt->sendBoardVer.nodeId - 1].nodeType,
                            &operpkt->sendBoardVer.nodeType, sizeof(u8)); //复制节点类型    -rq
                }
                else if (operpkt->sendBoardVer.protocolType == BN_PROTOCOL_HCPS) // 勾剪扣换控制板
                {
                    memcpy(&m_exboardInfo.hcpsInfo[operpkt->sendBoardVer.nodeId - 1].softwareVerStr,
                            operpkt->sendBoardVer.ver, BOARD_VER_LEN*sizeof(char));
                }
                else if (operpkt->sendBoardVer.protocolType == BN_PROTOCOL_DCUT) //D86
                {
                    memcpy(&m_exboardInfo.d86Info[operpkt->sendBoardVer.nodeId - 1].softwareVerStr,
                            operpkt->sendBoardVer.ver, BOARD_VER_LEN*sizeof(char));
                }

                emit(siEXBInfoChange());
                break;
            }

            case DCMD_SEND_MC_STATUS:			// 发送机器状态
            {
                setMcStatusAsMc(operpkt->dSendMcStatus.exData, operpkt->dSendMcStatus.exLen, operpkt->dSendMcStatus.toggle);
                break;
            }

            case DCMD_SEND_MC_PARAS:			// 发送机器参数
            {
                int type;

                type = operpkt->dSendMcParas.paraType;
                if (operpkt->dSendMcParas.exLen == sizeof(ParaStruct) ||
                    operpkt->dSendMcParas.exLen == sizeof(EmbMvAng))
                {
                    if (type == SEW_MCPARA_MACH || type == SEW_MCPARA_DEF_MC)
                    {
                        memcpy(&m_mcPara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_mcParaEn = 1;
                    }
                    else if (type == SEW_MCPARA_WORK || type == SEW_MCPARA_DEF_WK)
                    {
                        memcpy(&m_wkPara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_wkParaEn = 1;
                    }
                    else if (type == SEW_REVMCPARA_MACH || type == SEW_MCPARA_DEF_MC)
                    {
                        memcpy(&m_mcPrePara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_mcPreParaEn = 1;
                    }
                    else if (type == SEW_REVMCPARA_WORK || type == SEW_MCPARA_DEF_WK)
                    {
                        memcpy(&m_wkPrePara, operpkt->dSendMcParas.exData, sizeof(ParaStruct));
                        m_wkPreParaEn = 1;
                    }
                    else if(type == EMB_MVSTANG_PARA)
                    {
                        memcpy(&m_frameAnglePara, operpkt->dSendMcParas.exData, sizeof(EmbMvAng));
                        m_frameAngleParaEn = 1;
                    }
                    else
                    {
                        break;
                    }

                    //因为之前请求了机器参数和工作参数，所以当两个参数都返回时，再触发信号和槽
                    //  if( m_mcParaEn==1 && m_wkParaEn==1)
                    {
                        printf("emit SiParaChange\r\n");
                        emit(siParaChange(type, 0));
                    }
                }
                else if (operpkt->dSendMcParas.exLen == sizeof(u32))
                {
                    int id, idx;
                    id = operpkt->dSendMcParas.paraId;
                    idx = id - 1;
                    if (idx > 0 && idx < PARA_NUM)
                    {
                        idx *= sizeof(u32);
                        if (type == SEW_MCPARA_MACH)
                        {
                            memcpy((u8*)(&m_mcPara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_mcParaEn = 1;
                        }
                        else if (type == SEW_MCPARA_WORK)
                        {
                            memcpy((u8*)(&m_wkPara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_wkParaEn = 1;
                        }
                        else if (type == SEW_REVMCPARA_MACH)
                        {
                            memcpy((u8*)(&m_mcPrePara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_mcPreParaEn = 1;
                        }
                        else if (type == SEW_REVMCPARA_WORK)
                        {
                            memcpy((u8*)(&m_wkPrePara)+idx, operpkt->dSendMcParas.exData, sizeof(u32));
                            m_wkPreParaEn = 1;
                        }
                        else
                        {
                            break;
                        }
                        emit(siParaChange(type, id));
                    }
                }

                break;
            }

            case DCMD_SEND_SENSORS:         	// 发送传感信号
            {
                int len;
                len = sizeof(SensorsBitmap);
                if (len > operpkt->dSendSensors.exLen)
                {
                    len = operpkt->dSendSensors.exLen;
                }
                memset(m_sensorsStaDat.bitmap, 0, sizeof(SensorsBitmap));
                memcpy(m_sensorsStaDat.bitmap, operpkt->dSendSensors.exData, len);
                m_sensorStaEn = 1;
                //qDebug("get DCMD_SEND_SENSORS");
                emit(siSensorChange(m_sensorsStaDat));
                break;
            }
            case DCMD_SEND_FILE_INFO:			// 发送文件信息
            {
                memcpy(&m_ds16Head, operpkt->dSendFileInfo.exData, sizeof(DataDs16FileHead));
                emit(siFileInfoChange());
                break;
            }
            case DCMD_SEND_TRANS_RESULT:		// 发送传输结果
            {
                printf("get DCMD_SEND_TRANS_RESULT\r\n");
                m_transCtrl.lenBmp = operpkt->dSendTransResult.exLen;
                m_transCtrl.transActive = operpkt->dSendTransResult.active;
                m_transCtrl.transflag = operpkt->dSendTransResult.result;
                if (m_transCtrl.lenBmp != 0)
                {
                    memcpy(m_transCtrl.rsvBitmap, operpkt->dSendTransResult.exData, m_transCtrl.lenBmp);
                }
                m_fileTransEn = 1;

                emit (siTransResultChange());

                break;
            }
#if(0)
            case DCMD_SEND_TRANS_RESULT2:		// 发送传输结果2
            {
                printf("get DCMD_SEND_TRANS_RESULT2\r\n");
                m_transCtrl.lenBmp = operpkt->dSendTransResult.exLen+MAX_EXDP_LEN;
                m_transCtrl.transActive = operpkt->dSendTransResult.active;
                m_transCtrl.transflag = operpkt->dSendTransResult.result;
                if (m_transCtrl.lenBmp != 0)
                {
                    memcpy(&m_transCtrl.rsvBitmap[MAX_EXDP_LEN], operpkt->dSendTransResult.exData, m_transCtrl.lenBmp-MAX_EXDP_LEN);
                }
                m_fileTransEn = 1;

                emit (siTransResultChange());

                break;
            }
#endif
            case DCMD_SEND_SENSOR_BMP:		// 传感器信号有效位图
            {
                int len;
                len = sizeof(SensorsBitmap);
                if (len > operpkt->dSendSensorBmp.exLen)
                {
                    len = operpkt->dSendSensorBmp.exLen;
                }
                memset(m_sensorEnBmp.bitmap, 0, sizeof(SensorsBitmap));
                memcpy(m_sensorEnBmp.bitmap, operpkt->dSendSensorBmp.exData, len);
                m_sensorBmpEn = 1;
                qDebug("get DCMD_SEND_SENSOR_BMP");

                emit (siSensorEnBitmap(m_sensorEnBmp));
                break;
            }

            case  DCMD_SEND_HEADPARA:// 发送机头板参数
            {
                if (operpkt->dSendMcParas.exLen == PARA_NUM)
                {
                    memcpy(&m_exboardInfo.headInfo[operpkt->boardPara.nodeId - 1].paraBuf, &operpkt->boardPara.exData, operpkt->boardPara.exLen);
                    //节点类型，用于判断是毛巾还是平绣的机头板数据
                    memcpy(&m_exboardInfo.headInfo[operpkt->boardPara.nodeId - 1].nodeType, &operpkt->boardPara.nodeType,sizeof(u8));
                    emit(siEXBParaChange());
                    break;
                }
                else if (operpkt->dSendMcParas.exLen == sizeof(u32))
                {
                    int id, idx;
                    id = operpkt->dSendMcParas.paraId;
                    idx = id - 1;
                    if (idx > 0 && idx < PARA_NUM)
                    {
                        idx *= sizeof(u32);
                        memcpy((u8*)&m_exboardInfo.headInfo[operpkt->sendBoardVer.nodeId - 1].paraBuf+idx, operpkt->boardPara.exData, sizeof(u32));
                        emit(siEXBParaChange());
                        break;
                    }
                }
                break;
            }

            case  DCMD_SEND_HCPSPARA:// 发送勾剪扣换控制板参数(换色板)//目前是毛巾换色板，平绣换色板没用到-rq
            {
                if (operpkt->dSendMcParas.exLen == PARA_NUM)
                {
                    memcpy(&m_exboardInfo.hcpsInfo[operpkt->boardPara.nodeId-1].paraBuf, operpkt->boardPara.exData, sizeof(u32)*PARA_NUM);
                    emit(siEXBParaChange());
                    break;
                }
                else if (operpkt->dSendMcParas.exLen == sizeof(u32))
                {
                    int id, idx;
                    id = operpkt->dSendMcParas.paraId;
                    idx = id - 1;
                    if (idx > 0 && idx < PARA_NUM)
                    {
                        idx *= sizeof(u32);
                        memcpy((u8*)&m_exboardInfo.hcpsInfo[operpkt->sendBoardVer.nodeId].paraBuf+idx, operpkt->boardPara.exData, sizeof(u32));
                        emit(siEXBParaChange());
                        break;
                    }
                }
                break;
            }

            case  DCMD_SEND_LOTDATA:// 发送物联网数据
            {
                memcpy(&m_lotData, operpkt->dSendMcInfo.exData, sizeof(McLotData));
                //再定义一个结构体
                emit(siReceiveLotData());

                break;
            }

            case UCMD_SET_FILE_PARAS://边框检查超限后重新设置起绣点
            {
                DataFilePos newPos;
                memset(&newPos, 0, sizeof(DataFilePos));
                memcpy((u8*)&newPos, operpkt->setFileParas.exData, sizeof(DataFilePos));
                //qDebug()<<"siDataFilePos";
                emit(siDataFilePos(newPos));
                break;
            }

            default:
                break;
            }
        }
        else
        {
            break;
        }
    }while(1);
}

//-------------------------------------------------------------------
// 读取机器信息
void Machine::getInfoFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcInfo.cmdCode = UCMD_GET_MC_INFO;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

void Machine::getFileInfoFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcInfo.cmdCode = UCMD_GET_FILE_INFO;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取外围板程序版本
void Machine::getExboardInfoFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.rdBoardVer.cmdCode = UCMD_GET_BOARD_VER;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取机器状态
int Machine::getStatusFromMachine()
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcStatus.cmdCode = UCMD_GET_MC_STATUS;
    sendPacket.getMcStatus.toggle = m_statusToggle;
    rslt = m_statusToggle;
    m_statusToggle++;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
    return rslt;
}

// 读取机器物联数据
void Machine::getNetDataFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.boardPara.cmdCode = UCMD_GET_LOT_DATA;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取机器参数
void Machine::getParasFromMachine(int type, int id)
{
    int mctype = -1;
    int wktype = -1;
    int frametype = -1;//动框角度
    if (type == -1)
    {
        mctype = SEW_MCPARA_MACH;
        wktype = SEW_MCPARA_WORK;
        frametype = EMB_MVSTANG_PARA;
        m_mcParaEn = 0;
        m_wkParaEn = 0;
        m_frameAngleParaEn = 0;
    }
    else
    {
        if(type == SEW_MCPARA_MACH )
        {
            mctype = SEW_MCPARA_MACH;
            m_mcParaEn = 0;
        }
        if(type == SEW_MCPARA_WORK )
        {
            wktype = SEW_MCPARA_WORK;
            m_wkParaEn = 0;
        }
        if(type == EMB_MVSTANG_PARA)
        {
            frametype = EMB_MVSTANG_PARA;
            m_frameAngleParaEn = 0;
        }
    }

    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcParas.cmdCode = UCMD_GET_MC_PARAS;

    if (mctype == SEW_MCPARA_MACH)
    {
        sendPacket.getMcParas.paraType = (u16)mctype;
        sendPacket.getMcParas.paraId = (u16)id;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    if (wktype == SEW_MCPARA_WORK)
    {
        sendPacket.getMcParas.paraType = (u16)wktype;
        sendPacket.getMcParas.paraId = id;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    if (frametype == EMB_MVSTANG_PARA)
    {
        sendPacket.getMcParas.paraType = (u16)frametype;
        sendPacket.getMcParas.paraId = id;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }
}

// 读取毛巾换色板参数
void Machine::getHcpsParasFromMachine(int nodeType)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.boardPara.cmdCode = UCMD_GET_HCPS_PARA;
    sendPacket.boardPara.nodeId = nodeType;//毛巾换色板
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取外围板参数  （根据节点类型 ，发送读取平绣机头板参数，还是毛巾机头板参数）
void Machine::getHeadParasFromMachine(int id,int nodeType)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.boardPara.cmdCode = UCMD_GET_HEAD_PARA;
    sendPacket.boardPara.nodeId = id;
    sendPacket.boardPara.nodeType = nodeType;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取传感信号
void Machine::getSensorsFromMachine(int backtype)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getSensors.cmdCode = UCMD_GET_SENSORS;
    sendPacket.getSensors.backType = (u16)backtype;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 读取传输结果
void Machine::getTransResultFromMachine(int fileid)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getTransResult.cmdCode = UCMD_GET_TRANS_RESULT;
    sendPacket.getTransResult.fileId = (u16)fileid;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 获取传感器有效标志位图
void Machine::getSensorEnBmpFromMachine()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getSensorBmp.cmdCode = UCMD_GET_SENSOR_BMP;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

//-------------------------------------------------------------------
//----------------------------设置状态命令
#ifdef UCMD_SET_MC_STATUS
// 清除错误

void Machine::setMcStatus(int stacode, int para)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setMcStatus.cmdCode = UCMD_SET_MC_STATUS;
    sendPacket.setMcStatus.staCode = (u16)stacode;
    sendPacket.setMcStatus.para = (u16)para;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

void Machine::cleanError()
{
    setMcStatus(MC_STA_CLENA_ERR);
}

// 设置允许工作状态
void Machine::setEnableWorkSta()
{
    setMcStatus(MC_STA_EN_WORK);
}

// 设置禁止工作状态
void Machine::setDisableWorkSta()
{
    setMcStatus(MC_STA_DIS_WORK);
}

// 设置允许工作时间状态
void Machine::setEnableWorkTime()
{
    setMcStatus(MC_STA_EN_TIME);
}

// 设置禁止工作时间状态
void Machine::setDisableWorkTime()
{
    setMcStatus(MC_STA_DIS_TIME);
}

// 重置产量
void Machine::resetOutput()
{
    setMcStatus(MC_CLEAN_COUNT);
}

// 手动工作状态
void Machine::setToManualWork()
{
    setMcStatus(MC_STA_MANUAL);
}

// 自动工作状态
void Machine::setToAutoWork()
{
    setMcStatus(MC_STA_AUTO);
}

// 文件切换
void Machine::switchWorkFile(int idx)
{
    setMcStatus(MC_FILE_SWITCH, idx);
}

// 设置经过的时间(即关机时间)
void Machine::setShutDownTime(u8 type, u32 time)
{
    int rslt;
    OperPacket sendPacket;
    //int size = sizeof(ParaStruct);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setElapsedTime.cmdCode = UCMD_SET_ELAPSED_TIME;
    sendPacket.setElapsedTime.type = type;
    sendPacket.setElapsedTime.time = time;

    rslt = packetAFLDP(&sendPacket.packet);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }
}

// 文件失效
void Machine::invalidateWorkFile(int idx)
{
    setMcStatus(MC_INVALID_FILE, idx);
}

// 清除刷新参数标志
void Machine::cleanNewParaFlag()
{
    setMcStatus(MC_CLEAN_PARA_REF);
}

// 模拟工作状态
void Machine::setSimulateWork()
{
    setMcStatus(MC_SET_TO_SIMULATE);
}

// 正常工作状态
void Machine::setNormalWork()
{
    setMcStatus(MC_SET_TO_NORMAL);
}

//退出遍历状态
void Machine::exitTraverStates()
{
    setMcStatus(MC_STA_EXIT_TRA);
}

//退出断线测试
void Machine::exitDetectTest()
{
    setMcStatus(MC_STA_EXIT_THREADBK);
}

// 底线计数复位
void Machine::resetBobbinCounter()
{
    setMcStatus(MC_CLEAN_BOBBIN);
}

//  设置为 进入 扫描传感器状态
void Machine::entrySensorScan()
{
    //
    setMcStatus(MC_SET_ENTRY_SCAN_SENSOR);
}

//  设置为 退出 扫描传感器状态
void Machine::exitSensorScan()
{
    //
    setMcStatus(MC_SET_EXIT_SCAN_SENSOR);
}


#endif

//----------------------------

void Machine::setParasToMachine(int type, ParaStruct & para)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(ParaStruct);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

//设置动框角度参数
void Machine::setFrameAngleParasToMachine(int type, EmbMvAng &para)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(EmbMvAng);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

void Machine::setAParasToMachine(int type, int idx, u32 value)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(value);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;
    sendPacket.setParas.paraId = idx;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&value, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

//设置机头板参数
void Machine::setEXBHeadParasToMachine(HeadInfo &para,int id)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(u32)*PARA_NUM;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.boardPara.cmdCode = UCMD_SET_HEAD_PARA;
    sendPacket.boardPara.nodeId = 0;
    sendPacket.boardPara.nodeType = id;
    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para.paraBuf, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

//设置换色板参数
void Machine::setEXBHcpsParasToMachine(HcpsInfo &para, int idx)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(u32)*PARA_NUM;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.boardPara.cmdCode = UCMD_SET_HCPS_PARA;
    sendPacket.boardPara.nodeId = idx+1;
    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para.paraBuf, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

//隔头绣，贴布绣
void Machine::setHeadPatchParasToMachine(int type, ParaStruct &para, u16 packID)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(ParaStruct);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.paraId = packID;
    sendPacket.setParas.cmdCode = UCMD_SET_MC_PARAS;
    sendPacket.setParas.paraType = (u16)type;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

//毛巾高度
void Machine::setTowelHighParasToMachine(int type, ParaStruct &para, u16 packID)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(ParaStruct);
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setParas.paraId = packID;
    sendPacket.setParas.cmdCode = UCMD_SET_FILE_EXDATA;
    sendPacket.setParas.paraType = (u16)type;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&para, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

void Machine::setMcPara(ParaStruct * pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_mcPara, pPara, size);
    setParasToMachine(SEW_MCPARA_MACH, m_mcPara);
}

void Machine::setWkPara(ParaStruct * pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_wkPara, pPara, size);
    setParasToMachine(SEW_MCPARA_WORK, m_wkPara);
}

void Machine::setMcPrePara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_mcPrePara, pPara, size);
    setParasToMachine(SEW_REVMCPARA_MACH, m_mcPrePara);
}

void Machine::setWkPrePara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(ParaStruct);
    memcpy(&m_wkPrePara, pPara, size);
    setParasToMachine(SEW_REVMCPARA_WORK, m_wkPrePara);
}

//动框角度参数设置
void Machine::setFrameAnglePara(EmbMvAng *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(EmbMvAng);
    memcpy(&m_frameAnglePara, pPara, size);
    setFrameAngleParasToMachine(EMB_MVSTANG_PARA, m_frameAnglePara);
}

void Machine::setAMcPara(int id, u32 value)
{
    setAParasToMachine(SEW_MCPARA_MACH, id, value);
}

void Machine::setAWkPara(int id, u32 value)
{
    setAParasToMachine(SEW_MCPARA_WORK, id, value);
}

void Machine::setAMcPrePara(int id, u32 value)
{
    setAParasToMachine(SEW_REVMCPARA_MACH, id, value);
}

void Machine::setAWkPrePara(int id, u32 value)
{
    setAParasToMachine(SEW_REVMCPARA_WORK, id, value);
}

//设置机头板参数
void Machine::setHeadBoardPara(HeadInfo *pPara, int id)
{
    int temp = 0;
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(HeadInfo);

    if (id == 0)
    {
        temp = 1;             // 广播时以第一个机头板的参数为准
    }
    else
    {
        temp = id;
    }

    memcpy(&m_exboardInfo.headInfo[temp-1], pPara, size);
    setEXBHeadParasToMachine(m_exboardInfo.headInfo[temp-1], id);
}

//设置换色板参数
void Machine::setHcpsBoardPara(HcpsInfo *pPara, int idx)
{
    if (pPara == NULL)
    {
        return;
    }
    int size = sizeof(HeadInfo);
    memcpy(&m_exboardInfo.hcpsInfo[idx], pPara, size);
    setEXBHcpsParasToMachine(m_exboardInfo.hcpsInfo[idx],idx);
}

//设置机头参数
void Machine::setHeadPara(ParaStruct *pPara,u16 ID)
{
    if (pPara == NULL)
    {
        return;
    }
    ParaStruct headPara;
    int size = sizeof(ParaStruct);
    memcpy(&headPara, pPara, size);
    setHeadPatchParasToMachine(EMB_SEPTUM_DATA, headPara,ID);
}

//按色贴布绣
void Machine::setPatchColorPara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    ParaStruct patchPara;
    int size = sizeof(ParaStruct);
    memcpy(&patchPara, pPara, size);
    setHeadPatchParasToMachine(EMB_PATCH_DATA_COLOR, patchPara,0);
}

//按针贴布绣
void Machine::setPatchNeedlePara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    ParaStruct patchPara;
    int size = sizeof(ParaStruct);
    memcpy(&patchPara, pPara, size);
    setHeadPatchParasToMachine(EMB_PATCH_DATA_IDX, patchPara,0);
}

//设置毛巾高度
void Machine::setTowelHeightPara(ParaStruct *pPara)
{
    if (pPara == NULL)
    {
        return;
    }
    ParaStruct towelHeightPara;
    int size = sizeof(ParaStruct);
    memcpy(&towelHeightPara, pPara, size);
    setTowelHighParasToMachine(CHENILLE_HIGH_DATA, towelHeightPara,0);
}

// 设置文件参数
void Machine::setFilePara(int fileidx, int fileid, DataFilePara & filePara)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(DataFilePara);

    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setFileParas.cmdCode = UCMD_SET_FILE_PARAS;
    sendPacket.setFileParas.fileType = FILE_TYPE_DAT;
    sendPacket.setFileParas.fileIdx = (u8)fileidx;
    sendPacket.setFileParas.fileId = (u16)fileid;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&filePara, size);

    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

// 设置执行进度
void Machine::setFileExecProgress(int fileidx, int fileid, FileExecPara & fileExecPara)
{
    int rslt;
    OperPacket sendPacket;
    int size = sizeof(FileExecPara);

    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setFileParas.cmdCode = UCMD_SET_EXEC_PROGRESS;
    sendPacket.setFileParas.fileType = FILE_TYPE_DAT;
    sendPacket.setFileParas.fileIdx = (u8)fileidx;
    sendPacket.setFileParas.fileId = (u16)fileid;

    rslt = packetAVLDP(&sendPacket.packet, (u8*)&fileExecPara, size);
    if (rslt == 0)
    {
        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + size);
        emit(siSendData(dat));
    }
}

// 设置默认参数
void Machine::setToDefaultParas(int type, u8 id, u8 nodeType)
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setDefParas.cmdCode = (u16)type;
    sendPacket.setDefParas.id = id;
    sendPacket.setDefParas.nodeType = nodeType;
    rslt = packetAFLDP(&sendPacket.packet);

    if(rslt != 0)
    {
        //为了去掉构建警告
    }

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

//-------------------------------------------------------------------
// 手动动作
void Machine::actionByhand(int actcode, int para1, int para2, int para3)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.actByhand.cmdCode = UCMD_ACT_BYHAND;
    sendPacket.actByhand.actCode = (u16)actcode;
    sendPacket.actByhand.para1 = (u16)para1;
    sendPacket.actByhand.para2 = (u16)para2;
    sendPacket.actByhand.para3 = (u16)para3;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}
//-------------------------------------------------------------------

// 电机归零（辅助调试的功能，无安全保护和逻辑关系）
void Machine::motoToZero(int obj)
{
    actionByhand(MOTO_TO_ZERO, obj);
}

// 电机移动（辅助调试的功能，无安全保护和逻辑关系）
void Machine::motoMove(int obj, int dir, int spd)
{
    actionByhand(MOVE_BY_HAND, obj, dir, spd);
}

// 输出控制（辅助调试的功能，无安全保护和逻辑关系）
void Machine::outputCtrl(int obj, int act, int para)
{
    actionByhand(OUTPUT_CTRL, obj, act, para);
}

// 电机使能控制（辅助调试的功能，无安全保护和逻辑关系）
void Machine::motoServoCtrl(int obj, int onoff)
{
    actionByhand(MOTO_EN_CTRL, obj, onoff);
}

// 平绣主轴使能控制
void Machine::embMsServoOn()
{
    motoServoCtrl(MT_LEM, MT_SERVO_ON);
}
void Machine::embMsServoOff()
{
    motoServoCtrl(MT_LEM, MT_SERVO_OFF);
}

// 毛巾主轴使能控制
void Machine::towelMsServoOn()
{
    motoServoCtrl(MT_LTM, MT_SERVO_ON);
}
void Machine::towelMsServoOff()
{
    motoServoCtrl(MT_LTM, MT_SERVO_OFF);
}

// 毛巾M轴使能控制
void Machine::towelMMsServoOn()
{
    motoServoCtrl(MT_LTMM, MT_SERVO_ON);
}
void Machine::towelMMsServoOff()
{
    motoServoCtrl(MT_LTMM, MT_SERVO_OFF);
}

// 毛巾M轴使能控制
void Machine::towelRMMsServoOn()
{
    motoServoCtrl(MT_LRM, MT_SERVO_ON);
}
void Machine::towelRMMsServoOff()
{
    motoServoCtrl(MT_LRM, MT_SERVO_OFF);
}

void Machine::coilMsServoOn()
{
    motoServoCtrl(MT_LCM2, MT_SERVO_ON);
}

void Machine::coilMsServoOff()
{
    motoServoCtrl(MT_LCM2, MT_SERVO_OFF);
}

void Machine::coilMMsServoOn()
{
    motoServoCtrl(MT_LCMM, MT_SERVO_ON);
}

void Machine::coilMMsServoOff()
{
    motoServoCtrl(MT_LCMM, MT_SERVO_OFF);
}

// 手动动作功能（日常使用功能，有安全保护和逻辑时序关系）
void Machine::manualAction(int obj, int para2, int para3)
{
    actionByhand(MANUAL_ACTION, obj, para2, para3);
}

// 定工作范围
void Machine::setWorkRange()
{
    manualAction(AUTO_SET_RANGE);
}

// 手动加油
void Machine::manualOil(int nNum)
{
    mcWorkCmd(WORK_ACT_OIL,nNum);
}

// 重置反复次数
void Machine::resetRepeatNum()
{
    manualAction(RESET_REPEAT_NUM);
}

 //梭盘计数复位
void Machine::shuttleCounter()
{
    manualAction(RESET_SHUT_COUNTER);
}
//自动换一个梭
void Machine::changeOneShuttle()
{
   manualAction(AUTO_CHANGE_ONE_SHUT);
}

// 松紧线
void Machine::looseOnOff()
{
    manualAction(SEW_LOCLIP_TRD);
}

// 手动移框
void Machine::moveFrameByHand(char xy, char dir, int spd)
{
    int para1, para2;

    if (xy == 'x' || xy == 'X')
    {
        if (dir == 'l' || dir == 'L')
        {
            para1 = XY_MOVE_LEFT;
        }
        else if (dir == 'r' || dir == 'R')
        {
            para1 = XY_MOVE_RIGHT;
        }
        else
        {
            para1 = XY_MOVE_STOP;
        }
    }
    else if (xy == 'y' || xy == 'Y')
    {
        if (dir == 'f' || dir == 'F')
        {
            para1 = XY_MOVE_FRONT;
        }
        else if (dir == 'b' || dir == 'B')
        {
            para1 = XY_MOVE_BACK;
        }
        else
        {
            para1 = XY_MOVE_STOP;
        }
    }
    else
    {
        para1 = XY_MOVE_STOP;
    }

    para2 = spd;
    manualAction(para1, para2);
}

// 平绣点动
void Machine::embJog()
{
    manualAction(EMB_MS_JOG);
}
// 平绣锁头电机测试
void Machine::testLockMoto(int para)
{
    manualAction(EMB_TEST_LOCKMOTO,para);
}
// 毛巾点动
void Machine::chenilleJog()
{
    manualAction(CHENILLE_MS_JOG);
}

//毛巾提升电机控制
void Machine::hoistCtrl(int gearValue)
{
    manualAction(CHENILLE_HOIST_CTRL,gearValue);
}
//毛巾松紧线控制
void Machine::elasticCtrl(int posValue)
{
    manualAction(CHENILLE_ELASTIC_CTRL,posValue);
}
//测试电位器
void Machine::testADC(int para,int headNum)
{
    manualAction(TEST_ADC_POTVAL,para,headNum);
}
// 平绣换色
void Machine::embSwitchNeedle(int nNum)
{
    manualAction(EMB_SW_COLOR, nNum);
}

// 毛巾换色
void Machine::chenilleSwitchNeedle(int nNum)
{
    manualAction(CHENILLE_SW_COLOR, nNum);
}
// 毛巾换色调试
void Machine::chenilleColorDebug(int nNum)
{
    manualAction(CHENILLE_SW_DEBUG,nNum);
}
 // 亮片换色
void Machine::sequinSwitchNeedle(int nNum, s16 sq)
{
    if(sq == 0)//左亮片
    {
        manualAction(LEFT_SEQUIN_CHANGE_COLOR, nNum);
    }
    else if(sq == 1)//右亮片
    {
        manualAction(RIGHT_SEQUIN_CHANGE_COLOR, nNum);
    }
}

void Machine::embSpindleTest(s32 para1, s32 para2)
{
    manualAction(EMB_MS_RUN, para1, para2);
}

// 平绣主轴研车

/*
#define	EMB_MS_RUN				0x0022	// 平绣主轴研车
*/

// 平绣剪线
void Machine::embCutThread()
{
    manualAction(EMB_CUT_THREAD);
}

// 毛巾剪线
void Machine::chenilleCutThread()
{
    manualAction(CHENILLE_CUT_THREAD);
}
// 机头切换
void Machine::headSwitch(int para)
{
    manualAction(CHANGE_WORK_HEAD,para);
}

//遍历设置(进入遍历状态和退出遍历状态、断线检测、退出勾刀测试)
void Machine::enterOrExitStates(int obj, int para1, int para2, int para3, int para4)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.traverse.cmdCode = obj;
    sendPacket.traverse.protocolType = (u8)para1;
    sendPacket.traverse.nodeType = (u8)para2;
    sendPacket.traverse.traNum = (u8)para3;
    sendPacket.traverse.nodeId = (u8)para4;

    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

//-------------------------------------------------------
#ifdef UCMD_MC_WORK

void Machine::mcWorkCmd(int workcode, int para1, int para2)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.mcWork.cmdCode = UCMD_MC_WORK;
    sendPacket.mcWork.workCode = (u16)workcode;
    sendPacket.mcWork.para1 = (u32)para1;
    sendPacket.mcWork.para2 = (u16)(para2);
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 启动工作
void Machine::startWork()
{
    mcWorkCmd(WORK_START);
}

// 暂停工作
void Machine::pauseWork()
{
    mcWorkCmd(WORK_PAUSE);
}

// 流程复位（结束工作）
void Machine::allToReset()
{
    mcWorkCmd(WORK_FINISH);
}

// 自动找零(全部归零)
void Machine::allToZero()
{
    mcWorkCmd(WORK_FIND_ZERO);
}

// 回起针点
void Machine::gotoStartPos()
{
    mcWorkCmd(WORK_GOTO_ANCHOR);
}

// 定偏移点
void Machine::setOffsetPos()
{
    mcWorkCmd(WORK_SET_OFFSET);
}

// 定上料点
void Machine::setFeedPos()
{
    mcWorkCmd(WORK_SET_FEED);
}

// 回偏移点
void Machine::gotoOffsetPos()
{
    mcWorkCmd(WORK_GOTO_OFFSET);
}

// 回上料点
void Machine::gotoFeedPos()
{
    mcWorkCmd(WORK_GOTO_FEED);
}

// 边框检查
void Machine::checkFrame()
{
    mcWorkCmd(WORK_CHECK_FRAME);
}

// 空走边框
void Machine::simulateFrame()
{
    mcWorkCmd(WORK_SIMULATION_FRAME);
}

//进入匹绣
void Machine::enterClothEmbroidery()
{
    manualAction(EMB_ENTER_CLOTH);
}

//退出匹绣
void Machine::exitClothEmbroidery()
{
    manualAction(EMB_EXIT_CLOTH);
}

//自动定软限位
void Machine::autoSetSoftLimit()
{
    manualAction(XY_AUTO_SOFTLIMIT);
}

//平绣主轴齿轮比测试
void Machine::embSpindleTest()
{
    manualAction(TEST_EMB_SPINDLE_RATIO);
}
//毛巾主轴齿轮比测试
void Machine::chenSpindleTest()
{
    manualAction(TEST_CHEN_SPINDLE_RATIO);
}
//测试平绣主轴编码器宽度
void Machine::ecdWidthTest()
{
    manualAction(TEST_FLAT_ECD_WIDTH);
}

void Machine::footTest()
{
    manualAction(TEST_EMB_FOOT);
}

//机头板总线检测
void Machine::headBoardBusDetect()
{
    manualAction(CHECK_N5_CANBUS);
}

//线迹偏移
void Machine::traceOffset()
{
    manualAction(TRACE_OFST);
}

//线迹偏移数据复位
void Machine::resetTraceOffset()
{
    manualAction(RESET_TRAOFST);
}

//清除当前索引的线迹偏移数据
void Machine::clearCurTraceOffset()
{
    manualAction(CLEAN_CURTRAOFST);
}

/*
#define	WORK_CUT_FRAME			0x0009		// 边框切割
#define	WORK_CUT_XLINE			0x000A		// 手动断布
*/

// 快速进退
void Machine::fastJump(int idx)
{
    mcWorkCmd(WORK_FAST_JUMP, idx);
}

// 回工作点
void Machine::gotoWorkPos()
{
    mcWorkCmd(WORK_GOTO_WKPOS);
}

// 回穿线点
void Machine::gotoFixPos()
{
    mcWorkCmd(WORK_GOTO_FEEDT);
}

/*
#define	WORK_GOTO_CHGBO			0x000E		// 回换梭位
#define	WORK_FEED_MOVE			0x000F		// 进料退料
#define	WORK_DRAW_LATTICE		0x0010		// 画格子图
#define	WORK_GOTO_FINISH		0x0011		// 回结束点
*/

// 回零点(框架归零)
void Machine::gotoZeroPos()
{
    mcWorkCmd(WORK_GOTO_ZERO);
}

// 主轴点动
void Machine::mainShaftJog()
{
    mcWorkCmd(WORK_MS_JOG);
}

// 速度改变
// chgram 主轴转速改变值。例如：参数为10表示速度加10(升速)，参数为-10表示速度减10(降速)
void Machine::msRpmChange(int chgram, int flag)
{
    mcWorkCmd(WORK_RPM_CHG, chgram, flag);
}
#endif

//----------------------------
// 移动到XY坐标命令
void Machine::moveFrameTo(int x, int y)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.moveFrameTo.cmdCode = UCMD_MOVE_TO;
    sendPacket.moveFrameTo.posx = x;
    sendPacket.moveFrameTo.posy = y;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

void Machine::breakFileTrans()
{
    m_transBreak = 1;
}

#define SEND_STEP0      0
#define SEND_STEP1      1
#define SEND_STEP2      2
#define SEND_STEP3      3
#define SEND_STEP4      4
#define SEND_STEP5      5

#define SEND_STEP_MAX   10

#define SEND_ANSWER     100

void Machine::onSendTimer(void)
{
    int rslt;
    rslt = 0;

    //qDebug("file trans timer");

    if (m_transBreak != 0)      // 中断传输
    {
        qDebug("break file trans");
        m_transCtrl.transphase = SEND_STEP5;
    }

    if (m_transCtrl.transphase == SEND_STEP0)      // 文件失效
    {
        m_fileTransEn = 0;
        qDebug("SEND_STEP1 InvalidateWorkFile ");
        invalidateWorkFile(m_transCtrl.fileIdx);        // 文件失效
        m_transCtrl.transphase = SEND_STEP1;
        rslt = 1;
    }
    else if (m_transCtrl.transphase == SEND_STEP1)      // 启动文件传输
    {
        m_fileTransEn = 0;
        startFileTrans(m_transCtrl);

        qDebug("StartFileTrans ");

        qDebug("trans progress %d/%d", 0, m_transCtrl.packetNum);
        m_totalSendNum = 0;
        m_totalPacketNum = m_transCtrl.packetNum;
        emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));     // 发送进度信号
        m_transCtrl.transphase = SEND_STEP2;
        rslt = 1;

        if (m_transCtrl.fileType == FILE_TYPE_BOARD)
        {
            //如果是外围板升级需要增加延时，等待外围板noflash擦除
            QDateTime oldTime, curTime;
            oldTime = QDateTime::currentDateTime();
            while(1)
            {
                curTime = QDateTime::currentDateTime();
                if(oldTime.msecsTo(curTime) > 6000)
                {
                    break;
                }
            }
        }
    }
    else if (m_transCtrl.transphase == SEND_STEP2)       // 读取传输结果
    {
        qDebug("SEND_STEP2 send GetTransResult cmd ");

        m_fileTransEn = 0;
        getTransResultFromMachine(m_transCtrl.fileId);
        m_transCtrl.transphase = SEND_STEP3;
        rslt = 1;
    }
    else if (m_transCtrl.transphase == SEND_STEP3)       // 根据传输结果传输文件数据
    {
        if (m_fileTransEn == 1)
        {
            qDebug("GetTransResult from machine");

            if (m_transCtrl.transActive == TRANS_ACTIVE)
            {
                if (    m_transCtrl.transflag == TRANS_READY ||  // 准备好接收
                        m_transCtrl.transflag == TRANS_DOING ||  // 正在接收
                        0   )
                {
                    qDebug("trans sta = TRANS_READY or TRANS_DOING flag=%d", m_transCtrl.transflag);

#if (1)
                    int i, j;
                    int thissendnum = 0;
                    int totalsendnum = 0;
                    int send_count = 1000;

#if(1)//发一个包查询一次结果
                    if ( m_transCtrl.fileType == FILE_TYPE_DAT )//花样文件（大文件）
                    {
                        if(m_connectMode == USE_TCP_COMM)//网口
                        {
                            send_count = 400;
                        }
                        else if(m_connectMode == USE_SERIAL_COMM)//串口
                        {
                            send_count = 10;
                        }
                    }
                    else if ( m_transCtrl.fileType == FILE_TYPE_PGM ||  //升级等文件（小文件）
                              m_transCtrl.fileType == FILE_TYPE_FRAME ||
                              m_transCtrl.fileType == FILE_TYPE_BOARD )
                    {
                        send_count = 25;
                    }
#endif

                    u8 mod, temp;
                    for (i = 0; i < m_transCtrl.lenBmp; i++)
                    {
                        temp = m_transCtrl.rsvBitmap[i];
                        mod = 0x01;
                        for (j = 0; j < 8; j++)
                        {
                            if ((temp & mod) == 0)
                            {
                                if (thissendnum < send_count )       // 每发送send_count个包，查询一次结果
                                {
                                    thissendnum++;

                                    transFileData(m_transCtrl, i*8+j);

                                    if (m_transCtrl.fileType == FILE_TYPE_BOARD)
                                    {
                                        //如果是外围板升级需要增加延时，否则主控和外围板CAN缓存区会溢出
                                        QDateTime oldTime, curTime;
                                        oldTime = QDateTime::currentDateTime();
                                        while(1)
                                        {
                                            curTime = QDateTime::currentDateTime();
                                            if(oldTime.msecsTo(curTime) > 100)
                                            {
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                            else
                            {
                                totalsendnum++;
                            }
                            mod <<= 1;
                        }
                    }
                    m_totalSendNum = totalsendnum;
                    m_totalPacketNum = m_transCtrl.packetNum;
                    emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));             // 发送进度信号
                    m_transCtrl.transphase = SEND_STEP2;     // 重新发送查询命令
#else
                    int i, j;
                    int thissendnum = 0;
                    int totalsendnum = 0;
                    u8 mod, temp;
                    for (i = 0; i < m_transCtrl.lenBmp; i++)
                    {
                        temp = m_transCtrl.rsvBitmap[i];
                        mod = 0x01;
                        for (j = 0; j < 8; j++)
                        {
                            if ((temp & mod) == 0)
                            {
                                if (thissendnum < 200)       // 每发送200个包，查询一次结果，
                                {
                                    thissendnum++;
                                    TransFileData(m_transCtrl, i*8+j);
                                    qDebug("TransFileData idx=%d", i*8+j);
                                }
                            }
                            else
                            {
                                totalsendnum++;
                            }
                            mod <<= 1;
                        }
                    }
                    qDebug("trans progress = %d/%d", totalsendnum , m_transCtrl.packetNum);

                    emit(SiTransProgress(totalsendnum, m_transCtrl.packetNum));     // 发送进度信号
                    m_transCtrl.transphase = SEND_STEP2;     // 重新发送查询命令
#endif
                }
                else if (m_transCtrl.transflag == TRANS_DONE)    // 接收完成
                {
                    qDebug("trans sta = TRANS_DONE");

                    emit siSendDataDone();

                    m_totalSendNum = m_transCtrl.packetNum;
                    m_totalPacketNum = m_transCtrl.packetNum;
                    emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));     // 发送进度信号
                    m_transCtrl.transphase = SEND_STEP4;

                    //qDebug()<<"m_transCtrl.fileType"<<m_transCtrl.fileType;
                    if( m_transCtrl.fileType == FILE_TYPE_DAT  || m_transCtrl.fileType == FILE_TYPE_FRAME)
                    {

                    }
                    else if( m_transCtrl.fileType == FILE_TYPE_PGM )
                    {
                        qDebug() << "UpdateFirmware";
                        updateFirmware();
                    }
                    else if( m_transCtrl.fileType == FILE_TYPE_BOARD )
                    {
                        qDebug() << "Update ex board";
                        updateExBoard(m_transCtrl.pBoardHead->protocol, m_transCtrl.pBoardHead->nodeid,m_transCtrl.pBoardHead->nodeType);
                    }
                }
                else if (m_transCtrl.transflag == TRANS_REQUEST)    // 请求传输数据模式
                {
                    qDebug("trans sta = TRANS_REQUEST, sta=%d", m_transCtrl.transflag);
                    m_transCtrl.transphase = SEND_ANSWER;
                }
                else // if (m_transCtrl.transflag == TRANS_NOT_BEG) // 没有收到启动命令
                {
                    qDebug("trans sta = TRANS_NOT_BEG, sta=%d, back to SEND_STEP1", m_transCtrl.transflag);
                    m_transCtrl.transphase = SEND_STEP1;    // 重新发送启动文件传输
                }
            }
            else
            {
                qDebug("transActive != TRANS_ACTIVE, back to SEND_STEP1 ");
                m_transCtrl.transphase = SEND_STEP1;    // 重新发送启动文件传输
            }
            rslt = 1;
        }
        else
        {
            if (m_transCtrl.waitcount > SEND_STEP_MAX)      // 1秒没有回复
            {
                qDebug("waitcount > SEND_STEP_MAX, back to SEND_STEP2 ");
                m_transCtrl.transphase = SEND_STEP2;     // 重新发送查询命令
                rslt = 1;
            }
        }
    }

    if (rslt == 0)
    {
        m_transCtrl.waitcount++;
    }
    else
    {
        m_transCtrl.waitcount = 0;
    }

    if (    m_transCtrl.transphase != SEND_STEP1 &&
            m_transCtrl.transphase != SEND_STEP2 &&
            m_transCtrl.transphase != SEND_STEP3    )       // 结束
    {
        qDebug("trans file over, step=%d", m_transCtrl.transphase);
        if (m_transCtrl.transphase == SEND_STEP4)
        {
            m_totalSendNum = 0;
            m_totalPacketNum = 0;
            emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));        // 发送结束信号（成功）
        }
        else
        {
            m_totalSendNum = -1;
            m_totalPacketNum = -1;
            emit(siTransProgress(m_transCtrl.fileType, m_totalSendNum, m_totalPacketNum));      // 发送结束信号（失败）
        }
        m_pSendTimer->stop();               // 停止定时器
        m_transCtrl.filetransing = 0;
    }
}

//串口是否打开
void Machine::slIfOpenSerialPort(int val)
{
    if(val != 0)
    {
        if(m_connectMode == USE_SERIAL_COMM)
        {
            m_connected = 3;//串口已打开
        }
    }
}

// 发送文件过程
int Machine::sendFileProc(int type, int idx, int id, DataDs16FileHead & fileHead, u8 * pDatBuff)
{
    return sendFileProc(type, idx, id, &fileHead, pDatBuff);
}

int Machine::dySendFileProc(int type, int idx, int id, DataDs16FileHead *pfileHead, u8 *pDatBuff)
{
    if (pDatBuff == NULL || pfileHead == NULL)
    {
        return -1;
    }

    if ( pfileHead->dataSize <= 0 || pfileHead->dataSize > MAX_FILE_SIZE)
    {
        qDebug("pfileHead->dataSize <= 0 || pfileHead->dataSize > MAX_FILE_SIZE, not support");
        return -2;
    }

    QTime delayTime;
    int counter = 0;
    delayTime.start();

    if (m_transCtrl.filetransing != 0)      // 已经有文件在传输
    {
        return -3;
    }

    while (m_transCtrl.filetransing != 0)   // 已经有文件在传输
    {
        if (delayTime.elapsed() > 1000)
        {
            counter++;
            qDebug("%d. wait old file trans over", counter);
            delayTime.restart();
        }

        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    m_transBreak = 0;

    m_transCtrl.fileType = (u8)type;
    m_transCtrl.fileIdx = (u8)idx;
    m_transCtrl.fileId = (u16)id;
    memcpy(m_transCtrl.pFileHead, pfileHead, sizeof(DataDs16FileHead));
    memcpy(m_transCtrl.pDatBuff, pDatBuff, pfileHead->dataSize);
    m_transCtrl.packetSize = MAX_EXDP_LEN;
    m_transCtrl.packetNum = (pfileHead->dataSize + MAX_EXDP_LEN - 1) / MAX_EXDP_LEN;

    qDebug("StartFileTrans, fileType=%d, fileIdx=%d, fileId=%d, packetNum=%d, ",
           m_transCtrl.fileType, m_transCtrl.fileIdx, m_transCtrl.fileId, m_transCtrl.packetNum);

    m_transCtrl.filetransing = 1;
    m_transCtrl.transflag = TRANS_REQUEST;
    m_transCtrl.transActive = TRANS_ACTIVE;
    startFileDyTrans(m_transCtrl);
    m_transCtrl.filetransing = 0;

    return 0;
}

int Machine::sendFileProc(int type, int idx, int id, DataDs16FileHead * pfileHead, u8 * pDatBuff)
{
    if (pDatBuff == NULL || pfileHead == NULL)
    {
        return -1;
    }

    if ( pfileHead->dataSize <= 0 || pfileHead->dataSize > MAX_FILE_SIZE)
    {
        qDebug("pfileHead->dataSize <= 0 || pfileHead->dataSize > MAX_FILE_SIZE, not support");
        return -2;
    }

    QTime delayTime;
    int counter = 0;
    delayTime.start();

    if (m_transCtrl.filetransing != 0)      // 已经有文件在传输
    {
        return -3;
    }

    while (m_transCtrl.filetransing != 0)   // 已经有文件在传输
    {
        if (delayTime.elapsed() > 1000)
        {
            counter++;
            qDebug("%d. wait old file trans over", counter);
            delayTime.restart();
        }

        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);//进度条
    }

    m_transBreak = 0;

    m_transCtrl.fileType = (u8)type;
    m_transCtrl.fileIdx = (u8)idx;
    m_transCtrl.fileId = (u16)id;
    memcpy(m_transCtrl.pFileHead, pfileHead, sizeof(DataDs16FileHead));
    memcpy(m_transCtrl.pDatBuff, pDatBuff, pfileHead->dataSize);
    m_transCtrl.packetSize = MAX_EXDP_LEN;
    m_transCtrl.packetNum = (pfileHead->dataSize + MAX_EXDP_LEN - 1) / MAX_EXDP_LEN;

    qDebug("StartFileTrans, fileType=%d, fileIdx=%d, fileId=%d, packetNum=%d, ",
           m_transCtrl.fileType, m_transCtrl.fileIdx, m_transCtrl.fileId, m_transCtrl.packetNum);

    m_transCtrl.transphase = SEND_STEP1;
    m_transCtrl.filetransing = 1;

    m_pSendTimer->start();
    return 0;
}

//  发送文件过程
int Machine::sendAPPFileProc(int type, int idx, int id, AppFileHead & fileHead, u8 * pDatBuff)
{
    if (pDatBuff == NULL || fileHead.dataSize <= 0)
    {
        return -1;
    }

    if (fileHead.dataSize > MAX_FILE_SIZE)
    {
        qDebug("fileHead.dataSize > MAX_FILE_SIZE, not support");
        return -2;
    }

    QTime delayTime;
    int counter = 0;
    delayTime.start();

    while (m_transCtrl.filetransing != 0)   // 已经有文件在传输
    {
        if (delayTime.elapsed() > 1000)
        {
            counter++;
            qDebug("%d. wait old file trans over", counter);
            delayTime.restart();
        }

        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    m_transBreak = 0;

    // 拷贝数据到传输控制结构
    m_transCtrl.fileType = (u8)type;
    m_transCtrl.fileIdx = (u8)idx;
    m_transCtrl.fileId = (u16)id;
    memcpy(m_transCtrl.pAppHead, &fileHead, sizeof(AppFileHead));
    memcpy(m_transCtrl.pDatBuff, pDatBuff, fileHead.dataSize);
    m_transCtrl.packetSize = MAX_EXDP_LEN;
    m_transCtrl.packetNum = (fileHead.dataSize + MAX_EXDP_LEN - 1 ) / MAX_EXDP_LEN;

    qDebug("StartFileTrans, fileType=%d, fileIdx=%d, fileId=%d, packetNum=%d, ",
           m_transCtrl.fileType, m_transCtrl.fileIdx, m_transCtrl.fileId, m_transCtrl.packetNum);

    m_transCtrl.transphase = SEND_STEP1;
    m_transCtrl.filetransing = 1;

    // 启动定时器
    m_pSendTimer->start();
    return 0;
}

//  发送外围板文件过程
int Machine::sendBoardFileProc(int type, int idx, int id, BoardFileHead & fileHead, u8 * pDatBuff)
{
    if (pDatBuff == NULL || fileHead.dataSize <= 0)
    {
        return -1;
    }

    if (fileHead.dataSize > MAX_FILE_SIZE)
    {
        qDebug("fileHead.dataSize > MAX_FILE_SIZE, not support");
        return -2;
    }

    QTime delayTime;
    int counter = 0;
    delayTime.start();

    while (m_transCtrl.filetransing != 0)   // 已经有文件在传输
    {
        if (delayTime.elapsed() > 1000)
        {
            counter++;
            qDebug("%d. wait old file trans over", counter);
            delayTime.restart();
        }

        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
    }

    m_transBreak = 0;

    // 拷贝数据到传输控制结构
    m_transCtrl.fileType = (u8)type;
    m_transCtrl.fileIdx = (u8)idx;
    m_transCtrl.fileId = (u16)id;
    memcpy(m_transCtrl.pBoardHead, &fileHead, sizeof(BoardFileHead));
    memcpy(m_transCtrl.pDatBuff, pDatBuff, fileHead.dataSize);
    m_transCtrl.packetSize = MAX_EXDP_LEN;
    m_transCtrl.packetNum = (fileHead.dataSize + MAX_EXDP_LEN - 1 ) / MAX_EXDP_LEN;

    qDebug("StartFileTrans, fileType=%d, fileIdx=%d, fileId=%d, packetNum=%d, ",
           m_transCtrl.fileType, m_transCtrl.fileIdx, m_transCtrl.fileId, m_transCtrl.packetNum);

    m_transCtrl.transphase = SEND_STEP1;
    m_transCtrl.filetransing = 1;

    // 启动定时器
    m_pSendTimer->start();
    return 0;
}

// 启动文件传输
void Machine::startFileTrans(FileTransCtrl & transCtrl)
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.startTrans.cmdCode = UCMD_START_TRANS;
    sendPacket.startTrans.fileType = transCtrl.fileType;
    sendPacket.startTrans.fileIdx = transCtrl.fileIdx;
    sendPacket.startTrans.fileId = transCtrl.fileId;

    if( transCtrl.fileType == FILE_TYPE_DAT  || transCtrl.fileType == FILE_TYPE_FRAME)
    {
        rslt = packetAVLDP(&sendPacket.packet, (u8*)transCtrl.pFileHead, sizeof(DataDs16FileHead));
    }
    else if( transCtrl.fileType == FILE_TYPE_PGM )
    {
        rslt = packetAVLDP(&sendPacket.packet, (u8*)transCtrl.pAppHead, sizeof(AppFileHead));
    }
    else if ( transCtrl.fileType == FILE_TYPE_BOARD )
    {
        rslt = packetAVLDP(&sendPacket.packet, (u8*)transCtrl.pBoardHead, sizeof(BoardFileHead));
    }
    else
    {
        return ;
    }

    if (rslt == 0)
    {
        if( transCtrl.fileType == FILE_TYPE_DAT  || transCtrl.fileType == FILE_TYPE_FRAME)
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+sizeof(DataDs16FileHead));
            emit(siSendData(dat));
        }
        else if( transCtrl.fileType == FILE_TYPE_PGM )
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+sizeof(AppFileHead));
            emit(siSendData(dat));
        }
        else if ( transCtrl.fileType == FILE_TYPE_BOARD )
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+sizeof(BoardFileHead));
            emit(siSendData(dat));
        }
    }
}

void Machine::startFileDyTrans(FileTransCtrl &transCtrl)
{
    int rslt;
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.startTrans.cmdCode = UCMD_START_TRANS;
    sendPacket.startTrans.fileType = transCtrl.fileType;
    sendPacket.startTrans.fileIdx = transCtrl.fileIdx;
    sendPacket.startTrans.fileId = transCtrl.fileId;

    if( transCtrl.fileType == FILE_TYPE_DAT  || transCtrl.fileType == FILE_TYPE_FRAME)
    {
        rslt = packetAVLDP(&sendPacket.packet, (u8*)transCtrl.pFileHead, sizeof(DataDs16FileHead));
    }
    else
    {
        return ;
    }

    if (rslt == 0)
    {
        if( transCtrl.fileType == FILE_TYPE_DAT  || transCtrl.fileType == FILE_TYPE_FRAME)
        {
            //发送文件头
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+sizeof(DataDs16FileHead));
            emit(siSendData(dat));

            //发送第一个数据包
            //transFileData(m_transCtrl, 0);
        }
    }
}

// 文件数据传输
void Machine::transFileData(FileTransCtrl & transCtrl, int pktidx)
{
    int rslt;
    int actsize;
    u8 buff[MAX_EXDP_LEN];

    if (pktidx < 0 || transCtrl.pDatBuff == NULL)
    {
        return;
    }

    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.transFileData.cmdCode = UCMD_TRANS_FILE_DATA;
    sendPacket.transFileData.fileId = transCtrl.fileId;
    sendPacket.transFileData.pktIdx = pktidx;

    if (pktidx < (int)transCtrl.packetNum)
    {
        if( transCtrl.fileType == FILE_TYPE_DAT  || transCtrl.fileType == FILE_TYPE_FRAME)
        {
            actsize = transCtrl.pFileHead->dataSize - pktidx*transCtrl.packetSize;

            if (actsize >= transCtrl.packetSize)
            {
                actsize = transCtrl.packetSize;
            }
            else
            {
                memset(buff, 0, MAX_EXDP_LEN);
            }
        }
        else if( transCtrl.fileType == FILE_TYPE_PGM )
        {
            actsize = transCtrl.pAppHead->dataSize - pktidx*transCtrl.packetSize;

            if (actsize >= transCtrl.packetSize)
            {
                actsize = transCtrl.packetSize;
            }
            else
            {
                memset(buff, 0XFF, MAX_EXDP_LEN);
            }
        }
        else if ( transCtrl.fileType == FILE_TYPE_BOARD )
        {
            actsize = transCtrl.pBoardHead->dataSize - pktidx*transCtrl.packetSize;

            if (actsize >= transCtrl.packetSize)
            {
                actsize = transCtrl.packetSize;
            }
            else
            {
                memset(buff, 0XFF, MAX_EXDP_LEN);
            }
        }
        else
        {
            actsize = 0;
        }

        memcpy(buff, &(transCtrl.pDatBuff[pktidx*transCtrl.packetSize]), actsize);
        //qDebug("TransFileData pktidx=%d", pktidx);
#if (0)
        int i;
        for (i = 0; i < MAX_EXDP_LEN/16; i++)
        {
            qDebug("0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
                   buff[i*16+0], buff[i*16+1],buff[i*16+2],buff[i*16+3],buff[i*16+4],buff[i*16+5],buff[i*16+6],buff[i*16+7],
                    buff[i*16+8],buff[i*16+9],buff[i*16+10],buff[i*16+11],buff[i*16+12],buff[i*16+13],buff[i*16+14],buff[i*16+15]);
        }

#endif
        rslt = packetAVLDP(&sendPacket.packet, buff, MAX_EXDP_LEN);
        if (rslt == 0)
        {
            QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET+MAX_EXDP_LEN);
            emit(siSendData(dat));
        }
    }
}
// 下位机升级
void Machine::updateFirmware()
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.mcUpdate.cmdCode  = UCMD_MC_UPDATE;
    sendPacket.mcUpdate.upObj     = 0;
    sendPacket.mcUpdate.upFileID  = 0;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 外围板升级
void Machine::updateExBoard(u8 protocolType, u8 nodeId,u8 nodeType)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.updateBoard.cmdCode  = UCMD_BOARD_UPDATE;
    sendPacket.updateBoard.protocolType = protocolType;
    sendPacket.updateBoard.nodeId = nodeId;
    sendPacket.updateBoard.nodeType = nodeType;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 恢复出厂设置
void Machine::restoreFactorySetting(int type)
{
    int mctype = -1;
    int wktype = -1;
    if (type == -1)
    {
        mctype = SEW_MCPARA_DEF_MC;
        wktype = SEW_MCPARA_DEF_WK;
        m_mcParaEn = 0;
        m_wkParaEn = 0;
    }
    else
    {
        if(type == SEW_MCPARA_DEF_MC )
        {
            mctype = SEW_MCPARA_DEF_MC;
            m_mcParaEn = 0;
        }
        if(type == SEW_MCPARA_DEF_WK )
        {
            wktype = SEW_MCPARA_DEF_WK;
            m_wkParaEn = 0;
        }
    }

    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.getMcParas.cmdCode = UCMD_GET_MC_PARAS;

    if (mctype == SEW_MCPARA_DEF_MC)
    {
        sendPacket.getMcParas.paraType = (u16)mctype;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    if (wktype == SEW_MCPARA_DEF_WK)
    {
        sendPacket.getMcParas.paraType = (u16)wktype;
        packetAFLDP(&sendPacket.packet);

        QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
        emit(siSendData(dat));
    }

    sleep(3);
    setMcPara(&m_mcPara);
    setWkPara(&m_wkPara);
    setMcPara(&m_mcPrePara);
    setWkPara(&m_wkPrePara);
}

void Machine::sleep(int sec)
{
    QTime dieTime = QTime::currentTime().addSecs(sec);//延时sec秒
    //QTime dieTime = QTime::currentTime().addMSecs(msec);//延时msec毫秒
    while( QTime::currentTime() < dieTime )
        QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}

//定量移框
void Machine::quantityMoveFrame(s32 x, s32 y)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.moveFrameTo.cmdCode = UCMD_MOVE_OFST;
    sendPacket.moveFrameTo.posx = x;
    sendPacket.moveFrameTo.posy = y;
    packetAFLDP(&sendPacket.packet);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

void Machine::setTcpConnectState(int state)
{
    if(state == 0){}//为了去掉串口下的构建警告
    if(m_connectMode == USE_TCP_COMM)
    {
        if(m_pTcpClient != NULL)
        {
            m_pTcpClient->m_connected = state;
        }
    }
    else if(m_connectMode == USE_SERIAL_COMM)//串口
    {
        //注释掉此行代码，因为串口发送文件较慢，若是超过5秒不给上位机返状态就会检测断开，其实并未断开
        //m_connected = state;//改变连接状态
    }
}

// 设置经过的时间
void Machine::setElapsed(unsigned char i_type ,  unsigned char  i_time)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setElapsedTime.cmdCode = UCMD_SET_ELAPSED_TIME;

    sendPacket.setElapsedTime.type = i_type  ;
    sendPacket.setElapsedTime.time = i_time  ;

    packetAFLDP(&sendPacket.packet);
    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET);
    emit(siSendData(dat));
}

// 测试断线检测,1是面线，2是底线
void Machine::testThreadBK(int type,int needle,int headType)
{
    actionByhand(TEST_THREADBK, type, needle , headType);
}

// 测试锁头
void Machine::lockTest(int type, int para)
{
    actionByhand(TEST_LOCK, type, para);
}

// 设置机器的密钥
void Machine::setMacKey(unsigned char * p_dat ,  int i_size)
{
    OperPacket sendPacket;
    memset(&sendPacket, 0, sizeof(OperPacket));
    sendPacket.setMacKey.cmdCode = UCMD_SET_INSTALLMENT;

    memcpy( sendPacket.setMacKey.exData ,  p_dat , i_size);

    packetAVLDP(&sendPacket.packet, (u8*)p_dat, i_size);

    QByteArray dat((char*)(&sendPacket.packet), LEN_NORMAL_PACKET + i_size );

    emit(siSendData(dat));
}


//idx 现在默认是0，读第一个机头的机头板参数，方便以后读其他机头的机头板的参数   -rq
 HeadInfo* Machine::getHeadPara(int idx ,int nType)
{
     int i;
     for (i = 0; i < MAX_SUPPORT_N5; i++)
     {
         if (nType == m_exboardInfo.headInfo[i].nodeType)//平绣的nType是1
         {// 若广播,则读取相应节点类型的第一个节点
             if (idx <= 1)
             {
                 break;
             }
             else
             {
                 idx--;
             }
         }
     }
     if (i<MAX_SUPPORT_N5)
     {
         return &m_exboardInfo.headInfo[i];
     }
     else
     {
         return NULL;
     }
}
