#include "udphandler.h" #include #include "config.h" #define IPC_UDP_SYS_HOST "127.0.0.1" #define IPC_UDP_SYS_PORT 4001 #define IPC_UDP_GUI_PORT 4000 #define COMM_TIMEOUT_SEC 30 typedef struct { int header; char body[]; } STRUCT_PACK packet_t; UdpHandler *UdpHandler::instance = 0; UdpHandler::UdpHandler(QObject *parent) : QObject(parent) { bzero(&control, sizeof(control)); bzero(&state, sizeof(state)); m_steamhighctr_enabled = false; emitted = false; emitTimeoutTimer.setSingleShot(true); emitTimeoutTimer.setInterval(COMM_TIMEOUT_SEC * 1000); connect(&emitTimeoutTimer, SIGNAL(timeout()), SLOT(emitTimeout())); emitTimeoutTimer.start(); } bool UdpHandler::init() { sock = new QUdpSocket(this); if (!sock->bind(IPC_UDP_GUI_PORT)) return false; connect(sock, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); return true; } void UdpHandler::set_steam_high_sv_onoff(bool onoff) { if(onoff){ sendCommand(CMD_ONOFF, TG_MANUAL_RELAY, SWITCH_ON); sendCommand(CMD_ONOFF, TG_SSV, SWITCH_ON); m_steamhighctr_enabled = true; } else{ sendCommand(CMD_ONOFF, TG_SSV, SWITCH_OFF); sendCommand(CMD_ONOFF, TG_MANUAL_RELAY, SWITCH_OFF); m_steamhighctr_enabled = false; } } void UdpHandler::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 UdpHandler::processDatagram(QByteArray &datagram) { sock->writeDatagram(datagram, QHostAddress("localhost"), 40001); if (emitted) { emitted = false; emit recovered(); } packet_t *packet = (packet_t *) datagram.data(); switch (packet->header) { case HDR_OVEN_CONTROL: qDebug() << "Received Control"; processControl((oven_control_t *) packet->body); break; case HDR_OVEN_STATE: qDebug() << "Received State"; processState((oven_state_t *) packet->body); break; case HDR_ERROR_CODE: qDebug() << "Received Error"; break; } emitTimeoutTimer.start(); } void UdpHandler::processControl(oven_control_t *control) { if (memcmp(&this->control, control, sizeof(this->control))) { memcpy(&this->control, control, sizeof(this->control)); emit changed(); } } void UdpHandler::processState(oven_state_t *state) { if (memcmp(&this->state, state, sizeof(this->state))) { memcpy(&this->state, state, sizeof(this->state)); emit changed(); } } void UdpHandler::turnOn(int target) { if(m_steamhighctr_enabled){ sendCommand(CMD_ONOFF, TG_MANUAL_RELAY, SWITCH_OFF); m_steamhighctr_enabled = false; } sendCommand(CMD_ONOFF, target, SWITCH_ON); } void UdpHandler::turnOff(int target) { if(m_steamhighctr_enabled){ sendCommand(CMD_ONOFF, TG_MANUAL_RELAY, SWITCH_OFF); m_steamhighctr_enabled = false; } sendCommand(CMD_ONOFF, target, SWITCH_OFF); } void UdpHandler::set(int target, int value) { if(m_steamhighctr_enabled && target != TG_ERROR_CLEAR){ sendCommand(CMD_ONOFF, TG_MANUAL_RELAY, SWITCH_OFF); m_steamhighctr_enabled = false; } sendCommand(CMD_VALUE, target, value); } void UdpHandler::sendCommand(int cmd, int target, int value) { command_t command = { cmd, target, value }; qDebug() << "Send" << cmd << target << value; sock->writeDatagram((const char *) &command, sizeof(command), QHostAddress(IPC_UDP_SYS_HOST), IPC_UDP_SYS_PORT); } void UdpHandler::emitTimeout() { emitted = true; emit timeout(); } void UdpHandler::fillControl(oven_control_t &container) { memcpy(&container, &control, sizeof(control)); } void UdpHandler::fillData(oven_state_t &container) { memcpy(&container, &state, sizeof(state)); }