Beispiel #1
0
static void alloc_error(size_t size)
{
    PyGILState_STATE gilstate_save = PyGILState_Ensure();
    PyErr_Format(PyExc_MemoryError, "failed to allocate %zu bytes", size);
    PyGILState_Release(gilstate_save);
    sig_error();
}
void ClientConnection::open()
{
    qDebug() << QThread::currentThreadId() << Q_FUNC_INFO;

    if(! _opened)
    {
        _tcpSocket.setSocketDescriptor(_socketDescriptor);

        if(_tcpSocket.isValid())
        {
            _opened = true;

            qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "_tcpSocket.isValid()," << _opened;

             // Activation de l'option KeepAlive
            _tcpSocket.setSocketOption(QAbstractSocket::KeepAliveOption, 1);

            // Récupère l'adresse du client.
            _clientAddress = _tcpSocket.peerAddress().toString();
            qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "clientAddress:" << _clientAddress;

            filter();
        }
        else
        {
            emit sig_error("socket invalid"); // TODO : Utiliser un enum ?
            // deleteLater(); C'est Server qui crée des ClientConnection, c'est donc Server qui décide quand les détruire
        }
    }
}
void ClientConnection::on_disconnected()
{
    if (!_isAReader)
        qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "isNotAReader";
    else
    {
        qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "isAReader";
        QString nameDatabaseConnexion = QString::number(QThread::currentThreadId());
        {
            _mutex.lock();
            QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", nameDatabaseConnexion);
            _mutex.unlock();

            db.setHostName(BDD_HOST_NAME);
            db.setDatabaseName(BDD_DATABASE_NAME);
            db.setUserName(BDD_USER_NAME);
            db.setPassword(BDD_PASSWORD);

            if (!db.open())
            {
                qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "Error : QSqlDatabase::open() fail :" << db.lastError();
                emit sig_error("open database error");
            }
            else
            {
                QSqlQuery query(db);
                query.exec("UPDATE lecteur SET estConnecte=" + QString::number(false) + " WHERE ip=\"" + _clientAddress + "\";");
                if(!query.isActive())
                {
                    qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "QSqlQuery::exec() [Update reader.isDisconnected] ERROR";
                    emit sig_error("sql error : [Update reader.isDisconnected]");
                }
                else
                {
                    qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "QSqlQuery::exec() [Update lecteur.isDisconnected] ok";
                    query.finish();
                }
                db.close();
            }
        }

        QSqlDatabase::removeDatabase(nameDatabaseConnexion); // TODO : Semble inutile, db est détruit au bloc précédent. L'enlever et réindenter ?
    }
}
void ClientConnection::filter()
{
    qDebug() << QThread::currentThreadId() << Q_FUNC_INFO;

    // Demande à la BDD si c'est un lecteur.
    QString nameDatabaseConnexion = QString::number(QThread::currentThreadId());
    Reader reader;

    {
        _mutex.lock();
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", nameDatabaseConnexion);
        _mutex.unlock();

        db.setConnectOptions("MYSQL_OPT_RECONNECT=5");
        db.setHostName(BDD_HOST_NAME);
        // TODO : Envoyer un nom invalide à setDatabaseName pour tester le comportement du code
        db.setDatabaseName(BDD_DATABASE_NAME);
        db.setUserName(BDD_USER_NAME);
        db.setPassword(BDD_PASSWORD);

        if (!db.open())
        {
            qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "Error : QSqlDatabase::open() fail :" << db.lastError();
            emit sig_error("open database error");
            // TODO : Stopper proprement
            _tcpSocket.close();
        }
        else
        {
            qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "QSqlDatabase::open() : Success.";

            QSqlQuery query(db);
            // TODO : Glisser une erreur de requete pour tester le comportement du code
            query.exec("SELECT  num_lecteur, num_lieu, ip, estConnecte FROM lecteur WHERE ip like \"" + _clientAddress + "\"");
            if(!query.isActive())
            {
                qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "Error : QSqlQuery::exec() [reader ip" << _clientAddress << "exists ?] fail.";
                emit sig_error("sql error : [Select reader infos]");
                // TODO : Stopper proprement
                _tcpSocket.close();
            }
            else
            {
                qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "QSqlQuery::exec() [lecteur d'ip X existe ?] ok";

                if(query.size() == 0)
                {
                    qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "query.size() == 0 -> isNotAReader";
                    // Signale la détection d'un intrus
                    emit sig_isNotAReader(_clientAddress);

                    // Le laisser connecté (évite le flood de connexion déconnexion)
                    // Mais lui vider son buffer dès qu'il se remplit
                    this->connect(&_tcpSocket, SIGNAL(readyRead()), SLOT(bleedBuffer()));
                }
                else
                {
                    query.next();
                    reader.number(query.value(0).toInt());
                    reader.placeId(query.value(1).toInt());
                    reader.address(query.value(2).toString());
                    reader.isConnected(true);
                    query.finish();

                    // Update BDD (lecteur connecté)
                    // TODO : Glisser une erreur de requete pour tester le comportement du code
                    query.exec("UPDATE lecteur SET estConnecte=" + QString::number(reader.isConnected()) + " WHERE ip=\"" + reader.address() + "\";");
                    if(!query.isActive())
                    {
                        qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "QSqlQuery::exec() [Update lecteur.estConnecte] ERROR";
                        emit sig_error("sql error : [Update reader.isConnected]");
                        // TODO : Stopper proprement
                    }
                    else
                    {
                        _isAReader = true;
                        query.finish();

                        qDebug() << QThread::currentThreadId() << Q_FUNC_INFO << "QSqlQuery::exec() [Update lecteur.estConnecte] ok -> sig_isAReader(reader)";
                        qRegisterMetaType<Reader>("Reader");

                        // Signale la détection d'un lecteur
                        emit sig_isAReader(reader);

                        // Traiter les trames reçues
                        this->connect(&_tcpSocket, SIGNAL(readyRead()), SLOT(readyRead()));
                    }
                }
            }
            db.close();
        }
    }

    QSqlDatabase::removeDatabase(nameDatabaseConnexion); // TODO : Semble inutile, db est détruit au bloc précédent. L'enlever et réindenter ?
}