added new radio433 driver with collision detection

modified gpio class
This commit is contained in:
Simon Stürz 2014-07-06 09:46:47 +02:00 committed by Michael Zanetti
parent 8a90e7153d
commit aa528079b0
10 changed files with 555 additions and 235 deletions

View File

@ -40,7 +40,7 @@
/*! Constructs a \l{Gpio} object to represent a GPIO with the given \a gpio number and the \a parent. */
Gpio::Gpio(QObject *parent, int gpio) :
QThread(parent),m_gpio(gpio)
QObject(parent),m_gpio(gpio)
{
exportGpio();
}
@ -51,52 +51,6 @@ Gpio::~Gpio()
unexportGpio();
}
/*! The starting point for the thread. After calling start(), this thread calls this function and starts
* to poll the GPIO file. If an interrupt happens to this GPIO pin, the signal pinInterrupt() gets
* emited.
*/
void Gpio::run()
{
struct pollfd fdset[2];
int gpio_fd = openGpio();
int nfds = 2;
int rc;
int timeout = 3000;
char buf[64];
bool enabled = true;
m_mutex.lock();
m_enabled = true;
m_mutex.unlock();
while(enabled){
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = STDIN_FILENO;
fdset[0].events = POLLIN;
fdset[1].fd = gpio_fd;
fdset[1].events = POLLPRI;
rc = poll(fdset, nfds, timeout);
if (rc < 0) {
qDebug() << "ERROR: poll failed";
return;
}
if(rc == 0){
//timeout
}
if (fdset[1].revents & POLLPRI) {
read(fdset[1].fd, buf, 64);
emit pinInterrupt();
}
m_mutex.lock();
enabled = m_enabled;
m_mutex.unlock();
}
}
/*! Returns true if the GPIO could be exported in the system file "/sys/class/gpio/export".*/
bool Gpio::exportGpio()
{
@ -321,11 +275,3 @@ bool Gpio::setEdgeInterrupt(int edge)
close(fd);
return false;
}
/*! Stop the polling of the \l{run()} method.*/
void Gpio::stop()
{
m_mutex.lock();
m_enabled = false;
m_mutex.unlock();
}

View File

