Subversion Repositories Projects

Rev

Blame | 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 <QMessageBox>

#include "dlg_Main.h"

// Konstruktor Main-Form
////////////////////////
dlg_Main::dlg_Main()
{
    setupUi(this);

    o_Settings = new cSettings();

    o_Input = new Input();

    f_Terminal = new dlg_Terminal(this);

    init_GUI();
    init_Connections();

    init_TCP();
}

void dlg_Main::set_ARGV(char *Programm)
{
    QString tmp = QString(Programm);
    QMK_Dir = tmp.left(tmp.lastIndexOf("/"));
}

// Grafische Oberfläche initialisieren
//////////////////////////////////////
void dlg_Main::init_GUI()
{
    setWindowTitle(QA_NAME + " " + QA_VERSION);

    resize(o_Settings->GUI.Size);
    move(o_Settings->GUI.Point);

    if (o_Settings->GUI.isMax)
    {
        showMaximized();
    }

    // todo: In abhängigkeit von Settings
    wg_IP->setVisible(false);
    rb_Device->setChecked(true);

    for (int z = 0; z < DEV_IP_MAX; z++)
    {
        Item[z][0] = new QListWidgetItem();
        Item[z][1] = new QListWidgetItem();
    }

    for(int z = 0; z < o_Settings->CLIENT.TTY_MAX; z++)
    {
        if (cb_Device->findText(o_Settings->CLIENT.TTY_DEVICES[z]) == -1)
        {
            cb_Device->addItem(o_Settings->CLIENT.TTY_DEVICES[z]);
        }
    }

    cb_Device->setCurrentIndex(o_Settings->CLIENT.TTY_ID);
}

// Signale mit Slots verbinden
//////////////////////////////
void dlg_Main::init_Connections()
{
    // Connect-Button
    connect(btn_Connect,   SIGNAL(clicked()), this, SLOT(slot_btn_Connect()));

    connect(btn_cScope,    SIGNAL(clicked()), this, SLOT(slot_btn_cScope()));
    connect(btn_cSettings, SIGNAL(clicked()), this, SLOT(slot_btn_cSettings()));
    connect(btn_cMaps,     SIGNAL(clicked()), this, SLOT(slot_btn_cMaps()));
    connect(btn_cVoice,    SIGNAL(clicked()), this, SLOT(slot_btn_cVoice()));
    connect(btn_cLogger,   SIGNAL(clicked()), this, SLOT(slot_btn_cLogger()));

    connect(btn_Terminal, SIGNAL(clicked()), this, SLOT(slot_btn_Terminal()));

    // About QMK-Kernel & About-QT Dialog einfügen
    connect(ac_About, SIGNAL(triggered()), this, SLOT(slot_ac_About()));
    connect(ac_Server, SIGNAL(triggered()), this, SLOT(slot_ac_Server()));
    menu_Help->addAction(trUtf8("Über &Qt"), qApp, SLOT(aboutQt()));
}

// IP-Ports initialisiern
/////////////////////////
// todo: Port und Anzahl aus Settings
bool dlg_Main::init_TCP()
{
    Connect_Count = 0;
    Connection[0].TCP = false;
    Connection[0].UDP = false;

    for (int a = 0; a < DEV_IP_MAX; a++)
    {
        Connection[a].Open = false;
    }

    TCP_Server = new QTcpServer(this);

    if (TCP_Server->listen(QHostAddress::Any, qint16(o_Settings->SERVER.TCP_PORT)))
    {
        connect(TCP_Server, SIGNAL(newConnection()), this, SLOT(slot_TCP_NewConnection()));
    }

    return true;
}

// Eingangsdaten verarbeiten
////////////////////////////
void dlg_Main::parse_Input_Data(QString t_Data)
{
    unsigned char OutData[150];
    char *InData = t_Data.toLatin1().data();

    if (HandlerMK::Decode_64(InData, t_Data.length(), OutData) != 0)
    {
        switch(InData[2])
        {
            case 'V' : // Versions-Info
                {
                    o_Input->stop_Resend(DATA_VERSION);
                    VersionInfo = HandlerMK::parse_Version(OutData, InData[1] - 'a');
                    lb_Info->setText(tr("Verbunden mit ") + VersionInfo.Hardware + " " + VersionInfo.Version + trUtf8(" über ") + s_Input.Main + ".");

                    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);
                    }
                }
            break;
        }
    }
}

