mainwindow.cpp 3.47 KB
#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QTableWidgetItem>

#include "tablevalue.h"

typedef struct {
    int header;
    char body[];
} STRUCT_PACK packet_t;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    sock = new QUdpSocket(this);
    if (!sock->bind(4000))
        exit(EXIT_FAILURE);

    connect(sock, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));

    ui->controlTable->setRowCount(sizeof(oven_control_t) / sizeof(U16));
    ui->controlTable->setColumnCount(3);
    ui->controlTable->setHorizontalHeaderLabels(QString("Address,Value,Description").split(","));

    for (int row = 0; row < ui->controlTable->rowCount(); row++)
    {
        ui->controlTable->setItem(row, 0, new QTableWidgetItem(QString("").sprintf("0x%04X", row)));

        TableValue *item = new TableValue;
        item->setText("0x0000");
        ui->controlTable->setCellWidget(row, 1, item);
    }

    ui->stateTable->setRowCount(sizeof(oven_state_t) / sizeof(U16));
    ui->stateTable->setColumnCount(3);
    ui->stateTable->setHorizontalHeaderLabels(QString("Address,Value,Description").split(","));

    for (int row = 0; row < ui->stateTable->rowCount(); row++)
    {
        ui->stateTable->setItem(row, 0, new QTableWidgetItem(QString().sprintf("0x%04X", row)));

        TableValue *item = new TableValue;
        item->setText("0x0000");
        ui->stateTable->setCellWidget(row, 1, item);
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::readPendingDatagrams()
{
    while (sock->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(sock->pendingDatagramSize());
        QHostAddress sender;
        quint16 senderPort;

        sock->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort);

        processDatagram(datagram);
    }
}

void MainWindow::processDatagram(QByteArray &datagram)
{
    packet_t *packet = (packet_t *) datagram.data();
    switch (packet->header)
    {
    case HDR_OVEN_CONTROL:
        processControl((oven_control_t *) packet->body);
        break;
    case HDR_OVEN_STATE:
        processState((oven_state_t *) packet->body);
        break;
    case HDR_ERROR_CODE:
        break;
    }
}

void MainWindow::processControl(oven_control_t *control)
{
    if (memcmp(&this->control, control, sizeof(this->control)))
        updateControl(control);
}

void MainWindow::processState(oven_state_t *state)
{
    if (memcmp(&this->state, state, sizeof(this->state)))
        updateState(state);
}

void MainWindow::updateControl(oven_control_t *control)
{
    U16 *base = (U16 *) &this->control;
    U16 *operand = (U16 *) control;
    for (int row = 0; row < ui->controlTable->rowCount(); row++)
    {
        U16 b = *(base + row);
        U16 o = *(operand + row);
        if (b != o)
        {
            *(base + row) = o;
            TableValue *val = (TableValue *) ui->controlTable->cellWidget(row, 1);
            val->setText(QString().sprintf("0x%04X", o));
        }
    }
}

void MainWindow::updateState(oven_state_t *state)
{
    U16 *base = (U16 *) &this->state;
    U16 *operand = (U16 *) state;
    for (int row = 0; row < ui->stateTable->rowCount(); row++)
    {
        U16 b = *(base + row);
        U16 o = *(operand + row);
        if (b != o)
        {
            *(base + row) = o;
            TableValue *val = (TableValue *) ui->stateTable->cellWidget(row, 1);
            val->setText(QString().sprintf("0x%04X", o));
        }
    }
}