Example #1
0
static void ExecuteCommandAndAnswer(int Handle)
{
	uint32 Time = time(0);
	byte Result = 0;

	//int ret = pthread_mutex_lock(&DevMutex);

	switch (Request.Command)
	{
		case dcZero:
			printf("Zero\n");
			Result = devSendMessage(0x56, NULL, 0) >= 0 ? crSuccess : crSendCommandError;
			break;
		case dcReset:
			printf("Reset\n");
			Result = devSendMessage(0x42, NULL, 0) >= 0 ? crSuccess : crSendCommandError;
			break;
		case dcSCol:
		{
			char sData[strlen(Request.CommandData)+1];
			strcpy(sData, Request.CommandData);
			printf("SCol: '%s'\n", sData);
			Result = devSendMessage(0x3B, (byte *)Request.CommandData, strlen(Request.CommandData)) >= 0 ? crSuccess : crSendCommandError;
			//PrintHEX(Request.CommandData, strlen(Request.CommandData));
			break;
		}
		default:
			Result = crUnknownCommand;
			break;
	}

	//ret = pthread_mutex_unlock(&DevMutex);

	byte data[1+1+1 + 1+1+1 + 1+1+1 + 1+1+4 + 1+2+255]; // PackageID, Command, CommandResult, CommandTime, CommandData
	tBuffer buf;
	bufInit(&buf, data, sizeof(data));

	bufAppTLVByte(&buf, sctPackageID, scpCommand);
	bufAppTLVByte(&buf, sctCommand, Request.Command);
	bufAppTLVByte(&buf, sctCommandResult, Result);
	bufAppTLVUInt32(&buf, sctCommandTime, Time);
	int lenCmdData = strlen(Request.CommandData);
	if (lenCmdData > 0)
		bufAppTLV(&buf, sctCommandData, lenCmdData, (byte *)Request.CommandData);

	tcpSendMessage(Handle, buf.ptr, buf.pos, SendTimeoutMSec);
}
void RFIDMonitorDaemon::readDatagrams()
{
    QByteArray datagram;
    datagram.resize(m_udpSocket->pendingDatagramSize());
    QHostAddress sender;

    m_udpSocket->readDatagram(datagram.data(), datagram.size(), &sender);

    QJsonDocument broacast(QJsonDocument::fromJson(datagram));
#if QT_VERSION < 0x050200
    m_tcpAppSocket->connectToHost(sender, broacast.object().value("port").toVariant().toInt());
#else
    m_tcpAppSocket->connectToHost(sender, broacast.object().value("port").toInt());
#endif
    if(m_tcpAppSocket->waitForConnected())
        tcpSendMessage(m_tcpAppSocket, buildMessage(m_configManager->identification(), "SYN").toJson());
    else
        qDebug() <<  QString("Could not connect with %1").arg(sender.toString());
}
Example #3
0
static void AnswerDRMData(int Handle)
{
	byte data[sizeof(DRMData)*2];
	tBuffer buf;
	bufInit(&buf, data, sizeof(data));

	pthread_mutex_lock(&SyncMutex);
	//printf("TCP after lock\n");

	bufAppTLVByte(&buf, sctPackageID, scpDRMData);
	/*if (DRMData.dgyroReceived)*/ bufAppTLV(&buf, sctDGYRO, sizeof(DRMData.dgyro), (byte *)&(DRMData.dgyro));
	/*if (DRMData.dstatReceived)*/ bufAppTLV(&buf, sctDSTAT, sizeof(DRMData.dstat), (byte *)&(DRMData.dstat));
	/*if (DRMData.deposnReceived)*/ bufAppTLV(&buf, sctDEPOSN, sizeof(DRMData.deposn), (byte *)&(DRMData.deposn));
	/*if (DRMData.dorientReceived)*/ bufAppTLV(&buf, sctDORIENT, sizeof(DRMData.dorient), (byte *)&(DRMData.dorient));
	/*if (DRMData.dgpvtReceived)*/ bufAppTLV(&buf, sctDGPVT, sizeof(DRMData.dgpvt), (byte *)&(DRMData.dgpvt));

	//printf("TCP before unlock\n");
	pthread_mutex_unlock(&SyncMutex);

	tcpSendMessage(Handle, buf.ptr, buf.pos, SendTimeoutMSec);
}
/*
 * This function works pretty much like routTcpMessage only that this one interpretes message from RFIDMonitor and don't verify packages size.
 * it only tries to interpret data just arrived.
 */
