OpalLink.cc 5.75 KB
Newer Older
1 2
#include "OpalLink.h"

3 4 5 6 7
OpalLink::OpalLink() :
        connectState(false),
        heartbeatTimer(new QTimer(this)),
        heartbeatRate(MAVLINK_HEARTBEAT_DEFAULT_RATE),
        m_heartbeatsEnabled(true),
8 9
        getSignalsTimer(new QTimer(this)),
        getSignalsPeriod(1000),
10 11 12
        receiveBuffer(new QQueue<QByteArray>()),
        systemID(1),
        componentID(1)
13
{
14
    start(QThread::LowPriority);
Bryan Godbolt's avatar
Bryan Godbolt committed
15 16 17 18 19

    // Set unique ID and add link to the list of links
    this->id = getNextLinkId();
    this->name = tr("OpalRT link ") + QString::number(getId());
    LinkManager::instance()->add(this);
20 21 22

    // Start heartbeat timer, emitting a heartbeat at the configured rate
    QObject::connect(heartbeatTimer, SIGNAL(timeout()), this, SLOT(heartbeat()));
23 24

    QObject::connect(getSignalsTimer, SIGNAL(timeout()), this, SLOT(getSignals()));
25 26
}

27 28 29 30 31 32 33 34

/*
 *
  Communication
 *
 */

qint64 OpalLink::bytesAvailable()
35
{
36
    return 0;
Bryan Godbolt's avatar
Bryan Godbolt committed
37 38
}

39
void OpalLink::writeBytes(const char *bytes, qint64 length)
Bryan Godbolt's avatar
Bryan Godbolt committed
40
{
41

Bryan Godbolt's avatar
Bryan Godbolt committed
42 43
}

44

45
void OpalLink::readBytes()
Bryan Godbolt's avatar
Bryan Godbolt committed
46
{
47
    receiveDataMutex.lock();
48 49
    const qint64 maxLength = 2048;
    char bytes[maxLength];
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
    qDebug() << "OpalLink::readBytes(): Reading a message.  size of buffer: " << receiveBuffer->count();
    QByteArray message = receiveBuffer->dequeue();
    if (maxLength < message.size())
    {
        qDebug() << "OpalLink::readBytes:: Buffer Overflow";

        memcpy(bytes, message.data(), maxLength);
    }
    else
    {
        memcpy(bytes, message.data(), message.size());
    }

    emit bytesReceived(this, message);
    receiveDataMutex.unlock();

Bryan Godbolt's avatar
Bryan Godbolt committed
66 67
}

68
void OpalLink::receiveMessage(mavlink_message_t message)
Bryan Godbolt's avatar
Bryan Godbolt committed
69 70
{

71 72 73 74 75 76 77 78
    // Create buffer
    char buffer[MAVLINK_MAX_PACKET_LEN];
    // Write message into buffer, prepending start sign
    int len = mavlink_msg_to_send_buffer((uint8_t*)(buffer), &message);
    // If link is connected
    if (isConnected())
    {
        receiveBuffer->enqueue(QByteArray(buffer, len));
79
        readBytes();
80 81
    }

Bryan Godbolt's avatar
Bryan Godbolt committed
82 83
}

84
void OpalLink::heartbeat()
Bryan Godbolt's avatar
Bryan Godbolt committed
85
{
86 87 88 89 90 91 92 93 94

    if (m_heartbeatsEnabled)
    {
        qDebug() << "OpalLink::heartbeat(): Generate a heartbeat";
        mavlink_message_t beat;
        mavlink_msg_heartbeat_pack(systemID, componentID,&beat, MAV_HELICOPTER, MAV_AUTOPILOT_GENERIC);
        receiveMessage(beat);
    }

Bryan Godbolt's avatar
Bryan Godbolt committed
95 96
}

97
void OpalLink::getSignals()
Bryan Godbolt's avatar
Bryan Godbolt committed
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
//    qDebug() <<  "OpalLink::getSignals(): Attempting to acquire signals";
//
//
//    unsigned long  timeout = 0;
//    unsigned short acqGroup = 0; //this is actually group 1 in the model
//    unsigned short allocatedSignals = NUM_OUTPUT_SIGNALS;
//    unsigned short *numSignals = new unsigned short(0);
//    double *timestep = new double(0);
//    double values[NUM_OUTPUT_SIGNALS] = {};
//    unsigned short *lastValues = new unsigned short(false);
//    unsigned short *decimation = new unsigned short(0);
//
//    int returnVal = OpalGetSignals(timeout, acqGroup, allocatedSignals, numSignals, timestep,
//                                   values, lastValues, decimation);
//
//    if (returnVal == EOK )
//    {
//        qDebug() << "OpalLink::getSignals: Timestep=" << *timestep;// << ", Last? " << (bool)(*lastValues);
//    }
//    else if (returnVal == EAGAIN)
//    {
//        qDebug() << "OpalLink::getSignals: Data was not ready";
//    }
//    // if returnVal == EAGAIN => data just wasn't ready
//    else if (returnVal != EAGAIN)
//    {
//        getSignalsTimer->stop();
//        displayErrorMsg();
//    }
//    /* deallocate used memory */
//
//    delete timestep;
//    delete lastValues;
//    delete lastValues;
//    delete decimation;
134

