/**************************************************************************** * * (c) 2009-2016 QGROUNDCONTROL PROJECT * * QGroundControl is licensed according to the terms in the file * COPYING.md in the root of the source code directory. * ****************************************************************************/ #include "QGCSerialPortInfo.h" #include "JsonHelper.h" #include #include #include #include QGC_LOGGING_CATEGORY(QGCSerialPortInfoLog, "QGCSerialPortInfoLog") bool QGCSerialPortInfo::_jsonLoaded = false; const char* QGCSerialPortInfo::_jsonFileTypeValue = "USBBoardInfo"; const char* QGCSerialPortInfo::_jsonBoardInfoKey = "boardInfo"; const char* QGCSerialPortInfo::_jsonBoardFallbackKey = "boardFallback"; const char* QGCSerialPortInfo::_jsonVendorIDKey = "vendorID"; const char* QGCSerialPortInfo::_jsonProductIDKey = "productID"; const char* QGCSerialPortInfo::_jsonBoardClassKey = "boardClass"; const char* QGCSerialPortInfo::_jsonNameKey = "name"; const char* QGCSerialPortInfo::_jsonRegExpKey = "regExp"; const char* QGCSerialPortInfo::_jsonAndroidOnlyKey = "androidOnly"; const QGCSerialPortInfo::BoardClassString2BoardType_t QGCSerialPortInfo::_rgBoardClass2BoardType[] = { { "Pixhawk", QGCSerialPortInfo::BoardTypePixhawk }, { "PX4 Flow", QGCSerialPortInfo::BoardTypePX4Flow }, { "RTK GPS", QGCSerialPortInfo::BoardTypeRTKGPS }, { "SiK Radio", QGCSerialPortInfo::BoardTypeSiKRadio }, { "OpenPilot", QGCSerialPortInfo::BoardTypeOpenPilot }, }; QList QGCSerialPortInfo::_boardInfoList; QList QGCSerialPortInfo::_boardFallbackList; QGCSerialPortInfo::QGCSerialPortInfo(void) : QSerialPortInfo() { } QGCSerialPortInfo::QGCSerialPortInfo(const QSerialPort & port) : QSerialPortInfo(port) { } void QGCSerialPortInfo::_loadJsonData(void) { if (_jsonLoaded) { return; } _jsonLoaded = true; QFile file(QStringLiteral(":/json/USBBoardInfo.json")); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qWarning() << "Unable to open board info json:" << file.errorString(); return; } QByteArray bytes = file.readAll(); QJsonParseError jsonParseError; QJsonDocument jsonDoc(QJsonDocument::fromJson(bytes, &jsonParseError)); if (jsonParseError.error != QJsonParseError::NoError) { qWarning() << "Unable to parse board info json:" << jsonParseError.errorString(); return; } QJsonObject json = jsonDoc.object(); int fileVersion; QString errorString; if (!JsonHelper::validateQGCJsonFile(json, _jsonFileTypeValue, // expected file type 1, // minimum supported version 1, // maximum supported version fileVersion, errorString)) { qWarning() << errorString; return; } // Validate root object keys QList rootKeyInfoList = { { _jsonBoardInfoKey, QJsonValue::Array, true }, { _jsonBoardFallbackKey, QJsonValue::Array, true }, }; if (!JsonHelper::validateKeys(json, rootKeyInfoList, errorString)) { qWarning() << errorString; return; } // Load board info used to detect known board from vendor/product id QList boardKeyInfoList = { { _jsonVendorIDKey, QJsonValue::Double, true }, { _jsonProductIDKey, QJsonValue::Double, true }, { _jsonBoardClassKey, QJsonValue::String, true }, { _jsonNameKey, QJsonValue::String, true }, }; QJsonArray rgBoardInfo = json[_jsonBoardInfoKey].toArray(); for (int i=0; i fallbackKeyInfoList = { { _jsonRegExpKey, QJsonValue::String, true }, { _jsonBoardClassKey, QJsonValue::String, true }, { _jsonAndroidOnlyKey, QJsonValue::Bool, false }, }; QJsonArray rgBoardFallback = json[_jsonBoardFallbackKey].toArray(); for (int i=0; i QGCSerialPortInfo::availablePorts(void) { QList list; for(QSerialPortInfo portInfo: QSerialPortInfo::availablePorts()) { if (!isSystemPort(&portInfo)) { list << *((QGCSerialPortInfo*)&portInfo); } } return list; } bool QGCSerialPortInfo::isBootloader(void) const { BoardType_t boardType; QString name; if (getBoardInfo(boardType, name)) { // FIXME: Check SerialLink bootloade detect code which is different return boardType == BoardTypePixhawk && description().contains("BL"); } else { return false; } } bool QGCSerialPortInfo::isSystemPort(QSerialPortInfo* port) { // Known operating system peripherals that are NEVER a peripheral // that we should connect to. // XXX Add Linux (LTE modems, etc) and Windows as needed // MAC OS if (port->systemLocation().contains("tty.MALS") || port->systemLocation().contains("tty.SOC") || port->systemLocation().contains("tty.Bluetooth-Incoming-Port") // We open these by their cu.usbserial and cu.usbmodem handles // already. We don't want to open them twice and conflict // with ourselves. || port->systemLocation().contains("tty.usbserial") || port->systemLocation().contains("tty.usbmodem")) { return true; } return false; } bool QGCSerialPortInfo::canFlash(void) { BoardType_t boardType; QString name; if (getBoardInfo(boardType, name)) { switch(boardType){ case QGCSerialPortInfo::BoardTypePixhawk: case QGCSerialPortInfo::BoardTypePX4Flow: case QGCSerialPortInfo::BoardTypeSiKRadio: return true; default: return false; } } else { return false; } }