@ -68,15 +68,13 @@
**********************************
*/
class Gpio : public QThread
class Gpio : public QObject
{
Q_OBJECT
public:
explicit Gpio(QObject *parent = 0, int gpio = 0);
~Gpio();
void run() override;
bool exportGpio();
bool unexportGpio();
@ -87,17 +85,12 @@ public:
int getValue();
bool setEdgeInterrupt(int edge);
void stop();
private:
int m_gpio;
int m_dir;
QMutex m_mutex;
bool m_enabled;
signals:
/*! This signal is emited if the INPUT value changed, depending on the edge set in \l{setEdgeInterrupt}*/
void pinInterrupt();
public slots:

View File

@ -20,160 +20,43 @@
\class Radio433
\brief The Radio433 class helps to interact with the 433 MHz Receiver and Transmitter.
\l{http://tech.jolowe.se/home-automation-rf-protocols/}
\inmodule libguh
*/
#include "radio433.h"
#include <QDebug>
#include <sys/time.h>
/*! Constructs a \l{Radio433} object with the given \a parent and initializes the \l{Gpio} pins
* for the transmitter and the receiver.
*/
Radio433::Radio433(QObject *parent) :
QObject(parent)
{
// Set up receiver
m_receiver = new Gpio(this,27);
m_receiver->setDirection(INPUT);
m_receiver->setEdgeInterrupt(EDGE_BOTH);
m_receiver = new Radio433Receiver();
m_transmitter = new Radio433Trasmitter();
// Set up transmitter
m_transmitter = new Gpio(this,22);
m_transmitter->setDirection(OUTPUT);
m_transmitter->setValue(LOW);
connect(m_receiver,SIGNAL(readingChanged(bool)),this,SLOT(readingChanged(bool)));
connect(m_receiver, &Gpio::pinInterrupt, this, &Radio433::handleInterrupt);
m_receiver->start();
m_receiver->startReceiver();
m_transmitter->startTransmitter();
}
/*! Destroyes the \l{Radio433} object and stops the running threads. */
Radio433::~Radio433()
{
m_receiver->quit();
m_receiver->wait();
m_receiver->quit();
m_transmitter->wait();
m_transmitter->quit();
}
void Radio433::readingChanged(bool reading)
{
if(reading){
m_transmitter->allowSending(false);
}else{
m_transmitter->allowSending(true);
}
}
/*! Sends the given \a rawData over the transmitter. The sync signal has to be already in the
* \a rawData.
*/
void Radio433::sendData(QList<int> rawData)
{
//first we have to disable our receiver, to prevent reading this signal
m_receiver->stop();
m_transmitter->setValue(LOW);
int flag=1;
for(int i = 0; i <= 8; i++){
foreach (int delay, rawData) {
// 1 = High, 0 = Low
m_transmitter->setValue(flag %2);
flag++;
delayMicros(delay);
}
}
m_transmitter->setValue(LOW);
// re-enable it
m_transmitter->setValue(LOW);
m_receiver->start();
}
/*! Returns the current system time in microseconds. */
int Radio433::micros()
{
struct timeval tv ;
int now ;
gettimeofday (&tv, NULL) ;
now = (int)tv.tv_sec * (int)1000000 + (int)tv.tv_usec ;
return (int)(now - m_epochMicro) ;
}
/*! Creates a delay of a certain time (\a microSeconds). */
void Radio433::delayMicros(int microSeconds)
{
struct timespec sleeper;
sleeper.tv_sec = 0;
sleeper.tv_nsec = (long)(microSeconds * 1000);
nanosleep (&sleeper, NULL) ;
}
/*! This method handels an interrupt on the receiver pin and recognizes, if a valid message of
* 48 bit or 64 bit was received.
*/
void Radio433::handleInterrupt()
{
long currentTime = micros();
m_duration = currentTime - m_lastTime;
// filter nois
if (m_duration > 5000 && m_duration > m_timings[0] - 200 && m_duration < m_timings[0] + 200) {
m_repeatCount++;
m_changeCount--;
if(m_repeatCount == 2) {
// if we have a regular signal (1 bit sync + 48 bit data or 1bit sync + 64 bit data)
if(m_changeCount == 49 || m_changeCount == 65){
QList<int> rawData;
switch (m_changeCount) {
case 49:
// write rawdata to a List and reset values to 0
for(int i = 0; i < 49; i++ ){
rawData.append(m_timings[i]);
m_timings[i] = 0;
}
qDebug() << "-----------------------------------------------------------";
qDebug() << "| GENERIC signal |";
qDebug() << "-----------------------------------------------------------";
qDebug() << "signal length :" << 49;
qDebug() << "delay :" << rawData.first() /31;
qDebug() << rawData;
emit dataReceived(rawData);
break;
case 65:
// write rawdata to a List and reset values to 0
for(int i = 0; i < 65; i++ ){
rawData.append(m_timings[i]);
m_timings[i] = 0;
}
qDebug() << "-----------------------------------------------------------";
qDebug() << "| GENERIC signal |";
qDebug() << "-----------------------------------------------------------";
qDebug() << "signal length :" << 65;
qDebug() << "delay :" << rawData.first() /10;
qDebug() << rawData;
emit dataReceived(rawData);
default:
break;
}
}
m_repeatCount = 0;
}
m_changeCount = 0;
}else if(m_duration > 5000){
m_changeCount = 0;
}
if (m_changeCount >= RC_MAX_CHANGES) {
m_changeCount = 0;
m_repeatCount = 0;
}
m_timings[m_changeCount++] = m_duration;
m_lastTime = currentTime;
m_transmitter->sendData(rawData);
}

View File

@ -17,48 +17,34 @@
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef RADIO433_H
#define RADIO433_h
#define RADIO433_H
#include <QObject>
#include <QThread>
#include <hardware/gpio.h>
#define RC_MAX_CHANGES 67
#include "radio433receiver.h"
#include "radio433transmitter.h"
class Radio433: public QObject
class Radio433 : public QObject
{
Q_OBJECT
public:
Radio433(QObject *parent = 0);
explicit Radio433(QObject *parent = 0);
~Radio433();
public:
void sendData(QList<int> rawData);
private:
Gpio *m_receiver;
Gpio *m_transmitter;
unsigned int m_timings[RC_MAX_CHANGES];
unsigned int m_duration;
unsigned int m_changeCount;
unsigned long m_lastTime;
unsigned int m_repeatCount;
unsigned int m_epochMicro;
int micros();
void delayMicros(int microSeconds);
private slots:
void handleInterrupt();
Radio433Receiver *m_receiver;
Radio433Trasmitter *m_transmitter;
signals:
/*! This signal is emitted whenever a valid signal of 48 bits was recognized over the
* 433 MHz receiver. The sync signal and the message are in the integer list \a rawData.
*/
void dataReceived(QList<int> rawData);
private slots:
void readingChanged(bool reading);
public slots:
void sendData(QList<int> rawData);
};
#endif
#endif // RADIO433_H

View File

@ -0,0 +1,244 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include <QFile>
#include <QFileSystemWatcher>
#include <QDebug>
#include <sys/time.h>
#include "radio433receiver.h"
Radio433Receiver::Radio433Receiver(QObject *parent, int gpio) :
QThread(parent),m_gpioPin(gpio)
{
stopReceiver();
connect(this,SIGNAL(timingReady(int)),this,SLOT(handleTiming(int)),Qt::DirectConnection);
}
Radio433Receiver::~Radio433Receiver()
{
}
void Radio433Receiver::startReceiver()
{
m_mutex.lock();
m_enabled = true;
m_mutex.unlock();
m_timings.clear();
run();
}
void Radio433Receiver::stopReceiver()
{
m_mutex.lock();
m_enabled = false;
m_mutex.unlock();
}
void Radio433Receiver::run()
{
// init the gpio
setUpGpio();
struct pollfd fdset[2];
int gpio_fd = m_gpio->openGpio();
char buf[1];
bool enabled = true;
m_mutex.lock();
m_enabled = true;
m_mutex.unlock();
int lastTime = micros();
// poll the gpio file, if something changes...emit the signal wit the current pulse length
while(enabled){
memset((void*)fdset, 0, sizeof(fdset));
fdset[0].fd = STDIN_FILENO;
fdset[0].events = POLLIN;
fdset[1].fd = gpio_fd;
fdset[1].events = POLLPRI;
int rc = poll(fdset, 2, 3000);
if (rc < 0) {
qDebug() << "ERROR: poll failed";
return;
}
if(rc == 0){
//timeout
}
if (fdset[1].revents & POLLPRI){
read(fdset[1].fd, buf, 1);
int currentTime = micros();
int duration = currentTime - lastTime;
lastTime = currentTime;
emit timingReady(duration);
}
m_mutex.lock();
enabled = m_enabled;
m_mutex.unlock();
}
}
bool Radio433Receiver::setUpGpio()
{
m_gpio = new Gpio(this,m_gpioPin);
m_gpio->setDirection(INPUT);
m_gpio->setEdgeInterrupt(EDGE_BOTH);
return true;
}
int Radio433Receiver::micros()
{
struct timeval tv ;
int now ;
gettimeofday (&tv, NULL) ;
now = (int)tv.tv_sec * (int)1000000 + (int)tv.tv_usec ;
return (int)(now - m_epochMicro) ;
}
bool Radio433Receiver::valueInTolerance(int value, int sollValue)
{
// in in range of +- 35% of sollValue return true, eles return false
if(value >= (double)sollValue-200 && value <= (double)sollValue+200){
return true;
}
return false;
}
bool Radio433Receiver::checkValue(int value)
{
if(valueInTolerance(value,m_pulseProtocolOne) || valueInTolerance(value,2*m_pulseProtocolOne) || valueInTolerance(value,3*m_pulseProtocolOne) || valueInTolerance(value,4*m_pulseProtocolOne) || valueInTolerance(value,8*m_pulseProtocolOne)){
return true;
}
if(valueInTolerance(value,m_pulseProtocolTwo) || valueInTolerance(value,2*m_pulseProtocolTwo) || valueInTolerance(value,3*m_pulseProtocolTwo) || valueInTolerance(value,4*m_pulseProtocolTwo) || valueInTolerance(value,8*m_pulseProtocolTwo)){
return true;
}
return false;
}
bool Radio433Receiver::checkValues(Protocol protocol)
{
switch (protocol) {
case Protocol48:
for(int i = 1; i < m_timings.count(); i++){
if(!(valueInTolerance(m_timings.at(i),m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),2*m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),3*m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),4*m_pulseProtocolOne) || valueInTolerance(m_timings.at(i),8*m_pulseProtocolOne))){
break;
}
}
return true;
case Protocol64:
for(int i = 1; i < m_timings.count(); i++){
if(!(valueInTolerance(m_timings.at(i),m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),2*m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),3*m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),4*m_pulseProtocolTwo) || valueInTolerance(m_timings.at(i),8*m_pulseProtocolTwo))){
break;
}
}
return true;
default:
break;
}
return false;
}
void Radio433Receiver::changeReading(bool reading)
{
if(reading != m_reading){
m_reading = reading;
emit readingChanged(reading);
}
}
void Radio433Receiver::handleTiming(int duration)
{
// to short...
if(duration < 50){
changeReading(false);
m_timings.clear();
return;
}
// could by a sync signal...
bool sync = false;
if(duration > 2400 && duration < 14000){
changeReading(false);
sync = true;
}
// got sync signal and list is not empty...
if(!m_timings.isEmpty() && sync){
// 1 sync bit + 48 data bit
if(m_timings.count() == 49 && checkValues(Protocol48)){
qDebug() << "48 bit ->" << m_timings << "\n--------------------------";
changeReading(false);
emit dataReceived(m_timings);
}
// 1 sync bit + 64 data bit
if(m_timings.count() == 65 && checkValues(Protocol64)){
qDebug() << "64 bit ->" << m_timings << "\n--------------------------";
changeReading(false);
emit dataReceived(m_timings);
}
m_timings.clear();
m_pulseProtocolOne = 0;
m_pulseProtocolTwo = 0;
changeReading(false);
}
// got sync signal and list is empty...
if(m_timings.isEmpty() && sync){
m_timings.append(duration);
m_pulseProtocolOne = (int)((double)m_timings.first()/31);
m_pulseProtocolTwo = (int)((double)m_timings.first()/10);
changeReading(false);
return;
}
// list not empty and this is a possible value
if(!m_timings.isEmpty() && checkValue(duration)){
m_timings.append(duration);
// check if it could be a signal -> if we have a sync and 15 valid values
// set reading true to prevent a collision from own transmitter
if(m_timings.count() > 20 && (checkValues(Protocol48) || checkValues(Protocol64))){
changeReading(true);
}
// check if we have allready a vallid protocol
// 1 sync bit + 48 data bit
if(m_timings.count() == 49 && checkValues(Protocol48)){
qDebug() << "48 bit -> " << m_timings << "\n--------------------------";
emit dataReceived(m_timings);
}
// 1 sync bit + 64 data bit
if(m_timings.count() == 65 && checkValues(Protocol64)){
qDebug() << "64 bit -> " << m_timings << "\n--------------------------";
changeReading(false);
emit dataReceived(m_timings);
}
}
}

