From b4c8aa49db50f46c56f34225c5bf71f3ead2463a Mon Sep 17 00:00:00 2001 From: Collin Kidder Date: Tue, 9 Aug 2016 20:03:57 -0400 Subject: [PATCH] First pass at turning on functionality to allow frame sending from the new connection system. The fuzzing window has been modified to use the new system. This validates that it mostly works now. More screens will be modified to work soon. --- canconnectionmodel.cpp | 3 +- connections/canconmanager.cpp | 54 +++++++++++++++++++++++++++++++++++ connections/canconmanager.h | 13 +++++++++ connections/gvretserial.cpp | 47 +++++++++++++++++++++++++++++- fuzzingwindow.cpp | 27 +++++++++++------- mainwindow.cpp | 4 +-- 6 files changed, 132 insertions(+), 16 deletions(-) diff --git a/canconnectionmodel.cpp b/canconnectionmodel.cpp index 084d2cc..b7216aa 100644 --- a/canconnectionmodel.cpp +++ b/canconnectionmodel.cpp @@ -96,7 +96,8 @@ QVariant CANConnectionModel::data(const QModelIndex &index, int role) const switch (index.column()) { case 0: //bus - return QString::number(busId); + //return QString::number(busId); + return QString::number(index.row()); break; case 1: //type if (conn_p) diff --git a/connections/canconmanager.cpp b/connections/canconmanager.cpp index 5f645d1..33c4892 100644 --- a/connections/canconmanager.cpp +++ b/connections/canconmanager.cpp @@ -41,6 +41,16 @@ void CANConManager::remove(CANConnection* pConn_p) mConns.removeOne(pConn_p); } +//Get total number of buses currently registered with the program +int CANConManager::getNumBuses() +{ + int buses = 0; + foreach(CANConnection* conn_p, mConns) + { + buses += conn_p->getNumBuses(); + } + return buses; +} void CANConManager::refreshCanList() { @@ -92,3 +102,47 @@ void CANConManager::refreshConnection(CANConnection* pConn_p) if(frames.size()) emit framesReceived(pConn_p, frames); } + +/* + * Uses the requested bus to look up which CANConnection object handles this bus based on the order of + * the objects and how many buses they implement. For instance, if the request is to send on bus 2 + * and there is a GVRET object first then a socketcan object it'll send on the socketcan object as + * gvret will have claimed buses 0 and 1 and socketcan bus 2. But, each actual CANConnection expects + * its own bus numbers to start at zero so the frame bus number has to be offset accordingly. + * Also keep in mind that the CANConnection "sendFrame" function uses a blocking queued connection + * and so will force the frame to be delivered before it keeps going. This allows on the stack variables + * to be used but is slow. This function uses an on the stack copy of the frame so the way it works + * is a good thing but performance will suffer. TODO: Investigate a way to use non-blocking calls. +*/ +bool CANConManager::sendFrame(const CANFrame& pFrame) +{ + int busBase = 0; + CANFrame workingFrame = pFrame; + CANFrame *txFrame; + + foreach (CANConnection* conn, mConns) + { + //check if this CAN connection is supposed to handle the requested bus + if (pFrame.bus <= busBase + conn->getNumBuses()) + { + workingFrame.bus -= busBase; + txFrame = conn->getQueue().get(); + *txFrame = workingFrame; + conn->getQueue().queue(); + return conn->sendFrame(workingFrame); + } + busBase += conn->getNumBuses(); + } + return false; +} + +bool CANConManager::sendFrames(const QList& pFrames) +{ + foreach(const CANFrame& frame, pFrames) + { + if(!sendFrame(frame)) + return false; + } + + return true; +} diff --git a/connections/canconmanager.h b/connections/canconmanager.h index 66896f1..d9c7e40 100644 --- a/connections/canconmanager.h +++ b/connections/canconmanager.h @@ -20,6 +20,19 @@ public: CANConnection* getByName(const QString& pName) const; + int getNumBuses(); + + /** + * @brief sendFrame sends a single frame out the desired bus + * @param pFrame - reference to a CANFrame struct that has been filled out for sending + * @return bool specifying whether the send succeeded or not + * @note Finds which CANConnection object is responsible for this bus and automatically converts bus number to pass properly to CANConnection + */ + bool sendFrame(const CANFrame& pFrame); + + //just the multi-frame version of above function. + bool sendFrames(const QList& pFrames); + signals: void framesReceived(CANConnection* pConn_p, QVector& pFrames); diff --git a/connections/gvretserial.cpp b/connections/gvretserial.cpp index d9408b3..c76a5ee 100644 --- a/connections/gvretserial.cpp +++ b/connections/gvretserial.cpp @@ -141,7 +141,52 @@ void GVRetSerial::piSetBusSettings(int pBusIdx, CANBus bus) } -bool GVRetSerial::piSendFrame(const CANFrame&) {return false;} +bool GVRetSerial::piSendFrame(const CANFrame& frame) +{ + QByteArray buffer; + int c; + int ID; + CANFrame tempFrame = frame; + tempFrame.isReceived = false; + tempFrame.timestamp = ((QDateTime::currentMSecsSinceEpoch() - txTimestampBasis) * 1000); + + //qDebug() << "Sending out frame with id " << frame->ID; + + //show our sent frames in the list too. This happens even if we're not connected. + /* model lives in UI thread, we need to call invokeMethod */ + //QMetaObject::invokeMethod(model, "addFrame", + // Qt::QueuedConnection, + // Q_ARG(CANFrame, tempFrame), + // Q_ARG(bool, false)); + + framesRapid++; + + if (serial == NULL) return false; + if (!serial->isOpen()) return false; + //if (!isConnected) return false; + + ID = frame.ID; + if (frame.extended) ID |= 1 << 31; + + buffer[0] = (char)0xF1; //start of a command over serial + buffer[1] = 0; //command ID for sending a CANBUS frame + buffer[2] = (unsigned char)(ID & 0xFF); //four bytes of ID LSB first + buffer[3] = (unsigned char)(ID >> 8); + buffer[4] = (unsigned char)(ID >> 16); + buffer[5] = (unsigned char)(ID >> 24); + buffer[6] = (unsigned char)((frame.bus) & 1); + buffer[7] = (unsigned char)frame.len; + for (c = 0; c < frame.len; c++) + { + buffer[8 + c] = frame.data[c]; + } + buffer[8 + frame.len] = 0; + + //qDebug() << "writing " << buffer.length() << " bytes to serial port"; + serial->write(buffer); + + return true; +} diff --git a/fuzzingwindow.cpp b/fuzzingwindow.cpp index 45e564c..0ae427f 100644 --- a/fuzzingwindow.cpp +++ b/fuzzingwindow.cpp @@ -3,6 +3,7 @@ #include "utility.h" #include #include "mainwindow.h" +#include "connections/canconmanager.h" FuzzingWindow::FuzzingWindow(const QVector *frames, QWidget *parent) : QDialog(parent), @@ -36,9 +37,10 @@ FuzzingWindow::FuzzingWindow(const QVector *frames, QWidget *parent) : fuzzTimer->setInterval(ui->spinTiming->value()); - ui->cbBuses->addItem(tr("0")); - ui->cbBuses->addItem(tr("1")); - ui->cbBuses->addItem(tr("Both")); + int numBuses = CANConManager::getInstance()->getNumBuses(); + for (int n = 0; n < numBuses; n++) ui->cbBuses->addItem(QString::number(n)); + ui->cbBuses->addItem(tr("All")); + } FuzzingWindow::~FuzzingWindow() @@ -111,8 +113,7 @@ void FuzzingWindow::timerTriggered() { CANFrame thisFrame; sendingBuffer.clear(); - int buses = ui->cbBuses->currentIndex() + 1; - if (buses == 0) buses = 1; + int buses = ui->cbBuses->currentIndex(); for (int count = 0; count < ui->spinBurst->value(); count++) { thisFrame.ID = currentID; @@ -121,22 +122,26 @@ void FuzzingWindow::timerTriggered() else thisFrame.extended = false; thisFrame.bus = 0; //hard coded for now. TODO: do not hard code thisFrame.len = ui->spinBytes->value(); - if (buses & 1) + + if (buses < (ui->cbBuses->count() - 1)) { - thisFrame.bus = 0; + thisFrame.bus = buses; sendingBuffer.append(thisFrame); } - if (buses & 2) + else //fuzz all the buses! HACK THE PLANET! Er, something... { - thisFrame.bus = 1; - sendingBuffer.append(thisFrame); + for (int j = 0; j < ui->cbBuses->count() - 1; j++) + { + thisFrame.bus = j; + sendingBuffer.append(thisFrame); + } } calcNextID(); calcNextBitPattern(); numSentFrames++; } - emit sendFrameBatch(&sendingBuffer); + CANConManager::getInstance()->sendFrames(sendingBuffer); ui->lblNumFrames->setText("# of sent frames: " + QString::number(numSentFrames)); } diff --git a/mainwindow.cpp b/mainwindow.cpp index 27546b4..802d571 100644 --- a/mainwindow.cpp +++ b/mainwindow.cpp @@ -918,8 +918,6 @@ void MainWindow::showFuzzingWindow() if (!fuzzingWindow) { fuzzingWindow = new FuzzingWindow(model->getListReference()); - connect(fuzzingWindow, SIGNAL(sendCANFrame(const CANFrame*)), connectionWindow, SLOT(sendFrame(const CANFrame*))); - connect(fuzzingWindow, SIGNAL(sendFrameBatch(const QList*)), connectionWindow, SLOT(sendFrameBatch(const QList*))); } fuzzingWindow->show(); } @@ -929,7 +927,7 @@ void MainWindow::showUDSScanWindow() if (!udsScanWindow) { udsScanWindow = new UDSScanWindow(model->getListReference()); - connect(udsScanWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), connectionWindow, SLOT(sendFrame(const CANFrame*))); + //connect(udsScanWindow, SIGNAL(sendCANFrame(const CANFrame*,int)), connectionWindow, SLOT(sendFrame(const CANFrame*))); } udsScanWindow->show(); }