Subversion Repositories Projects

Rev

Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed

/***************************************************************************
 *   Copyright (C) 2009 by Manuel Schrape                                  *
 *   manuel.schrape@gmx.de                                                 *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License.        *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QSettings>
#include <QMessageBox>
#include <QCryptographicHash>

#include "wgt_Connection.h"

wgt_Connection::wgt_Connection(QWidget *parent) : QWidget(parent)
{
    setupUi(this);

    o_Input = new Input();

    o_AboTimer = new QTimer();
    o_AboTimer->setInterval(3500);

    connect(btn_Connect, SIGNAL(clicked()), this, SLOT(slot_btn_Connect()));
    connect(sb_Intervall, SIGNAL(valueChanged(int)), this, SLOT(slot_sb_Intervall(int)));

    connect(o_AboTimer, SIGNAL(timeout()), this, SLOT(slot_TimeOut_AboTimer()));
}

void wgt_Connection::read_Settings()
{
    QSettings Setting("QMK", "QMK-Connection");

    Setting.beginGroup("DATA");
        SERVER.Intervall  = Setting.value(QString("Intervall_%1").arg(gi_ID), 500).toInt();
    Setting.endGroup();

    Setting.beginGroup("SERVER");
        SERVER.Password = Setting.value("Password", QString("")).toString();
        SERVER.IP_MAX = Setting.value("IP_MAX", 1).toInt();
        SERVER.IP_ID  = Setting.value("IP_ID",  0).toInt();

        for (int z = 0; z < SERVER.IP_MAX; z++)
        {
            SERVER.IP[z] = Setting.value("IP_" + QString("%1").arg(z), QString("127.0.0.1:64400")).toString();
        }
    Setting.endGroup();

    for(int z = 0; z < SERVER.IP_MAX; z++)
    {
        if (cb_Server->findText(SERVER.IP[z]) == -1)
        {
            cb_Server->addItem(SERVER.IP[z]);
        }
    }

    cb_Server->setCurrentIndex(SERVER.IP_ID);

    le_Password->setText(SERVER.Password);

    sb_Intervall->setValue(SERVER.Intervall);

}

void wgt_Connection::write_Settings()
{
    SERVER.Intervall = sb_Intervall->value();

    SERVER.Password = le_Password->text();
    SERVER.IP_MAX  = cb_Server->count();
    SERVER.IP_ID   = cb_Server->currentIndex();

    for (int z = 0; z < cb_Server->count(); z++)
    {
        if (z < 10)
        {
            SERVER.IP[z] = cb_Server->itemText(z);
        }
    }

    QSettings Setting("QMK", "QMK-Connection");

    Setting.beginGroup("DATA");
        Setting.setValue(QString("Intervall_%1").arg(gi_ID), SERVER.Intervall);
    Setting.endGroup();

    Setting.beginGroup("SERVER");
        Setting.setValue("Password", SERVER.Password);
        Setting.setValue("IP_MAX", SERVER.IP_MAX);
        Setting.setValue("IP_ID",  SERVER.IP_ID);

        for (int z = 0; z < SERVER.IP_MAX; z++)
        {
            Setting.setValue("IP_" + QString("%1").arg(z), SERVER.IP[z]);
        }
    Setting.endGroup();
}

void wgt_Connection::set_Client(int li_ID, QString ls_Client, QString ls_Fields)
{
    gi_Interval[0] = false;
    gi_Interval[1] = false;

    gs_Client = ls_Client;
    gs_Fields = ls_Fields;
    gi_ID     = li_ID;

    if (ls_Fields.contains('D'))
        gi_Interval[0] = true;

    if (ls_Fields.contains('O'))
        gi_Interval[1] = true;

    read_Settings();
}

void wgt_Connection::set_SelectVisible(bool pi_Visible)
{
    wg_Select->setVisible(pi_Visible);
}

void wgt_Connection::set_IntervalVisible(bool pi_Visible)
{
    wg_Interval->setVisible(pi_Visible);
}

void wgt_Connection::set_ButtonVisible(bool pi_Visible)
{
    btn_Connect->setVisible(pi_Visible);
}

void wgt_Connection::send_Data(QString ps_Data, int pi_ID)
{
    o_Input->send_Data(ps_Data, pi_ID);
}

// MK-Eingangsdaten verarbeiten
void wgt_Connection::parse_MK_Data(QString t_Data)
{
    unsigned char OutData[200];
    char *InData = t_Data.toLatin1().data();

    if (HandlerMK::Decode_64(InData, t_Data.length(), OutData) != 0)
    {

        switch(InData[2])
        {
            case 'A' : // Analog-Labels
                {
                    o_Input->stop_Resend(DATA_READ_LABEL);

                    s_MK_DebugLabels MK_DebugLabels;

                    MK_DebugLabels.Position = OutData[0];

                    if (MK_DebugLabels.Position < 32)
                    {
                        MK_DebugLabels.Text = HandlerMK::Data2QString(OutData,1,17).trimmed();
                        if (MK_DebugLabels.Text == "")
                        {
                            MK_DebugLabels.Text = "Debug-" + QString("%1").arg(MK_DebugLabels.Position);
                        }

                        if (((MK_DebugLabels.Position + 1) < 32))// && (get_Analoglabels == true))
                        {
                            c_Data[0] = MK_DebugLabels.Position + 1;
                            o_Input->send_Data(HandlerMK::make_Frame('a', ADDRESS_ALL, c_Data, 1).toLatin1().data(), DATA_READ_LABEL);
                        }

                        emit(sig_MK_DebugLabels(MK_DebugLabels));
                    }
                }
            break;
            case 'D' : // Debug-Daten
                {
                    s_MK_Debug MK_Debug;

                    memcpy((unsigned char *)&MK_Debug, (unsigned char *)&OutData, sizeof(MK_Debug));

                    emit(sig_MK_Debug(MK_Debug));
                    emit(sig_RawData(t_Data));
                }
            break;
            case 'N' : // MotorMixer lesen
                {
                    o_Input->stop_Resend(DATA_READ_MIXER);

                    s_MK_Mixer MK_Mixer;

                    memcpy((unsigned char *)&MK_Mixer, (unsigned char *)&OutData, sizeof(MK_Mixer));

                    emit (sig_MK_ReadMotorMixer(MK_Mixer));
                }
            break;
            case 'M' : // MotorMixer geschrieben
                {
                    o_Input->stop_Resend(DATA_WRITE_MIXER);

                    emit (sig_MK_WriteMotorMixer(OutData[0]));
                }
            break;

            case 'O' : // Navi-OSD-Data
                {
                    if (InData[1] - 'a' == ADDRESS_NC)
                    {
                        s_MK_NaviData MK_NaviData;

                        memcpy((unsigned char *)&MK_NaviData, (unsigned char *)&OutData, sizeof(MK_NaviData));
                        if (MK_NaviData.Version == MK_VERSION_NAVI)
                        {
                            emit(sig_MK_NaviData(MK_NaviData));
                            emit(sig_RawData(t_Data));
                        }
                    }
                }
            break;

            case 'P' : // RC-Kanäle
                {
                    s_MK_PPM_Data PPM_in;

                    memcpy((unsigned char *)&PPM_in, (unsigned char *)&OutData, sizeof(PPM_in));

//                    qDebug() << PPM_in[0] << ", " << PPM_in[1] << ", " << PPM_in[2] << ", " << PPM_in[3];

                    emit(sig_MK_PPMData(PPM_in));
                }
            break;

            case 'Q' : // Settings lesen
                {
                    o_Input->stop_Resend(DATA_READ_SETTINGS);

                    s_MK_Settings MK_Set;

                    memcpy((unsigned char *)&MK_Set, (unsigned char *)&OutData, sizeof(MK_Set));

                    emit (sig_MK_ReadSettings(MK_Set));
                }
            break;
            case 'S' : // Settings geschrieben
                {
                    o_Input->stop_Resend(DATA_WRITE_SETTINGS);

                    emit (sig_MK_WriteSettings(OutData[0]));
                }
            break;

            case 'V' : // Versions-Info
                {
                    o_Input->stop_Resend(DATA_VERSION);
                    VersionInfo = HandlerMK::parse_Version(OutData, InData[1] - 'a');

                    if (VersionInfo.ID == ADDRESS_FC)
                    {
                        rb_FC->setChecked(true);
                    }
                    if (VersionInfo.ID == ADDRESS_NC)
                    {
                        rb_NC->setChecked(true);
                    }
                    if (VersionInfo.ID == ADDRESS_MK3MAG)
                    {
                        rb_MK3MAG->setChecked(true);
                    }

                    slot_sb_Intervall(sb_Intervall->value());

                    emit sig_MK_Version(VersionInfo);
                }
            break;
            case 'W' : // WayPoints
                {
                    o_Input->stop_Resend(DATA_WRITE_WAYPOINT);

                    emit(sig_MK_WayPoint(OutData[0]));
                }
            break;
        }
    }
}

// IP-Daten verarbeiten..
void wgt_Connection::parse_IP_Data(QString t_Data)
{
    QStringList Data;
    Data = t_Data.split(":");

    if (Data.count() > 1)
    {
        int CMD = Data[2].toInt();

        switch(CMD)
        {
            case 101 :
            {
                o_Input->send_Data(HandlerIP::make_Frame(gi_ID, 101, gs_Client));
            }
            break;
            case 502 :
            {
                switch (Data[3].toInt())
                {
                    case 105 :
                    {
                        QString s_MD5PW;
                        QByteArray a_MD5PW;

                        a_MD5PW = QCryptographicHash::hash(le_Password->text().toAscii(),QCryptographicHash::Md5);

                        s_MD5PW = QString(a_MD5PW.toHex().data());

                        o_Input->send_Data(HandlerIP::make_Frame(gi_ID, 105, s_MD5PW));
                    }
                    break;
                    case 106 :
                    {
                        o_Input->send_Data(HandlerIP::make_Frame(gi_ID, 106, gs_Fields));
                    }
                    break;
                }
            }
            break;
            case 505 :
            {
                if (Data[3] == "OK")
                {
                }
                else
                {
                    QMessageBox::warning(this, gs_Client, trUtf8("Authentifizierung fehlgeschlagen. <br />Daten senden zum Mikrokopter nicht möglich."), QMessageBox::Ok);
                }
            }
            break;
        }
    }
}

// Datenintervall geändert.
void wgt_Connection::slot_sb_Intervall(int t_Intervall)
{
    if (t_Intervall == 0)
    {
        c_Data[0] = 0;
    }
    else
    {
        c_Data[0] = t_Intervall / 10;
    }

//    if (wg_Interval->isVisible())
    {
        if (gi_Interval[0])
        {
           o_Input->send_Data(HandlerMK::make_Frame('d', ADDRESS_ALL, c_Data, 1).toLatin1().data());
        }

        if (gi_Interval[1])
        {
           o_Input->send_Data(HandlerMK::make_Frame('o', ADDRESS_ALL, c_Data, 1).toLatin1().data());
        }
    }
}

void wgt_Connection::slot_send_Data(QString ps_Data, int pi_ID)
{
    send_Data(ps_Data, pi_ID);
}

void wgt_Connection::slot_TimeOut_AboTimer()
{
//    qDebug("Timer");
    slot_sb_Intervall(sb_Intervall->value());
}

void wgt_Connection::slot_btn_Connect()
{
    if (!o_Input->IsOpen())
    {
        if (cb_Server->findText(cb_Server->currentText()) == -1)
        {
            cb_Server->addItem(cb_Server->currentText());
            cb_Server->setCurrentIndex(cb_Server->findText(cb_Server->currentText()));
        }

        cb_Server->setEnabled(false);
        le_Password->setEnabled(false);

        if (cb_Server->currentText().startsWith('/'))
        {
            o_Input = new Input_TTY();
            o_Input->Init();

            set_Input s_Input;
            s_Input.Main = cb_Server->currentText();

            if (o_Input->Open(s_Input) == true)
            {
                emit sig_Status(true);
                btn_Connect->setChecked(true);
                o_AboTimer->start();

                connect(o_Input, SIGNAL(sig_NewData(QString)), this, SLOT(slot_Input_Data(QString)));

                o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
            }
            else
            {
                cb_Server->setEnabled(true);
                le_Password->setEnabled(true);
            }

        }
        else
        {
            o_Input = new Input_TCP();
            o_Input->Init();

            set_Input s_Input;

            QStringList Server = cb_Server->currentText().split(":");

            s_Input.Main = Server[0];
            s_Input.Sub  = Server[1];

            if (o_Input->Open(s_Input) == true)
            {
                connect(o_Input, SIGNAL(sig_Disconnected(int)), this, SLOT(slot_Input_Disconnected(int)));
                connect(o_Input, SIGNAL(sig_Connected()), this, SLOT(slot_Input_Connected()));
            }
        }
    }
    else
    {
        cb_Server->setEnabled(true);
        le_Password->setEnabled(true);

        emit sig_Status(false);
        btn_Connect->setChecked(false);
        o_AboTimer->stop();

        o_Input->Close();
        disconnect(o_Input, SIGNAL(sig_NewData(QString)), 0, 0);
        if (o_Input->Mode() == TCP)
        {
            disconnect(o_Input, SIGNAL(sig_Disconnected(int)), 0, 0);
            disconnect(o_Input, SIGNAL(sig_Connected()), 0, 0);
        }
    }
}

// Neue Daten empfangen.
void wgt_Connection::slot_Input_Data(QString t_Data)
{
    if ((t_Data[0] == '#'))
    {
        if ((HandlerMK::Check_CRC(t_Data.toLatin1().data(), t_Data.length() - 1)) || ((o_Input->Mode() == TTY) && (HandlerMK::Check_CRC(t_Data.toLatin1().data(), t_Data.length()))))
        {
            parse_MK_Data(t_Data);
        }
        else
        {
//            qDebug(QString("CRC-Error - " + t_Data).toLatin1().data());
        }
    }
    else if ((o_Input->Mode() == TCP) && (t_Data[0] == '$'))
    {
        parse_IP_Data(t_Data);
    }
}

// Neue Serververbindung.
void wgt_Connection::slot_Input_Connected()
{
    connect(o_Input, SIGNAL(sig_NewData(QString)), this, SLOT(slot_Input_Data(QString)));

    o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
    emit sig_Status(true);
    btn_Connect->setChecked(true);
    o_AboTimer->start();
}

// Serververbindung beendet
void wgt_Connection::slot_Input_Disconnected(int Error)
{
    cb_Server->setEnabled(true);
    le_Password->setEnabled(true);

    disconnect(o_Input, SIGNAL(sig_NewData(QString)), 0, 0);
    disconnect(o_Input, SIGNAL(sig_Disconnected(int)), 0, 0);
    disconnect(o_Input, SIGNAL(sig_Connected()), 0, 0);

    emit sig_Status(false);
    btn_Connect->setChecked(false);
    o_AboTimer->stop();

    switch (Error)
    {
        case REMOTECLOSED :
        {
//            lb_Status->setText(tr("Verbindung vom Server beendet."));
            QMessageBox::warning(this, gs_Client,tr("QMK-Datenserver: Verbindung wurde vom Server beendet."), QMessageBox::Ok);
        }
        break;
        case REFUSED :
        {
//            lb_Status->setText(tr("Server nicht gefunden."));
            QMessageBox::warning(this, gs_Client,tr("QMK-Datenserver: Kann nicht zum Server verbinden."), QMessageBox::Ok);
        }
        break;
        case 3 :
        {
//            lb_Status->setText(tr("Serververbindung getrennt. Logindaten falsch."));
            QMessageBox::warning(this, gs_Client,tr("QMK-Datenserver: Loginname oder Password falsch."), QMessageBox::Ok);
        }
        break;
        default :
        {
//            lb_Status->setText(tr("Getrennt vom QMK-Datenserver."));
        }
        break;
    }

}

wgt_Connection::~wgt_Connection()
{
    write_Settings();
}