Subversion Repositories Projects

Rev

Rev 711 | 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 Con_Server; 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 Con_Server, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include <QMessageBox>
#include <QCryptographicHash>

#include "dlg_Main.h"

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

    s_Buffer = "";
    o_Settings = new cSettings();

    o_Input = new Input();
    o_Output = 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] = new QListWidgetItem();
    }

    // Liste der Devices
    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);

    // Liste der IP-Server
    for(int z = 0; z < o_Settings->CLIENT.TCP_MAX; z++)
    {
        if (cb_Server->findText(o_Settings->CLIENT.TCP_SERVER[z]) == -1)
        {
            cb_Server->addItem(o_Settings->CLIENT.TCP_SERVER[z]);
        }
    }

    cb_Server->setCurrentIndex(o_Settings->CLIENT.TCP_ID);

    // Password für IP-Verbindung.
    le_Password->setText(o_Settings->CLIENT.TCP_Password);

}

// 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()));
    connect(btn_ConnectServer, SIGNAL(clicked()), this, SLOT(slot_btn_ConnectServer()));

    // 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;

    Con_Server[0].Status = 0;

    Con_Server[0].TCP = false;
    Con_Server[0].UDP = false;

    for (int a = 0; a < DEV_IP_MAX; a++)
    {
        Con_Server[a].Status = 0;
    }

    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 (Con_Server[a].Status > 0)
        {
            if (Con_Server[a].TCP == true)
            {
                if ((Con_Server[a].Fields == "") || (Con_Server[a].Fields.contains(t_Data.at(2)) == true))
                {
                    if (o_Input->Mode() == TTY)
                    {
                        send_TCP(o_TCP[a], t_Data + "\r");
                    }
                    else
                    {
                        send_TCP(o_TCP[a], t_Data);
                    }
                }
                else
                {
//                    qDebug("Not Send Data");
//                    qDebug(t_Data.toLatin1().data());
                }
            }
        }
    }
    if ((o_Output->IsOpen()) && ((Con_Output.Fields == "") || (Con_Output.Fields.contains(t_Data.at(2)) == true)))
    {
        o_Output->send_Data(t_Data);
    }
}

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

    if (Data.count() > 1)
    {
        int CMD = Data[2].toInt();
        QString A = Data[2];
//        qDebug(A.toLatin1().data());

        switch(CMD)
        {
            case 101 :
            {
                Con_Server[t_ID].Version = Data[3];
                Item[t_ID]->setText(" " + QString(o_TCP[t_ID]->peerAddress().toString()).leftJustified(15,' ') + " - " + Con_Server[t_ID].Version);

                if (Con_Server[t_ID].Status == 2)
                {
                    Item[t_ID]->setText("*" + QString(o_TCP[t_ID]->peerAddress().toString()).leftJustified(15,' ') + " - " + Con_Server[t_ID].Version);
                }
                else
                {
                    send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 502, "105"));
                }

                send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 502, "106"));
            }
            break;
            case 105 :
            {
                if (Con_Server[t_ID].Status != 2)
                {
//                    qDebug("Get 105");
                    QString s_MD5PW;
                    QByteArray a_MD5PW;

                    a_MD5PW = QCryptographicHash::hash(o_Settings->SERVER.Password.toAscii(),QCryptographicHash::Md5);

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

                    if ((o_Settings->SERVER.Password != "") && (Data[3] == s_MD5PW))
                    {
//                        qDebug("Set 505 OK");
                        send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 505, "OK"));

                        Con_Server[t_ID].Status = 2;
                        Item[t_ID]->setText("*" + QString(o_TCP[t_ID]->peerAddress().toString()).leftJustified(15,' ') + " - " + Con_Server[t_ID].Version);
                    }
                    else
                    {
//                        qDebug("Set 505 NO");
                        send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 505, "NO"));
                    }
                }
                else
                {
                    send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 505, "OK"));
                }
            }
            break;
            case 106 : // Datenfelder anfordern.
            {
                if (Con_Server[t_ID].Status == 2)
                {
                    Con_Server[t_ID].Fields = Data[3];
                    Item[t_ID]->setText("*" + QString(o_TCP[t_ID]->peerAddress().toString()).leftJustified(15,' ') + " - " + Con_Server[t_ID].Version + " - " + Con_Server[t_ID].Fields);
//                    send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 506, Con_Server[t_ID].Fields));
                }
            }
        }
    }
}