void dlg_Main::route_Input_Data(QString t_Data)
{
    // An alle offenen TCP-Sockets senden.
    for (int a = 1; a < DEV_IP_MAX; a++)
    {
        if (Connection[a].Open == true)
        {
            if (Connection[a].TCP == true)
            {
                send_TCP(o_TCP[a], t_Data + "\r");
            }
        }
    }
}

void dlg_Main::parse_TCP_Data(QString t_Data, int t_ID)
{
    QStringList Data;
    Data = t_Data.split(":");

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

        switch(CMD)
        {
            case 101 :
            {
                Item[t_ID][1]->setText(Data[3]);
                if (Connection[t_ID].Auth == true)
                    Item[t_ID][1]->setText("* " + Data[3]);
            }
            break;
            case 105 :
            {
                if (Connection[t_ID].Auth == false)
                {
                    if ((o_Settings->SERVER.Password != "") && (Data[3] == o_Settings->SERVER.Password))
                    {
                        send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 505, "OK"));

                        Connection[t_ID].Auth = true;
                        Item[t_ID][1]->setText("* " + Item[t_ID][1]->text());
                    }
                    else
                    {
                        send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 505, "NO"));
                    }
                }
            }
            break;
        }
    }
}

// Freies IP-Socket ermitteln
int dlg_Main::get_FreeSocket()
{
    for (int a = 1; a < DEV_IP_MAX; a++)
    {
        if (Connection[a].Open == false)
            return a;
    }
    return 0;
}

// Daten auf TCP Senden
void dlg_Main::send_TCP(QTcpSocket *Socket, QString Data)
{
    QByteArray SendText = Data.toAscii();

    Socket->write(SendText + "\n");
}

///////////ettings
// Slots //
///////////

void dlg_Main::slot_btn_cScope()
{
    QString Programm = QMK_Dir + "/QMK-Scope";

    QStringList Argumente;

    o_cScope = new QProcess();

    Argumente << "";

    o_cScope->start(Programm, Argumente); // Programmaufruf
}

void dlg_Main::slot_btn_cSettings()
{
    QString Programm = QMK_Dir + "/QMK-Settings";

    QStringList Argumente;

    o_cSettings = new QProcess();

    Argumente << "";

    o_cSettings->start(Programm, Argumente); // Programmaufruf
}

void dlg_Main::slot_btn_cMaps()
{
    QString Programm = QMK_Dir + "/QMK-Maps";

    QStringList Argumente;

    o_cMaps = new QProcess();

    Argumente << "";

    o_cMaps->start(Programm, Argumente); // Programmaufruf
}

void dlg_Main::slot_btn_cVoice()
{
    QString Programm = QMK_Dir + "/QMK-Voice";

    QStringList Argumente;

    o_cVoice = new QProcess();

    Argumente << "";

    o_cVoice->start(Programm, Argumente); // Programmaufruf
}

void dlg_Main::slot_btn_cLogger()
{
    QString Programm = QMK_Dir + "/QMK-Logger";

    QStringList Argumente;

    o_cLogger = new QProcess();

    Argumente << "";

    o_cLogger->start(Programm, Argumente); // Programmaufruf
}

void dlg_Main::slot_btn_Terminal()
{
    if (!f_Terminal->isVisible())
    {
        f_Terminal->show();
    }
}

// Verbindung herstellen
void dlg_Main::slot_btn_Connect()
{
    if (!o_Input->IsOpen())
    {
        if (rb_Device->isChecked())
        {
            if (cb_Device->findText(cb_Device->currentText()) == -1)
            {
                cb_Device->addItem(cb_Device->currentText());
                cb_Device->setCurrentIndex(cb_Device->findText(cb_Device->currentText()));
            }

            s_Input.Main = cb_Device->currentText();

            o_Input = new Input_TTY();
            o_Input->Init();

            if (o_Input->Open(s_Input) == true)
            {
                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);

                btn_Connect->setText(tr("Trennen"));
                cb_Device->setEnabled(false);
            }
        }
    }
    else
    {
        if (rb_Device->isChecked())
        {
            o_Input->Close();
            btn_Connect->setText(tr("Verbinden"));
            cb_Device->setEnabled(true);
        }
    }
}

// About-Dialog
void dlg_Main::slot_ac_About()
{
    QMessageBox::about(this, trUtf8(("Über ")) + QA_NAME, QA_ABOUT);
}

void dlg_Main::slot_ac_Server()
{
    dlg_Preferences *f_Preferences = new dlg_Preferences(this);

    f_Preferences->set_Settings(o_Settings);

    if (f_Preferences->exec()==QDialog::Accepted)
    {
        o_Settings = f_Preferences->get_Settings();
        o_Settings->write_Settings();
    }
}

