303 lines
7.3 KiB
C++
303 lines
7.3 KiB
C++
/**
|
|
* @file cusdr_discoverer.cpp
|
|
* @brief HPSDR device discoverer class
|
|
* @author Hermann von Hasseln, DL3HVH
|
|
* @version 0.1
|
|
* @date 2012-05-19
|
|
*/
|
|
|
|
/*
|
|
*
|
|
* Copyright 2012 Hermann von Hasseln, DL3HVH
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License version 2 as
|
|
* published by the Free Software Foundation
|
|
*
|
|
* This program 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 Library General Public
|
|
* License along with this program; if not, write to the
|
|
* Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#define LOG_DISCOVERER
|
|
|
|
#include "cusdr_discoverer_P1.h"
|
|
#include "Util/cusdr_buttons.h"
|
|
|
|
|
|
//#include <QComboBox>
|
|
//#include <QDialogButtonBox>
|
|
//#include <QLabel>
|
|
//#include <QPushButton>
|
|
//#include <QVBoxLayout>
|
|
//#include <QCheckBox>
|
|
//#include <QSlider>
|
|
//#include <QSpinBox>
|
|
|
|
|
|
|
|
//#define btn_height 18
|
|
//#define btn_width 74
|
|
|
|
DiscovererP1::DiscovererP1(THPSDRParameter *ioData)
|
|
: QObject()
|
|
, set(Settings::instance())
|
|
, io(ioData)
|
|
{
|
|
m_deviceCards = set->getMetisCardsList();
|
|
}
|
|
|
|
DiscovererP1::~DiscovererP1() {
|
|
}
|
|
|
|
TNetworkDevicecard mcP1;
|
|
|
|
void DiscovererP1::initHPSDRDevice() {
|
|
|
|
m_searchTime.start();
|
|
|
|
int deviceNo = 0;
|
|
while (deviceNo == 0) {
|
|
|
|
deviceNo = findHPSDRDevices();
|
|
|
|
if (deviceNo > 1) {
|
|
|
|
set->setHPSDRDeviceNumber(deviceNo);
|
|
break;
|
|
}
|
|
|
|
if (deviceNo > 0) {
|
|
|
|
set->setHPSDRDeviceNumber(deviceNo);
|
|
break;
|
|
}
|
|
|
|
if (m_searchTime.elapsed() > 1000) {
|
|
|
|
set->setHPSDRDeviceNumber(0);
|
|
break;
|
|
}
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "no device found - trying again...";
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
|
|
io->networkIOMutex.lock();
|
|
io->devicefound.wakeAll();
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
|
|
int DiscovererP1::findHPSDRDevices() {
|
|
|
|
int devicesFound = 0;
|
|
|
|
m_findDatagram.resize(63);
|
|
m_findDatagram[0] = (char)0xEF;
|
|
m_findDatagram[1] = (char)0xFE;
|
|
m_findDatagram[2] = (char)0x02;
|
|
for (int i = 3; i < 63; i++)
|
|
m_findDatagram[i] = (char)0x00;
|
|
|
|
QUdpSocket socket;
|
|
|
|
CHECKED_CONNECT(
|
|
&socket,
|
|
SIGNAL(error(QAbstractSocket::SocketError)),
|
|
this,
|
|
SLOT(displayDiscoverySocketError(QAbstractSocket::SocketError)));
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "using " << qPrintable(QHostAddress(set->getHPSDRDeviceLocalAddr()).toString()) << " for discovery.";
|
|
io->networkIOMutex.unlock();
|
|
|
|
// clear comboBox entries in the network dialogue
|
|
set->clearNetworkIOComboBoxEntry();
|
|
|
|
#if defined(Q_OS_WIN32)
|
|
|
|
if (socket.bind(
|
|
QHostAddress(set->getHPSDRDeviceLocalAddr()), 0,
|
|
QUdpSocket::ReuseAddressHint | QUdpSocket::ShareAddress))
|
|
//QUdpSocket::ReuseAddressHint))
|
|
{
|
|
set->setMetisPort(this, socket.localPort());
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery_socket bound successfully to port " << socket.localPort();
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
else {
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery_socket bind failed.";
|
|
io->networkIOMutex.unlock();
|
|
|
|
socket.close();
|
|
return 0;
|
|
}
|
|
#elif defined(Q_OS_LINUX)
|
|
|
|
if (socket.bind(
|
|
QHostAddress(set->getHPSDRDeviceLocalAddr()),
|
|
QUdpSocket::DefaultForPlatform))
|
|
{
|
|
CHECKED_CONNECT(
|
|
&socket,
|
|
SIGNAL(error(QAbstractSocket::SocketError)),
|
|
this,
|
|
SLOT(displayDiscoverySocketError(QAbstractSocket::SocketError)));
|
|
|
|
set->setMetisPort(this, socket.localPort());
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery_socket bound successfully to port " << socket.localPort();
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
else {
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery_socket bind failed.";
|
|
io->networkIOMutex.unlock();
|
|
|
|
socket.close();
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
if (socket.writeDatagram(m_findDatagram, QHostAddress::Broadcast, DEVICE_PORT) == 63) {
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery data sent.";
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
else {
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery data not sent.";
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
|
|
|
|
// wait a little
|
|
//SleeperThread::msleep(30);
|
|
SleeperThread::msleep(500);
|
|
|
|
while (socket.hasPendingDatagrams()) {
|
|
|
|
quint16 port;
|
|
|
|
m_deviceDatagram.resize(socket.pendingDatagramSize());
|
|
socket.readDatagram(m_deviceDatagram.data(), m_deviceDatagram.size(), &mcP1.ip_address, &port);
|
|
|
|
if (m_deviceDatagram[0] == (char)0xEF && m_deviceDatagram[1] == (char)0xFE) {
|
|
|
|
if (m_deviceDatagram[2] == (char)0x02) {
|
|
|
|
sprintf(mcP1.mac_address, "%02X:%02X:%02X:%02X:%02X:%02X",
|
|
m_deviceDatagram[3] & 0xFF, m_deviceDatagram[4] & 0xFF, m_deviceDatagram[5] & 0xFF,
|
|
m_deviceDatagram[6] & 0xFF, m_deviceDatagram[7] & 0xFF, m_deviceDatagram[8] & 0xFF);
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "Device found at " << qPrintable(mcP1.ip_address.toString()) << ":" << port << "; Mac addr: [" << mcP1.mac_address << "]";
|
|
DISCOVERER_DEBUG << "Device code version: " << qPrintable(QString::number(m_deviceDatagram.at(9), 16));
|
|
io->networkIOMutex.unlock();
|
|
|
|
int no = m_deviceDatagram.at(10);
|
|
QString str;
|
|
if (no == 0)
|
|
str = "Metis";
|
|
else if (no == 1)
|
|
str = "Hermes";
|
|
else if (no == 2)
|
|
str = "Griffin";
|
|
else if (no == 4)
|
|
str = "Angelia";
|
|
else if (no == 5)
|
|
str = "Orion";
|
|
else if (no == 6) {
|
|
str = "Hermes-Lite";
|
|
}
|
|
|
|
mcP1.boardID = no;
|
|
mcP1.boardName = str;
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "Device board ID: " << no;
|
|
DISCOVERER_DEBUG << "Device is: " << qPrintable(str);
|
|
io->networkIOMutex.unlock();
|
|
|
|
m_deviceCards.append(mcP1);
|
|
|
|
str += " (";
|
|
str += mcP1.ip_address.toString();
|
|
str += ")";
|
|
|
|
set->addNetworkIOComboBoxEntry(str);
|
|
devicesFound++;
|
|
}
|
|
else if (m_deviceDatagram[2] == (char)0x03) {
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "Device already sending data - trying to shut down...";
|
|
io->networkIOMutex.unlock();
|
|
|
|
shutdownHPSDRDevice();
|
|
clear();
|
|
}
|
|
}
|
|
|
|
}
|
|
set->setMetisCardList(m_deviceCards);
|
|
|
|
if (devicesFound == 1) {
|
|
|
|
set->setCurrentHPSDRDevice(m_deviceCards.at(0));
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "Device selected: " << qPrintable(m_deviceCards.at(0).ip_address.toString());
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
|
|
socket.close();
|
|
return devicesFound;
|
|
}
|
|
|
|
void DiscovererP1::displayDiscoverySocketError(QAbstractSocket::SocketError error) {
|
|
|
|
io->networkIOMutex.lock();
|
|
DISCOVERER_DEBUG << "discovery socket error: " << error;
|
|
io->networkIOMutex.unlock();
|
|
}
|
|
|
|
void DiscovererP1::clear() {
|
|
|
|
//m_metisDeviceComboBox->clear();
|
|
m_deviceCards.clear();
|
|
}
|
|
|
|
void DiscovererP1::shutdownHPSDRDevice() {
|
|
|
|
QByteArray arr;
|
|
arr.resize(64);
|
|
arr[0] = (char)0xEF;
|
|
arr[1] = (char)0xFE;
|
|
arr[2] = (char)0x04;
|
|
arr[3] = (char)0x00;
|
|
|
|
for (int i = 4; i < 64; i++) arr[i] = 0x00;
|
|
|
|
QUdpSocket socket;
|
|
QHostAddress addr = mcP1.ip_address;
|
|
|
|
for (int i = 0; i < 10; i++) {
|
|
|
|
if (socket.writeDatagram(arr, addr, DEVICE_PORT) < 0) {
|
|
DISCOVERER_DEBUG << "forced shutdown socket write failed.";
|
|
}
|
|
}
|
|
}
|