View File

@ -0,0 +1,75 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef RADIO433RECEIVER_H
#define RADIO433RECEIVER_H
#include <QThread>
#include "gpio.h"
class Radio433Receiver : public QThread
{
Q_OBJECT
public:
explicit Radio433Receiver(QObject *parent = 0, int gpio = 27);
~Radio433Receiver();
enum Protocol{
Protocol48,
Protocol64,
ProtocolNone
};
void startReceiver();
void stopReceiver();
private:
int m_gpioPin;
Gpio *m_gpio;
unsigned int m_epochMicro;
unsigned int m_pulseProtocolOne;
unsigned int m_pulseProtocolTwo;
QList<int> m_timings;
QMutex m_mutex;
bool m_enabled;
bool m_reading;
void run();
bool setUpGpio();
int micros();
bool valueInTolerance(int value, int sollValue);
bool checkValue(int value);
bool checkValues(Protocol protocol);
void changeReading(bool reading);
private slots:
void handleTiming(int duration);
signals:
void timingReady(int duration);
void dataReceived(QList<int> rawData);
void readingChanged(const bool &reading);
public slots:
};
#endif // RADIO433RECEIVER_H

View File

@ -0,0 +1,120 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "radio433transmitter.h"
Radio433Trasmitter::Radio433Trasmitter(QObject *parent, int gpio) :
QThread(parent),m_gpioPin(gpio)
{
stopTransmitter();
}
Radio433Trasmitter::~Radio433Trasmitter()
{
}
void Radio433Trasmitter::startTransmitter()
{
m_mutex.lock();
m_enabled = true;
m_mutex.unlock();
run();
}
void Radio433Trasmitter::stopTransmitter()
{
m_mutex.lock();
m_enabled = false;
m_mutex.unlock();
}
void Radio433Trasmitter::run()
{
bool enabled = true;
m_mutex.lock();
m_enabled = true;
m_mutex.unlock();
QList<int> rawData;
while(enabled){
m_queueMutex.lock();
m_allowSendingMutex.lock();
//check if we have data in the sending queue and we are allowed to send...
if(!m_rawDataQueue.isEmpty() && m_allowSending){
m_allowSendingMutex.unlock();
rawData = m_rawDataQueue.dequeue();
m_queueMutex.unlock();
m_gpio->setValue(LOW);
int flag=1;
// send raw data 8 times
for(int i = 0; i <= 8; i++){
foreach (int delay, rawData) {
// 1 = High, 0 = Low
m_gpio->setValue(flag %2);
flag++;
usleep(delay);
}
//check if we can continue or we should stop
m_allowSendingMutex.lock();
if(!m_allowSending){
m_allowSendingMutex.unlock();
break;
}
m_allowSendingMutex.unlock();
}
m_gpio->setValue(LOW);
}
m_queueMutex.unlock();
m_allowSendingMutex.unlock();
m_mutex.lock();
enabled = m_enabled;
m_mutex.unlock();
}
}
void Radio433Trasmitter::allowSending(bool sending)
{
m_allowSendingMutex.lock();
m_allowSending = sending;
m_allowSendingMutex.unlock();
}
bool Radio433Trasmitter::setUpGpio()
{
m_gpio = new Gpio(this,m_gpioPin);
if(!m_gpio->setDirection(OUTPUT) || m_gpio->setValue(LOW)){
return false;
}
return true;
}
void Radio433Trasmitter::sendData(QList<int> rawData)
{
m_queueMutex.lock();
m_rawDataQueue.enqueue(rawData);
m_queueMutex.unlock();
}