void RFIDMonitorDaemon::routeIpcMessage()
{
    QByteArray message = ipcConnection->readAll();
    json::NodeJSMessage nodeMessage;

    nodeMessage.read(QJsonDocument::fromJson(message).object());
    QString messageType(nodeMessage.type());

    if(messageType == "SYN"){

        m_restoreTimer.stop();
        ipcSendMessage(buildMessage(QJsonObject(), "ACK-SYN").toJson());
        qApp->processEvents();

        /* When the deskApp change some configuration the RFIDMonitor is restarted.
         * But, the RFIDMonitor starts with flag connection=false. And if the server is connected the RFIDMonitor don't know that yet.
         * To solve this, after 1 seconds a SYNC message is sent to RFIDMonitor to set true to connection flag.
         */
        if(isConnected)
        {
            QTimer *timer = new QTimer();
            timer->setSingleShot(true);
            timer->setInterval(1000);
            connect(timer, &QTimer::timeout, [=](){
                ipcSendMessage(buildMessage(QJsonObject(), "SYNC").toJson());
                timer->deleteLater();
            });
            timer->start();
        }

        m_configManager->restartNetwork();

    }else if (messageType == "READER-RESPONSE") {
        QJsonObject command(nodeMessage.jsonData());
        /*
         * When a 'reader response' message is received is because someone sent a 'reader command' message. So it needs to know who did it.
         * To perform this it uses a field called 'sender' that carry the name of who sent the 'command message'.
         * And based on that, it will respond to the server connection or to the deskApp connection.
         *
         * see reoutTcpMessage (messageType == "READER-COMMAND")
         */
        if(command.value("sender").toString() == "server")
            tcpSendMessage(m_tcpSocket, message);
        else
            tcpSendMessage(m_tcpAppSocket, message);

    }else if (messageType == "DATA"){
        /*
         * A Data message means that the RFIDMonitor is trying to sync some data into the server. So, it just send this message to the server.
         */
//        qDebug() <<  "DATA Message Received from Monitor\n";
//        qDebug() <<  QString(QJsonDocument(nodeMessage.jsonData()).toJson());
        // Only a node.js server receives DATA messages.
        tcpSendMessage(m_tcpSocket, message);

    }else if (messageType == "STOPPED"){
        qDebug() << "STOPPED";
        m_process.kill();
//        qDebug() << "Process Killed, PID: " << m_process.pid();
    }
    else if (messageType == "ACK-UNKNOWN") {
        QJsonDocument unknown(nodeMessage.jsonData());
        QJsonObject dataObj(unknown.object().value("unknownmessage").toObject());
        qDebug() <<  "The Monitor don't understand the message type: "
                        << dataObj.value("type").toString();
    }
    else{
        /* When receives a message that can't be interpreted like any type is an unknown message.
         * In this case an ACK-UNKNOWN message is built and sent to the connection that received this message
         */
        qDebug() <<  "UNKNOWN MESSAGE";

        QJsonObject unknownObj;
        unknownObj.insert("unknownmessage", QJsonDocument::fromJson(message).object());
        unknownObj.insert("errorinfo", QString("Unknown message received"));

        ipcSendMessage(buildMessage(unknownObj, "ACK-UNKNOWN").toJson());
    }
}
/*
 * The routeTcpMessage() receives messages from any TCP connection. The Daemon can be connected with server and deskApp at the same time, but it will know which connection received data.
 * Any message arrive by TCP must to have two parts. The first part defines the data size of the coming package (second part) and must to be an 8 bytes String (always 8 bytes).
 *
 * The algoritm works like this:
 * When some data arrive it verifies (using the hasPackage variable) if is the first part or the second one of the complete message;
 * If hasPackage is true then is especting the second part of the message, otherwise the dada just arrived is the size information.
 *
 * The information of size correspond to the size of the message package. So, when more data arrive it verifies if the size is greater than or equals to the expected size.
 * If true the message is all here and can go on, otherwise the message is coming and it will wait for more data.
 *
 * When all the message arrives it will interpret and route it (by message type) to the right way.
 *
 */