// Neue Daten empfangen.
void dlg_Main::show_Terminal(int t_Typ, QString t_Data)
{
    if (f_Terminal->isVisible())
    {
        f_Terminal->show_Data(t_Typ, t_Data);
    }
}

void dlg_Main::slot_Input_Data(QString t_Data)
{
    if (HandlerMK::Check_CRC(t_Data.toLatin1().data(), t_Data.length()))
    {
        show_Terminal(1, t_Data);
        parse_Input_Data(t_Data);
        route_Input_Data(t_Data);
    }
    else
    {
        show_Terminal(2, t_Data);
    }
}

//////////////
// IP-Slots //
//////////////

void dlg_Main::slot_TCP_NewConnection()
{
    if (!o_Input->IsOpen())
        slot_btn_Connect();

    int ID = get_FreeSocket();

    if (ID != 0)
    {
        Connect_Count++;
        // Leeres Connection erzeugen
        Connection[ID] = Connection[0];
        Connection[ID].Open = true;
        Connection[ID].TCP  = true;
        Connection[ID].Auth = false;

        o_TCP[ID] = TCP_Server->nextPendingConnection();
        o_TCP[ID]->setProperty("ID", ID);

        send_TCP(o_TCP[ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 501,  QA_NAME + " " + QA_VERSION));

        connect(o_TCP[ID], SIGNAL(disconnected()),o_TCP[ID], SLOT(deleteLater()));
        connect(o_TCP[ID], SIGNAL(disconnected()),this,      SLOT(slot_TCP_Disconnect()));
        connect(o_TCP[ID], SIGNAL(readyRead()),this,         SLOT(slot_TCP_Read()));

        Item[ID][0]->setText(o_TCP[ID]->peerAddress().toString());
        lw_ClientsIP->addItem(Item[ID][0]);
        Item[ID][1]->setText("n/a");
        lw_Clients->addItem(Item[ID][1]);

        if (Item[ID][0]->text() == "127.0.0.1")
            Connection[ID].Auth = true;

        if (Connection[ID].Auth)
            Item[ID][1]->setText("* n/a");

    }
    else
    { // Server voll
        o_TCP[ID] = TCP_Server->nextPendingConnection();
        o_TCP[ID]->setProperty("ID", ID);

//        send_TCP(o_TCP[ID], QString("SERVER FULL\n"));
        o_TCP[ID]->disconnectFromHost();
    }
}

void dlg_Main::slot_TCP_Read()
{
    QTcpSocket *Socket = (QTcpSocket*)sender();

//    if (Socket->canReadLine())
    {
        int ID = Socket->property("ID").toUInt();
        ID = ID;

        QString t_Data = QString(Socket->readLine((Socket->bytesAvailable())));

        QStringList s_Data = t_Data.split('\r');

        for (int z = 0; z < s_Data.count() - 1; z++)
        {
            if (s_Data[z][0] == '$')
            {
//                qDebug(QString("TCP: " + s_Data[z]).toLatin1().data());
                parse_TCP_Data(s_Data[z], ID);
            }
            else                
            { // Daten vom Client an den MK. todo: Nur erlauben wenn autemtifiziert oder Localhost
                if ((Connection[ID].Auth == true))
                {
                    show_Terminal(3, s_Data[z]);
                    o_Input->send_Data(s_Data[z]);
                }
            }
        }
    }
}

void dlg_Main::slot_TCP_Disconnect()
{
    QTcpSocket *Socket = (QTcpSocket*)sender();

    int ID = Socket->property("ID").toUInt();

    Item[ID][1]->setText("Disconected");

    Connection[ID] = Connection[0];
    Connection[ID].Open = false;

    Connect_Count--;

    Socket->setProperty("ID", 0);

    if (Connect_Count == 0)
        slot_btn_Connect();
}


// Programm Ende
////////////////
dlg_Main::~dlg_Main()
{
    o_Settings->GUI.isMax       = isMaximized();
    o_Settings->GUI.Size        = size();
    o_Settings->GUI.Point       = pos();

    o_Settings->CLIENT.TTY_MAX = cb_Device->count();
    o_Settings->CLIENT.TTY_ID  = cb_Device->currentIndex();

    for (int z = 0; z < cb_Device->count(); z++)
    {
        if (z < 10)
        {
            o_Settings->CLIENT.TTY_DEVICES[z] = cb_Device->itemText(z);
        }
    }


    o_Settings->write_Settings();

//    qDebug("Ende.");
}