File: psk_reporter.cpp

package info (click to toggle)
jtdx 2.2.159%2Bimproved-3
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 75,336 kB
  • sloc: cpp: 38,503; f90: 31,141; python: 27,061; ansic: 11,772; sh: 409; fortran: 353; makefile: 232
file content (142 lines) | stat: -rw-r--r-- 5,704 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// KISS Interface for posting spots to PSK Reporter web site
// Implemented by Edson Pereira PY2SDR
//
// Reports will be sent in batch mode every 5 minutes.

#include "psk_reporter.h"

#include <QHostInfo>
#include <QTimer>
#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0)
#include <QRandomGenerator>
#endif

#include "MessageClient.hpp"

#include "moc_psk_reporter.cpp"

namespace
{
  int constexpr MAX_PAYLOAD_LENGTH {1400};
}

PSK_Reporter::PSK_Reporter(MessageClient * message_client, QObject *parent) :
    QObject {parent},
    m_messageClient {message_client},
    reportTimer {new QTimer {this}},
    m_sequenceNumber {0}
{
    m_header_h = "000Allllttttttttssssssssiiiiiiii";

    // We use 50E2 and 50E3 for link Id
    m_rxInfoDescriptor_h = "0003002C50E200040000"
                           "8002FFFF0000768F"     // 2. Rx Call
                           "8004FFFF0000768F"     // 4. Rx Grid
                           "8008FFFF0000768F"     // 8. Rx Soft
                           "8009FFFF0000768F"     // 9. Rx Antenna
                           "0000";

    m_txInfoDescriptor_h = "0002003C50E30007"
                           "8001FFFF0000768F" // 1. Tx Call
                           "800500040000768F" // 5. Tx Freq
                           "800600010000768F" // 6. Tx snr
                           "800AFFFF0000768F" // 10. Tx Mode
                           "8003FFFF0000768F" // 3. Tx Grid
                           "800B00010000768F" // 11. Tx info src
                           "00960004";        // Report time


    m_randomId_h = QString("%1").arg(
#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
    qrand()
#else
    QRandomGenerator::global ()->generate ()
#endif
    ,8,16,QChar('0'));

    QHostInfo::lookupHost("report.pskreporter.info", this, SLOT(dnsLookupResult(QHostInfo)));

    connect(reportTimer, SIGNAL(timeout()), this, SLOT(sendReport()));
    reportTimer->start(5*60*1000); // 5 minutes;
}

void PSK_Reporter::setLocalStation(QString call, QString gridSquare, QString antenna, QString programInfo)
{
  m_rxCall = call;
  m_rxGrid = gridSquare;
  m_rxAnt = antenna;
  m_progId = programInfo;
}

void PSK_Reporter::addRemoteStation(QString call, QString grid, QString freq, QString mode, QString snr, QString time )
{
    QHash<QString,QString> spot;
    spot["call"] = call;
    spot["grid"] = grid;
    spot["snr"] = snr;
    spot["freq"] = freq;
    spot["mode"] = mode;
    spot["time"] = time;
    m_spotQueue.enqueue(spot);
}

void PSK_Reporter::sendReport()
{
  while (!m_spotQueue.isEmpty()) {
    QString report_h;

    // Header
    QString header_h = m_header_h;
    header_h.replace("tttttttt", QString("%1").arg(QDateTime::currentDateTime().toTime_t(),8,16,QChar('0')));
    header_h.replace("ssssssss", QString("%1").arg(++m_sequenceNumber,8,16,QChar('0')));
    header_h.replace("iiiiiiii", m_randomId_h);

    // Receiver information
    QString rxInfoData_h = "50E2llll";
    rxInfoData_h += QString("%1").arg(m_rxCall.length(),2,16,QChar('0')) + m_rxCall.toUtf8().toHex();
    rxInfoData_h += QString("%1").arg(m_rxGrid.length(),2,16,QChar('0')) + m_rxGrid.toUtf8().toHex();
    rxInfoData_h += QString("%1").arg(m_progId.length(),2,16,QChar('0')) + m_progId.toUtf8().toHex();
    rxInfoData_h += QString("%1").arg(m_rxAnt.length(),2,16,QChar('0')) + m_rxAnt.toUtf8().toHex();
    rxInfoData_h += "0000";
    rxInfoData_h.replace("50E2llll", "50E2" + QString("%1").arg(rxInfoData_h.length()/2,4,16,QChar('0')));

    // Sender information
    QString txInfoData_h = "50E3llll";
    while (!m_spotQueue.isEmpty()
           && (header_h.size () + m_rxInfoDescriptor_h.size () + m_txInfoDescriptor_h.size () + rxInfoData_h.size () + txInfoData_h.size ()) / 2 < MAX_PAYLOAD_LENGTH) {
      QHash<QString,QString> spot = m_spotQueue.dequeue();
      txInfoData_h += QString("%1").arg(spot["call"].length(),2,16,QChar('0')) + spot["call"].toUtf8().toHex();
      txInfoData_h += QString("%1").arg(spot["freq"].toLongLong(),8,16,QChar('0'));
      txInfoData_h += QString("%1").arg(spot["snr"].toInt(),8,16,QChar('0')).right(2);
      txInfoData_h += QString("%1").arg(spot["mode"].length(),2,16,QChar('0')) + spot["mode"].toUtf8().toHex();
      txInfoData_h += QString("%1").arg(spot["grid"].length(),2,16,QChar('0')) + spot["grid"].toUtf8().toHex();
      txInfoData_h += QString("%1").arg(1,2,16,QChar('0')); // REPORTER_SOURCE_AUTOMATIC
      txInfoData_h += QString("%1").arg(spot["time"].toInt(),8,16,QChar('0'));
    }
    txInfoData_h += "0000";
    txInfoData_h.replace("50E3llll", "50E3" + QString("%1").arg(txInfoData_h.length()/2,4,16,QChar('0')));
    report_h = header_h + m_rxInfoDescriptor_h + m_txInfoDescriptor_h + rxInfoData_h + txInfoData_h;
    //qDebug() << "Sending Report TX: ";

    report_h.replace("000Allll", "000A" + QString("%1").arg(report_h.length()/2,4,16,QChar('0')));
    QByteArray report = QByteArray::fromHex(report_h.toUtf8());

    // Send data to PSK Reporter site
    if (!m_pskReporterAddress.isNull()) {
      m_messageClient->send_raw_datagram (report, m_pskReporterAddress, 4739);
    }
  }
}

void PSK_Reporter::dnsLookupResult(QHostInfo info)
{
    if (!info.addresses().isEmpty()) {
        m_pskReporterAddress = info.addresses().at(0);
        //        qDebug() << "PSK Reporter IP: " << m_pskReporterAddress;

        // deal with miss-configured settings that attempt to set a
        // Pskreporter Internet address for the WSJT-X UDP protocol
        // server address
        m_messageClient->add_blocked_destination (m_pskReporterAddress);
    }
}