Bryan Godbolt's avatar
Bryan Godbolt committed
135 136
}

137 138 139 140 141 142
/*
 *
  Administrative
 *
 */
void OpalLink::run()
Bryan Godbolt's avatar
Bryan Godbolt committed
143
{
144
    qDebug() << "OpalLink::run():: Starting the thread";
145 146
}

147 148 149
int OpalLink::getId()
{
    return id;
Bryan Godbolt's avatar
Bryan Godbolt committed
150 151
}

152
QString OpalLink::getName()
Bryan Godbolt's avatar
Bryan Godbolt committed
153
{
154
    return name;
Bryan Godbolt's avatar
Bryan Godbolt committed
155 156
}

157
void OpalLink::setName(QString name)
Bryan Godbolt's avatar
Bryan Godbolt committed
158
{
159 160
    this->name = name;
    emit nameChanged(this->name);
Bryan Godbolt's avatar
Bryan Godbolt committed
161 162
}

163 164 165
bool OpalLink::isConnected() {
    //qDebug() << "OpalLink::isConnected:: connectState: " << connectState;
    return connectState;
Bryan Godbolt's avatar
Bryan Godbolt committed
166 167 168 169
}



170 171 172

bool OpalLink::connect()
{
Bryan Godbolt's avatar
Bryan Godbolt committed
173
    short modelState;
174 175

    /// \todo allow configuration of instid in window
176 177
//    if (OpalConnect(101, false, &modelState) == EOK)
//    {
178
        connectState = true;
179 180 181
        emit connected();
        heartbeatTimer->start(1000/heartbeatRate);
        getSignalsTimer->start(getSignalsPeriod);
182 183 184 185 186 187
//    }
//    else
//    {
//        connectState = false;
//        displayErrorMsg();
//    }
188 189 190

    emit connected(connectState);
    return connectState;
191 192 193 194 195 196 197
}

bool OpalLink::disconnect()
{
    return false;
}

198 199 200 201 202 203 204 205 206
void OpalLink::displayErrorMsg()
{
    setLastErrorMsg();
    QMessageBox msgBox;
    msgBox.setIcon(QMessageBox::Critical);
    msgBox.setText(lastErrorMsg);
    msgBox.exec();
}

207 208
void OpalLink::setLastErrorMsg()
{
209 210 211 212 213
//    char buf[512];
//    unsigned short len;
//    OpalGetLastErrMsg(buf, sizeof(buf), &len);
//    lastErrorMsg.clear();
//    lastErrorMsg.append(buf);
214 215
}

216 217 218 219 220 221 222 223

/*
 *
  Statisctics
 *
 */

qint64 OpalLink::getNominalDataRate()
224
{
225
    return 0; //unknown
226
}
Bryan Godbolt's avatar
Bryan Godbolt committed
227

228
int OpalLink::getLinkQuality()
Bryan Godbolt's avatar
Bryan Godbolt committed
229
{
230
    return -1; //not supported
Bryan Godbolt's avatar
Bryan Godbolt committed
231 232
}

233
qint64 OpalLink::getTotalUpstream()
Bryan Godbolt's avatar
Bryan Godbolt committed
234
{
235 236 237 238 239
    statisticsMutex.lock();
    qint64 totalUpstream =  bitsSentTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
    return totalUpstream;
}
Bryan Godbolt's avatar
Bryan Godbolt committed
240

241 242 243 244 245
qint64 OpalLink::getTotalDownstream() {
    statisticsMutex.lock();
    qint64 totalDownstream = bitsReceivedTotal / ((MG::TIME::getGroundTimeNow() - connectionStartTime) / 1000);
    statisticsMutex.unlock();
    return totalDownstream;
246 247
}

248
qint64 OpalLink::getCurrentUpstream()
249
{
250 251
    return 0; //unknown
}
252

253 254 255 256
qint64 OpalLink::getMaxUpstream()
{
    return 0; //unknown
}
257

258 259
qint64 OpalLink::getBitsSent() {
    return bitsSentTotal;
260 261
}

262 263 264
qint64 OpalLink::getBitsReceived() {
    return bitsReceivedTotal;
}
265 266


267 268 269
bool OpalLink::isFullDuplex()
{
    return false;
Bryan Godbolt's avatar
Bryan Godbolt committed
270
}