/*
Copyright (c) 2022 Ethan Zonca
This file is part of cangaroo.
cangaroo is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
cangaroo is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with cangaroo. If not, see .
*/
#include "CANBlasterDriver.h"
#include "CANBlasterInterface.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
CANBlasterDriver::CANBlasterDriver(Backend &backend)
: CanDriver(backend),
setupPage(new GenericCanSetupPage())
{
QObject::connect(&backend, SIGNAL(onSetupDialogCreated(SetupDialog&)), setupPage, SLOT(onSetupDialogCreated(SetupDialog&)));
}
CANBlasterDriver::~CANBlasterDriver() {
}
bool CANBlasterDriver::update() {
deleteAllInterfaces();
// TODO: Listen for multicast packets for discovery of canblaster servers
QUdpSocket udpSocket;
QHostAddress groupAddress;
groupAddress.setAddress("239.255.43.21");
udpSocket.bind(QHostAddress::AnyIPv4, 20000, QUdpSocket::ShareAddress);
udpSocket.joinMulticastGroup(groupAddress);
// Record start time
struct timeval start_time;
gettimeofday(&start_time,NULL);
fprintf(stderr, "CANblaster: start listen\r\n");
QList detected_servers;
while(1)
{
while (udpSocket.hasPendingDatagrams())
{
QNetworkDatagram res = udpSocket.receiveDatagram(1024);
if(res.isValid())
{
QByteArray asd = res.data();
qDebug() << asd;
QJsonDocument document = QJsonDocument::fromJson(res.data());
QJsonObject rootObj = document.object();
if(rootObj.length() == 2 &&
rootObj["protocol"].toString() == "CANblaster" &&
rootObj["version"].toInt() == 1)
{
if(!detected_servers.contains(res.senderAddress().toString()))
detected_servers.append(res.senderAddress().toString());
}
else
{
fprintf(stderr, "Invalid CANblaster server. Protocol: %s Version: %d \r\n", rootObj["protocol"].toString().toStdString().c_str(), rootObj["version"].toInt());
}
}
}
struct timeval tv;
gettimeofday(&tv,NULL);
// Iterate until timer expires
if(tv.tv_sec - start_time.tv_sec > 2)
break;
}
fprintf(stderr, "CANblaster: stop listen\r\n");
fprintf(stderr, "Found %d servers: \r\n", detected_servers.length());
int interface_cnt = 0;
for(QString server: detected_servers)
{
fprintf(stderr, " - %s\r\n", server.toStdString().c_str());
createOrUpdateInterface(interface_cnt++, server, false);
}
return true;
}
QString CANBlasterDriver::getName() {
return "CANblaster";
}
CANBlasterInterface *CANBlasterDriver::createOrUpdateInterface(int index, QString name, bool fd_support) {
foreach (CanInterface *intf, getInterfaces()) {
CANBlasterInterface *scif = dynamic_cast(intf);
if (scif->getIfIndex() == index) {
scif->setName(name);
return scif;
}
}
CANBlasterInterface *scif = new CANBlasterInterface(this, index, name, fd_support);
addInterface(scif);
return scif;
}