diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 58dad6150948df5bda50e696f51a56549912fc73..c0fa5c5469f7e655bca9eff212097c1c3493c59d 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -533,3 +533,20 @@ win32:exists(src/lib/opalrt/OpalApi.h):exists(C:/OPAL-RT/RT-LAB7.2.4/Common/bin) } TRANSLATIONS += es-MX.ts \ en-US.ts + +# xbee support +# libxbee only supported by linux and windows systems +win32-msvc2008|win32-msvc2010|linux{ + HEADERS += src/comm/XbeeLinkInterface.h \ + src/comm/XbeeLink.h \ + src/ui/XbeeConfigurationWindow.h \ + src/comm/CallConv.h + SOURCES += src/comm/XbeeLink.cpp \ + src/ui/XbeeConfigurationWindow.cpp + DEFINES += XBEELINK + INCLUDEPATH += thirdParty/libxbee +# TO DO: build library when it does not exists already + LIBS += -LthirdParty/libxbee/lib \ + -llibxbee + +} diff --git a/src/comm/CallConv.h b/src/comm/CallConv.h new file mode 100644 index 0000000000000000000000000000000000000000..6c13955cf42c75340822aba1910537368bc282b9 --- /dev/null +++ b/src/comm/CallConv.h @@ -0,0 +1,11 @@ +#ifndef _CALLCONV_H_ +#define _CALLCONV_H_ + +#ifdef Q_OS_WIN +#define CALLTYPEXBEE __stdcall +#else // Q_OS_WIN +#define CALLTYPEXBEE +#endif // Q_OS_WIN + + +#endif // _CALLCONV_H_ \ No newline at end of file diff --git a/src/comm/XbeeLink.cpp b/src/comm/XbeeLink.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0a272675448034a12bb0397f8c28b034c1ae5166 --- /dev/null +++ b/src/comm/XbeeLink.cpp @@ -0,0 +1,268 @@ +#include +#include +#include +#include +#include +#include +#include "XbeeLink.h" + +XbeeLink::XbeeLink(QString portName, int baudRate) : + m_xbeeCon(NULL), m_portName(NULL), m_portNameLength(0), m_baudRate(baudRate), m_connected(false), m_id(-1) +{ + + /* setup the xbee */ + this->setPortName(portName); + + //this->connect(); + // Set unique ID and add link to the list of links + this->m_id = getNextLinkId(); + // set the Name + this->m_name = tr("xbee link") + QString::number(this->m_id); + emit nameChanged(this->m_name); +} + +XbeeLink::~XbeeLink() +{ + if(m_portName) + { + delete m_portName; + m_portName = NULL; + } + this->disconnect(); +} + +QString XbeeLink::getPortName() +{ + QString portName; + for(unsigned int i = 0;im_portNameLength;i++) + { + portName.append(this->m_portName[i]); + } + return portName; +} + +int XbeeLink::getBaudRate() +{ + return this->m_baudRate; +} + +bool XbeeLink::setPortName(QString portName) +{ + bool reconnect(false); + if(this->m_connected) + { + this->disconnect(); + reconnect = true; + } + if(m_portName) + { + delete m_portName; + m_portName = NULL; + } + QStringList list = portName.split(QRegExp("\\s+"),QString::SkipEmptyParts); + if(list.size()>0) + { + this->m_portNameLength = list[0].size()+1; + m_portName = new char[this->m_portNameLength]; + for(int i=0;im_portName[i]=list[0][i].toAscii(); + } + this->m_portName[list[0].size()] = '\0'; + } + else + { + this->m_portNameLength = 1; + m_portName = new char[this->m_portNameLength]; + this->m_portName[0] = '\0'; + } + + bool retVal(true); + if(reconnect) + { + retVal = this->connect(); + } + + return retVal; +} + +bool XbeeLink::setBaudRate(int rate) +{ + bool reconnect(false); + if(this->m_connected) + { + this->disconnect(); + reconnect = true; + } + bool retVal(true); + this->m_baudRate = rate; + if(reconnect) + { + retVal = this->connect(); + } + return retVal; +} + +int XbeeLink::getId() +{ + return this->m_id; +} + +QString XbeeLink::getName() +{ + return this->m_name; +} + +bool XbeeLink::isConnected() +{ + return this->m_connected; +} + +qint64 XbeeLink::getNominalDataRate() +{ + return this->m_baudRate; +} + +bool XbeeLink::isFullDuplex() +{ + return false; +} + +int XbeeLink::getLinkQuality() +{ + return -1; // TO DO: +} + +qint64 XbeeLink::getTotalUpstream() +{ + return 0; // TO DO: +} + +qint64 XbeeLink::getCurrentUpstream() +{ + return 0; // TO DO: +} + +qint64 XbeeLink::getMaxUpstream() +{ + return 0; // TO DO: +} + +qint64 XbeeLink::getBitsSent() +{ + return 0; // TO DO: +} + +qint64 XbeeLink::getBitsReceived() +{ + return 0; // TO DO: +} + +bool XbeeLink::hardwareConnect() +{ + if(this->isConnected()) + { + this->disconnect(); + } + if (*this->m_portName == '\0') + { + return false; + } + if (xbee_setupAPI(this->m_portName,this->m_baudRate,0x2B,0x3E8) == -1) + { + /* oh no... it failed */ + qDebug() <<"xbee_setup() failed...\n"; + return false; + } + this->m_xbeeCon = xbee_newcon('A',xbee2_data,0x13A200,0x403D0935); + this->m_connected = true; + emit connected(); + emit connected(true); + return true; +} + +bool XbeeLink::connect() +{ + if (this->isRunning()) this->disconnect(); + this->start(LowPriority); + return true; +} + +bool XbeeLink::disconnect() +{ + if(this->isRunning()) this->terminate(); //stop running the thread, restart it upon connect + + if(this->m_xbeeCon) + { + xbee_endcon(this->m_xbeeCon); + this->m_xbeeCon = NULL; + } + this->m_connected = false; + + emit disconnected(); + emit connected(false); + return true; +} + +qint64 XbeeLink::bytesAvailable() +{ + return 0; +} + +void XbeeLink::writeBytes(const char *bytes, qint64 length) // TO DO: delete the data array +{ + char *data; + data = new char[length]; + for(long i=0;im_xbeeCon,data,length)) // return value of 0 is successful written + { + } + else + { + this->disconnect(); + emit communicationError(this->getName(), tr("Could not send data - link %1 is disconnected!").arg(this->getName())); + } +} + +void XbeeLink::readBytes() +{ + xbee_pkt *xbeePkt; + xbeePkt = xbee_getpacketwait(this->m_xbeeCon); + if(!(NULL==xbeePkt)) + { + QByteArray data; + for(unsigned int i=0;i<=xbeePkt->datalen;i++) + { + data.push_back(xbeePkt->data[i]); + } + qDebug() << data; + emit bytesReceived(this,data); + } +} + +void XbeeLink::run() +{ + // Initialize the connection + if(this->hardwareConnect()) + { + // Qt way to make clear what a while(1) loop does + forever + { + this->readBytes(); + } + } +} + +/* +void CALLTYPE XbeeLink::portCallback(xbee_con *xbeeCon, xbee_pkt *XbeePkt) +{ + QByteArray buf; + for(quint8 i=0;idatalen;i++) + { + buf.push_back(XbeePkt->data[i]); + } + emit bytesReceived(this, buf); +}*/ \ No newline at end of file diff --git a/src/comm/XbeeLink.h b/src/comm/XbeeLink.h new file mode 100644 index 0000000000000000000000000000000000000000..befd8a63c1be45452be95360b24ac7124cd7d1e1 --- /dev/null +++ b/src/comm/XbeeLink.h @@ -0,0 +1,70 @@ +#ifndef _XBEELINK_H_ +#define _XBEELINK_H_ + +#include +#include +#include +#include +#include +#include +#include "XbeeLinkInterface.h" +#include +#include "CallConv.h" + +class XbeeLink : public XbeeLinkInterface +{ + Q_OBJECT + +public: + XbeeLink(QString portName = "", int baudRate=57600); + ~XbeeLink(); + +public: // virtual functions from XbeeLinkInterface + QString getPortName(); + int getBaudRate(); + +public slots: // virtual functions from XbeeLinkInterface + bool setPortName(QString portName); + bool setBaudRate(int rate); + +public: // virtual functions from LinkInterface + int getId(); + QString getName(); + bool isConnected(); + qint64 getNominalDataRate(); + bool isFullDuplex(); + int getLinkQuality(); + qint64 getTotalUpstream(); + qint64 getCurrentUpstream(); + qint64 getMaxUpstream(); + qint64 getBitsSent(); + qint64 getBitsReceived(); + bool connect(); + bool disconnect(); + qint64 bytesAvailable(); + +public slots: // virtual functions from LinkInterface + void writeBytes(const char *bytes, qint64 length); + +protected slots: // virtual functions from LinkInterface + void readBytes(); + +public: + void run(); // initiating the thread + +protected: + xbee_con *m_xbeeCon; + int m_id; + char *m_portName; + unsigned int m_portNameLength; + int m_baudRate; + bool m_connected; + QString m_name; + +private: + bool hardwareConnect(); + //void CALLTYPE portCallback(xbee_con *XbeeCon, xbee_pkt *XbeePkt); +}; + + +#endif // _XBEELINK_H_ \ No newline at end of file diff --git a/src/comm/XbeeLinkInterface.h b/src/comm/XbeeLinkInterface.h new file mode 100644 index 0000000000000000000000000000000000000000..96bd0c001969429ba7324228bbd99083637c47b7 --- /dev/null +++ b/src/comm/XbeeLinkInterface.h @@ -0,0 +1,21 @@ +#ifndef XBEELINKINTERFACE_H_ +#define XBEELINKINTERFACE_H_ + +#include +#include +#include + +class XbeeLinkInterface : public LinkInterface +{ + Q_OBJECT + +public: + virtual QString getPortName() = 0; + virtual int getBaudRate() = 0; + +public slots: + virtual bool setPortName(QString portName) = 0; + virtual bool setBaudRate(int rate) = 0; +}; + +#endif // XBEELINKINTERFACE_H_ diff --git a/src/ui/XbeeConfigurationWindow.cpp b/src/ui/XbeeConfigurationWindow.cpp new file mode 100644 index 0000000000000000000000000000000000000000..07e97ac8e83bcc529f2b3fdcddf91a4137cec089 --- /dev/null +++ b/src/ui/XbeeConfigurationWindow.cpp @@ -0,0 +1,384 @@ +#include + +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#endif + +#if defined (__APPLE__) && defined (__MACH__) +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __MWERKS__ +#define __CF_USE_FRAMEWORK_INCLUDES__ +#endif + + +#include + +#include +#include +#if defined(MAC_OS_X_VERSION_10_3) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_3) +#include +#endif +#include + +// Apple internal modems default to local echo being on. If your modem has local echo disabled, +// undefine the following macro. +#define LOCAL_ECHO + +#define kATCommandString "AT\r" + +#ifdef LOCAL_ECHO +#define kOKResponseString "AT\r\r\nOK\r\n" +#else +#define kOKResponseString "\r\nOK\r\n" +#endif +#endif + + +// Some helper functions for serial port enumeration +#if defined (__APPLE__) && defined (__MACH__) + +enum { + kNumRetries = 3 +}; + +// Function prototypes +static kern_return_t FindModems(io_iterator_t *matchingServices); +static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize); + +// Returns an iterator across all known modems. Caller is responsible for +// releasing the iterator when iteration is complete. +static kern_return_t FindModems(io_iterator_t *matchingServices) +{ + kern_return_t kernResult; + CFMutableDictionaryRef classesToMatch; + + /*! @function IOServiceMatching + @abstract Create a matching dictionary that specifies an IOService class match. + @discussion A very common matching criteria for IOService is based on its class. IOServiceMatching will create a matching dictionary that specifies any IOService of a class, or its subclasses. The class is specified by C-string name. + @param name The class name, as a const C-string. Class matching is successful on IOService's of this class or any subclass. + @result The matching dictionary created, is returned on success, or zero on failure. The dictionary is commonly passed to IOServiceGetMatchingServices or IOServiceAddNotification which will consume a reference, otherwise it should be released with CFRelease by the caller. */ + + // Serial devices are instances of class IOSerialBSDClient + classesToMatch = IOServiceMatching(kIOSerialBSDServiceValue); + if (classesToMatch == NULL) { + printf("IOServiceMatching returned a NULL dictionary.\n"); + } else { + /*! + @function CFDictionarySetValue + Sets the value of the key in the dictionary. + @param theDict The dictionary to which the value is to be set. If this + parameter is not a valid mutable CFDictionary, the behavior is + undefined. If the dictionary is a fixed-capacity dictionary and + it is full before this operation, and the key does not exist in + the dictionary, the behavior is undefined. + @param key The key of the value to set into the dictionary. If a key + which matches this key is already present in the dictionary, only + the value is changed ("add if absent, replace if present"). If + no key matches the given key, the key-value pair is added to the + dictionary. If added, the key is retained by the dictionary, + using the retain callback provided + when the dictionary was created. If the key is not of the sort + expected by the key retain callback, the behavior is undefined. + @param value The value to add to or replace into the dictionary. The value + is retained by the dictionary using the retain callback provided + when the dictionary was created, and the previous value if any is + released. If the value is not of the sort expected by the + retain or release callbacks, the behavior is undefined. + */ + CFDictionarySetValue(classesToMatch, + CFSTR(kIOSerialBSDTypeKey), + CFSTR(kIOSerialBSDModemType)); + + // Each serial device object has a property with key + // kIOSerialBSDTypeKey and a value that is one of kIOSerialBSDAllTypes, + // kIOSerialBSDModemType, or kIOSerialBSDRS232Type. You can experiment with the + // matching by changing the last parameter in the above call to CFDictionarySetValue. + + // As shipped, this sample is only interested in modems, + // so add this property to the CFDictionary we're matching on. + // This will find devices that advertise themselves as modems, + // such as built-in and USB modems. However, this match won't find serial modems. + } + + /*! @function IOServiceGetMatchingServices + @abstract Look up registered IOService objects that match a matching dictionary. + @discussion This is the preferred method of finding IOService objects currently registered by IOKit. IOServiceAddNotification can also supply this information and install a notification of new IOServices. The matching information used in the matching dictionary may vary depending on the class of service being looked up. + @param masterPort The master port obtained from IOMasterPort(). + @param matching A CF dictionary containing matching information, of which one reference is consumed by this function. IOKitLib can contruct matching dictionaries for common criteria with helper functions such as IOServiceMatching, IOOpenFirmwarePathMatching. + @param existing An iterator handle is returned on success, and should be released by the caller when the iteration is finished. + @result A kern_return_t error code. */ + + kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, classesToMatch, matchingServices); + if (KERN_SUCCESS != kernResult) { + printf("IOServiceGetMatchingServices returned %d\n", kernResult); + goto exit; + } + +exit: + return kernResult; +} + +/** Given an iterator across a set of modems, return the BSD path to the first one. + * If no modems are found the path name is set to an empty string. + */ +static kern_return_t GetModemPath(io_iterator_t serialPortIterator, char *bsdPath, CFIndex maxPathSize) +{ + io_object_t modemService; + kern_return_t kernResult = KERN_FAILURE; + Boolean modemFound = false; + + // Initialize the returned path + *bsdPath = '\0'; + + // Iterate across all modems found. In this example, we bail after finding the first modem. + + while ((modemService = IOIteratorNext(serialPortIterator)) && !modemFound) { + CFTypeRef bsdPathAsCFString; + + // Get the callout device's path (/dev/cu.xxxxx). The callout device should almost always be + // used: the dialin device (/dev/tty.xxxxx) would be used when monitoring a serial port for + // incoming calls, e.g. a fax listener. + + bsdPathAsCFString = IORegistryEntryCreateCFProperty(modemService, + CFSTR(kIOCalloutDeviceKey), + kCFAllocatorDefault, + 0); + if (bsdPathAsCFString) { + Boolean result; + + // Convert the path from a CFString to a C (NUL-terminated) string for use + // with the POSIX open() call. + + result = CFStringGetCString((CFStringRef)bsdPathAsCFString, + bsdPath, + maxPathSize, + kCFStringEncodingUTF8); + CFRelease(bsdPathAsCFString); + + if (result) { + //printf("Modem found with BSD path: %s", bsdPath); + modemFound = true; + kernResult = KERN_SUCCESS; + } + } + + printf("\n"); + + // Release the io_service_t now that we are done with it. + + (void) IOObjectRelease(modemService); + } + + return kernResult; +} +#endif + +XbeeConfigurationWindow::XbeeConfigurationWindow(LinkInterface* link, QWidget *parent, Qt::WindowFlags flags): QWidget(parent, flags), + userConfigured(false) +{ + XbeeLinkInterface *xbeeLink = dynamic_cast(link); + + if(xbeeLink != 0) + { + this->link = xbeeLink; + + action = new QAction(QIcon(":/images/devices/network-wireless.svg"), "", link); + + baudLabel = new QLabel; + baudLabel->setText(tr("Baut Rate")); + baudBox = new QComboBox; + baudBox->addItem("1200",1200); + baudBox->addItem("2400",2400); + baudBox->addItem("4800",4800); + baudBox->addItem("9600",9600); + baudBox->addItem("19200",19200); + baudBox->addItem("38400",38400); + baudBox->addItem("57600",57600); + baudBox->setCurrentIndex(1); + baudLabel->setBuddy(baudBox); + portLabel = new QLabel; + portLabel->setText(tr("SerialPort")); + portBox = new QComboBox; + this->setupPortList(); + portBox->setEditable(true); + portLabel->setBuddy(portBox); + actionLayout = new QGridLayout; + actionLayout->addWidget(baudLabel,1,1); + actionLayout->addWidget(baudBox,1,2); + actionLayout->addWidget(portLabel,2,1); + actionLayout->addWidget(portBox,2,2); + tmpLayout = new QVBoxLayout; + tmpLayout->addStretch(); + tmpLayout->addLayout(actionLayout); + xbeeLayout = new QHBoxLayout; + xbeeLayout->addStretch(); + xbeeLayout->addLayout(tmpLayout); + this->setLayout(xbeeLayout); + + //connect(portBox,SIGNAL(activated(QString)),this,SLOT(setPortName(QString))); + //connect(baudBox,SIGNAL(activated(QString)),this,SLOT(setBaudRateString(QString))); + connect(portBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(setPortName(QString))); + connect(portBox,SIGNAL(editTextChanged(QString)),this,SLOT(setPortName(QString))); + connect(baudBox,SIGNAL(currentIndexChanged(QString)),this,SLOT(setBaudRateString(QString))); + + portCheckTimer = new QTimer(this); + portCheckTimer->setInterval(1000); + connect(portCheckTimer, SIGNAL(timeout()), this, SLOT(setupPortList())); + + // Display the widget + this->window()->setWindowTitle(tr("Xbee Communication Settings")); + } + else + { + qDebug() << "This is not a Xbee Link"; + } +} + +XbeeConfigurationWindow::~XbeeConfigurationWindow() +{ + +} + +void XbeeConfigurationWindow::setupPortList() +{ + #ifdef __linux + + // TODO Linux has no standard way of enumerating serial ports + // However the device files are only present when the physical + // device is connected, therefore listing the files should be + // sufficient. + + QString devdir = "/dev"; + QDir dir(devdir); + dir.setFilter(QDir::System); + + QFileInfoList list = dir.entryInfoList(); + for (int i = 0; i < list.size(); ++i) { + QFileInfo fileInfo = list.at(i); + if (fileInfo.fileName().contains(QString("ttyUSB")) || fileInfo.fileName().contains(QString("ttyS"))) { + if (portBox->findText(fileInfo.canonicalFilePath()) == -1) { + portBox->addItem(fileInfo.canonicalFilePath()); + if (!userConfigured) portBox->setEditText(fileInfo.canonicalFilePath()); + } + } + } +#endif + +#if defined (__APPLE__) && defined (__MACH__) + + // Enumerate serial ports + //int fileDescriptor; + kern_return_t kernResult; // on PowerPC this is an int (4 bytes) + + io_iterator_t serialPortIterator; + char bsdPath[MAXPATHLEN]; + + kernResult = FindModems(&serialPortIterator); + + kernResult = GetModemPath(serialPortIterator, bsdPath, sizeof(bsdPath)); + + IOObjectRelease(serialPortIterator); // Release the iterator. + + // Add found modems + if (bsdPath[0]) { + if (portBox->findText(QString(bsdPath)) == -1) { + portBox->addItem(QString(bsdPath)); + if (!userConfigured) portBox->setEditText(QString(bsdPath)); + } + } + + // Add USB serial port adapters + // TODO Strangely usb serial port adapters are not enumerated, even when connected + QString devdir = "/dev"; + QDir dir(devdir); + dir.setFilter(QDir::System); + + QFileInfoList list = dir.entryInfoList(); + for (int i = list.size() - 1; i >= 0; i--) { + QFileInfo fileInfo = list.at(i); + if (fileInfo.fileName().contains(QString("ttyUSB")) || fileInfo.fileName().contains(QString("ttyS")) || fileInfo.fileName().contains(QString("tty.usbserial"))) { + if (portBox->findText(fileInfo.canonicalFilePath()) == -1) { + portBox->addItem(fileInfo.canonicalFilePath()); + if (!userConfigured) portBox->setEditText(fileInfo.canonicalFilePath()); + } + } + } + + +#endif + +#ifdef _WIN32 + // Get the ports available on this system + QList ports = QextSerialEnumerator::getPorts(); + + // Add the ports in reverse order, because we prepend them to the list + for (int i = ports.size() - 1; i >= 0; i--) { + QString portString = QString(ports.at(i).portName.toLocal8Bit().constData()) + " - " + QString(ports.at(i).friendName.toLocal8Bit().constData()).split("(").first(); + // Prepend newly found port to the list + if (portBox->findText(portString) == -1) { + portBox->insertItem(0, portString); + if (!userConfigured) portBox->setEditText(portString); + } + } + + //printf("port name: %s\n", ports.at(i).portName.toLocal8Bit().constData()); + //printf("friendly name: %s\n", ports.at(i).friendName.toLocal8Bit().constData()); + //printf("physical name: %s\n", ports.at(i).physName.toLocal8Bit().constData()); + //printf("enumerator name: %s\n", ports.at(i).enumName.toLocal8Bit().constData()); + //printf("===================================\n\n"); +#endif +} + +void XbeeConfigurationWindow::showEvent(QShowEvent* event) +{ + Q_UNUSED(event); + portCheckTimer->start(); +} + +void XbeeConfigurationWindow::hideEvent(QHideEvent* event) +{ + Q_UNUSED(event); + portCheckTimer->stop(); +} + +QAction* XbeeConfigurationWindow::getAction() +{ + return action; +} + +void XbeeConfigurationWindow::configureCommunication() +{ + this->setupPortList(); + this->show(); +} + +void XbeeConfigurationWindow::setPortName(QString port) +{ + link->setPortName(port); +} + +void XbeeConfigurationWindow::setBaudRateString(QString baud) +{ + int rate = baud.toInt(); + this->link->setBaudRate(rate); +} \ No newline at end of file diff --git a/src/ui/XbeeConfigurationWindow.h b/src/ui/XbeeConfigurationWindow.h new file mode 100644 index 0000000000000000000000000000000000000000..8c9ef5d923377d9bbc5d927832524605f6d8057b --- /dev/null +++ b/src/ui/XbeeConfigurationWindow.h @@ -0,0 +1,52 @@ +#ifndef _XBEECONFIGURATIONWINDOW_H_ +#define _XBEECONFIGURATIONWINDOW_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include"XbeeLinkInterface.h" + + +class XbeeConfigurationWindow : public QWidget +{ + Q_OBJECT + +public: + XbeeConfigurationWindow(LinkInterface* link, QWidget *parent = 0, Qt::WindowFlags flags = Qt::Sheet); + ~XbeeConfigurationWindow(); + + QAction* getAction(); + +public slots: + void configureCommunication(); + void setPortName(QString port); + void setBaudRateString(QString baud); + void setupPortList(); + +protected: + void showEvent(QShowEvent* event); + void hideEvent(QHideEvent* event); + bool userConfigured; ///< Switch to detect if current values are user-selected and shouldn't be overriden + +private: + QLabel *portLabel; + QLabel *baudLabel; + QComboBox *portBox; + QComboBox *baudBox; + QGridLayout *actionLayout; + QHBoxLayout *xbeeLayout; + QVBoxLayout *tmpLayout; + XbeeLinkInterface* link; + QAction* action; + QTimer* portCheckTimer; +}; + + +#endif //_XBEECONFIGURATIONWINDOW_H_ \ No newline at end of file