diff --git a/coordinator/coordinator.lua b/coordinator/coordinator.lua index 26410e6..ff8bcee 100644 --- a/coordinator/coordinator.lua +++ b/coordinator/coordinator.lua @@ -204,7 +204,8 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range sv_seq_num = 0, sv_r_seq_num = nil, modem = modem, - connected = false + connected = false, + last_est_ack = ESTABLISH_ACK.ALLOW } ---@class coord_comms @@ -312,6 +313,16 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range if terminated then coordinator.log_comms("supervisor connection attempt cancelled by user") + elseif not self.sv_linked then + if self.last_est_ack == ESTABLISH_ACK.DENY then + coordinator.log_comms("supervisor connection attempt denied") + elseif self.last_est_ack == ESTABLISH_ACK.COLLISION then + coordinator.log_comms("supervisor connection failed due to collision") + elseif self.last_est_ack == ESTABLISH_ACK.BAD_VERSION then + coordinator.log_comms("supervisor connection failed due to version mismatch") + else + coordinator.log_comms("supervisor connection failed with no valid response") + end end return self.sv_linked @@ -538,12 +549,30 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range log.error("invalid supervisor configuration table received, establish failed") end else - log.debug("supervisor connection denied") + log.debug("SCADA_MGMT establish packet reply (len = 2) unsupported") end - elseif packet.length == 1 and packet.data[1] == ESTABLISH_ACK.DENY then - log.debug("supervisor connection denied") - elseif packet.length == 1 and packet.data[1] == ESTABLISH_ACK.COLLISION then - log.debug("supervisor connection denied due to collision") + + self.last_est_ack = est_ack + elseif packet.length == 1 then + local est_ack = packet.data[1] + + if est_ack == ESTABLISH_ACK.DENY then + if self.last_est_ack ~= est_ack then + log.debug("supervisor connection denied") + end + elseif est_ack == ESTABLISH_ACK.COLLISION then + if self.last_est_ack ~= est_ack then + log.debug("supervisor connection denied due to collision") + end + elseif est_ack == ESTABLISH_ACK.BAD_VERSION then + if self.last_est_ack ~= est_ack then + log.info("supervisor comms version mismatch") + end + else + log.debug("SCADA_MGMT establish packet reply (len = 1) unsupported") + end + + self.last_est_ack = est_ack else log.debug("SCADA_MGMT establish packet length mismatch") end diff --git a/coordinator/startup.lua b/coordinator/startup.lua index c146477..51d8b6a 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -19,7 +19,7 @@ local iocontrol = require("coordinator.iocontrol") local renderer = require("coordinator.renderer") local sounder = require("coordinator.sounder") -local COORDINATOR_VERSION = "beta-v0.9.13" +local COORDINATOR_VERSION = "beta-v0.9.14" local print = util.print local println = util.println @@ -167,7 +167,7 @@ local function main() -- attempt to establish a connection with the supervisory computer if not coord_comms.sv_connect(60, tick_waiting, task_done) then - log_comms("supervisor connection failed") + log_sys("supervisor connection failed, shutting down...") log.fatal("failed to connect to supervisor") return false end diff --git a/reactor-plc/plc.lua b/reactor-plc/plc.lua index 4eecdf4..5e7297c 100644 --- a/reactor-plc/plc.lua +++ b/reactor-plc/plc.lua @@ -421,6 +421,7 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, reactor = reactor, scrammed = false, linked = false, + last_est_ack = ESTABLISH_ACK.ALLOW, resend_build = false, auto_ack_token = 0, status_cache = nil, @@ -917,12 +918,18 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, elseif est_ack == ESTABLISH_ACK.COLLISION then println_ts("received unsolicited link collision, unlinking") log.warning("unsolicited establish request collision") + elseif est_ack == ESTABLISH_ACK.BAD_VERSION then + println_ts("received unsolicited link version mismatch, unlinking") + log.warning("unsolicited establish request version mismatch") else println_ts("invalid unsolicited link response") log.error("unsolicited unknown establish request response") end self.linked = est_ack == ESTABLISH_ACK.ALLOW + + -- clear this since this is for something that was unsolicited + self.last_est_ack = ESTABLISH_ACK.ALLOW else log.debug("SCADA_MGMT establish packet length mismatch") end @@ -968,18 +975,24 @@ function plc.comms(id, version, modem, local_port, server_port, range, reactor, public.send_status(plc_state.no_reactor, plc_state.reactor_formed) log.debug("sent initial status data") - elseif est_ack == ESTABLISH_ACK.DENY then - println_ts("link request denied, retrying...") - log.debug("establish request denied") - elseif est_ack == ESTABLISH_ACK.COLLISION then - println_ts("reactor PLC ID collision (check config), retrying...") - log.warning("establish request collision") - else - println_ts("invalid link response, bad channel? retrying...") - log.error("unknown establish request response") + elseif self.last_est_ack ~= est_ack then + if est_ack == ESTABLISH_ACK.DENY then + println_ts("link request denied, retrying...") + log.debug("establish request denied") + elseif est_ack == ESTABLISH_ACK.COLLISION then + println_ts("reactor PLC ID collision (check config), retrying...") + log.warning("establish request collision") + elseif est_ack == ESTABLISH_ACK.BAD_VERSION then + println_ts("supervisor version mismatch (try updating), retrying...") + log.warning("establish request version mismatch") + else + println_ts("invalid link response, bad channel? retrying...") + log.error("unknown establish request response") + end end self.linked = est_ack == ESTABLISH_ACK.ALLOW + self.last_est_ack = est_ack else log.debug("SCADA_MGMT establish packet length mismatch") end diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 584afbe..52b7229 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -14,7 +14,7 @@ local config = require("reactor-plc.config") local plc = require("reactor-plc.plc") local threads = require("reactor-plc.threads") -local R_PLC_VERSION = "beta-v0.10.10" +local R_PLC_VERSION = "beta-v0.10.11" local print = util.print local println = util.println diff --git a/rtu/rtu.lua b/rtu/rtu.lua index eb75d1a..ff81659 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -175,7 +175,8 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog modem = modem, s_port = server_port, l_port = local_port, - conn_watchdog = conn_watchdog + conn_watchdog = conn_watchdog, + last_est_ack = ESTABLISH_ACK.ALLOW } ---@class rtu_comms @@ -414,10 +415,21 @@ function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog log.info("supervisor connection established") else -- establish denied + if est_ack ~= self.last_est_ack then + if est_ack == ESTABLISH_ACK.BAD_VERSION then + -- version mismatch + println_ts("supervisor comms version mismatch (try updating), retrying...") + log.warning("supervisor connection denied due to comms version mismatch") + else + println_ts("supervisor connection denied, retrying...") + log.warning("supervisor connection denied") + end + end + public.unlink(rtu_state) - println_ts("supervisor connection denied") - log.warning("supervisor connection denied by remote host") end + + self.last_est_ack = est_ack else log.debug("SCADA_MGMT establish packet length mismatch") end diff --git a/rtu/startup.lua b/rtu/startup.lua index 7bfa330..375e93f 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -25,7 +25,7 @@ local sna_rtu = require("rtu.dev.sna_rtu") local sps_rtu = require("rtu.dev.sps_rtu") local turbinev_rtu = require("rtu.dev.turbinev_rtu") -local RTU_VERSION = "beta-v0.10.5" +local RTU_VERSION = "beta-v0.10.6" local rtu_t = types.rtu_t diff --git a/scada-common/comms.lua b/scada-common/comms.lua index 6b1918a..ad7d460 100644 --- a/scada-common/comms.lua +++ b/scada-common/comms.lua @@ -14,7 +14,7 @@ local insert = table.insert local max_distance = nil -comms.version = "1.3.2" +comms.version = "1.3.3" ---@alias PROTOCOLS integer local PROTOCOLS = { @@ -68,7 +68,8 @@ local CAPI_TYPES = { local ESTABLISH_ACK = { ALLOW = 0, -- link approved DENY = 1, -- link denied - COLLISION = 2 -- link denied due to existing active link + COLLISION = 2, -- link denied due to existing active link + BAD_VERSION = 3 -- link denied due to comms version mismatch } ---@alias DEVICE_TYPES integer diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 40f4659..1c4b0d0 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -14,7 +14,7 @@ local svsessions = require("supervisor.session.svsessions") local config = require("supervisor.config") local supervisor = require("supervisor.supervisor") -local SUPERVISOR_VERSION = "beta-v0.11.8" +local SUPERVISOR_VERSION = "beta-v0.11.9" local print = util.print local println = util.println diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index 12f5291..5cadad4 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -170,8 +170,8 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen session.in_queue.push_packet(packet) else -- unknown session, force a re-link - log.debug("PLC_EST: no session but not an establish, force relink") - _send_dev_establish((packet.scada_frame.seq_num() + 1), r_port, { ESTABLISH_ACK.DENY }) + log.debug("PLC_ESTABLISH: no session but not an establish, forcing relink") + _send_dev_establish(packet.scada_frame.seq_num() + 1, r_port, { ESTABLISH_ACK.DENY }) end elseif protocol == PROTOCOLS.SCADA_MGMT then -- look for an associated session @@ -194,7 +194,7 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen if comms_v ~= comms.version then log.debug(util.c("dropping establish packet with incorrect comms version v", comms_v, " (expected v", comms.version, ")")) - _send_dev_establish(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) + _send_dev_establish(next_seq_id, r_port, { ESTABLISH_ACK.BAD_VERSION }) return end @@ -269,7 +269,7 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen if comms_v ~= comms.version then log.debug(util.c("dropping establish packet with incorrect comms version v", comms_v, " (expected v", comms.version, ")")) - _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.DENY }) + _send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.BAD_VERSION }) return elseif dev_type ~= DEVICE_TYPES.CRDN then log.debug(util.c("illegal establish packet for device ", dev_type, " on CRDN listening channel"))