// IP-Input-Daten verarbeiten.
void dlg_Main::parse_TCP_Input_Data(QString t_Data)
{
    QStringList Data;
    Data = t_Data.split(":");

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

        switch(CMD)
        {
            case 502 :
            {
//                qDebug("Request Data");
                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(ID_COMMUNICATOR, 105, s_MD5PW));
                    }
                    break;
                }
            }
            break;
            case 505 :
            {
                if (Data[3] == "OK")
                {
                }
                else
                {
                    QMessageBox::warning(this, QA_NAME, trUtf8("Authentifizierung fehlgeschlagen. <br />Daten senden zum Mikrokopter nicht möglich."), QMessageBox::Ok);
                }
            }
            break;
        }
    }
}

// IP-Input-Daten verarbeiten.
void dlg_Main::parse_TCP_Output_Data(QString t_Data)
{
    QStringList Data;
    Data = t_Data.split(":");

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

        switch(CMD)
        {
            case 101 :
            {
                Con_Output.Version = Data[3];
                o_Output->send_Data(HandlerIP::make_Frame(ID_COMMUNICATOR, 101, QA_NAME + " " + QA_VERSION));
            }
            break;
            case 106 : // Datenfelder anfordern.
            {
                Con_Output.Fields = Data[3];
//                    send_TCP(o_TCP[t_ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 506, Con_Server[t_ID].Fields));
            }
            break;
            case 502 :
            {
                switch (Data[3].toInt())
                {
                    case 104 :
                    {
//                        qDebug("Request PW");
                        QString s_MD5PW;
                        QByteArray a_MD5PW;

                        a_MD5PW = QCryptographicHash::hash(QString("madlen").toAscii(),QCryptographicHash::Md5);

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

                        o_Output->send_Data(HandlerIP::make_Frame(ID_COMMUNICATOR, 104, "keyoz@c64-power.net;" + s_MD5PW));
                    }
                    break;
                }
            }
            break;
            case 504 :
            {
                if (Data[3] == "OK")
                {
                    Con_Output.Status = 2;
                    o_Output->send_Data(HandlerIP::make_Frame(ID_COMMUNICATOR, 502, "106"));
                }
                else
                {
                    QMessageBox::warning(this, QA_NAME, trUtf8("Authentifizierung fehlgeschlagen."), QMessageBox::Ok);
                }
            }
            break;
        }
    }
}

// Freies IP-Socket ermitteln
int dlg_Main::get_FreeSocket()
{
    for (int a = 1; a < DEV_IP_MAX; a++)
    {
        if (Con_Server[a].Status == 0)
            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");
    Socket->flush();

//    qDebug(SendText.data());
}

///////////
// 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 zum Datenserver
void dlg_Main::slot_btn_ConnectServer()
{
    if (!o_Output->IsOpen())
    {
        Con_Output = Con_Server[0];

        s_Output.Main = "127.0.0.1";//Server[0];
        s_Output.Sub  = "64410";//Server[1];

        o_Output = new Input_TCP();
        o_Output->Init();

        if (o_Output->Open(s_Output) == true)
        {
            connect(o_Output, SIGNAL(sig_Disconnected(int)), this, SLOT(slot_Output_Disconnected(int)));
            connect(o_Output, SIGNAL(sig_Connected()), this, SLOT(slot_Output_Connected()));
        }
        btn_ConnectServer->setText(tr("Trenne Server"));
        Con_Output.Status = 1;
    }
    else
    {
        btn_ConnectServer->setText(tr("Verbinde Server"));

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

void dlg_Main::slot_Output_Disconnected(int Error)
{
//    cb_Server->setEnabled(true);
//    le_Password->setEnabled(true);

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

    btn_ConnectServer->setText(tr("Verbinde Server"));

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


}

void dlg_Main::slot_Output_Connected()
{
    connect(o_Output, SIGNAL(sig_NewData(QString)), this, SLOT(slot_Output_Data(QString)));

//    o_Output->send_Data(HandlerIP::make_Frame(ID_COMMUNICATOR, 101, QA_NAME + " " + QA_VERSION));
//    o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
//    btn_Connect->setText(tr("Trennen"));
}

void dlg_Main::slot_Output_Data(QString t_Data)
{
    if ((t_Data[0] == '#'))
    {
    }
    else if (o_Output->Mode() == TCP)
    {
        show_Terminal(6, t_Data);
        parse_TCP_Output_Data(t_Data);
    }
}

// Verbindung herstellen zum Kopter
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_TCP->isChecked())
        {
            if (cb_Server->findText(cb_Device->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);

            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_Device->setEnabled(true);
            cb_Server->setEnabled(true);
            le_Password->setEnabled(true);

            o_Input->Close();
            btn_Connect->setText(tr("Verbinden"));
            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 dlg_Main::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()))))
        {
            show_Terminal(1, "MK: " + t_Data);
            parse_Input_Data(t_Data);
            route_Input_Data(t_Data);
        }
        else
        {
            show_Terminal(2, t_Data);
        }
    }
    else if ((o_Input->Mode() == TCP) && (t_Data[0] == '$'))
    {
        show_Terminal(4, t_Data);
        parse_TCP_Input_Data(t_Data);
    }
    else
    {
        show_Terminal(2, t_Data);
    }


}

