diff --git a/udpcommander/devicepluginudpcommander.cpp b/udpcommander/devicepluginudpcommander.cpp index 0d2c13ce..51f97f65 100644 --- a/udpcommander/devicepluginudpcommander.cpp +++ b/udpcommander/devicepluginudpcommander.cpp @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright (C) 2015 Simon Stürz * + * Copyright (C) 2015-2018 Simon Stürz * * Copyright (C) 2017 Bernhard Trinnes * * * * This file is part of nymea. * @@ -70,42 +70,39 @@ DevicePluginUdpCommander::DevicePluginUdpCommander() DeviceManager::DeviceSetupStatus DevicePluginUdpCommander::setupDevice(Device *device) { - // check port - // TODO ports used by an input should be available for outputs and vice versa - if ((device->deviceClassId() == udpInputDeviceClassId) || (device->deviceClassId() == udpOutputDeviceClassId)) { - bool portOk = false; - int port = device->paramValue(portParamTypeId).toInt(&portOk); - if (!portOk || port <= 0 || port > 65535) { - qCWarning(dcUdpCommander) << device->name() << ": invalid port:" << device->paramValue(portParamTypeId).toString() << "."; - return DeviceManager::DeviceSetupStatusFailure; - } + qCDebug(dcUdpCommander()) << "Setup device" << device->name() << device->params(); + if (device->deviceClassId() == udpReceiverDeviceClassId) { QUdpSocket *udpSocket = new QUdpSocket(this); - - if (!udpSocket->bind(QHostAddress::Any, port)) { - qCWarning(dcUdpCommander) << device->name() << "can't bind to port" << port << "."; + int port = device->paramValue(udpReceiverPortParamTypeId).toInt(); + if (!udpSocket->bind(QHostAddress::Any, port, QUdpSocket::ShareAddress)) { + qCWarning(dcUdpCommander()) << device->name() << "cannot bind to port" << port; delete udpSocket; return DeviceManager::DeviceSetupStatusFailure; } connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams())); - m_commanderList.insert(udpSocket, device); + m_receiverList.insert(udpSocket, device); + return DeviceManager::DeviceSetupStatusSuccess; + } else if (device->deviceClassId() == udpCommanderDeviceClassId) { + QUdpSocket *udpSocket = new QUdpSocket(this); + m_commanderList.insert(udpSocket, device); return DeviceManager::DeviceSetupStatusSuccess; } + return DeviceManager::DeviceSetupStatusFailure; } DeviceManager::DeviceError DevicePluginUdpCommander::executeAction(Device *device, const Action &action) { - if (device->deviceClassId() == udpOutputDeviceClassId) { - - if (action.actionTypeId() == outputDataActionTypeId) { + if (device->deviceClassId() == udpCommanderDeviceClassId) { + if (action.actionTypeId() == udpCommanderOutputDataActionTypeId) { QUdpSocket *udpSocket = m_commanderList.key(device); - int port = device->paramValue(portParamTypeId).toInt(); - QHostAddress address = QHostAddress(device->paramValue(ipv4AddressParamTypeId).toString()); - QByteArray data = action.param(outputDataAreaParamTypeId).value().toByteArray(); + int port = device->paramValue(udpCommanderPortParamTypeId).toInt(); + QHostAddress address = QHostAddress(device->paramValue(udpCommanderAddressParamTypeId).toString()); + QByteArray data = action.param(udpCommanderDataParamTypeId).value().toByteArray(); qDebug(dcUdpCommander()) << "Send UDP datagram:" << data << "address:" << address.toIPv4Address() << "port:" << port; udpSocket->writeDatagram(data, address, port); @@ -118,11 +115,15 @@ DeviceManager::DeviceError DevicePluginUdpCommander::executeAction(Device *devic void DevicePluginUdpCommander::deviceRemoved(Device *device) { - if ((device->deviceClassId() == udpInputDeviceClassId) || (device->deviceClassId() == udpOutputDeviceClassId)){ + if (device->deviceClassId() == udpReceiverDeviceClassId) { + QUdpSocket *socket = m_receiverList.key(device); + m_receiverList.remove(socket); + socket->close(); + socket->deleteLater(); + } else if (device->deviceClassId() == udpCommanderDeviceClassId) { QUdpSocket *socket = m_commanderList.key(device); m_commanderList.remove(socket); - socket->close(); socket->deleteLater(); } @@ -130,8 +131,11 @@ void DevicePluginUdpCommander::deviceRemoved(Device *device) void DevicePluginUdpCommander::readPendingDatagrams() { - QUdpSocket *socket= qobject_cast(sender()); - Device *device = m_commanderList.value(socket); + QUdpSocket *socket= static_cast(sender()); + Device *device = m_receiverList.value(socket); + + if (!device) + return; QByteArray datagram; QHostAddress sender; @@ -142,13 +146,14 @@ void DevicePluginUdpCommander::readPendingDatagrams() socket->readDatagram(datagram.data(), datagram.size(), &sender, &senderPort); } - device->setStateValue(inputDataStateTypeId, datagram); + device->setStateValue(udpReceiverInputDataStateTypeId, datagram); - //TO CHECK remove command param and event, comparison may be done in the rule engine - if (datagram == device->paramValue(commandParamTypeId).toByteArray() || - datagram == device->paramValue(commandParamTypeId).toByteArray() + "\n") { - qCDebug(dcUdpCommander) << device->name() << " got command from" << sender.toString() << senderPort; - emit emitEvent(Event(commanderCommandReceivedEventTypeId, device->id())); + if (datagram == device->paramValue(udpReceiverCommandParamTypeId).toByteArray() || + datagram == device->paramValue(udpReceiverCommandParamTypeId).toByteArray() + "\n") { + qCDebug(dcUdpCommander()) << device->name() << "got command from" << sender.toString() << senderPort; + emit emitEvent(Event(udpReceiverCommandReceivedEventTypeId, device->id())); + + // Send response for verification socket->writeDatagram("OK\n", sender, senderPort); } } diff --git a/udpcommander/devicepluginudpcommander.h b/udpcommander/devicepluginudpcommander.h index bb90e5af..f5c9f9e3 100644 --- a/udpcommander/devicepluginudpcommander.h +++ b/udpcommander/devicepluginudpcommander.h @@ -1,6 +1,6 @@ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Copyright (C) 2015 Simon Stürz * + * Copyright (C) 2015-2018 Simon Stürz * * Copyright (C) 2017 Bernhard Trinnes * * * * This file is part of nymea. * @@ -43,7 +43,9 @@ public: void deviceRemoved(Device *device) override; DeviceManager::DeviceError executeAction(Device *device, const Action &action) override; + private: + QHash m_receiverList; QHash m_commanderList; private slots: diff --git a/udpcommander/devicepluginudpcommander.json b/udpcommander/devicepluginudpcommander.json index 71eceeb9..c9d2a0a5 100644 --- a/udpcommander/devicepluginudpcommander.json +++ b/udpcommander/devicepluginudpcommander.json @@ -10,72 +10,69 @@ "deviceClasses": [ { "id": "6ecd5a8d-595a-4520-85e3-dcc9679edf66", - "displayName": "UDP Commander", - "name": "commander", + "displayName": "UDP Receiver", + "name": "udpReceiver", "deviceIcon": "Network", - "basicTags": [ - "Service", - "Sensor" - ], + "basicTags": ["Service", "Sensor"], "createMethods": ["user"], "paramTypes": [ { "id": "1843adcb-e377-44d1-8d70-ab4f9eeb32ec", "name": "port", - "displayName": "port", - "type": "int" + "displayName": "Port", + "type": "int", + "minValue": 0, + "maxValue": 65535, + "defaultValue": 4242 }, { "id": "d0f29961-1624-4b91-a0e8-9b1cc86c44c7", "name": "command", - "displayName": "command", + "displayName": "Command", "type": "QString", - "inputType": "TextLine" + "defaultValue": "Hello" } ], "stateTypes":[ { "id": "065a1a0a-d324-4ae6-a461-bef8143e8795", - "idName": "inputData", - "name": "Input Data", + "name": "inputData", + "displayName": "Received data", + "displayNameEvent": "Received data changed", "type": "QString", - "defaultValue": "", - "eventTypeName": "input data changed", - "index": 0 + "defaultValue": "" } ], "eventTypes": [ { "id": "5fecbba3-ffbb-456b-872c-a2f571c681cb", "name": "commandReceived", - "displayName": "command received" + "displayName": "Command received" } ] }, { "id": "31b00639-8904-4522-84ed-54c46a54c63c", - "name": "UDP Output", - "idName": "udpOutput", + "name": "udpCommander", + "displayName": "UDP Commander", "deviceIcon": "Network", - "basicTags": [ - "Service", - "Sensor" - ], + "basicTags": ["Service", "Sensor"], "createMethods": ["user"], "paramTypes": [ { - "id": "1843adcb-e377-44d1-8d70-ab4f9eeb32ec", - "idName": "port", + "id": "eb204dfe-11f8-413f-8b68-8bffef3f9a7f", "name": "port", - "index": 0, - "type": "int" + "displayName": "Port", + "type": "int", + "minValue": 0, + "maxValue": 65535, + "defaultValue": 4242 }, { "id": "ea1be9fc-9a9b-44ba-a28d-e021aef4f046", - "idName": "ipv4Address", - "name": "IPv4 Address", + "name": "address", + "displayName": "Address", "type": "QString", - "index": 1, "inputType": "IPv4Address", "defaultValue": "127.0.0.1" } @@ -83,17 +80,14 @@ "actionTypes": [ { "id": "6bc52462-b192-46a4-a6df-92cc5a479c89", - "idName": "outputData", - "name": "Send Data", - "index": 0, + "name": "outputData", + "displayName": "Send data", "paramTypes": [ { "id": "6604c852-6b24-4707-b8e5-1ddd8032efcc", - "idName": "outputDataArea", - "name": "Data", - "type": "QString", - "index": 0, - "inputType": "TextArea" + "name": "data", + "displayName": "Data", + "type": "QString" } ] }