diff --git a/coordinator/config.lua b/coordinator/config.lua index b88593f..c293fa2 100644 --- a/coordinator/config.lua +++ b/coordinator/config.lua @@ -8,11 +8,13 @@ config.SCADA_SV_LISTEN = 16101 config.SCADA_API_LISTEN = 16200 -- max trusted modem message distance (0 to disable check) config.TRUSTED_RANGE = 0 +-- time in seconds (>= 1) before assuming a remote device is no longer active +config.COMMS_TIMEOUT = 5 -- expected number of reactor units, used only to require that number of unit monitors config.NUM_UNITS = 4 --- graphics color +-- override default display colors (prettier in my opinion) config.RECOLOR = true -- alarm sounder volume (0.0 to 3.0, 1.0 being standard max volume, this is the option given to to speaker.play()) @@ -29,9 +31,4 @@ config.LOG_PATH = "/log.txt" -- 1 = NEW (replaces existing file on start) config.LOG_MODE = 0 --- crypto config -config.SECURE = true --- must be common between all devices -config.PASSWORD = "testpassword!" - return config diff --git a/coordinator/startup.lua b/coordinator/startup.lua index d095d67..46f907a 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.6" +local COORDINATOR_VERSION = "beta-v0.9.7" local print = util.print local println = util.println @@ -42,14 +42,15 @@ cfv.assert_port(config.SCADA_SV_PORT) cfv.assert_port(config.SCADA_SV_LISTEN) cfv.assert_port(config.SCADA_API_LISTEN) cfv.assert_type_int(config.TRUSTED_RANGE) +cfv.assert_type_num(config.COMMS_TIMEOUT) +cfv.assert_min(config.COMMS_TIMEOUT, 1) cfv.assert_type_int(config.NUM_UNITS) cfv.assert_type_bool(config.RECOLOR) cfv.assert_type_num(config.SOUNDER_VOLUME) cfv.assert_type_bool(config.TIME_24_HOUR) cfv.assert_type_str(config.LOG_PATH) cfv.assert_type_int(config.LOG_MODE) -cfv.assert_type_bool(config.SECURE) -cfv.assert_type_str(config.PASSWORD) + assert(cfv.valid(), "bad config file: missing/invalid fields") ---------------------------------------- @@ -142,7 +143,7 @@ local function main() end -- create connection watchdog - local conn_watchdog = util.new_watchdog(5) + local conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) conn_watchdog.cancel() log.debug("boot> conn watchdog created") diff --git a/reactor-plc/config.lua b/reactor-plc/config.lua index f1a33a0..adc9b35 100644 --- a/reactor-plc/config.lua +++ b/reactor-plc/config.lua @@ -4,12 +4,16 @@ local config = {} config.NETWORKED = true -- unique reactor ID config.REACTOR_ID = 1 + -- port to send packets TO server config.SERVER_PORT = 16000 -- port to listen to incoming packets FROM server config.LISTEN_PORT = 14001 -- max trusted modem message distance (0 to disable check) config.TRUSTED_RANGE = 0 +-- time in seconds (>= 1) before assuming a remote device is no longer active +config.COMMS_TIMEOUT = 5 + -- log path config.LOG_PATH = "/log.txt" -- log mode diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index d390a19..e78b1b5 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.9" +local R_PLC_VERSION = "beta-v0.10.10" local print = util.print local println = util.println @@ -32,8 +32,11 @@ cfv.assert_type_int(config.REACTOR_ID) cfv.assert_port(config.SERVER_PORT) cfv.assert_port(config.LISTEN_PORT) cfv.assert_type_int(config.TRUSTED_RANGE) +cfv.assert_type_num(config.COMMS_TIMEOUT) +cfv.assert_min(config.COMMS_TIMEOUT, 1) cfv.assert_type_str(config.LOG_PATH) cfv.assert_type_int(config.LOG_MODE) + assert(cfv.valid(), "bad config file: missing/invalid fields") ---------------------------------------- @@ -157,8 +160,8 @@ local function main() log.debug("init> rps init") if __shared_memory.networked then - -- comms watchdog, 3 second timeout - smem_sys.conn_watchdog = util.new_watchdog(3) + -- comms watchdog + smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) log.debug("init> conn watchdog started") -- start comms diff --git a/rtu/config.lua b/rtu/config.lua index 50122ea..afd94cf 100644 --- a/rtu/config.lua +++ b/rtu/config.lua @@ -6,14 +6,18 @@ local config = {} config.SERVER_PORT = 16000 -- port to listen to incoming packets FROM server config.LISTEN_PORT = 15001 --- max trusted modem message distance (0 to disable check) +-- max trusted modem message distance (< 1 to disable check) config.TRUSTED_RANGE = 0 +-- time in seconds (>= 1) before assuming a remote device is no longer active +config.COMMS_TIMEOUT = 5 + -- log path config.LOG_PATH = "/log.txt" -- log mode -- 0 = APPEND (adds to existing file on start) -- 1 = NEW (replaces existing file on start) config.LOG_MODE = 0 + -- RTU peripheral devices (named: side/network device name) config.RTU_DEVICES = { { diff --git a/rtu/startup.lua b/rtu/startup.lua index 22f6f2d..d036203 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.3" +local RTU_VERSION = "beta-v0.10.4" local rtu_t = types.rtu_t @@ -43,6 +43,8 @@ local cfv = util.new_validator() cfv.assert_port(config.SERVER_PORT) cfv.assert_port(config.LISTEN_PORT) cfv.assert_type_int(config.TRUSTED_RANGE) +cfv.assert_type_num(config.COMMS_TIMEOUT) +cfv.assert_min(config.COMMS_TIMEOUT, 1) cfv.assert_type_str(config.LOG_PATH) cfv.assert_type_int(config.LOG_MODE) cfv.assert_type_table(config.RTU_DEVICES) @@ -400,7 +402,7 @@ local function main() if configure() then -- start connection watchdog - smem_sys.conn_watchdog = util.new_watchdog(5) + smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) log.debug("boot> conn watchdog started") -- setup comms diff --git a/supervisor/config.lua b/supervisor/config.lua index a7ceb7e..bbf4175 100644 --- a/supervisor/config.lua +++ b/supervisor/config.lua @@ -6,6 +6,11 @@ config.SCADA_DEV_LISTEN = 16000 config.SCADA_SV_LISTEN = 16100 -- max trusted modem message distance (0 to disable check) config.TRUSTED_RANGE = 0 +-- time in seconds (>= 1) before assuming a remote device is no longer active +config.PLC_TIMEOUT = 5 +config.RTU_TIMEOUT = 5 +config.CRD_TIMEOUT = 5 + -- expected number of reactors config.NUM_REACTORS = 4 -- expected number of boilers/turbines for each reactor @@ -15,6 +20,7 @@ config.REACTOR_COOLING = { { BOILERS = 1, TURBINES = 1 }, -- reactor unit 3 { BOILERS = 1, TURBINES = 1 } -- reactor unit 4 } + -- log path config.LOG_PATH = "/log.txt" -- log mode diff --git a/supervisor/session/coordinator.lua b/supervisor/session/coordinator.lua index 9075d2a..d17659b 100644 --- a/supervisor/session/coordinator.lua +++ b/supervisor/session/coordinator.lua @@ -42,11 +42,12 @@ local PERIODICS = { } -- coordinator supervisor session ----@param id integer ----@param in_queue mqueue ----@param out_queue mqueue ----@param facility facility -function coordinator.new_session(id, in_queue, out_queue, facility) +---@param id integer session ID +---@param in_queue mqueue in message queue +---@param out_queue mqueue out message queue +---@param timeout number communications timeout +---@param facility facility facility data table +function coordinator.new_session(id, in_queue, out_queue, timeout, facility) local log_header = "crdn_session(" .. id .. "): " local self = { @@ -57,7 +58,7 @@ function coordinator.new_session(id, in_queue, out_queue, facility) seq_num = 0, r_seq_num = nil, connected = true, - conn_watchdog = util.new_watchdog(5), + conn_watchdog = util.new_watchdog(timeout), last_rtt = 0, -- periodic messages periodics = { diff --git a/supervisor/session/plc.lua b/supervisor/session/plc.lua index 7947526..7c07825 100644 --- a/supervisor/session/plc.lua +++ b/supervisor/session/plc.lua @@ -46,15 +46,15 @@ local PERIODICS = { } -- PLC supervisor session ----@param id integer ----@param for_reactor integer ----@param in_queue mqueue ----@param out_queue mqueue -function plc.new_session(id, for_reactor, in_queue, out_queue) +---@param id integer session ID +---@param for_reactor integer reactor ID +---@param in_queue mqueue in message queue +---@param out_queue mqueue out message queue +---@param timeout number communications timeout +function plc.new_session(id, for_reactor, in_queue, out_queue, timeout) local log_header = "plc_session(" .. id .. "): " local self = { - id = id, for_reactor = for_reactor, in_q = in_queue, out_q = out_queue, @@ -70,7 +70,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) connected = true, received_struct = false, received_status_cache = false, - plc_conn_watchdog = util.new_watchdog(3), + plc_conn_watchdog = util.new_watchdog(timeout), last_rtt = 0, -- periodic messages periodics = { @@ -248,7 +248,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) local s_pkt = comms.scada_packet() local r_pkt = comms.rplc_packet() - r_pkt.make(self.id, msg_type, msg) + r_pkt.make(for_reactor, msg_type, msg) s_pkt.make(self.seq_num, PROTOCOLS.RPLC, r_pkt.raw_sendable()) self.out_q.push_packet(s_pkt) @@ -503,7 +503,7 @@ function plc.new_session(id, for_reactor, in_queue, out_queue) -- PUBLIC FUNCTIONS -- -- get the session ID - function public.get_id() return self.id end + function public.get_id() return id end -- get the session database function public.get_db() return self.sDB end diff --git a/supervisor/session/rtu.lua b/supervisor/session/rtu.lua index 607f4f6..573a5ac 100644 --- a/supervisor/session/rtu.lua +++ b/supervisor/session/rtu.lua @@ -32,12 +32,13 @@ local PERIODICS = { } -- create a new RTU session ----@param id integer ----@param in_queue mqueue ----@param out_queue mqueue ----@param advertisement table ----@param facility facility -function rtu.new_session(id, in_queue, out_queue, advertisement, facility) +---@param id integer session ID +---@param in_queue mqueue in message queue +---@param out_queue mqueue out message queue +---@param timeout number communications timeout +---@param advertisement table RTU device advertisement +---@param facility facility facility data table +function rtu.new_session(id, in_queue, out_queue, timeout, advertisement, facility) local log_header = "rtu_session(" .. id .. "): " local self = { @@ -50,7 +51,7 @@ function rtu.new_session(id, in_queue, out_queue, advertisement, facility) seq_num = 0, r_seq_num = nil, connected = true, - rtu_conn_watchdog = util.new_watchdog(3), + rtu_conn_watchdog = util.new_watchdog(timeout), last_rtt = 0, -- periodic messages periodics = { diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index 04e2f5e..e7ce735 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -2,6 +2,8 @@ local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") local util = require("scada-common.util") +local config = require("supervisor.config") + local facility = require("supervisor.session.facility") local svqtypes = require("supervisor.session.svqtypes") @@ -292,7 +294,7 @@ function svsessions.establish_plc_session(local_port, remote_port, for_reactor, instance = nil ---@type plc_session } - plc_s.instance = plc.new_session(self.next_plc_id, for_reactor, plc_s.in_queue, plc_s.out_queue) + plc_s.instance = plc.new_session(self.next_plc_id, for_reactor, plc_s.in_queue, plc_s.out_queue, config.PLC_TIMEOUT) table.insert(self.plc_sessions, plc_s) local units = self.facility.get_units() @@ -329,7 +331,7 @@ function svsessions.establish_rtu_session(local_port, remote_port, advertisement instance = nil ---@type rtu_session } - rtu_s.instance = rtu.new_session(self.next_rtu_id, rtu_s.in_queue, rtu_s.out_queue, advertisement, self.facility) + rtu_s.instance = rtu.new_session(self.next_rtu_id, rtu_s.in_queue, rtu_s.out_queue, config.RTU_TIMEOUT, advertisement, self.facility) table.insert(self.rtu_sessions, rtu_s) log.debug("established new RTU session to " .. remote_port .. " with ID " .. self.next_rtu_id) @@ -359,7 +361,7 @@ function svsessions.establish_coord_session(local_port, remote_port, version) instance = nil ---@type coord_session } - coord_s.instance = coordinator.new_session(self.next_coord_id, coord_s.in_queue, coord_s.out_queue, self.facility) + coord_s.instance = coordinator.new_session(self.next_coord_id, coord_s.in_queue, coord_s.out_queue, config.CRD_TIMEOUT, self.facility) table.insert(self.coord_sessions, coord_s) log.debug("established new coordinator session to " .. remote_port .. " with ID " .. self.next_coord_id) diff --git a/supervisor/startup.lua b/supervisor/startup.lua index 2ae0df3..037b62b 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.1" +local SUPERVISOR_VERSION = "beta-v0.11.2" local print = util.print local println = util.println @@ -30,6 +30,12 @@ local cfv = util.new_validator() cfv.assert_port(config.SCADA_DEV_LISTEN) cfv.assert_port(config.SCADA_SV_LISTEN) cfv.assert_type_int(config.TRUSTED_RANGE) +cfv.assert_type_num(config.PLC_TIMEOUT) +cfv.assert_min(config.PLC_TIMEOUT, 1) +cfv.assert_type_num(config.RTU_TIMEOUT) +cfv.assert_min(config.RTU_TIMEOUT, 1) +cfv.assert_type_num(config.CRD_TIMEOUT) +cfv.assert_min(config.CRD_TIMEOUT, 1) cfv.assert_type_int(config.NUM_REACTORS) cfv.assert_type_table(config.REACTOR_COOLING) cfv.assert_type_str(config.LOG_PATH)