From 336662de624eb6f75b5c29ca9040b4b39e69cab0 Mon Sep 17 00:00:00 2001 From: Mikayla Fischler Date: Sun, 25 Jun 2023 12:59:38 -0400 Subject: [PATCH] #51 nic integration with rtu and supervisor --- coordinator/startup.lua | 2 +- pocket/startup.lua | 2 +- reactor-plc/startup.lua | 2 +- rtu/rtu.lua | 30 ++++++++---------------------- rtu/startup.lua | 29 +++++++++++++---------------- rtu/threads.lua | 9 +++++---- supervisor/session/svsessions.lua | 18 ++++++------------ supervisor/startup.lua | 18 +++++++++++------- supervisor/supervisor.lua | 24 ++++++------------------ 9 files changed, 52 insertions(+), 82 deletions(-) diff --git a/coordinator/startup.lua b/coordinator/startup.lua index ab4f948..d21ec63 100644 --- a/coordinator/startup.lua +++ b/coordinator/startup.lua @@ -148,7 +148,7 @@ local function main() conn_watchdog.cancel() log.debug("startup> conn watchdog created") - -- init network interface then start comms + -- create network interface then setup comms local nic = network.nic(modem) local coord_comms = coordinator.comms(COORDINATOR_VERSION, nic, config.CRD_CHANNEL, config.SVR_CHANNEL, config.PKT_CHANNEL, config.TRUSTED_RANGE, conn_watchdog) diff --git a/pocket/startup.lua b/pocket/startup.lua index 7f08dd4..29fdcb7 100644 --- a/pocket/startup.lua +++ b/pocket/startup.lua @@ -89,7 +89,7 @@ local function main() log.debug("startup> conn watchdogs created") - -- init network interface then start comms + -- create network interface then setup comms local nic = network.nic(modem) local pocket_comms = pocket.comms(POCKET_VERSION, nic, config.PKT_CHANNEL, config.SVR_CHANNEL, config.CRD_CHANNEL, config.TRUSTED_RANGE, conn_wd.sv, conn_wd.api) diff --git a/reactor-plc/startup.lua b/reactor-plc/startup.lua index 284008f..31dc600 100644 --- a/reactor-plc/startup.lua +++ b/reactor-plc/startup.lua @@ -200,7 +200,7 @@ local function main() smem_sys.conn_watchdog = util.new_watchdog(config.COMMS_TIMEOUT) log.debug("init> conn watchdog started") - -- init network interface then start comms + -- create network interface then setup comms smem_sys.nic = network.nic(smem_dev.modem) smem_sys.plc_comms = plc.comms(config.REACTOR_ID, R_PLC_VERSION, smem_sys.nic, config.PLC_CHANNEL, config.SVR_CHANNEL, config.TRUSTED_RANGE, smem_dev.reactor, smem_sys.rps, smem_sys.conn_watchdog) diff --git a/rtu/rtu.lua b/rtu/rtu.lua index 831e231..3832986 100644 --- a/rtu/rtu.lua +++ b/rtu/rtu.lua @@ -158,12 +158,12 @@ end -- RTU Communications ---@nodiscard ---@param version string RTU version ----@param modem table modem device +---@param nic nic network interface device ---@param rtu_channel integer PLC comms channel ---@param svr_channel integer supervisor server channel ---@param range integer trusted device connection range ---@param conn_watchdog watchdog watchdog reference -function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdog) +function rtu.comms(version, nic, rtu_channel, svr_channel, range, conn_watchdog) local self = { sv_addr = comms.BROADCAST, seq_num = 0, @@ -179,12 +179,8 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo -- PRIVATE FUNCTIONS -- -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(rtu_channel) - end - - _conf_channels() + nic.closeAll() + nic.open(rtu_channel) -- send a scada management packet ---@param msg_type SCADA_MGMT_TYPE @@ -196,7 +192,7 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo m_pkt.make(msg_type, msg) s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) - modem.transmit(svr_channel, rtu_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, rtu_channel, s_pkt) self.seq_num = self.seq_num + 1 end @@ -240,17 +236,10 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo function public.send_modbus(m_pkt) local s_pkt = comms.scada_packet() s_pkt.make(self.sv_addr, self.seq_num, PROTOCOL.MODBUS_TCP, m_pkt.raw_sendable()) - modem.transmit(svr_channel, rtu_channel, s_pkt.raw_sendable()) + nic.transmit(svr_channel, rtu_channel, s_pkt) self.seq_num = self.seq_num + 1 end - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - _conf_channels() - end - -- unlink from the server ---@param rtu_state rtu_state function public.unlink(rtu_state) @@ -295,13 +284,10 @@ function rtu.comms(version, modem, rtu_channel, svr_channel, range, conn_watchdo ---@param distance integer ---@return modbus_frame|mgmt_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 s_pkt = comms.scada_packet() - -- parse packet as generic SCADA packet - s_pkt.receive(side, sender, reply_to, message, distance) - - if s_pkt.is_valid() then + if s_pkt then -- get as MODBUS TCP packet if s_pkt.protocol() == PROTOCOL.MODBUS_TCP then local m_pkt = comms.modbus_packet() diff --git a/rtu/startup.lua b/rtu/startup.lua index 85f3220..085a7b4 100644 --- a/rtu/startup.lua +++ b/rtu/startup.lua @@ -8,6 +8,7 @@ local comms = require("scada-common.comms") local crash = require("scada-common.crash") local log = require("scada-common.log") local mqueue = require("scada-common.mqueue") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local rsio = require("scada-common.rsio") local types = require("scada-common.types") @@ -28,7 +29,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 = "v1.3.7" +local RTU_VERSION = "v1.4.0" local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE @@ -81,6 +82,14 @@ local function main() -- mount connected devices ppm.mount_all() + -- get modem + local modem = ppm.get_wireless_modem() + if modem == nil then + println("boot> wireless modem not found") + log.fatal("no wireless modem on startup") + return + end + ---@class rtu_shared_memory local __shared_memory = { -- RTU system state flags @@ -91,16 +100,12 @@ local function main() shutdown = false }, - -- core RTU devices - rtu_dev = { - modem = ppm.get_wireless_modem() - }, - -- system objects rtu_sys = { + nic = network.nic(modem), rtu_comms = nil, ---@type rtu_comms conn_watchdog = nil, ---@type watchdog - units = {} ---@type table + units = {} }, -- message queues @@ -109,16 +114,8 @@ local function main() } } - local smem_dev = __shared_memory.rtu_dev local smem_sys = __shared_memory.rtu_sys - -- get modem - if smem_dev.modem == nil then - println("boot> wireless modem not found") - log.fatal("no wireless modem on startup") - return - end - databus.tx_hw_modem(true) ---------------------------------------- @@ -471,7 +468,7 @@ local function main() log.debug("startup> conn watchdog started") -- setup comms - smem_sys.rtu_comms = rtu.comms(RTU_VERSION, smem_dev.modem, config.RTU_CHANNEL, config.SVR_CHANNEL, + smem_sys.rtu_comms = rtu.comms(RTU_VERSION, smem_sys.nic, config.RTU_CHANNEL, config.SVR_CHANNEL, config.TRUSTED_RANGE, smem_sys.conn_watchdog) log.debug("startup> comms init") diff --git a/rtu/threads.lua b/rtu/threads.lua index 6d51dec..c27052d 100644 --- a/rtu/threads.lua +++ b/rtu/threads.lua @@ -46,7 +46,7 @@ function threads.thread__main(smem) -- load in from shared memory local rtu_state = smem.rtu_state - local rtu_dev = smem.rtu_dev + local nic = smem.rtu_sys.nic local rtu_comms = smem.rtu_sys.rtu_comms local conn_watchdog = smem.rtu_sys.conn_watchdog local units = smem.rtu_sys.units @@ -93,7 +93,9 @@ function threads.thread__main(smem) if type ~= nil and device ~= nil then if type == "modem" then -- we only care if this is our wireless modem - if device == rtu_dev.modem then + if nic.is_modem(device) then + nic.disconnect() + println_ts("wireless modem disconnected!") log.warning("comms modem disconnected!") @@ -127,8 +129,7 @@ function threads.thread__main(smem) if type == "modem" then if device.isWireless() then -- reconnected modem - rtu_dev.modem = device - rtu_comms.reconnect_modem(rtu_dev.modem) + nic.connect(device) println_ts("wireless modem reconnected.") log.info("comms modem reconnected") diff --git a/supervisor/session/svsessions.lua b/supervisor/session/svsessions.lua index a311ab9..075f090 100644 --- a/supervisor/session/svsessions.lua +++ b/supervisor/session/svsessions.lua @@ -34,7 +34,7 @@ local SESSION_TYPE = { svsessions.SESSION_TYPE = SESSION_TYPE local self = { - modem = nil, ---@type table|nil + nic = nil, ---@type nic|nil fp_ok = false, num_reactors = 0, facility = nil, ---@type facility|nil @@ -60,7 +60,7 @@ local function _sv_handle_outq(session) if msg ~= nil then if msg.qtype == mqueue.TYPE.PACKET then -- handle a packet to be sent - self.modem.transmit(session.r_chan, config.SVR_CHANNEL, msg.message.raw_sendable()) + self.nic.transmit(session.r_chan, config.SVR_CHANNEL, msg.message) elseif msg.qtype == mqueue.TYPE.COMMAND then -- handle instruction/notification elseif msg.qtype == mqueue.TYPE.DATA then @@ -135,7 +135,7 @@ local function _shutdown(session) while session.out_queue.ready() do local msg = session.out_queue.pop() if msg ~= nil and msg.qtype == mqueue.TYPE.PACKET then - self.modem.transmit(session.r_chan, config.SVR_CHANNEL, msg.message.raw_sendable()) + self.nic.transmit(session.r_chan, config.SVR_CHANNEL, msg.message) end end @@ -195,23 +195,17 @@ end -- PUBLIC FUNCTIONS -- -- initialize svsessions ----@param modem table modem device +---@param nic nic network interface device ---@param fp_ok boolean front panel active ---@param num_reactors integer number of reactors ---@param cooling_conf table cooling configuration definition -function svsessions.init(modem, fp_ok, num_reactors, cooling_conf) - self.modem = modem +function svsessions.init(nic, fp_ok, num_reactors, cooling_conf) + self.nic = nic self.fp_ok = fp_ok self.num_reactors = num_reactors self.facility = facility.new(num_reactors, cooling_conf) end --- re-link the modem ----@param modem table -function svsessions.relink_modem(modem) - self.modem = modem -end - -- find an RTU session by the computer ID ---@nodiscard ---@param source_addr integer diff --git a/supervisor/startup.lua b/supervisor/startup.lua index d3f2d81..8fb1897 100644 --- a/supervisor/startup.lua +++ b/supervisor/startup.lua @@ -7,6 +7,7 @@ require("/initenv").init_env() local crash = require("scada-common.crash") local comms = require("scada-common.comms") local log = require("scada-common.log") +local network = require("scada-common.network") local ppm = require("scada-common.ppm") local tcd = require("scada-common.tcd") local util = require("scada-common.util") @@ -20,7 +21,7 @@ local supervisor = require("supervisor.supervisor") local svsessions = require("supervisor.session.svsessions") -local SUPERVISOR_VERSION = "v0.17.10" +local SUPERVISOR_VERSION = "v0.18.0" local println = util.println local println_ts = util.println_ts @@ -115,8 +116,9 @@ local function main() println_ts = function (_) end end - -- start comms - local superv_comms = supervisor.comms(SUPERVISOR_VERSION, modem, fp_ok) + -- create network interface then setup comms + local nic = network.nic(modem) + local superv_comms = supervisor.comms(SUPERVISOR_VERSION, nic, fp_ok) -- base loop clock (6.67Hz, 3 ticks) local MAIN_CLOCK = 0.15 @@ -139,9 +141,12 @@ local function main() if type ~= nil and device ~= nil then if type == "modem" then -- we only care if this is our wireless modem - if device == modem then + if nic.is_modem(device) then + nic.disconnect() + println_ts("wireless modem disconnected!") log.warning("comms modem disconnected") + databus.tx_hw_modem(false) else log.warning("non-comms modem disconnected") @@ -153,10 +158,9 @@ local function main() if type ~= nil and device ~= nil then if type == "modem" then - if device.isWireless() then + if device.isWireless() and not nic.connected() then -- reconnected modem - modem = device - superv_comms.reconnect_modem(modem) + nic.connect(device) println_ts("wireless modem reconnected.") log.info("comms modem reconnected") diff --git a/supervisor/supervisor.lua b/supervisor/supervisor.lua index cfc52d8..b9c14ce 100644 --- a/supervisor/supervisor.lua +++ b/supervisor/supervisor.lua @@ -16,10 +16,10 @@ local SCADA_MGMT_TYPE = comms.SCADA_MGMT_TYPE -- supervisory controller communications ---@nodiscard ---@param _version string supervisor version ----@param modem table modem device +---@param nic nic network interface device ---@param fp_ok boolean if the front panel UI is running ---@diagnostic disable-next-line: unused-local -function supervisor.comms(_version, modem, fp_ok) +function supervisor.comms(_version, nic, fp_ok) -- print a log message to the terminal as long as the UI isn't running local function println(message) if not fp_ok then util.println_ts(message) end end @@ -43,15 +43,11 @@ function supervisor.comms(_version, modem, fp_ok) -- PRIVATE FUNCTIONS -- -- configure modem channels - local function _conf_channels() - modem.closeAll() - modem.open(svr_channel) - end - - _conf_channels() + nic.closeAll() + nic.open(svr_channel) -- pass modem, status, and config data to svsessions - svsessions.init(modem, fp_ok, num_reactors, cooling_conf) + svsessions.init(nic, fp_ok, num_reactors, cooling_conf) -- send an establish request response ---@param packet scada_packet @@ -64,7 +60,7 @@ function supervisor.comms(_version, modem, fp_ok) m_pkt.make(SCADA_MGMT_TYPE.ESTABLISH, { ack, data }) s_pkt.make(packet.src_addr(), packet.seq_num() + 1, PROTOCOL.SCADA_MGMT, m_pkt.raw_sendable()) - modem.transmit(packet.remote_channel(), svr_channel, s_pkt.raw_sendable()) + nic.transmit(packet.remote_channel(), svr_channel, s_pkt) self.last_est_acks[packet.src_addr()] = ack end @@ -73,14 +69,6 @@ function supervisor.comms(_version, modem, fp_ok) ---@class superv_comms local public = {} - -- reconnect a newly connected modem - ---@param new_modem table - function public.reconnect_modem(new_modem) - modem = new_modem - svsessions.relink_modem(new_modem) - _conf_channels() - end - -- parse a packet ---@nodiscard ---@param side string