/* 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 CANBlasterDriver::CANBlasterDriver(Backend &backend) : CanDriver(backend) { } 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; }