diff --git a/.gitignore b/.gitignore index 03e3788fe9716cf58b6b9bc0846c18524b10e33c..a294f37fbb6c921c73026f59b96db667fc64190a 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,7 @@ user_config.pri *.cproject *.sln *.suo + +thirdParty/qserialport-build-desktop/ +thirdParty/qserialport/bin/ +thirdParty/qserialport/lib/ diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 8d36b6cade1f0998893b995ceba066fff00c2ef0..a59c37b8bb21bf2a355bd345c7ee64c56436c60c 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -58,36 +58,47 @@ exists(user_config.pri) { } INCLUDEPATH += $$BASEDIR/../mavlink/include/common +INCLUDEPATH += $$BASEDIR/../mavlink/include +INCLUDEPATH += $$BASEDIR/thirdParty/mavlink/include/common +INCLUDEPATH += $$BASEDIR/thirdParty/mavlink/include contains(MAVLINK_CONF, pixhawk) { # Remove the default set - it is included anyway INCLUDEPATH -= $$BASEDIR/../mavlink/include/common + INCLUDEPATH -= $$BASEDIR/thirdParty/mavlink/include/common # PIXHAWK SPECIAL MESSAGES INCLUDEPATH += $$BASEDIR/../mavlink/include/pixhawk + INCLUDEPATH += $$BASEDIR/thirdParty/mavlink/include/pixhawk DEFINES += QGC_USE_PIXHAWK_MESSAGES } contains(MAVLINK_CONF, slugs) { # Remove the default set - it is included anyway INCLUDEPATH -= $$BASEDIR/../mavlink/include/common + INCLUDEPATH -= $$BASEDIR/thirdParty/mavlink/include/common # SLUGS SPECIAL MESSAGES INCLUDEPATH += $$BASEDIR/../mavlink/include/slugs + INCLUDEPATH += $$BASEDIR/thirdParty/mavlink/include/slugs DEFINES += QGC_USE_SLUGS_MESSAGES } contains(MAVLINK_CONF, ualberta) { # Remove the default set - it is included anyway INCLUDEPATH -= $$BASEDIR/../mavlink/include/common + INCLUDEPATH -= $$BASEDIR/thirdParty/mavlink/include/common # UALBERTA SPECIAL MESSAGES INCLUDEPATH += $$BASEDIR/../mavlink/include/ualberta + INCLUDEPATH += $$BASEDIR/thirdParty/mavlink/include/ualberta DEFINES += QGC_USE_UALBERTA_MESSAGES } contains(MAVLINK_CONF, ardupilotmega) { # Remove the default set - it is included anyway INCLUDEPATH -= $$BASEDIR/../mavlink/include/common + INCLUDEPATH -= $$BASEDIR/thirdParty/mavlink/include/common # UALBERTA SPECIAL MESSAGES INCLUDEPATH += $$BASEDIR/../mavlink/include/ardupilotmega + INCLUDEPATH += $$BASEDIR/thirdParty/mavlink/include/ardupilotmega DEFINES += QGC_USE_ARDUPILOTMEGA_MESSAGES } @@ -97,13 +108,6 @@ contains(MAVLINK_CONF, ardupilotmega) { # done by the plugins above include(qgroundcontrol.pri) -# QWT plot and QExtSerial depend on paths set by qgroundcontrol.pri -# Include serial port library -include(src/lib/qextserialport/qextserialport.pri) - -# include qserial library -include(thirdParty/qserial/qserialport.prf) - # Include QWT plotting library include(src/lib/qwt/qwt.pri) DEPENDPATH += . \ @@ -111,11 +115,22 @@ DEPENDPATH += . \ lib/QMapControl/src \ lib/opmapcontrol \ lib/opmapcontrol/src \ - plugins + plugins \ + thirdParty/qserialport/include \ + thirdParty/qserialport/include/QtSerialPort \ + thirdParty/qserialport INCLUDEPATH += . \ lib/QMapControl \ lib/opmapcontrol \ - $$BASEDIR/../mavlink/include + thirdParty/qserialport/include \ + thirdParty/qserialport/include/QtSerialPort \ + thirdParty/qserialport/src + +# Include serial port library +include(src/lib/qextserialport/qextserialport.pri) +# include qserial library +include(thirdParty/qserialport/qgroundcontrol-qserialport.pri) + # ../mavlink/include \ # MAVLink/include \ diff --git a/src/comm/MAVLinkProtocol.cc b/src/comm/MAVLinkProtocol.cc index 0c43dbd6e07039c4f96c598fc85b42f50f3c8600..69ee72af4d437d2e56a7eee212d545e22eb9ac3b 100644 --- a/src/comm/MAVLinkProtocol.cc +++ b/src/comm/MAVLinkProtocol.cc @@ -182,6 +182,14 @@ void MAVLinkProtocol::receiveBytes(LinkInterface* link, QByteArray b) unsigned int decodeState = mavlink_parse_char(link->getId(), (uint8_t)(b.at(position)), &message, &status); if (decodeState == 1) { +#ifdef MAVLINK_MESSAGE_LENGTHS + const uint8_t message_lengths[] = MAVLINK_MESSAGE_LENGTHS; + if (message.msgid >= sizeof(message_lengths) || + message.len != message_lengths[message.msgid]) { + qDebug() << "MAVLink message " << message.msgid << " length incorrect (was " << message.len << " expected " << message_lengths[message.msgid] << ")"; + continue; + } +#endif // Log data if (m_loggingEnabled && m_logfile) { const int len = MAVLINK_MAX_PACKET_LEN+sizeof(quint64); diff --git a/src/comm/MAVLinkXMLParser.cc b/src/comm/MAVLinkXMLParser.cc index 5aeb84338118faec5d3ec7a15bd32d093689d9c1..2ef5ab873b14beba809038a7ae17b66d8202b5a1 100644 --- a/src/comm/MAVLinkXMLParser.cc +++ b/src/comm/MAVLinkXMLParser.cc @@ -90,6 +90,16 @@ bool MAVLinkXMLParser::generate() int mavlinkVersion = 0; + // we need to gather the message lengths across multiple includes, + // which we can do via detecting recursion + static unsigned message_lengths[256]; + static int highest_message_id; + static int recursion_level; + + if (recursion_level == 0) { + highest_message_id = 0; + memset(message_lengths, 0, sizeof(message_lengths)); + } // Start main header @@ -138,7 +148,9 @@ bool MAVLinkXMLParser::generate() MAVLinkXMLParser includeParser(incFilePath, topLevelOutputDirName, this); connect(&includeParser, SIGNAL(parseState(QString)), this, SIGNAL(parseState(QString))); // Generate and write + recursion_level++; includeParser.generate(); + recursion_level--; mainHeader += "\n#include \"../" + pureIncludeFileName + "/" + pureIncludeFileName + ".h\"\n"; @@ -340,7 +352,7 @@ bool MAVLinkXMLParser::generate() QString decodeLines; QString sendArguments; QString commentLines; - + unsigned message_length = 0; // Get the message fields @@ -437,6 +449,40 @@ bool MAVLinkXMLParser::generate() } + // message length calculation + unsigned element_multiplier = 1; + unsigned element_length = 0; + const struct { + const char *prefix; + unsigned length; + } length_map[] = { + { "array", 1 }, + { "char", 1 }, + { "uint8", 1 }, + { "int8", 1 }, + { "uint16", 2 }, + { "int16", 2 }, + { "uint32", 4 }, + { "int32", 4 }, + { "uint64", 8 }, + { "int64", 8 }, + { "float", 4 }, + { "double", 8 }, + }; + if (fieldType.contains("[")) { + element_multiplier = fieldType.split("[").at(1).split("]").first().toInt(); + } + for (unsigned i=0; iERROR: Unable to calculate length for %2 near line %1\nAbort.").arg(QString::number(e.lineNumber()), fieldType)); + } + message_length += element_length; + // // QString unpackingCode; @@ -489,6 +535,11 @@ bool MAVLinkXMLParser::generate() f = f.nextSibling(); } + if (messageId > highest_message_id) { + highest_message_id = messageId; + } + message_lengths[messageId] = message_length; + cStruct = cStruct.arg(cStructName, cStructLines); lcmStructDefs.append("\n").append(cStruct).append("\n"); pack = pack.arg(messageName, packParameters, messageName.toUpper(), packLines); @@ -540,6 +591,15 @@ bool MAVLinkXMLParser::generate() mainHeader += includeLine.arg(messagesDirName + "/" + cFiles.at(i).first); } + mainHeader += "\n\n// MESSAGE LENGTHS\n\n"; + mainHeader += "#undef MAVLINK_MESSAGE_LENGTHS\n"; + mainHeader += "#define MAVLINK_MESSAGE_LENGTHS { "; + for (int i=0; isetTimeout(timeout); - }; + } virtual void setFlow(SerialInterface::flowType flow) { // TODO implement - }; + _port->setFlowControl((FlowType)flow); + } }; using namespace TNX; @@ -262,11 +269,11 @@ public: virtual void setTimeout(qint64 timeout) { // TODO implement //_port->setTimeout(timeout); - }; + } virtual void setFlow(SerialInterface::flowType flow) { // TODO map settings.setFlowControl(QPortSettings::FLOW_OFF); - }; + } }; #endif // SERIALINTERFACE_H diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index d6176543103cc8c33f20055048f8018c22f09100..9efe0f309b19ac0ff66fe809053dc993f7885d95 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -48,32 +48,14 @@ SerialLink::SerialLink(QString portname, SerialInterface::baudRateType baudrate, this->timeout = 1; ///< The timeout controls how long the program flow should wait for new serial bytes. As we're polling, we don't want to wait at all. // Set the port name - if (porthandle == "") { - // name = tr("serial link ") + QString::number(getId()) + tr(" (unconfigured)"); + if (porthandle == "") + { name = tr("Serial Link ") + QString::number(getId()); - } else { - name = portname.trimmed(); } - -#ifdef _WIN3232 - // Windows 32bit & 64bit serial connection - winPort = CreateFile(porthandle, - GENERIC_READ | GENERIC_WRITE, - 0, - 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - 0); - if(winPort==INVALID_HANDLE_VALUE) { - if(GetLastError()==ERROR_FILE_NOT_FOUND) { - //serial port does not exist. Inform user. - } - //some other error occurred. Inform user. + else + { + name = portname.trimmed(); } -#else - -#endif - loadSettings(); } diff --git a/src/comm/UDPLink.cc b/src/comm/UDPLink.cc index a091beb480b52fbc34d96ba10d070108de0b78c7..5ffea46f0cdeee5a322a73e2cc3726ce617f9ef9 100644 --- a/src/comm/UDPLink.cc +++ b/src/comm/UDPLink.cc @@ -85,29 +85,32 @@ void UDPLink::setPort(int port) */ void UDPLink::addHost(const QString& host) { - qDebug() << "UDP:" << "ADDING HOST:" << host; - if (host.contains(":")) { - qDebug() << "HOST: " << host.split(":").first(); - QHostInfo info = QHostInfo::fromName(host.split(":").first()); - // Add host - QList hostAddresses = info.addresses(); - QHostAddress address; - for (int i = 0; i < hostAddresses.size(); i++) { - // Exclude loopback IPv4 and all IPv6 addresses - if (!hostAddresses.at(i).toString().contains(":")) { - address = hostAddresses.at(i); + if (host != "") + { + qDebug() << "UDP:" << "ADDING HOST:" << host; + if (host.contains(":")) { + qDebug() << "HOST: " << host.split(":").first(); + QHostInfo info = QHostInfo::fromName(host.split(":").first()); + // Add host + QList hostAddresses = info.addresses(); + QHostAddress address; + for (int i = 0; i < hostAddresses.size(); i++) { + // Exclude loopback IPv4 and all IPv6 addresses + if (!hostAddresses.at(i).toString().contains(":")) { + address = hostAddresses.at(i); + } } + hosts.append(address); + qDebug() << "Address:" << address.toString(); + // Set port according to user input + ports.append(host.split(":").last().toInt()); + } else { + QHostInfo info = QHostInfo::fromName(host); + // Add host + hosts.append(info.addresses().first()); + // Set port according to default (this port) + ports.append(port); } - hosts.append(address); - qDebug() << "Address:" << address.toString(); - // Set port according to user input - ports.append(host.split(":").last().toInt()); - } else { - QHostInfo info = QHostInfo::fromName(host); - // Add host - hosts.append(info.addresses().first()); - // Set port according to default (this port) - ports.append(port); } } @@ -137,20 +140,21 @@ void UDPLink::removeHost(const QString& hostname) void UDPLink::writeBytes(const char* data, qint64 size) { // Broadcast to all connected systems - //QList::iterator h; - // for (h = hosts->begin(); h != hosts->end(); ++h) - - - for (int h = 0; h < hosts.size(); h++) { + for (int h = 0; h < hosts.size(); h++) + { QHostAddress currentHost = hosts.at(h); quint16 currentPort = ports.at(h); - - qDebug() << "WRITING TO" << currentHost.toIPv4Address() << currentPort; + QString bytes; + QString ascii; + //qDebug() << "WRITING DATA TO" << currentHost.toString() << currentPort; for (int i=0; iwriteDatagram(data, size, currentHost, currentPort); } diff --git a/thirdParty/qserialport/qgroundcontrol-qserialport.pri b/thirdParty/qserialport/qgroundcontrol-qserialport.pri new file mode 100644 index 0000000000000000000000000000000000000000..122d0b1864b80e6d8f66d1b105341d63fa93d817 --- /dev/null +++ b/thirdParty/qserialport/qgroundcontrol-qserialport.pri @@ -0,0 +1,47 @@ +###################################################################### +# Automatically generated by qmake (2.01a) Sa. Apr 2 10:42:30 2011 +###################################################################### + +DEPENDPATH += . \ + include/QtSerialPort \ + src/common \ + src/posix \ + src/win32 +INCLUDEPATH += include \ + include/QtSerialPort \ + src/posix \ + src/win32 + +# Input +HEADERS += include/QtSerialPort/qportsettings.h \ + include/QtSerialPort/qserialport.h \ + include/QtSerialPort/qserialport_export.h \ + include/QtSerialPort/qserialportnative.h + +macx|linux-g++|linux-g++-64 { +HEADERS += src/posix/termioshelper.h +} + +win32-msvc2008|win32-g++ { +HEADERS += src/win32/commdcbhelper.h \ + src/win32/qwincommevtnotifier.h \ + src/win32/wincommevtbreaker.h \ + src/win32/commdcbhelper.h \ + src/win32/qwincommevtnotifier.h \ + src/win32/wincommevtbreaker.h +} + +SOURCES += src/common/qportsettings.cpp \ + src/common/qserialport.cpp + +macx|linux-g++|linux-g++-64 { +SOURCES += src/posix/qserialportnative_posix.cpp \ + src/posix/termioshelper.cpp +} + +win32-msvc2008|win32-g++ { +SOURCES += src/win32/commdcbhelper.cpp \ + src/win32/qserialportnative_win32.cpp \ + src/win32/qwincommevtnotifier.cpp \ + src/win32/wincommevtbreaker.cpp +}