View File

@ -0,0 +1,66 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* This file is part of guh. *
* *
* Guh 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, version 2 of the License. *
* *
* Guh 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 guh. If not, see <http://www.gnu.org/licenses/>. *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#ifndef RADIO433TRASMITTER_H
#define RADIO433TRASMITTER_H
#include <QObject>
#include <QThread>
#include <QMutex>
#include <QQueue>
#include <QDebug>
#include "gpio.h"
class Radio433Trasmitter : public QThread
{
Q_OBJECT
public:
explicit Radio433Trasmitter(QObject *parent = 0, int gpio = 22);
~Radio433Trasmitter();
void startTransmitter();
void stopTransmitter();
void sendData(QList<int> rawData);
private:
int m_gpioPin;
Gpio *m_gpio;
QMutex m_mutex;
bool m_enabled;
QMutex m_allowSendingMutex;
bool m_allowSending;
void run();
bool setUpGpio();
QMutex m_queueMutex;
QQueue<QList<int> > m_rawDataQueue;
signals:
public slots:
void allowSending(bool sending);
};
#endif // RADIO433TRASMITTER_H

View File

@ -13,8 +13,10 @@ SOURCES += plugin/device.cpp \
plugin/deviceplugin.cpp \
plugin/devicedescriptor.cpp \
devicemanager.cpp \
hardware/radio433.cpp \
hardware/gpio.cpp \
hardware/radio433.cpp \
hardware/radio433transmitter.cpp \
hardware/radio433receiver.cpp \
types/action.cpp \
types/actiontype.cpp \
types/state.cpp \
@ -26,15 +28,17 @@ SOURCES += plugin/device.cpp \
types/paramtype.cpp \
types/param.cpp \
types/paramdescriptor.cpp \
types/statedescriptor.cpp
types/statedescriptor.cpp \
HEADERS += plugin/device.h \
plugin/deviceclass.h \
plugin/deviceplugin.h \
plugin/devicedescriptor.h \
devicemanager.h \
hardware/radio433.h \
hardware/gpio.h \
hardware/radio433.h \
hardware/radio433transmitter.h \
hardware/radio433receiver.h \
types/action.h \
types/actiontype.h \
types/state.h \
@ -47,5 +51,5 @@ HEADERS += plugin/device.h \
types/paramtype.h \
types/param.h \
types/paramdescriptor.h \
types/statedescriptor.h
types/statedescriptor.h \

View File

@ -28,8 +28,11 @@ TcpServer::TcpServer(QObject *parent) :
qDebug() << "network interfaces:";
foreach(const QNetworkInterface &interface, QNetworkInterface::allInterfaces()){
qDebug() << " -------------------------";
qDebug() << " name:" << interface.name();
qDebug() << " mac: " << interface.hardwareAddress();
qDebug() << " name :" << interface.name();
if(!interface.addressEntries().isEmpty()){
qDebug() << " ip :" << interface.addressEntries().first().ip().toString();
}
qDebug() << " mac : " << interface.hardwareAddress();
}
qDebug() << "----------------------------";