void RFIDMonitorDaemon::routeTcpMessage()
{
    QTcpSocket *connection = (QTcpSocket *) QObject::sender();

    static bool hasPackage = false;
    static quint64 packageSize = 0;

    if( ! hasPackage){

        if((quint64)connection->bytesAvailable() < sizeof(quint64))
            return;

        //    	m_tcpSocket->read((char *)&packageSize, sizeof(quint64));
        QString packageSizeStr(connection->read(sizeof(quint64)));
        packageSize = packageSizeStr.toULongLong();

        qDebug() <<  QString("Message = %1 - Size of coming package: %2").arg(packageSizeStr).arg(QString::number(packageSize));
        hasPackage = true;
    }

    if((quint64)connection->bytesAvailable() >=  packageSize){
        QByteArray data(connection->read(packageSize));

        json::NodeJSMessage nodeMessage;

        nodeMessage.read(QJsonDocument::fromJson(data).object());
        QString messageType(nodeMessage.type());

        qDebug() << QString("New Message Received: %1").arg(QString(data));


        if(messageType == "SYN-ALIVE"){

            tcpSendMessage(connection, buildMessage(m_configManager->identification(), "ACK-ALIVE").toJson());
            qDebug() << QString("New Message Received: %1").arg(messageType);
        }
        else if (messageType == "ACK-SYN") {

            QJsonObject obj(nodeMessage.jsonData());
            if(!obj.isEmpty()){
                m_configManager->setIdentification(obj);
            }

            bool statusDateTime = m_configManager->setDateTime(nodeMessage.dateTime());
            QJsonObject response = m_configManager->identification();
            response["success"] = QJsonValue(statusDateTime);

            tcpSendMessage(connection, buildMessage(response, "ACK").toJson());

            // Informe RFIDMonitor that server is now connected. Wait 2 seconds;
            if(connection->objectName() == "server"){
                isConnected = true;
                QTimer *timer = new QTimer();
                timer->setSingleShot(true);
                timer->setInterval(2000);
                connect(timer, &QTimer::timeout, [=](){
                    ipcSendMessage(buildMessage(QJsonObject(), "SYNC").toJson());
                    timer->deleteLater();
                });
                timer->start();
            }
        }else if (messageType == "GET-CONFIG") {
            tcpSendMessage(connection, buildMessage(m_configManager->currentConfig(), "CONFIG").toJson());

        }else if (messageType == "READER-COMMAND") {

            QJsonObject command(nodeMessage.jsonData());
            /*
             * When a 'reader command' message is received is because someone is sending a command to the reader. So it needs to send also who is doing this.
             * To perform this it uses a field called 'sender' that carry the name of who is sending the 'command message'.
             * And based on that, it will respond to the server connection or to the deskApp connection
             *
             * see reoutIcpMessage (messageType == "READER-RESPONSE")
             */
            if(connection->objectName() == "server")
                command.insert("sender", QString("server"));
            else
                command.insert("sender", QString("app"));

            ipcSendMessage(buildMessage(command, "READER-COMMAND").toJson());

        }else if (messageType == "NEW-CONFIG") {

            QJsonObject newConfig(nodeMessage.jsonData());
            bool ackConf;
            if(m_configManager->newConfig(newConfig))
            {
                // Send a message to stop the RFIDMonitor
                emit restartMonitor();
                ackConf = true;
            }else{
                ackConf = false;
            }
            QJsonObject dataObj;
            dataObj.insert("success", QJsonValue(ackConf));
            tcpSendMessage(connection, buildMessage(dataObj, "ACK-NEW-CONFIG").toJson());

            if(m_tcpAppSocket->isOpen())
                m_tcpAppSocket->close();

        }else if (messageType == "DATETIME") {

            QJsonObject dataObj;
            dataObj["success"] =  QJsonValue(m_configManager->setDateTime(nodeMessage.dateTime()));
            tcpSendMessage(connection, buildMessage(dataObj, "ACK").toJson());

        }else if (messageType == "ACK-DATA") {
            // A ACK-DATA message means that the server is trying to inform the RFIDMonitor that some data is now synced. So, it just send this message to the RFIDMonitor.
            ipcSendMessage(data);

        }else if (messageType == "GET-NET-CONFIG") {
            // Only return the network configuration.
            tcpSendMessage(connection, buildMessage(m_configManager->netConfig(), "NET-CONFIG").toJson());

        }else if (messageType == "NEW-NET") {

            QJsonObject network = nodeMessage.jsonData();
            // Receive a new configuration for the network (ssid and password).
            QJsonObject dataObj;
            dataObj.insert("success", QJsonValue(m_configManager->setNetConfig(network)));

            // returns a message ACK-NET to inform the sender that the new configuration was set
            tcpSendMessage(connection, buildMessage(dataObj, "ACK-NET").toJson());

            // Try to restar the network service to already use the new configuration
            bool resetNet = m_configManager->restartNetwork();
            qDebug() <<  QString(resetNet? "Network restarted" : "Networkt Don't restarted");

        }else if (messageType == "ACK-UNKNOWN") {
            QJsonDocument unknown(nodeMessage.jsonData());
            QJsonObject oldMessage(unknown.object().value("unknownmessage").toObject());
            qDebug() <<  "The server don't understand the message type: " << oldMessage.value("type").toString();
            qDebug() <<  "ERROR message: " << unknown.object().value("errorinfo").toString();

        }else if (messageType == "FULL-READ"){
            ipcSendMessage(data);

        }else{
            /* When receives a message that can't be interpreted like any type is an unknown message.
             * In this case an ACK-UNKNOWN message is built and sent to the connection that received this message
             */
            qDebug() <<  "UNKNOWN MESSAGE";
            QJsonObject unknownObj;
            unknownObj.insert("unknownmessage", QJsonValue(QJsonDocument::fromJson(data).object()));
            unknownObj.insert("errorinfo", QString("Unknown message received"));
            tcpSendMessage(connection, buildMessage(unknownObj, "ACK-UNKNOWN").toJson());
        }

        /* when all the process is done, reset the expecting message size to zero and the haspackage to false.
         * Then when more data arrive it must to be the size information again.
         */
        packageSize = 0;
        hasPackage = false;
    }
}
void RFIDMonitorDaemon::tcpConnected()
{
    qDebug() <<  QString("Connected to %1 on port %2").arg(m_hostName).arg(m_tcpPort );
    tcpSendMessage(m_tcpSocket, buildMessage(m_configManager->identification(), "SYN").toJson());
}