From 2e01b478f14f691fb422ed8697ef9f78de7ae628 Mon Sep 17 00:00:00 2001 From: Mikayla Date: Mon, 10 Nov 2025 23:00:52 +0000 Subject: [PATCH] #635 comms optimizations --- coordinator/config/facility.lua | 6 +- coordinator/coordinator.lua | 12 +-- coordinator/startup.lua | 2 +- pocket/pocket.lua | 14 +--- pocket/startup.lua | 2 +- reactor-plc/config/check.lua | 6 +- reactor-plc/plc.lua | 8 +- reactor-plc/startup.lua | 2 +- rtu/config/check.lua | 6 +- rtu/rtu.lua | 12 +-- rtu/startup.lua | 2 +- scada-common/comms.lua | 132 +++++++++++++++----------------- scada-common/util.lua | 2 +- supervisor/startup.lua | 2 +- supervisor/supervisor.lua | 16 +--- 15 files changed, 90 insertions(+), 134 deletions(-) diff --git a/coordinator/config/facility.lua b/coordinator/config/facility.lua index 0e30e1a..9a81ce2 100644 --- a/coordinator/config/facility.lua +++ b/coordinator/config/facility.lua @@ -327,10 +327,10 @@ function facility.receive_sv(side, sender, reply_to, message, distance) local s_pkt = self.nic.receive(side, sender, reply_to, message, distance) if s_pkt and s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then + local pkt = comms.mgmt_packet().decode(s_pkt) + if pkt then tcd.abort(handle_timeout) - handle_packet(mgmt_pkt.get()) + handle_packet(pkt) end end end diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 4374b3c..e271c43 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -374,18 +374,10 @@ function coordinator.comms(version, nic, wl_nic, sv_watchdog) local pkt = nil if s_pkt then - -- get as SCADA management packet if s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then - pkt = mgmt_pkt.get() - end - -- get as coordinator packet + pkt = comms.mgmt_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.SCADA_CRDN then - local crdn_pkt = comms.crdn_packet() - if crdn_pkt.decode(s_pkt) then - pkt = crdn_pkt.get() - end + pkt = comms.crdn_packet().decode(s_pkt) else log.debug("attempted parse of illegal packet type " .. s_pkt.protocol(), true) end diff --git a/coordinator/startup.lua b/coordinator/startup.lua index 125609c..70cb343 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -20,7 +20,7 @@ local renderer = require("coordinator.renderer") local sounder = require("coordinator.sounder") local threads = require("coordinator.threads") -local COORDINATOR_VERSION = "v1.7.0" +local COORDINATOR_VERSION = "v1.7.1" local CHUNK_LOAD_DELAY_S = 30.0 diff --git a/pocket/pocket.lua b/pocket/pocket.lua index 73b5161..b40d7d9 100644 --- a/pocket/pocket.lua +++ b/pocket/pocket.lua @@ -626,21 +626,13 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav) ---@return mgmt_frame|crdn_frame|nil packet function public.parse_packet(side, sender, reply_to, message, distance) local s_pkt = nic.receive(side, sender, reply_to, message, distance) - local pkt = nil + local pkt = nil if s_pkt then - -- get as SCADA management packet if s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then - pkt = mgmt_pkt.get() - end - -- get as coordinator packet + pkt = comms.mgmt_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.SCADA_CRDN then - local crdn_pkt = comms.crdn_packet() - if crdn_pkt.decode(s_pkt) then - pkt = crdn_pkt.get() - end + pkt = comms.crdn_packet().decode(s_pkt) else log.debug("attempted parse of illegal packet type " .. s_pkt.protocol(), true) end diff --git a/pocket/startup.lua b/pocket/startup.lua index a849b3a..ea99f41 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -22,7 +22,7 @@ local pocket = require("pocket.pocket") local renderer = require("pocket.renderer") local threads = require("pocket.threads") -local POCKET_VERSION = "v1.0.4" +local POCKET_VERSION = "v1.0.5" local println = util.println local println_ts = util.println_ts diff --git a/reactor-plc/config/check.lua b/reactor-plc/config/check.lua index 2a06a54..3da4e08 100644 --- a/reactor-plc/config/check.lua +++ b/reactor-plc/config/check.lua @@ -249,10 +249,10 @@ function check.receive_sv(side, sender, reply_to, message, distance) local s_pkt = self.nic.receive(side, sender, reply_to, message, distance) if s_pkt and s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then + local pkt = comms.mgmt_packet().decode(s_pkt) + if pkt then tcd.abort(handle_timeout) - handle_packet(mgmt_pkt.get()) + handle_packet(pkt) end end end diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index f7f92b9..9ba032e 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -923,14 +923,10 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog) local pkt = nil if s_pkt then - -- get as RPLC packet if s_pkt.protocol() == PROTOCOL.RPLC then - local rplc_pkt = comms.rplc_packet() - if rplc_pkt.decode(s_pkt) then pkt = rplc_pkt.get() end - -- get as SCADA management packet + pkt = comms.rplc_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then pkt = mgmt_pkt.get() end + pkt = comms.mgmt_packet().decode(s_pkt) else log.debug("unsupported packet type " .. s_pkt.protocol(), true) end diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 324cb68..3ce6eb2 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -19,7 +19,7 @@ local plc = require("reactor-plc.plc") local renderer = require("reactor-plc.renderer") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "v1.10.0" +local R_PLC_VERSION = "v1.10.1" local println = util.println local println_ts = util.println_ts diff --git a/rtu/config/check.lua b/rtu/config/check.lua index 59d2930..0369671 100644 --- a/rtu/config/check.lua +++ b/rtu/config/check.lua @@ -326,10 +326,10 @@ function check.receive_sv(side, sender, reply_to, message, distance) local s_pkt = self.nic.receive(side, sender, reply_to, message, distance) if s_pkt and s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then + local pkt = comms.mgmt_packet().decode(s_pkt) + if pkt then tcd.abort(handle_timeout) - handle_packet(mgmt_pkt.get()) + handle_packet(pkt) end end end diff --git a/rtu/rtu.lua b/rtu/rtu.lua index fa9908f..17042f8 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -425,18 +425,10 @@ function rtu.comms(version, nic, conn_watchdog) local pkt = nil if s_pkt then - -- get as MODBUS TCP packet if s_pkt.protocol() == PROTOCOL.MODBUS_TCP then - local m_pkt = comms.modbus_packet() - if m_pkt.decode(s_pkt) then - pkt = m_pkt.get() - end - -- get as SCADA management packet + pkt = comms.modbus_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then - pkt = mgmt_pkt.get() - end + pkt = comms.mgmt_packet().decode(s_pkt) else log.debug("illegal packet type " .. s_pkt.protocol(), true) end diff --git a/rtu/startup.lua b/rtu/startup.lua index 322a9ae..b2726f3 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -21,7 +21,7 @@ local rtu = require("rtu.rtu") local threads = require("rtu.threads") local uinit = require("rtu.uinit") -local RTU_VERSION = "v1.13.0" +local RTU_VERSION = "v1.13.1" local println = util.println local println_ts = util.println_ts diff --git a/scada-common/comms.lua b/scada-common/comms.lua index 716ea1b..c4aad9f 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -414,6 +414,7 @@ function comms.modbus_packet() ---@param unit_id integer ---@param func_code MODBUS_FCODE ---@param data table + ---@return boolean success function public.make(txn_id, unit_id, func_code, data) if type(data) == "table" then self.txn_id = txn_id @@ -425,37 +426,33 @@ function comms.modbus_packet() -- populate raw array self.raw = { self.txn_id, self.unit_id, self.func_code } for i = 1, self.length do insert(self.raw, data[i]) end - else - log.error("COMMS: modbus_packet.make(): data not a table") + + return true end + + log.error("COMMS: modbus_packet.make(): data not a table") + return false end -- decode a MODBUS packet from a SCADA frame ---@param frame scada_packet - ---@return boolean success + ---@return modbus_frame|nil frame the decoded frame, if valid function public.decode(frame) if frame then self.frame = frame if frame.protocol() == PROTOCOL.MODBUS_TCP then - local size_ok = frame.length() >= 3 - - if size_ok then + if frame.length() >= 3 then local data = frame.data() - public.make(data[1], data[2], data[3], { table.unpack(data, 4, #data) }) + + if public.make(data[1], data[2], data[3], { table.unpack(data, 4, #data) }) then + return public.get() + end end + else log.debug("COMMS: attempted MODBUS_TCP parse of incorrect protocol " .. frame.protocol(), true) end + else log.debug("COMMS: nil frame encountered", true) end - local valid = type(self.txn_id) == "number" and type(self.unit_id) == "number" and type(self.func_code) == "number" - - return size_ok and valid - else - log.debug("COMMS: attempted MODBUS_TCP parse of incorrect protocol " .. frame.protocol(), true) - return false - end - else - log.debug("COMMS: nil frame encountered", true) - return false - end + return nil end -- get raw to send @@ -500,6 +497,7 @@ function comms.rplc_packet() ---@param id integer ---@param packet_type RPLC_TYPE ---@param data table + ---@return boolean success function public.make(id, packet_type, data) if type(data) == "table" then -- packet accessor properties @@ -511,37 +509,33 @@ function comms.rplc_packet() -- populate raw array self.raw = { self.id, self.type } for i = 1, #data do insert(self.raw, data[i]) end - else - log.error("COMMS: rplc_packet.make(): data not a table") + + return true end + + log.error("COMMS: rplc_packet.make(): data not a table") + return false end -- decode an RPLC packet from a SCADA frame ---@param frame scada_packet - ---@return boolean success + ---@return rplc_frame|nil frame the decoded frame, if valid function public.decode(frame) if frame then self.frame = frame if frame.protocol() == PROTOCOL.RPLC then - local ok = frame.length() >= 2 - - if ok then + if frame.length() >= 2 then local data = frame.data() - public.make(data[1], data[2], { table.unpack(data, 3, #data) }) + + if public.make(data[1], data[2], { table.unpack(data, 3, #data) }) and (type(self.id) == "number") then + return public.get() + end end + else log.debug("COMMS: attempted RPLC parse of incorrect protocol " .. frame.protocol(), true) end + else log.debug("COMMS: nil frame encountered", true) end - ok = ok and type(self.id) == "number" - - return ok - else - log.debug("COMMS: attempted RPLC parse of incorrect protocol " .. frame.protocol(), true) - return false - end - else - log.debug("COMMS: nil frame encountered", true) - return false - end + return nil end -- get raw to send @@ -583,6 +577,7 @@ function comms.mgmt_packet() -- make a SCADA management packet ---@param packet_type MGMT_TYPE ---@param data table + ---@return boolean success function public.make(packet_type, data) if type(data) == "table" then -- packet accessor properties @@ -593,35 +588,33 @@ function comms.mgmt_packet() -- populate raw array self.raw = { self.type } for i = 1, #data do insert(self.raw, data[i]) end - else - log.error("COMMS: mgmt_packet.make(): data not a table") + + return true end + + log.error("COMMS: mgmt_packet.make(): data not a table") + return false end -- decode a SCADA management packet from a SCADA frame ---@param frame scada_packet - ---@return boolean success + ---@return mgmt_frame|nil frame the decoded frame, if valid function public.decode(frame) if frame then self.frame = frame if frame.protocol() == PROTOCOL.SCADA_MGMT then - local ok = frame.length() >= 1 - - if ok then + if frame.length() >= 1 then local data = frame.data() - public.make(data[1], { table.unpack(data, 2, #data) }) - end - return ok - else - log.debug("COMMS: attempted SCADA_MGMT parse of incorrect protocol " .. frame.protocol(), true) - return false - end - else - log.debug("COMMS: nil frame encountered", true) - return false - end + if public.make(data[1], { table.unpack(data, 2, #data) }) then + return public.get() + end + end + else log.debug("COMMS: attempted SCADA_MGMT parse of incorrect protocol " .. frame.protocol(), true) end + else log.debug("COMMS: nil frame encountered", true) end + + return nil end -- get raw to send @@ -662,6 +655,7 @@ function comms.crdn_packet() -- make a coordinator packet ---@param packet_type CRDN_TYPE ---@param data table + ---@return boolean success function public.make(packet_type, data) if type(data) == "table" then -- packet accessor properties @@ -672,35 +666,33 @@ function comms.crdn_packet() -- populate raw array self.raw = { self.type } for i = 1, #data do insert(self.raw, data[i]) end - else - log.error("COMMS: crdn_packet.make(): data not a table") + + return true end + + log.error("COMMS: crdn_packet.make(): data not a table") + return false end -- decode a coordinator packet from a SCADA frame ---@param frame scada_packet - ---@return boolean success + ---@return crdn_frame|nil frame the decoded frame, if valid function public.decode(frame) if frame then self.frame = frame if frame.protocol() == PROTOCOL.SCADA_CRDN then - local ok = frame.length() >= 1 - - if ok then + if frame.length() >= 1 then local data = frame.data() - public.make(data[1], { table.unpack(data, 2, #data) }) - end - return ok - else - log.debug("COMMS: attempted SCADA_CRDN parse of incorrect protocol " .. frame.protocol(), true) - return false - end - else - log.debug("COMMS: nil frame encountered", true) - return false - end + if public.make(data[1], { table.unpack(data, 2, #data) }) then + return public.get() + end + end + else log.debug("COMMS: attempted SCADA_CRDN parse of incorrect protocol " .. frame.protocol(), true) end + else log.debug("COMMS: nil frame encountered", true) end + + return nil end -- get raw to send diff --git a/scada-common/util.lua b/scada-common/util.lua index a5d4830..7aee4d9 100644 --- a/scada-common/util.lua +++ b/scada-common/util.lua @@ -24,7 +24,7 @@ local t_pack = table.pack local util = {} -- scada-common version -util.version = "1.6.0" +util.version = "1.6.1" util.TICK_TIME_S = 0.05 util.TICK_TIME_MS = 50 diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 1601f20..f6ad4bc 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -24,7 +24,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v1.8.0" +local SUPERVISOR_VERSION = "v1.8.1" local println = util.println local println_ts = util.println_ts diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index fedb35f..a138c38 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -413,22 +413,14 @@ function supervisor.comms(_version, fp_ok, facility) end if s_pkt then - -- get as MODBUS TCP packet if s_pkt.protocol() == PROTOCOL.MODBUS_TCP then - local m_pkt = comms.modbus_packet() - if m_pkt.decode(s_pkt) then pkt = m_pkt.get() end - -- get as RPLC packet + pkt = comms.modbus_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.RPLC then - local rplc_pkt = comms.rplc_packet() - if rplc_pkt.decode(s_pkt) then pkt = rplc_pkt.get() end - -- get as SCADA management packet + pkt = comms.rplc_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.SCADA_MGMT then - local mgmt_pkt = comms.mgmt_packet() - if mgmt_pkt.decode(s_pkt) then pkt = mgmt_pkt.get() end - -- get as coordinator packet + pkt = comms.mgmt_packet().decode(s_pkt) elseif s_pkt.protocol() == PROTOCOL.SCADA_CRDN then - local crdn_pkt = comms.crdn_packet() - if crdn_pkt.decode(s_pkt) then pkt = crdn_pkt.get() end + pkt = comms.crdn_packet().decode(s_pkt) else log.debug("parse_packet(" .. side .. "): attempted parse of illegal packet type " .. s_pkt.protocol(), true) end