From b7bb37048bc1938edbdf465289b329a096cdf2e1 Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Sun, 21 Oct 2018 11:50:24 -0400 Subject: [PATCH] Enabled ability to use any QT SerialBus driver in SavvyCAN. Now PeakCAN, ValueCAN, SocketCAN, and J2534 should all work. --- connections/canconconst.h | 2 +- connections/canconfactory.cpp | 6 +- connections/canconfactory.h | 2 +- connections/canconnection.cpp | 6 ++ connections/canconnection.h | 12 +++- connections/canconnectionmodel.cpp | 4 +- connections/connectionwindow.cpp | 106 ++++++++++++++++++---------- connections/connectionwindow.h | 10 ++- connections/gvretserial.cpp | 2 +- connections/serialbusconnection.cpp | 8 +-- connections/serialbusconnection.h | 2 +- ui/connectionwindow.ui | 26 +++---- 12 files changed, 118 insertions(+), 68 deletions(-) diff --git a/connections/canconconst.h b/connections/canconconst.h index fa117b3..f70ebd9 100644 --- a/connections/canconconst.h +++ b/connections/canconconst.h @@ -16,7 +16,7 @@ namespace CANCon { { GVRET_SERIAL, KVASER, - SOCKETCAN, + SERIALBUS, REMOTE, NONE }; diff --git a/connections/canconfactory.cpp b/connections/canconfactory.cpp index 55e1727..d40dd98 100644 --- a/connections/canconfactory.cpp +++ b/connections/canconfactory.cpp @@ -5,11 +5,11 @@ using namespace CANCon; -CANConnection* CanConFactory::create(type pType, QString pPortName) +CANConnection* CanConFactory::create(type pType, QString pPortName, QString pDriverName) { switch(pType) { - case SOCKETCAN: - return new SerialBusConnection(pPortName); + case SERIALBUS: + return new SerialBusConnection(pPortName, pDriverName); case GVRET_SERIAL: return new GVRetSerial(pPortName, false); case REMOTE: diff --git a/connections/canconfactory.h b/connections/canconfactory.h index 2b482f5..668568e 100644 --- a/connections/canconfactory.h +++ b/connections/canconfactory.h @@ -7,7 +7,7 @@ class CanConFactory { public: - static CANConnection* create(CANCon::type, QString pPortName); + static CANConnection* create(CANCon::type, QString pPortName, QString pDriverName); }; #endif // CANCONFACTORY_H diff --git a/connections/canconnection.cpp b/connections/canconnection.cpp index 8617ac9..ec99099 100644 --- a/connections/canconnection.cpp +++ b/connections/canconnection.cpp @@ -3,6 +3,7 @@ #include "canconnection.h" CANConnection::CANConnection(QString pPort, + QString pDriver, CANCon::type pType, int pNumBuses, int pQueueLen, @@ -10,6 +11,7 @@ CANConnection::CANConnection(QString pPort, mQueue(), mNumBuses(pNumBuses), mPort(pPort), + mDriver(pDriver), mType(pType), mIsCapSuspended(false), mStatus(CANCon::NOT_CONNECTED), @@ -227,6 +229,10 @@ QString CANConnection::getPort() { return mPort; } +QString CANConnection::getDriver() +{ + return mDriver; +} LFQueue& CANConnection::getQueue() { return mQueue; diff --git a/connections/canconnection.h b/connections/canconnection.h index 0966ea2..a450134 100644 --- a/connections/canconnection.h +++ b/connections/canconnection.h @@ -19,13 +19,15 @@ protected: /** * @brief CANConnection constructor * @param pPort: string containing port name + * @param pDriver: string containing driver name - Really only used for SerialBus connections * @param pType: the type of connection @ref CANCon::type * @param pNumBuses: the number of buses the device has * @param pQueueLen: the length of the lock free queue to use * @param pUseThread: if set to true, object will be execute in a dedicated thread */ CANConnection(QString pPort, - CANCon::type pType, + QString pDriver, + CANCon::type pType, int pNumBuses, int pQueueLen, bool pUseThread); @@ -50,6 +52,13 @@ public: */ QString getPort(); + /** + * @brief getDriver + * @return returns the name of the driver used for this device + */ + QString getDriver(); + + /** * @brief getQueue * @return the lock free queue of the device @@ -294,6 +303,7 @@ protected: private: LFQueue mQueue; const QString mPort; + const QString mDriver; const CANCon::type mType; bool mIsCapSuspended; QAtomicInt mStatus; diff --git a/connections/canconnectionmodel.cpp b/connections/canconnectionmodel.cpp index 719ca38..ef4b5f8 100644 --- a/connections/canconnectionmodel.cpp +++ b/connections/canconnectionmodel.cpp @@ -152,7 +152,7 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const bool ret; if (!conn_p) return QVariant(); ret = conn_p->getBusSettings(busId, bus); - bool isSocketCAN = (conn_p->getType() == CANCon::SOCKETCAN) ? true: false; + bool isSocketCAN = (conn_p->getType() == CANCon::SERIALBUS) ? true: false; //qDebug() << "ConnP: " << conn_p << " ret " << ret; @@ -167,7 +167,7 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const if (conn_p) switch (conn_p->getType()) { case CANCon::KVASER: return "KVASER"; - case CANCon::SOCKETCAN: return "SocketCAN"; + case CANCon::SERIALBUS: return "SerialBus"; case CANCon::GVRET_SERIAL: return "GVRET"; default: {} } diff --git a/connections/connectionwindow.cpp b/connections/connectionwindow.cpp index cadaaaa..4fbc7a2 100644 --- a/connections/connectionwindow.cpp +++ b/connections/connectionwindow.cpp @@ -43,16 +43,13 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : /* load connection configuration */ loadConnections(); - ui->rbSocketCAN->setEnabled(isSocketCanAvailable()); -#ifdef Q_OS_WIN - ui->rbKvaser->setEnabled(true); -#endif + ui->rbSocketCAN->setEnabled(isSerialBusAvailable()); connect(ui->btnOK, &QAbstractButton::clicked, this, &ConnectionWindow::handleOKButton); connect(ui->rbGVRET, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); - connect(ui->rbKvaser, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); connect(ui->rbSocketCAN, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); connect(ui->rbRemote, &QAbstractButton::clicked, this, &ConnectionWindow::handleConnTypeChanged); + connect(ui->cbDeviceType, QOverload::of(&QComboBox::currentIndexChanged), this, &ConnectionWindow::handleDeviceTypeChanged); connect(ui->tableConnections->selectionModel(), &QItemSelectionModel::currentRowChanged, this, &ConnectionWindow::currentRowChanged); connect(ui->btnActivateAll, &QPushButton::clicked, this, &ConnectionWindow::handleEnableAll); connect(ui->btnDeactivateAll, &QPushButton::clicked, this, &ConnectionWindow::handleDisableAll); @@ -62,6 +59,9 @@ ConnectionWindow::ConnectionWindow(QWidget *parent) : connect(ui->btnSendHex, &QPushButton::clicked, this, &ConnectionWindow::handleSendHex); connect(ui->btnSendText, &QPushButton::clicked, this, &ConnectionWindow::handleSendText); connect(ui->ckEnableConsole, &QCheckBox::toggled, this, &ConnectionWindow::consoleEnableChanged); + + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); } ConnectionWindow::~ConnectionWindow() @@ -117,7 +117,7 @@ bool ConnectionWindow::eventFilter(QObject *obj, QEvent *event) // standard event processing return QObject::eventFilter(obj, event); } - return false; + //return false; } void ConnectionWindow::readSettings() @@ -199,7 +199,7 @@ void ConnectionWindow::consoleEnableChanged(bool checked) { connect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); } else { //turn it off - disconnect(conn_p, SIGNAL(debugOutput(QString)), 0, 0); + disconnect(conn_p, SIGNAL(debugOutput(QString)), nullptr, nullptr); disconnect(this, SIGNAL(sendDebugData(QByteArray)), conn_p, SLOT(debugInput(QByteArray))); } } @@ -225,11 +225,18 @@ void ConnectionWindow::handleDisableAll() void ConnectionWindow::handleConnTypeChanged() { if (ui->rbGVRET->isChecked()) selectSerial(); - if (ui->rbKvaser->isChecked()) selectKvaser(); if (ui->rbSocketCAN->isChecked()) selectSocketCan(); if (ui->rbRemote->isChecked()) selectRemote(); } +void ConnectionWindow::handleDeviceTypeChanged() +{ + ui->cbPort->clear(); + canDevices = QCanBus::instance()->availableDevices(ui->cbDeviceType->currentText()); + + for (int i = 0; i < canDevices.count(); i++) + ui->cbPort->addItem(canDevices[i].name()); +} /* status */ void ConnectionWindow::connectionStatus(CANConStatus pStatus) @@ -243,12 +250,12 @@ void ConnectionWindow::connectionStatus(CANConStatus pStatus) void ConnectionWindow::handleOKButton() { - CANConnection* conn_p = NULL; + CANConnection* conn_p = nullptr; if( ! CANConManager::getInstance()->getByName(getPortName()) ) { /* create connection */ - conn_p = create(getConnectionType(), getPortName()); + conn_p = create(getConnectionType(), getPortName(), getDriverName()); if(!conn_p) return; /* add connection to model */ @@ -280,7 +287,7 @@ return; ui->btnOK->setText(tr("Create New Connection")); ui->rbGVRET->setChecked(true); setSpeed(0); - setPortName(CANCon::GVRET_SERIAL, ""); + setPortName(CANCon::GVRET_SERIAL, "", ""); } else { @@ -299,7 +306,7 @@ return; ui->btnOK->setText(tr("Update Connection Settings")); setSpeed(bus.getSpeed()); - setPortName(conn_p->getType(), conn_p->getPort()); + setPortName(conn_p->getType(), conn_p->getPort(), conn_p->getDriver()); } } @@ -332,6 +339,8 @@ void ConnectionWindow::selectSerial() ui->lPort->setText("Port:"); /* set combobox page visible */ ui->stPort->setCurrentWidget(ui->cbPage); + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); ui->cbPort->clear(); ports = QSerialPortInfo::availablePorts(); @@ -340,41 +349,42 @@ void ConnectionWindow::selectSerial() ui->cbPort->addItem(ports[i].portName()); } -void ConnectionWindow::selectKvaser() -{ - ui->lPort->setText("Port:"); - /* set combobox page visible */ - ui->stPort->setCurrentWidget(ui->cbPage); -} - void ConnectionWindow::selectSocketCan() { ui->lPort->setText("Port:"); /* set edit text page visible */ - ui->stPort->setCurrentWidget(ui->etPage); + ui->stPort->setCurrentWidget(ui->cbPage); + ui->lblDeviceType->setHidden(false); + ui->cbDeviceType->setHidden(false); + + ui->cbDeviceType->clear(); + QStringList plugins; + plugins = QCanBus::instance()->plugins(); + for (int i = 0; i < plugins.count(); i++) + ui->cbDeviceType->addItem(plugins[i]); } void ConnectionWindow::selectRemote() { ui->lPort->setText("IP Address:"); ui->stPort->setCurrentWidget(ui->etPage); + ui->lblDeviceType->setHidden(true); + ui->cbDeviceType->setHidden(true); } void ConnectionWindow::setSpeed(int speed0) { + Q_UNUSED(speed0); } -void ConnectionWindow::setPortName(CANCon::type pType, QString pPortName) +void ConnectionWindow::setPortName(CANCon::type pType, QString pPortName, QString pDriver) { switch(pType) { case CANCon::GVRET_SERIAL: ui->rbGVRET->setChecked(true); break; - case CANCon::KVASER: - ui->rbKvaser->setChecked(true); - break; - case CANCon::SOCKETCAN: + case CANCon::SERIALBUS: ui->rbSocketCAN->setChecked(true); //you can't configure any of the below three with socketcan so dim them out break; @@ -393,7 +403,16 @@ void ConnectionWindow::setPortName(CANCon::type pType, QString pPortName) ui->cbPort->setCurrentIndex(idx); break; } - case CANCon::SOCKETCAN: + case CANCon::SERIALBUS: + { + int idx = ui->cbDeviceType->findText(pDriver); + if (idx < 0) idx = 0; + ui->cbDeviceType->setCurrentIndex(idx); + idx = ui->cbPort->findText(pPortName); + if( idx < 0 ) idx = 0; + ui->cbPort->setCurrentIndex(idx); + break; + } case CANCon::REMOTE: { ui->lePort->setText(pPortName); @@ -414,9 +433,8 @@ QString ConnectionWindow::getPortName() { switch( getConnectionType() ) { case CANCon::GVRET_SERIAL: - case CANCon::KVASER: + case CANCon::SERIALBUS: return ui->cbPort->currentText(); - case CANCon::SOCKETCAN: case CANCon::REMOTE: return ui->lePort->text(); default: @@ -426,11 +444,20 @@ QString ConnectionWindow::getPortName() return ""; } +QString ConnectionWindow::getDriverName() +{ + if (getConnectionType() == CANCon::SERIALBUS) + { + return ui->cbDeviceType->currentText(); + } + + return ""; +} + CANCon::type ConnectionWindow::getConnectionType() { if (ui->rbGVRET->isChecked()) return CANCon::GVRET_SERIAL; - if (ui->rbKvaser->isChecked()) return CANCon::KVASER; - if (ui->rbSocketCAN->isChecked()) return CANCon::SOCKETCAN; + if (ui->rbSocketCAN->isChecked()) return CANCon::SERIALBUS; if (ui->rbRemote->isChecked()) return CANCon::REMOTE; qDebug() << "getConnectionType: error"; return CANCon::NONE; @@ -439,6 +466,7 @@ CANCon::type ConnectionWindow::getConnectionType() void ConnectionWindow::setSWMode(bool mode) { + Q_UNUSED(mode); } bool ConnectionWindow::getSWMode() @@ -474,21 +502,19 @@ void ConnectionWindow::handleRevert() } -bool ConnectionWindow::isSocketCanAvailable() +bool ConnectionWindow::isSerialBusAvailable() { -#ifdef Q_OS_LINUX - if (QCanBus::instance()->plugins().contains(QStringLiteral("socketcan"))) return true; -#endif + if (QCanBus::instance()->plugins().count() > 0) return true; return false; } -CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName) +CANConnection* ConnectionWindow::create(CANCon::type pTye, QString pPortName, QString pDriver) { CANConnection* conn_p; /* create connection */ - conn_p = CanConFactory::create(pTye, pPortName); + conn_p = CanConFactory::create(pTye, pPortName, pDriver); if(conn_p) { /* connect signal */ @@ -511,11 +537,12 @@ void ConnectionWindow::loadConnections() /* fill connection list */ QVector portNames = settings.value("connections/portNames").value>(); + QVector driverNames = settings.value("connections/driverNames").value>(); QVector devTypes = settings.value("connections/types").value>(); - for(int i=0 ; iadd(conn_p); } @@ -532,14 +559,17 @@ void ConnectionWindow::saveConnections() QSettings settings; QVector portNames; QVector devTypes; + QVector driverNames; /* save connections */ foreach(CANConnection* conn_p, conns) { portNames.append(conn_p->getPort()); devTypes.append(conn_p->getType()); + driverNames.append(conn_p->getDriver()); } settings.setValue("connections/portNames", QVariant::fromValue(portNames)); settings.setValue("connections/types", QVariant::fromValue(devTypes)); + settings.setValue("connections/driverNames", QVariant::fromValue(driverNames)); } diff --git a/connections/connectionwindow.h b/connections/connectionwindow.h index 3d000ba..7b44a1d 100644 --- a/connections/connectionwindow.h +++ b/connections/connectionwindow.h @@ -9,6 +9,7 @@ #include #include #include +#include #include "canconnectionmodel.h" #include "connections/canconnection.h" @@ -47,6 +48,7 @@ public slots: private slots: void handleOKButton(); void handleConnTypeChanged(); + void handleDeviceTypeChanged(); void currentRowChanged(const QModelIndex ¤t, const QModelIndex &previous); void consoleEnableChanged(bool checked); void handleRemoveConn(); @@ -63,6 +65,7 @@ private slots: private: Ui::ConnectionWindow *ui; QList ports; + QList canDevices; QSettings *settings; CANConnectionModel *connModel; @@ -70,13 +73,14 @@ private: void selectKvaser(); void selectSocketCan(); void selectRemote(); - bool isSocketCanAvailable(); + bool isSerialBusAvailable(); int getSpeed(); QString getPortName(); - void setPortName(CANCon::type pType, QString pPortName); + QString getDriverName(); + void setPortName(CANCon::type pType, QString pPortName, QString pDriver); void setActiveAll(bool pActive); - CANConnection* create(CANCon::type pTye, QString pPortName); + CANConnection* create(CANCon::type pTye, QString pPortName, QString pDriver); void loadConnections(); void saveConnections(); void showEvent(QShowEvent *); diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp index 9479a36..74987e7 100644 --- a/connections/gvretserial.cpp +++ b/connections/gvretserial.cpp @@ -9,7 +9,7 @@ #include "gvretserial.h" GVRetSerial::GVRetSerial(QString portName, bool useTcp) : - CANConnection(portName, CANCon::GVRET_SERIAL, 3, 4000, true), + CANConnection(portName, "gvret", CANCon::GVRET_SERIAL, 3, 4000, true), useTcp(useTcp), mTimer(this) /*NB: set this as parent of timer to manage it from working thread */ { diff --git a/connections/serialbusconnection.cpp b/connections/serialbusconnection.cpp index a8dc36b..cf16461 100644 --- a/connections/serialbusconnection.cpp +++ b/connections/serialbusconnection.cpp @@ -11,8 +11,8 @@ /**** class definition ****/ /***********************************/ -SerialBusConnection::SerialBusConnection(QString portName) : - CANConnection(portName, CANCon::SOCKETCAN, 1, 4000, true), +SerialBusConnection::SerialBusConnection(QString portName, QString driverName) : + CANConnection(portName, driverName, CANCon::SERIALBUS, 1, 4000, true), mTimer(this) /*NB: set connection as parent of timer to manage it from working thread */ { } @@ -77,10 +77,10 @@ void SerialBusConnection::piSetBusSettings(int pBusIdx, CANBus bus) /* create device */ QString errorString; - mDev_p = QCanBus::instance()->createDevice("socketcan", getPort(), &errorString); + mDev_p = QCanBus::instance()->createDevice(getDriver(), getPort(), &errorString); if (!mDev_p) { disconnectDevice(); - qDebug() << "Error: createDevice(" << getType() << getPort() << "):" << errorString; + qDebug() << "Error: createDevice(" << getType() << getDriver() << getPort() << "):" << errorString; return; } diff --git a/connections/serialbusconnection.h b/connections/serialbusconnection.h index 2c9d357..e430ebd 100644 --- a/connections/serialbusconnection.h +++ b/connections/serialbusconnection.h @@ -12,7 +12,7 @@ class SerialBusConnection : public CANConnection Q_OBJECT public: - SerialBusConnection(QString portName); + SerialBusConnection(QString portName, QString driverName); virtual ~SerialBusConnection(); protected: diff --git a/ui/connectionwindow.ui b/ui/connectionwindow.ui index 197703f..b679a1b 100644 --- a/ui/connectionwindow.ui +++ b/ui/connectionwindow.ui @@ -81,16 +81,6 @@ Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - false - - - Kvaser - - - @@ -101,17 +91,17 @@ - + false - SocketCAN + QT SerialBus Devices (SocketCAN, PeakCAN, etc) - + Remote Host @@ -121,6 +111,16 @@ + + + + Device Type: + + + + + +