mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#76 added trusted connection ranges for modem messages
This commit is contained in:
parent
1d3a1672c8
commit
6c09772a74
@ -6,6 +6,8 @@ config.SCADA_SV_PORT = 16100
|
||||
config.SCADA_SV_LISTEN = 16101
|
||||
-- listen port for SCADA coordinator API access
|
||||
config.SCADA_API_LISTEN = 16200
|
||||
-- max trusted modem message distance (0 to disable check)
|
||||
config.TRUSTED_RANGE = 0
|
||||
|
||||
-- expected number of reactor units, used only to require that number of unit monitors
|
||||
config.NUM_UNITS = 4
|
||||
|
@ -191,13 +191,14 @@ function coordinator.log_comms_connecting(message)
|
||||
end
|
||||
|
||||
-- coordinator communications
|
||||
---@param version string
|
||||
---@param modem table
|
||||
---@param sv_port integer
|
||||
---@param sv_listen integer
|
||||
---@param api_listen integer
|
||||
---@param version string coordinator version
|
||||
---@param modem table modem device
|
||||
---@param sv_port integer port of configured supervisor
|
||||
---@param sv_listen integer listening port for supervisor replys
|
||||
---@param api_listen integer listening port for pocket API
|
||||
---@param range integer trusted device connection range
|
||||
---@param sv_watchdog watchdog
|
||||
function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_watchdog)
|
||||
function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, range, sv_watchdog)
|
||||
local self = {
|
||||
sv_linked = false,
|
||||
sv_seq_num = 0,
|
||||
@ -209,6 +210,8 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa
|
||||
---@class coord_comms
|
||||
local public = {}
|
||||
|
||||
comms.set_trusted_range(range)
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- configure modem channels
|
||||
@ -512,8 +515,8 @@ function coordinator.comms(version, modem, sv_port, sv_listen, api_listen, sv_wa
|
||||
|
||||
---@class facility_conf
|
||||
local conf = {
|
||||
num_units = config[1],
|
||||
defs = {} -- boilers and turbines
|
||||
num_units = config[1], ---@type integer
|
||||
defs = {} -- boilers and turbines
|
||||
}
|
||||
|
||||
if (#config - 1) == (conf.num_units * 2) then
|
||||
|
@ -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.1"
|
||||
local COORDINATOR_VERSION = "beta-v0.9.2"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@ -41,6 +41,7 @@ local cfv = util.new_validator()
|
||||
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_int(config.NUM_UNITS)
|
||||
cfv.assert_type_bool(config.RECOLOR)
|
||||
cfv.assert_type_num(config.SOUNDER_VOLUME)
|
||||
@ -146,7 +147,8 @@ local function main()
|
||||
log.debug("boot> conn watchdog created")
|
||||
|
||||
-- start comms, open all channels
|
||||
local coord_comms = coordinator.comms(COORDINATOR_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_SV_LISTEN, config.SCADA_API_LISTEN, conn_watchdog)
|
||||
local coord_comms = coordinator.comms(COORDINATOR_VERSION, modem, config.SCADA_SV_PORT, config.SCADA_SV_LISTEN,
|
||||
config.SCADA_API_LISTEN, config.TRUSTED_RANGE, conn_watchdog)
|
||||
log.debug("boot> comms init")
|
||||
log_comms("comms initialized")
|
||||
|
||||
|
@ -8,6 +8,8 @@ config.REACTOR_ID = 1
|
||||
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
|
||||
-- log path
|
||||
config.LOG_PATH = "/log.txt"
|
||||
-- log mode
|
||||
|
@ -404,15 +404,16 @@ function plc.rps_init(reactor, is_formed)
|
||||
end
|
||||
|
||||
-- Reactor PLC Communications
|
||||
---@param id integer
|
||||
---@param version string
|
||||
---@param modem table
|
||||
---@param local_port integer
|
||||
---@param server_port integer
|
||||
---@param reactor table
|
||||
---@param rps rps
|
||||
---@param conn_watchdog watchdog
|
||||
function plc.comms(id, version, modem, local_port, server_port, reactor, rps, conn_watchdog)
|
||||
---@param id integer reactor ID
|
||||
---@param version string PLC version
|
||||
---@param modem table modem device
|
||||
---@param local_port integer local listening port
|
||||
---@param server_port integer remote server port
|
||||
---@param range integer trusted device connection range
|
||||
---@param reactor table reactor device
|
||||
---@param rps rps RPS reference
|
||||
---@param conn_watchdog watchdog watchdog reference
|
||||
function plc.comms(id, version, modem, local_port, server_port, range, reactor, rps, conn_watchdog)
|
||||
local self = {
|
||||
seq_num = 0,
|
||||
r_seq_num = nil,
|
||||
@ -428,6 +429,13 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
||||
max_burn_rate = nil
|
||||
}
|
||||
|
||||
---@class plc_comms
|
||||
local public = {}
|
||||
|
||||
comms.set_trusted_range(range)
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- configure modem channels
|
||||
local function _conf_channels()
|
||||
self.modem.closeAll()
|
||||
@ -436,11 +444,6 @@ function plc.comms(id, version, modem, local_port, server_port, reactor, rps, co
|
||||
|
||||
_conf_channels()
|
||||
|
||||
---@class plc_comms
|
||||
local public = {}
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- send an RPLC packet
|
||||
---@param msg_type RPLC_TYPES
|
||||
---@param msg table
|
||||
|
@ -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.5"
|
||||
local R_PLC_VERSION = "beta-v0.10.6"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@ -31,6 +31,7 @@ cfv.assert_type_bool(config.NETWORKED)
|
||||
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_str(config.LOG_PATH)
|
||||
cfv.assert_type_int(config.LOG_MODE)
|
||||
assert(cfv.valid(), "bad config file: missing/invalid fields")
|
||||
@ -162,7 +163,7 @@ local function main()
|
||||
|
||||
-- start comms
|
||||
smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_dev.modem, config.LISTEN_PORT, config.SERVER_PORT,
|
||||
smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog)
|
||||
config.TRUSTED_RANGE, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog)
|
||||
log.debug("init> comms init")
|
||||
else
|
||||
println("boot> starting in offline mode")
|
||||
|
@ -6,13 +6,15 @@ 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)
|
||||
config.TRUSTED_RANGE = 0
|
||||
-- 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 (name: side/network device name)
|
||||
-- RTU peripheral devices (named: side/network device name)
|
||||
config.RTU_DEVICES = {
|
||||
{
|
||||
name = "boilerValve_0",
|
||||
@ -33,17 +35,22 @@ config.RTU_REDSTONE = {
|
||||
-- {
|
||||
-- port = rsio.IO.WASTE_PO,
|
||||
-- side = "top",
|
||||
-- bundled_color = colors.blue
|
||||
-- bundled_color = colors.red
|
||||
-- },
|
||||
-- {
|
||||
-- port = rsio.IO.WASTE_PU,
|
||||
-- side = "top",
|
||||
-- bundled_color = colors.cyan
|
||||
-- bundled_color = colors.orange
|
||||
-- },
|
||||
-- {
|
||||
-- port = rsio.IO.WASTE_POPL,
|
||||
-- side = "top",
|
||||
-- bundled_color = colors.yellow
|
||||
-- },
|
||||
-- {
|
||||
-- port = rsio.IO.WASTE_AM,
|
||||
-- side = "top",
|
||||
-- bundled_color = colors.purple
|
||||
-- bundled_color = colors.lime
|
||||
-- }
|
||||
-- }
|
||||
-- }
|
||||
|
29
rtu/rtu.lua
29
rtu/rtu.lua
@ -160,12 +160,13 @@ function rtu.init_unit()
|
||||
end
|
||||
|
||||
-- RTU Communications
|
||||
---@param version string
|
||||
---@param modem table
|
||||
---@param local_port integer
|
||||
---@param server_port integer
|
||||
---@param conn_watchdog watchdog
|
||||
function rtu.comms(version, modem, local_port, server_port, conn_watchdog)
|
||||
---@param version string RTU version
|
||||
---@param modem table modem device
|
||||
---@param local_port integer local listening port
|
||||
---@param server_port integer remote server port
|
||||
---@param range integer trusted device connection range
|
||||
---@param conn_watchdog watchdog watchdog reference
|
||||
function rtu.comms(version, modem, local_port, server_port, range, conn_watchdog)
|
||||
local self = {
|
||||
version = version,
|
||||
seq_num = 0,
|
||||
@ -177,6 +178,15 @@ function rtu.comms(version, modem, local_port, server_port, conn_watchdog)
|
||||
conn_watchdog = conn_watchdog
|
||||
}
|
||||
|
||||
---@class rtu_comms
|
||||
local public = {}
|
||||
|
||||
local insert = table.insert
|
||||
|
||||
comms.set_trusted_range(range)
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- configure modem channels
|
||||
local function _conf_channels()
|
||||
self.modem.closeAll()
|
||||
@ -185,13 +195,6 @@ function rtu.comms(version, modem, local_port, server_port, conn_watchdog)
|
||||
|
||||
_conf_channels()
|
||||
|
||||
---@class rtu_comms
|
||||
local public = {}
|
||||
|
||||
local insert = table.insert
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- send a scada management packet
|
||||
---@param msg_type SCADA_MGMT_TYPES
|
||||
---@param msg table
|
||||
|
@ -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.9.13"
|
||||
local RTU_VERSION = "beta-v0.10.0"
|
||||
|
||||
local rtu_t = types.rtu_t
|
||||
|
||||
@ -42,6 +42,7 @@ 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_str(config.LOG_PATH)
|
||||
cfv.assert_type_int(config.LOG_MODE)
|
||||
cfv.assert_type_table(config.RTU_DEVICES)
|
||||
@ -390,7 +391,8 @@ local function main()
|
||||
log.debug("boot> conn watchdog started")
|
||||
|
||||
-- setup comms
|
||||
smem_sys.rtu_comms = rtu.comms(RTU_VERSION, smem_dev.modem, config.LISTEN_PORT, config.SERVER_PORT, smem_sys.conn_watchdog)
|
||||
smem_sys.rtu_comms = rtu.comms(RTU_VERSION, smem_dev.modem, config.LISTEN_PORT, config.SERVER_PORT,
|
||||
config.TRUSTED_RANGE, smem_sys.conn_watchdog)
|
||||
log.debug("boot> comms init")
|
||||
|
||||
-- init threads
|
||||
|
@ -12,6 +12,8 @@ local rtu_t = types.rtu_t
|
||||
|
||||
local insert = table.insert
|
||||
|
||||
local max_distance = nil
|
||||
|
||||
comms.version = "1.3.0"
|
||||
|
||||
---@alias PROTOCOLS integer
|
||||
@ -136,6 +138,17 @@ comms.FAC_COMMANDS = FAC_COMMANDS
|
||||
---@alias packet scada_packet|modbus_packet|rplc_packet|mgmt_packet|crdn_packet|capi_packet
|
||||
---@alias frame modbus_frame|rplc_frame|mgmt_frame|crdn_frame|capi_frame
|
||||
|
||||
-- configure the maximum allowable message receive distance <br/>
|
||||
-- packets received with distances greater than this will be silently discarded
|
||||
---@param distance integer max modem message distance (less than 1 disables the limit)
|
||||
function comms.set_trusted_range(distance)
|
||||
if distance < 1 then
|
||||
max_distance = nil
|
||||
else
|
||||
max_distance = distance
|
||||
end
|
||||
end
|
||||
|
||||
-- generic SCADA packet object
|
||||
function comms.scada_packet()
|
||||
local self = {
|
||||
@ -181,6 +194,10 @@ function comms.scada_packet()
|
||||
|
||||
self.raw = self.modem_msg_in.msg
|
||||
|
||||
if (type(max_distance) == "number") and (distance > max_distance) then
|
||||
-- outside of maximum allowable transmission distance
|
||||
-- log.debug("comms.scada_packet.receive(): discarding packet with distance " .. distance .. " outside of trusted range")
|
||||
else
|
||||
if type(self.raw) == "table" then
|
||||
if #self.raw >= 3 then
|
||||
self.seq_num = self.raw[1]
|
||||
@ -196,6 +213,7 @@ function comms.scada_packet()
|
||||
self.valid = type(self.seq_num) == "number" and
|
||||
type(self.protocol) == "number" and
|
||||
type(self.payload) == "table"
|
||||
end
|
||||
end
|
||||
|
||||
return self.valid
|
||||
|
@ -4,6 +4,8 @@ local config = {}
|
||||
config.SCADA_DEV_LISTEN = 16000
|
||||
-- listen port for SCADA supervisor access by coordinators
|
||||
config.SCADA_SV_LISTEN = 16100
|
||||
-- max trusted modem message distance (0 to disable check)
|
||||
config.TRUSTED_RANGE = 0
|
||||
-- expected number of reactors
|
||||
config.NUM_REACTORS = 4
|
||||
-- expected number of boilers/turbines for each reactor
|
||||
|
@ -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.9.14"
|
||||
local SUPERVISOR_VERSION = "beta-v0.10.0"
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@ -29,6 +29,7 @@ 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_int(config.NUM_REACTORS)
|
||||
cfv.assert_type_table(config.REACTOR_COOLING)
|
||||
cfv.assert_type_str(config.LOG_PATH)
|
||||
@ -81,7 +82,7 @@ local function main()
|
||||
|
||||
-- start comms, open all channels
|
||||
local superv_comms = supervisor.comms(SUPERVISOR_VERSION, config.NUM_REACTORS, config.REACTOR_COOLING, modem,
|
||||
config.SCADA_DEV_LISTEN, config.SCADA_SV_LISTEN)
|
||||
config.SCADA_DEV_LISTEN, config.SCADA_SV_LISTEN, config.TRUSTED_RANGE)
|
||||
|
||||
-- base loop clock (6.67Hz, 3 ticks)
|
||||
local MAIN_CLOCK = 0.15
|
||||
|
@ -9,9 +9,7 @@ local supervisor = {}
|
||||
local PROTOCOLS = comms.PROTOCOLS
|
||||
local DEVICE_TYPES = comms.DEVICE_TYPES
|
||||
local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
||||
local RPLC_TYPES = comms.RPLC_TYPES
|
||||
local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES
|
||||
local SCADA_CRDN_TYPES = comms.SCADA_CRDN_TYPES
|
||||
|
||||
local print = util.print
|
||||
local println = util.println
|
||||
@ -19,13 +17,14 @@ local print_ts = util.print_ts
|
||||
local println_ts = util.println_ts
|
||||
|
||||
-- supervisory controller communications
|
||||
---@param version string
|
||||
---@param num_reactors integer
|
||||
---@param cooling_conf table
|
||||
---@param modem table
|
||||
---@param dev_listen integer
|
||||
---@param coord_listen integer
|
||||
function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen, coord_listen)
|
||||
---@param version string supervisor version
|
||||
---@param num_reactors integer number of reactors
|
||||
---@param cooling_conf table cooling configuration table
|
||||
---@param modem table modem device
|
||||
---@param dev_listen integer listening port for PLC/RTU devices
|
||||
---@param coord_listen integer listening port for coordinator
|
||||
---@param range integer trusted device connection range
|
||||
function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen, coord_listen, range)
|
||||
local self = {
|
||||
version = version,
|
||||
num_reactors = num_reactors,
|
||||
@ -38,6 +37,8 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
|
||||
---@class superv_comms
|
||||
local public = {}
|
||||
|
||||
comms.set_trusted_range(range)
|
||||
|
||||
-- PRIVATE FUNCTIONS --
|
||||
|
||||
-- configure modem channels
|
||||
@ -205,12 +206,12 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
|
||||
|
||||
if plc_id == false then
|
||||
-- reactor already has a PLC assigned
|
||||
log.debug(util.c("PLC_ESTABLISH: assignment collision with reactor ", reactor_id))
|
||||
log.warning(util.c("PLC_ESTABLISH: assignment collision with reactor ", reactor_id))
|
||||
_send_dev_establish(next_seq_id, r_port, { ESTABLISH_ACK.COLLISION })
|
||||
else
|
||||
-- got an ID; assigned to a reactor successfully
|
||||
println(util.c("reactor ", reactor_id, " PLC (", firmware_v, ") [:", r_port, "] \xbb connected"))
|
||||
log.debug(util.c("PLC_ESTABLISH: link accepted for PLC (", firmware_v, ") [:", r_port, "] connected with session ID ", plc_id))
|
||||
println(util.c("PLC (", firmware_v, ") [:", r_port, "] \xbb reactor ", reactor_id, " connected"))
|
||||
log.info(util.c("PLC_ESTABLISH: PLC (", firmware_v, ") [:", r_port, "] reactor unit ", reactor_id, " PLC connected with session ID ", plc_id))
|
||||
_send_dev_establish(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW })
|
||||
end
|
||||
else
|
||||
@ -224,7 +225,7 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
|
||||
local s_id = svsessions.establish_rtu_session(l_port, r_port, rtu_advert, firmware_v)
|
||||
|
||||
println(util.c("RTU (", firmware_v, ") [:", r_port, "] \xbb connected"))
|
||||
log.debug(util.c("RTU_ESTABLISH: RTU (",firmware_v, ") [:", r_port, "] connected with session ID ", s_id))
|
||||
log.info(util.c("RTU_ESTABLISH: RTU (",firmware_v, ") [:", r_port, "] connected with session ID ", s_id))
|
||||
_send_dev_establish(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW })
|
||||
else
|
||||
log.debug("RTU_ESTABLISH: packet length mismatch")
|
||||
@ -286,8 +287,8 @@ function supervisor.comms(version, num_reactors, cooling_conf, modem, dev_listen
|
||||
table.insert(config, cooling_conf[i].TURBINES)
|
||||
end
|
||||
|
||||
println(util.c("coordinator (",firmware_v, ") [:", r_port, "] \xbb connected"))
|
||||
log.debug(util.c("CRDN_ESTABLISH: coordinator (",firmware_v, ") [:", r_port, "] connected with session ID ", s_id))
|
||||
println(util.c("CRD (",firmware_v, ") [:", r_port, "] \xbb connected"))
|
||||
log.info(util.c("CRDN_ESTABLISH: coordinator (",firmware_v, ") [:", r_port, "] connected with session ID ", s_id))
|
||||
_send_crdn_establish(next_seq_id, r_port, { ESTABLISH_ACK.ALLOW, config })
|
||||
else
|
||||
log.debug("CRDN_ESTABLISH: denied new coordinator due to already being connected to another coordinator")
|
||||
|
Loading…
Reference in New Issue
Block a user