/** * @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 //#include //#include //#include //#include //#include //#include //#include //#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."; } } }