#include #include #include #include #include #include #include #include #include "logreceiver.h" #include #include #include "status.h" #include "dhcp.h" LogReceiver::LogReceiver() { server = new QLocalServer(this); } LogReceiver::~LogReceiver() { } void LogReceiver::initAndRun(QString serverPath, QString pathToExe, QStringList* args) { if (serverPath != DEFAULT_QTSOCKETADDRESS) { dhcpcdArguments.append("-q"); dhcpcdArguments.append(serverPath); } if (!server->listen(serverPath)) { /* QMessageBox::critical(this, tr("LogReceiver"), tr( "Unable to start the server: %1.") .arg(server->errorString())); close(); */ // emit signal to the gui that a critial error occoured qDebug() << "--- \t [LogReceiver::initAndRun] Unable to start server:" << server->errorString(); return; } connect(server, SIGNAL(newConnection()), this, SLOT(handleNewConnection())); pathToDhcpcdExe = pathToExe; if (args != NULL && !args->isEmpty()) { qDebug() << "--- \t [LogReceiver::initAndRun] added additional args"; dhcpcdArguments.append(*args); } numberOfProcesses = 0; // start the main work: QList list = getListOfNetworkInterfaces(); if (list.size() > 0) { //list = checkCarrierState(list); //dhcpcdArguments.append("-d"); QString ifName("eth0"); numberOfProcesses = list.size(); runDHCPCD(list); } else { qDebug() << "list is empty. Haven't found usable interface."; emit abortBoot("Haven't found usable interface"); return; } } QList LogReceiver::getListOfNetworkInterfaces() { QList nIList = QNetworkInterface::allInterfaces(); QList result; if (nIList.size() > 0) { foreach(QNetworkInterface nI, nIList) { if (((!(nI.flags() & QNetworkInterface::CanBroadcast) || nI.flags() & QNetworkInterface::IsLoopBack) || nI.flags() & QNetworkInterface::IsPointToPoint) || checkBlackList(nI.humanReadableName())) { continue; } if (!checkCarrierState(nI.humanReadableName())) { continue; } result.append(nI.humanReadableName()); emit addNewInterface(nI.humanReadableName()); } } else { qDebug() << "no interfaces found!"; } return result; } QList LogReceiver::checkCarrierState(QList &interfaces) { QList result; foreach(QString nI, interfaces) { if(checkCarrierState(nI)) { // everything is fine, cable is plugged, // go on with the next interface //continue; result.append(nI); } } return result; } bool LogReceiver::checkCarrierState(QString interface) { qDebug() << "check carrier state for interface " << interface; QByteArray ba = interface.toAscii(); const char * iface = ba.data(); struct sysfs_class_device *class_device = sysfs_open_class_device("net", iface); struct dlist *attrlist = sysfs_get_classdev_attributes(class_device); if (attrlist != NULL) { struct sysfs_attribute *attr = NULL; dlist_for_each_data(attrlist, attr, struct sysfs_attribute) { if (strcmp("carrier", attr->name) == 0) { QString value(attr->value); bool ok = false; bool * pok = &ok; int v = value.toInt(pok); if (*pok) { if (v == 1) { qDebug() << "carrier is 1. Cable is plugged. return true"; return true; } else { qDebug() << "carrier is 0. Cable is unplugged. return false"; return false; } } else { qDebug() << "conversion error"; } } } } else { qDebug() << "attrlist is Null"; } sysfs_close_class_device(class_device); return true; } void LogReceiver::runDHCPCD(QList &interfaces) { foreach(QString nI, interfaces) { runDHCPCD(nI); } } void LogReceiver::runDHCPCD(QString interface) { emit updateStatusLabel(interface,"start DHCP"); dhcpcdArguments.append(interface); QProcess * p = new QProcess(this); qDebug() << dhcpcdArguments; clientProcessToIfNameMap.insert(p, interface); qDebug() << clientProcessToIfNameMap; p->start(pathToDhcpcdExe,dhcpcdArguments); connect(p, SIGNAL(started()), this, SLOT(handleProcessStarted())); connect(p, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(handleProcessFinished(int, QProcess::ExitStatus))); dhcpcdArguments.removeLast(); } void LogReceiver::checkInternetConnection(QString ifName) { QString command("ping"); QStringList argList; QString timeout("1"); QString total("2"); int exitCode = -1; QString destination("www.google.de"); argList << "-I" << "ifName" << "-W" << timeout << "-c" << total << destination; argList.replace(1, ifName); QProcess * p = new QProcess(this); p->start(command, argList); p->waitForFinished(); exitCode = p->exitCode(); if (exitCode > 0) { qDebug() << "no internet connection with interface" << ifName; //remove interface from list and inform user via debug console emit updateStatusLabel(ifName, "connection not possible"); } else if (exitCode == 0) { qDebug() << "internet: check passed! for interface" << ifName; emit updateStatusLabel(ifName, "connection possible"); emit connectionEstablished(ifName); } } void LogReceiver::checkInternetConnection(QList &interfaces) { foreach(QString nI, interfaces) { checkInternetConnection(nI); } } void LogReceiver::checkInternetConnectionViaTCP(QString ifName) { const bool canStartIAP = (configurationManager.capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces); QList configs = configurationManager.allConfigurations(); QNetworkConfiguration cfg; foreach(QNetworkConfiguration nC, configs) { if (nC.name() == ifName) { qDebug() << "found config" << nC.name(); cfg = nC; break; } } if (!cfg.isValid() || (!canStartIAP && cfg.state() != QNetworkConfiguration::Active)) { qDebug() << "config is not valid" << cfg.name(); return; } QNetworkSession *session = new QNetworkSession(cfg, this); session->open(); if (session->waitForOpened(-1)) { QTcpSocket *tcpSocket = new QTcpSocket(this); tcpSocket->connectToHost(QString("209.85.148.105"), 80); if (!tcpSocket->waitForConnected()) { qDebug() << tcpSocket->errorString(); emit updateStatusLabel(ifName, "connection not possible"); } else { emit updateStatusLabel(ifName, "connection possible"); emit connectionEstablished(ifName); } } else { qDebug() << "couldn't open session"; } session->close(); } void LogReceiver::handleNewConnection() { qDebug() << "New Connection arrived"; QLocalSocket * client = server ->nextPendingConnection(); clients.insert(client, client); connect(client, SIGNAL(disconnected()), client, SLOT(deleteLater())); connect(client, SIGNAL(readyRead()), this, SLOT(handleNewInput())); } void LogReceiver::handleNewInput() { QObject* sender = const_cast (QObject::sender()); QLocalSocket* socket = static_cast (sender); QLocalSocket * client = clients.value(socket); QString data(client->readAll()); data = data.trimmed(); QStringList lines = data.split("\n"); for (int i=0; i < lines.length(); i++) { handleNewInputLine(lines.at(i)); } } void LogReceiver::handleNewInput_(QLocalSocket *client) { QString data(client->readAll()); data = data.trimmed(); QStringList lines = data.split("\n"); for (int i=0; i < lines.length(); i++) { handleNewInputLine(lines.at(i)); } } void LogReceiver::handleNewInputLine(QString data) { QString logMsg(data); QString interface = logMsg.section(";",0,0); QString s_state = logMsg.section(";", 1, 1); QString s_subState = logMsg.section(";", 2, 2); QString msg = logMsg.section(";", 3, 3); int st = s_state.trimmed().toInt(); int sst = s_subState.trimmed().toInt(); qDebug() << logMsg; switch (st) { case LOG_INFO: switch (sst) { case DHCP_DISCOVER: emit changeProgressBarValue(interface, 10); break; case DHCP_OFFER: emit changeProgressBarValue(interface, 20); break; case DHCP_REQUEST: emit changeProgressBarValue(interface, 30); break; case DHCP_ACK: emit changeProgressBarValue(interface, 40); break; case DHCP_NAK: emit changeProgressBarValue(interface, 40); break; case DHCPCD_ARP_TEST: emit changeProgressBarValue(interface, 50); break; case DHCP_DECLINE: emit changeProgressBarValue(interface, 60); break; case DHCP_RELEASE: break; case DHCP_INFORM: break; case DHCPCD_CONFIGURE: emit changeProgressBarValue(interface, 70); break; case DHCPCD_WRITE: emit changeProgressBarValue(interface, 80); break; case DHCPCD_EXIT: emit changeProgressBarValue(interface, 100); break; case DHCPCD_LOG: default: break; } break; case LOG_ERR: qDebug() << "received stat_error"; break; default: qDebug() << logMsg; } } void LogReceiver::handleProcessFinished(int exitCode, QProcess::ExitStatus exitStatus) { QProcess* p = qobject_cast(QObject::sender()); QString ifName = clientProcessToIfNameMap.value(p,"ifName"); if(ifName.compare("ifName") == 0) { qDebug() << "--- \t [LogReceiver::handleProcessFinished] haven't found process!"; } else { qDebug() << "process for interface"<< ifName << "finished" << exitCode << exitStatus; if(exitCode > 0) { qDebug() << "process exited unexpected"; emit updateStatusLabel(ifName, "process exited unexpected"); } else { qDebug() << "process normal exit"; qDebug() << "check internet connction"; emit updateStatusLabel(ifName, "check connectivity"); //checkInternetConnection(ifName); checkInternetConnectionViaTCP(ifName); } } if (numberOfProcesses == 1) { QLocalSocket *s; qDebug() << "try to read socket buffer.."; foreach(s, clients.keys()) { if (s->bytesAvailable() > 0) { qDebug() << "read socket buffer.."; handleNewInput_(s); } } } numberOfProcesses = numberOfProcesses -1; if (numberOfProcesses <= 0) { emit allProcessesFinished(); } } void LogReceiver::handleProcessStarted() { QProcess* p = qobject_cast(QObject::sender()); QString ifName = clientProcessToIfNameMap.value(p,"ifName"); qDebug() << "process started for interface:" << ifName; } bool LogReceiver::checkBlackList(QString i) { if (i.startsWith("v", Qt::CaseInsensitive)) { return true; } else if(i.startsWith("d", Qt::CaseInsensitive)) { return true; } else { return false; } }