summaryrefslogblamecommitdiffstats
path: root/workspace/LogReceiver/logreceiver.cpp
blob: 93e837339ac70a74dfa16d17f20a254b9521f935 (plain) (tree)
1
2
3
4
5
6
7
8
9
                
                     

                    
 

                    
                    
                    
                            



                          
                    
                  

 
                            

                                        





                             

                                                                   
 




                                                    
                  



                                                                                 
                                                                       

                                                                                      


                       

                                                                                    

                                    
                                               



                                                                                     




















                                                                             

 
                                                          
                                                                             


















                                                                                                  



                      



                                                                           

                                                                

                                          
                 
         
                      









































                                                                                                                    


                                                         



                                                
                                                           













                                                                                              
















                                                                              
                                                                          

                                                                              
                                                                      
                                                   

         
 

                                                                       
     
                                            
         
 






















                                                                                                                             
 

































                                                                             






                                               
                                                                   

                                
                                                                   

                                  
                                                                   

                              
                                                                   

                              
                                                                   

                                     
                                                                   

                                  
                                                                   






                                      
                                                                   

                                  
                                                                   

                                 
                                                                    













                                                  
 

                                                     
                                                                   
 

 



                                                                                                 

              


                                                                                                      
                                                                            



                                                       
                                                                     


                                                
         



                                                 


                                          


                                                                    

 
 










                                                         
 #include <QMap>
 #include <QtNetwork>
 #include <QProcess>


 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
 #include <syslog.h>
 #include <sysfs/libsysfs.h>

 #include "logreceiver.h"
 #include <qlocalserver.h>
 #include <qlocalsocket.h>
 #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<QString> 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<QString> LogReceiver::getListOfNetworkInterfaces() {
	QList<QNetworkInterface> nIList = QNetworkInterface::allInterfaces();
	QList<QString> 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<QString> LogReceiver::checkCarrierState(QList<QString> &interfaces) {
	QList<QString> 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<QString> &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<QString> &interfaces) {
	foreach(QString nI, interfaces)
    {
		checkInternetConnection(nI);
	}
}
void LogReceiver::checkInternetConnectionViaTCP(QString ifName) {

    const bool canStartIAP = (configurationManager.capabilities() & QNetworkConfigurationManager::CanStartAndStopInterfaces);
    QList<QNetworkConfiguration> configs = configurationManager.allConfigurations();
    QNetworkConfiguration cfg;
    foreach(QNetworkConfiguration nC, configs) {
       if(nC.name() == ifName)	 {
           cfg = nC;
       }
    }

    if(!cfg.isValid() || (!canStartIAP && cfg.state() != QNetworkConfiguration::Active)) {

        return;
    }
    session = new QNetworkSession(cfg, this);
    session->open();
    session->waitForOpened(-1);


    QTcpSocket *tcpSocket = new QTcpSocket(this);
    tcpSocket->connectToHost();
}

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*> (QObject::sender());
	QLocalSocket* socket = static_cast<QLocalSocket*> (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::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<QProcess * >(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);
	    }

	}
	numberOfProcesses = numberOfProcesses -1;
	if (numberOfProcesses <= 0) {
		emit allProcessesFinished();
	}
}

void LogReceiver::handleProcessStarted() {
	QProcess* p = qobject_cast<QProcess * >(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;
	}
}