void dlg_Main::slot_Input_Disconnected(int Error)
{
    cb_Server->setEnabled(true);
    le_Password->setEnabled(true);

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

    btn_Connect->setText(tr("Verbinden"));

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


}

void dlg_Main::slot_Input_Connected()
{
    connect(o_Input, SIGNAL(sig_NewData(QString)), this, SLOT(slot_Input_Data(QString)));

    o_Input->send_Data(HandlerIP::make_Frame(ID_COMMUNICATOR, 101, QA_NAME + " " + QA_VERSION));
    o_Input->send_Data(HandlerMK::make_Frame('v', 0, c_Data, 0).toLatin1().data(), DATA_VERSION);
    btn_Connect->setText(tr("Trennen"));
}

// 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();
    }
}

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

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

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

    int ID = get_FreeSocket();

    if (ID != 0)
    {
        Connect_Count++;

        // Leeres Con_Server erzeugen
        Con_Server[ID] = Con_Server[0];

        Con_Server[ID].Status = 1;
        Con_Server[ID].TCP  = true;

        Con_Server[ID].Fields = "";
        Con_Server[ID].Version = "n/a";

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

        send_TCP(o_TCP[ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 101,  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]->setText(" " + QString(o_TCP[ID]->peerAddress().toString()).leftJustified(15,' ') + " - n/a");
        lw_Clients->addItem(Item[ID]);

        if (o_TCP[ID]->peerAddress().toString() == "127.0.0.1")
        {
            Con_Server[ID].Status = 2;
            Item[ID]->setText("*" + QString(o_TCP[ID]->peerAddress().toString()).leftJustified(15,' ') + " - n/a");
        }

        if (o_Input->IsOpen())
        {
//            send_TCP(o_TCP[ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 520, cb_Device->currentText()));
        }

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

        send_TCP(o_TCP[ID],HandlerIP::make_Frame(ID_COMMUNICATOR, 521, "Sorry, Server full."));
        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(TCP_Socket->readLine(TCP_Socket->bytesAvailable())).remove(QChar('\n'));
        QString t_Data = s_Buffer + QString(Socket->readAll());
        s_Buffer = "";

        QStringList l_Data = t_Data.split('\n');

        for (int z = 0; z < l_Data.count(); z++)
        {
            if ((l_Data[z][l_Data[z].length() - 1] == '\r'))
            {
                l_Data[z].remove(QChar('\r'));
                if (l_Data[z][0] == '$')
                {
                    parse_TCP_Server_Data(l_Data[z], ID);
                    show_Terminal(5, "IP: " + l_Data[z]);
                }
                else
                {
                    if ((Con_Server[ID].Status >= 2))
                    {
                        show_Terminal(3, "MK> " + l_Data[z]);
                        o_Input->send_Data(l_Data[z]);
                    }
                }
            }
            else
            {
                qDebug("Ohne Ende");
                s_Buffer = s_Buffer + l_Data[z];
            }

        }

/*
        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] == '$')
            {
                parse_TCP_Server_Data(s_Data[z], ID);
                show_Terminal(5, "IP: " + s_Data[z]);

            }
            else
            {
                if ((Con_Server[ID].Status >= 2))
                {
                    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]->setText(" " + QString(o_TCP[ID]->peerAddress().toString()).leftJustified(15,' ') + " - Disconected");

    Con_Server[ID] = Con_Server[0];
    Con_Server[ID].Status = 0;

    Connect_Count--;

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

    if ((Connect_Count == 0) && (o_Input->IsOpen()))
        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->CLIENT.TCP_MAX = cb_Server->count();
    o_Settings->CLIENT.TCP_ID  = cb_Server->currentIndex();

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

    o_Settings->write_Settings();

//    qDebug("Ende.");
}