mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
#537 close sessions on receiving an ESTABLISH packet to allow for retries
This commit is contained in:
parent
0ab2d57b66
commit
b3be2d4bfc
@ -520,7 +520,7 @@ function coordinator.comms(version, nic, sv_watchdog)
|
|||||||
if self.sv_r_seq_num == nil then
|
if self.sv_r_seq_num == nil then
|
||||||
self.sv_r_seq_num = packet.scada_frame.seq_num() + 1
|
self.sv_r_seq_num = packet.scada_frame.seq_num() + 1
|
||||||
elseif self.sv_r_seq_num ~= packet.scada_frame.seq_num() then
|
elseif self.sv_r_seq_num ~= packet.scada_frame.seq_num() then
|
||||||
log.warning("sequence out-of-order: last = " .. self.sv_r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
log.warning("sequence out-of-order: next = " .. self.sv_r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
||||||
return false
|
return false
|
||||||
elseif self.sv_linked and src_addr ~= self.sv_addr then
|
elseif self.sv_linked and src_addr ~= self.sv_addr then
|
||||||
log.debug("received packet from unknown computer " .. src_addr .. " while linked; channel in use by another system?")
|
log.debug("received packet from unknown computer " .. src_addr .. " while linked; channel in use by another system?")
|
||||||
|
@ -106,7 +106,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
|||||||
local function _handle_packet(pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
||||||
log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
log.warning(log_header .. "sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
||||||
@ -186,6 +186,10 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout)
|
|||||||
elseif pkt.type == MGMT_TYPE.CLOSE then
|
elseif pkt.type == MGMT_TYPE.CLOSE then
|
||||||
-- close the session
|
-- close the session
|
||||||
_close()
|
_close()
|
||||||
|
elseif pkt.type == MGMT_TYPE.ESTABLISH then
|
||||||
|
-- something is wrong, kill the session
|
||||||
|
_close()
|
||||||
|
log.warning(log_header .. "terminated session due to an unexpected ESTABLISH packet")
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
|
@ -19,7 +19,7 @@ local renderer = require("coordinator.renderer")
|
|||||||
local sounder = require("coordinator.sounder")
|
local sounder = require("coordinator.sounder")
|
||||||
local threads = require("coordinator.threads")
|
local threads = require("coordinator.threads")
|
||||||
|
|
||||||
local COORDINATOR_VERSION = "v1.5.5"
|
local COORDINATOR_VERSION = "v1.5.6"
|
||||||
|
|
||||||
local CHUNK_LOAD_DELAY_S = 30.0
|
local CHUNK_LOAD_DELAY_S = 30.0
|
||||||
|
|
||||||
|
@ -610,7 +610,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
|||||||
if self.api.r_seq_num == nil then
|
if self.api.r_seq_num == nil then
|
||||||
self.api.r_seq_num = packet.scada_frame.seq_num() + 1
|
self.api.r_seq_num = packet.scada_frame.seq_num() + 1
|
||||||
elseif self.api.r_seq_num ~= packet.scada_frame.seq_num() then
|
elseif self.api.r_seq_num ~= packet.scada_frame.seq_num() then
|
||||||
log.warning("sequence out-of-order (API): last = " .. self.api.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
log.warning("sequence out-of-order (API): next = " .. self.api.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
elseif self.api.linked and (src_addr ~= self.api.addr) then
|
elseif self.api.linked and (src_addr ~= self.api.addr) then
|
||||||
log.debug("received packet from unknown computer " .. src_addr .. " while linked (API expected " .. self.api.addr ..
|
log.debug("received packet from unknown computer " .. src_addr .. " while linked (API expected " .. self.api.addr ..
|
||||||
@ -697,24 +697,24 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
|||||||
else
|
else
|
||||||
log.debug("received coordinator establish allow without facility configuration")
|
log.debug("received coordinator establish allow without facility configuration")
|
||||||
end
|
end
|
||||||
elseif est_ack == ESTABLISH_ACK.DENY then
|
|
||||||
if self.api.last_est_ack ~= est_ack then
|
|
||||||
log.info("coordinator connection denied")
|
|
||||||
end
|
|
||||||
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
|
||||||
if self.api.last_est_ack ~= est_ack then
|
|
||||||
log.info("coordinator connection denied due to collision")
|
|
||||||
end
|
|
||||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
|
||||||
if self.api.last_est_ack ~= est_ack then
|
|
||||||
log.info("coordinator comms version mismatch")
|
|
||||||
end
|
|
||||||
elseif est_ack == ESTABLISH_ACK.BAD_API_VERSION then
|
|
||||||
if self.api.last_est_ack ~= est_ack then
|
|
||||||
log.info("coordinator api version mismatch")
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
log.debug("coordinator SCADA_MGMT establish packet reply unsupported")
|
if self.api.last_est_ack ~= est_ack then
|
||||||
|
if est_ack == ESTABLISH_ACK.DENY then
|
||||||
|
log.info("coordinator connection denied")
|
||||||
|
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
||||||
|
log.info("coordinator connection denied due to collision")
|
||||||
|
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||||
|
log.info("coordinator comms version mismatch")
|
||||||
|
elseif est_ack == ESTABLISH_ACK.BAD_API_VERSION then
|
||||||
|
log.info("coordinator api version mismatch")
|
||||||
|
else
|
||||||
|
log.debug("coordinator SCADA_MGMT establish packet reply unsupported")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- unlink
|
||||||
|
self.api.addr = comms.BROADCAST
|
||||||
|
self.api.linked = false
|
||||||
end
|
end
|
||||||
|
|
||||||
self.api.last_est_ack = est_ack
|
self.api.last_est_ack = est_ack
|
||||||
@ -730,7 +730,7 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
|||||||
if self.sv.r_seq_num == nil then
|
if self.sv.r_seq_num == nil then
|
||||||
self.sv.r_seq_num = packet.scada_frame.seq_num() + 1
|
self.sv.r_seq_num = packet.scada_frame.seq_num() + 1
|
||||||
elseif self.sv.r_seq_num ~= packet.scada_frame.seq_num() then
|
elseif self.sv.r_seq_num ~= packet.scada_frame.seq_num() then
|
||||||
log.warning("sequence out-of-order (SVR): last = " .. self.sv.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
log.warning("sequence out-of-order (SVR): next = " .. self.sv.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
elseif self.sv.linked and (src_addr ~= self.sv.addr) then
|
elseif self.sv.linked and (src_addr ~= self.sv.addr) then
|
||||||
log.debug("received packet from unknown computer " .. src_addr .. " while linked (SVR expected " .. self.sv.addr ..
|
log.debug("received packet from unknown computer " .. src_addr .. " while linked (SVR expected " .. self.sv.addr ..
|
||||||
@ -831,20 +831,22 @@ function pocket.comms(version, nic, sv_watchdog, api_watchdog, nav)
|
|||||||
else
|
else
|
||||||
iocontrol.report_link_state(LINK_STATE.SV_LINK_ONLY, self.sv.addr, nil)
|
iocontrol.report_link_state(LINK_STATE.SV_LINK_ONLY, self.sv.addr, nil)
|
||||||
end
|
end
|
||||||
elseif est_ack == ESTABLISH_ACK.DENY then
|
|
||||||
if self.sv.last_est_ack ~= est_ack then
|
|
||||||
log.info("supervisor connection denied")
|
|
||||||
end
|
|
||||||
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
|
||||||
if self.sv.last_est_ack ~= est_ack then
|
|
||||||
log.info("supervisor connection denied due to collision")
|
|
||||||
end
|
|
||||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
|
||||||
if self.sv.last_est_ack ~= est_ack then
|
|
||||||
log.info("supervisor comms version mismatch")
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
log.debug("supervisor SCADA_MGMT establish packet reply unsupported")
|
if self.sv.last_est_ack ~= est_ack then
|
||||||
|
if est_ack == ESTABLISH_ACK.DENY then
|
||||||
|
log.info("supervisor connection denied")
|
||||||
|
elseif est_ack == ESTABLISH_ACK.COLLISION then
|
||||||
|
log.info("supervisor connection denied due to collision")
|
||||||
|
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||||
|
log.info("supervisor comms version mismatch")
|
||||||
|
else
|
||||||
|
log.debug("supervisor SCADA_MGMT establish packet reply unsupported")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- unlink
|
||||||
|
self.sv.addr = comms.BROADCAST
|
||||||
|
self.sv.linked = false
|
||||||
end
|
end
|
||||||
|
|
||||||
self.sv.last_est_ack = est_ack
|
self.sv.last_est_ack = est_ack
|
||||||
|
@ -20,7 +20,7 @@ local pocket = require("pocket.pocket")
|
|||||||
local renderer = require("pocket.renderer")
|
local renderer = require("pocket.renderer")
|
||||||
local threads = require("pocket.threads")
|
local threads = require("pocket.threads")
|
||||||
|
|
||||||
local POCKET_VERSION = "v0.11.6-alpha"
|
local POCKET_VERSION = "v0.11.7-alpha"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
@ -833,7 +833,7 @@ function plc.comms(version, nic, reactor, rps, conn_watchdog)
|
|||||||
if self.r_seq_num == nil then
|
if self.r_seq_num == nil then
|
||||||
self.r_seq_num = packet.scada_frame.seq_num() + 1
|
self.r_seq_num = packet.scada_frame.seq_num() + 1
|
||||||
elseif self.r_seq_num ~= packet.scada_frame.seq_num() then
|
elseif self.r_seq_num ~= packet.scada_frame.seq_num() then
|
||||||
log.warning("sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
log.warning("sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
elseif self.linked and (src_addr ~= self.sv_addr) then
|
elseif self.linked and (src_addr ~= self.sv_addr) then
|
||||||
log.debug("received packet from unknown computer " .. src_addr .. " while linked (expected " .. self.sv_addr ..
|
log.debug("received packet from unknown computer " .. src_addr .. " while linked (expected " .. self.sv_addr ..
|
||||||
|
@ -18,7 +18,7 @@ local plc = require("reactor-plc.plc")
|
|||||||
local renderer = require("reactor-plc.renderer")
|
local renderer = require("reactor-plc.renderer")
|
||||||
local threads = require("reactor-plc.threads")
|
local threads = require("reactor-plc.threads")
|
||||||
|
|
||||||
local R_PLC_VERSION = "v1.8.5"
|
local R_PLC_VERSION = "v1.8.6"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
@ -444,7 +444,7 @@ function rtu.comms(version, nic, conn_watchdog)
|
|||||||
if self.r_seq_num == nil then
|
if self.r_seq_num == nil then
|
||||||
self.r_seq_num = packet.scada_frame.seq_num() + 1
|
self.r_seq_num = packet.scada_frame.seq_num() + 1
|
||||||
elseif self.r_seq_num ~= packet.scada_frame.seq_num() then
|
elseif self.r_seq_num ~= packet.scada_frame.seq_num() then
|
||||||
log.warning("sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
log.warning("sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. packet.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
elseif rtu_state.linked and (src_addr ~= self.sv_addr) then
|
elseif rtu_state.linked and (src_addr ~= self.sv_addr) then
|
||||||
log.debug("received packet from unknown computer " .. src_addr .. " while linked (expected " .. self.sv_addr ..
|
log.debug("received packet from unknown computer " .. src_addr .. " while linked (expected " .. self.sv_addr ..
|
||||||
|
@ -31,7 +31,7 @@ local sna_rtu = require("rtu.dev.sna_rtu")
|
|||||||
local sps_rtu = require("rtu.dev.sps_rtu")
|
local sps_rtu = require("rtu.dev.sps_rtu")
|
||||||
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
local turbinev_rtu = require("rtu.dev.turbinev_rtu")
|
||||||
|
|
||||||
local RTU_VERSION = "v1.10.5"
|
local RTU_VERSION = "v1.10.6"
|
||||||
|
|
||||||
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
local RTU_UNIT_TYPE = types.RTU_UNIT_TYPE
|
||||||
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
local RTU_UNIT_HW_STATE = databus.RTU_UNIT_HW_STATE
|
||||||
|
@ -53,7 +53,7 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
-- print a log message to the terminal as long as the UI isn't running
|
-- 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
|
local function println(message) if not fp_ok then util.println_ts(message) end end
|
||||||
|
|
||||||
local log_header = "crdn_session(" .. id .. "): "
|
local log_tag = "crdn_session(" .. id .. "): "
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
units = facility.get_units(),
|
units = facility.get_units(),
|
||||||
@ -184,7 +184,7 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
local function _handle_packet(pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
||||||
log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
log.warning(log_tag .. "sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
||||||
@ -205,7 +205,7 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
self.last_rtt = srv_now - srv_start
|
self.last_rtt = srv_now - srv_start
|
||||||
|
|
||||||
if self.last_rtt > 750 then
|
if self.last_rtt > 750 then
|
||||||
log.warning(log_header .. "COORD KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)")
|
log.warning(log_tag .. "COORD KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log.debug(log_header .. "COORD RTT = " .. self.last_rtt .. "ms")
|
-- log.debug(log_header .. "COORD RTT = " .. self.last_rtt .. "ms")
|
||||||
@ -213,13 +213,17 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
|
|
||||||
databus.tx_crd_rtt(self.last_rtt)
|
databus.tx_crd_rtt(self.last_rtt)
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA keep alive packet length mismatch")
|
log.debug(log_tag .. "SCADA keep alive packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == MGMT_TYPE.CLOSE then
|
elseif pkt.type == MGMT_TYPE.CLOSE then
|
||||||
-- close the session
|
-- close the session
|
||||||
_close()
|
_close()
|
||||||
|
elseif pkt.type == MGMT_TYPE.ESTABLISH then
|
||||||
|
-- something is wrong, kill the session
|
||||||
|
_close()
|
||||||
|
log.warning(log_tag .. "terminated session due to an unexpected ESTABLISH packet")
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
log.debug(log_tag .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_CRDN then
|
elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_CRDN then
|
||||||
---@cast pkt crdn_frame
|
---@cast pkt crdn_frame
|
||||||
@ -252,7 +256,7 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
|
|
||||||
_send(CRDN_TYPE.FAC_CMD, { cmd, table.unpack(facility.auto_start(config)) })
|
_send(CRDN_TYPE.FAC_CMD, { cmd, table.unpack(facility.auto_start(config)) })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN auto start (with configuration) packet length mismatch")
|
log.debug(log_tag .. "CRDN auto start (with configuration) packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif cmd == FAC_COMMAND.ACK_ALL_ALARMS then
|
elseif cmd == FAC_COMMAND.ACK_ALL_ALARMS then
|
||||||
facility.ack_all()
|
facility.ack_all()
|
||||||
@ -261,25 +265,25 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_waste_product(pkt.data[2]) })
|
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_waste_product(pkt.data[2]) })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN set waste mode packet length mismatch")
|
log.debug(log_tag .. "CRDN set waste mode packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
elseif cmd == FAC_COMMAND.SET_PU_FB then
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_pu_fallback(pkt.data[2]) })
|
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_pu_fallback(pkt.data[2]) })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN set pu fallback packet length mismatch")
|
log.debug(log_tag .. "CRDN set pu fallback packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
elseif cmd == FAC_COMMAND.SET_SPS_LP then
|
||||||
if pkt.length == 2 then
|
if pkt.length == 2 then
|
||||||
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_sps_low_power(pkt.data[2]) })
|
_send(CRDN_TYPE.FAC_CMD, { cmd, facility.set_sps_low_power(pkt.data[2]) })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN set sps low power packet length mismatch")
|
log.debug(log_tag .. "CRDN set sps low power packet length mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN facility command unknown")
|
log.debug(log_tag .. "CRDN facility command unknown")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN facility command packet length mismatch")
|
log.debug(log_tag .. "CRDN facility command packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == CRDN_TYPE.UNIT_BUILDS then
|
elseif pkt.type == CRDN_TYPE.UNIT_BUILDS then
|
||||||
-- acknowledgement to coordinator receiving builds
|
-- acknowledgement to coordinator receiving builds
|
||||||
@ -307,13 +311,13 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
if pkt.length == 3 then
|
if pkt.length == 3 then
|
||||||
out_queue.push_data(SV_Q_DATA.SET_BURN, data)
|
out_queue.push_data(SV_Q_DATA.SET_BURN, data)
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command burn rate missing option")
|
log.debug(log_tag .. "CRDN unit command burn rate missing option")
|
||||||
end
|
end
|
||||||
elseif cmd == UNIT_COMMAND.SET_WASTE then
|
elseif cmd == UNIT_COMMAND.SET_WASTE then
|
||||||
if (pkt.length == 3) and (type(pkt.data[3]) == "number") and (pkt.data[3] > 0) and (pkt.data[3] <= 4) then
|
if (pkt.length == 3) and (type(pkt.data[3]) == "number") and (pkt.data[3] > 0) and (pkt.data[3] <= 4) then
|
||||||
unit.set_waste_mode(pkt.data[3])
|
unit.set_waste_mode(pkt.data[3])
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command set waste missing/invalid option")
|
log.debug(log_tag .. "CRDN unit command set waste missing/invalid option")
|
||||||
end
|
end
|
||||||
elseif cmd == UNIT_COMMAND.ACK_ALL_ALARMS then
|
elseif cmd == UNIT_COMMAND.ACK_ALL_ALARMS then
|
||||||
unit.ack_all()
|
unit.ack_all()
|
||||||
@ -322,32 +326,32 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
if pkt.length == 3 then
|
if pkt.length == 3 then
|
||||||
unit.ack_alarm(pkt.data[3])
|
unit.ack_alarm(pkt.data[3])
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command ack alarm missing alarm id")
|
log.debug(log_tag .. "CRDN unit command ack alarm missing alarm id")
|
||||||
end
|
end
|
||||||
elseif cmd == UNIT_COMMAND.RESET_ALARM then
|
elseif cmd == UNIT_COMMAND.RESET_ALARM then
|
||||||
if pkt.length == 3 then
|
if pkt.length == 3 then
|
||||||
unit.reset_alarm(pkt.data[3])
|
unit.reset_alarm(pkt.data[3])
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command reset alarm missing alarm id")
|
log.debug(log_tag .. "CRDN unit command reset alarm missing alarm id")
|
||||||
end
|
end
|
||||||
elseif cmd == UNIT_COMMAND.SET_GROUP then
|
elseif cmd == UNIT_COMMAND.SET_GROUP then
|
||||||
if (pkt.length == 3) and (type(pkt.data[3]) == "number") and (pkt.data[3] >= 0) and (pkt.data[3] <= 4) then
|
if (pkt.length == 3) and (type(pkt.data[3]) == "number") and (pkt.data[3] >= 0) and (pkt.data[3] <= 4) then
|
||||||
facility.set_group(unit.get_id(), pkt.data[3])
|
facility.set_group(unit.get_id(), pkt.data[3])
|
||||||
_send(CRDN_TYPE.UNIT_CMD, { cmd, uid, pkt.data[3] })
|
_send(CRDN_TYPE.UNIT_CMD, { cmd, uid, pkt.data[3] })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command set group missing group id")
|
log.debug(log_tag .. "CRDN unit command set group missing group id")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command unknown")
|
log.debug(log_tag .. "CRDN unit command unknown")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command invalid")
|
log.debug(log_tag .. "CRDN unit command invalid")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "CRDN unit command packet length mismatch")
|
log.debug(log_tag .. "CRDN unit command packet length mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unexpected SCADA_CRDN packet type " .. pkt.type)
|
log.debug(log_tag .. "handler received unexpected SCADA_CRDN packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -370,7 +374,7 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
_close()
|
_close()
|
||||||
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
||||||
println("connection to coordinator " .. id .. " closed by server")
|
println("connection to coordinator " .. id .. " closed by server")
|
||||||
log.info(log_header .. "session closed by server")
|
log.info(log_tag .. "session closed by server")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
@ -437,14 +441,14 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
_send(CRDN_TYPE.FAC_BUILDS, { facility.get_build(cmd.val.type) })
|
_send(CRDN_TYPE.FAC_BUILDS, { facility.get_build(cmd.val.type) })
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.error(log_header .. "unsupported data command received in in_queue (this is a bug)", true)
|
log.error(log_tag .. "unsupported data command received in in_queue (this is a bug)", true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- max 100ms spent processing queue
|
-- max 100ms spent processing queue
|
||||||
if util.time() - handle_start > 100 then
|
if util.time() - handle_start > 100 then
|
||||||
log.warning(log_header .. "exceeded 100ms queue process limit")
|
log.warning(log_tag .. "exceeded 100ms queue process limit")
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -452,7 +456,7 @@ function coordinator.new_session(id, s_addr, i_seq_num, in_queue, out_queue, tim
|
|||||||
-- exit if connection was closed
|
-- exit if connection was closed
|
||||||
if not self.connected then
|
if not self.connected then
|
||||||
println("connection to coordinator closed by remote host")
|
println("connection to coordinator closed by remote host")
|
||||||
log.info(log_header .. "session closed by remote host")
|
log.info(log_tag .. "session closed by remote host")
|
||||||
return self.connected
|
return self.connected
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -58,7 +58,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
-- print a log message to the terminal as long as the UI isn't running
|
-- 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
|
local function println(message) if not fp_ok then util.println_ts(message) end end
|
||||||
|
|
||||||
local log_header = "plc_session(" .. id .. "): "
|
local log_tag = "plc_session(" .. id .. "): "
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
commanded_state = false,
|
commanded_state = false,
|
||||||
@ -184,7 +184,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.sDB.max_op_temp_H2O = max_burn * 2 * (JOULES_PER_MB * heat_cap ^ -1) + BASE_BOIL_TEMP
|
self.sDB.max_op_temp_H2O = max_burn * 2 * (JOULES_PER_MB * heat_cap ^ -1) + BASE_BOIL_TEMP
|
||||||
self.sDB.max_op_temp_Na = max_burn * (JOULES_PER_MB * heat_cap ^ -1) + BASE_BOIL_TEMP
|
self.sDB.max_op_temp_Na = max_burn * (JOULES_PER_MB * heat_cap ^ -1) + BASE_BOIL_TEMP
|
||||||
|
|
||||||
log.info(util.sprintf(log_header .. "computed maximum operational temperatures %.3fK (H2O) and %.3fK (Na)",
|
log.info(util.sprintf(log_tag .. "computed maximum operational temperatures %.3fK (H2O) and %.3fK (Na)",
|
||||||
self.sDB.max_op_temp_H2O, self.sDB.max_op_temp_Na))
|
self.sDB.max_op_temp_H2O, self.sDB.max_op_temp_Na))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -289,12 +289,12 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
_copy_status(pkt.data[7])
|
_copy_status(pkt.data[7])
|
||||||
self.received_status_cache = true
|
self.received_status_cache = true
|
||||||
else
|
else
|
||||||
log.error(log_header .. "RPLC status packet reactor data length mismatch")
|
log.error(log_tag .. "RPLC status packet reactor data length mismatch")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC status packet invalid")
|
log.debug(log_tag .. "RPLC status packet invalid")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
if pkt.length == 1 then
|
if pkt.length == 1 then
|
||||||
return pkt.data[1]
|
return pkt.data[1]
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC ACK length mismatch")
|
log.debug(log_tag .. "RPLC ACK length mismatch")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -351,7 +351,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
local function _handle_packet(pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
||||||
log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
log.warning(log_tag .. "sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
||||||
@ -362,7 +362,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
---@cast pkt rplc_frame
|
---@cast pkt rplc_frame
|
||||||
-- check reactor ID
|
-- check reactor ID
|
||||||
if pkt.id ~= reactor_id then
|
if pkt.id ~= reactor_id then
|
||||||
log.warning(log_header .. "discarding RPLC packet with ID not matching reactor ID: reactor " .. reactor_id .. " != " .. pkt.id)
|
log.warning(log_tag .. "discarding RPLC packet with ID not matching reactor ID: reactor " .. reactor_id .. " != " .. pkt.id)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
if pkt.length >= 5 then
|
if pkt.length >= 5 then
|
||||||
_handle_status(pkt)
|
_handle_status(pkt)
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC status packet length mismatch")
|
log.debug(log_tag .. "RPLC status packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.MEK_STRUCT then
|
elseif pkt.type == RPLC_TYPE.MEK_STRUCT then
|
||||||
-- received reactor structure, record it
|
-- received reactor structure, record it
|
||||||
@ -385,7 +385,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.received_struct = true
|
self.received_struct = true
|
||||||
out_queue.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, reactor_id)
|
out_queue.push_data(svqtypes.SV_Q_DATA.PLC_BUILD_CHANGED, reactor_id)
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC struct packet length mismatch")
|
log.debug(log_tag .. "RPLC struct packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.MEK_BURN_RATE then
|
elseif pkt.type == RPLC_TYPE.MEK_BURN_RATE then
|
||||||
-- burn rate acknowledgement
|
-- burn rate acknowledgement
|
||||||
@ -393,7 +393,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
if ack then
|
if ack then
|
||||||
self.acks.burn_rate = true
|
self.acks.burn_rate = true
|
||||||
elseif ack == false then
|
elseif ack == false then
|
||||||
log.debug(log_header .. "burn rate update failed!")
|
log.debug(log_tag .. "burn rate update failed!")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- send acknowledgement to coordinator
|
-- send acknowledgement to coordinator
|
||||||
@ -408,7 +408,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
if ack then
|
if ack then
|
||||||
self.sDB.control_state = true
|
self.sDB.control_state = true
|
||||||
elseif ack == false then
|
elseif ack == false then
|
||||||
log.debug(log_header .. "enable failed!")
|
log.debug(log_tag .. "enable failed!")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- send acknowledgement to coordinator
|
-- send acknowledgement to coordinator
|
||||||
@ -424,7 +424,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.acks.disable = true
|
self.acks.disable = true
|
||||||
self.sDB.control_state = false
|
self.sDB.control_state = false
|
||||||
elseif ack == false then
|
elseif ack == false then
|
||||||
log.debug(log_header .. "disable failed!")
|
log.debug(log_tag .. "disable failed!")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.RPS_SCRAM then
|
elseif pkt.type == RPLC_TYPE.RPS_SCRAM then
|
||||||
-- manual SCRAM acknowledgement
|
-- manual SCRAM acknowledgement
|
||||||
@ -433,7 +433,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.acks.scram = true
|
self.acks.scram = true
|
||||||
self.sDB.control_state = false
|
self.sDB.control_state = false
|
||||||
elseif ack == false then
|
elseif ack == false then
|
||||||
log.debug(log_header .. "manual SCRAM failed!")
|
log.debug(log_tag .. "manual SCRAM failed!")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- send acknowledgement to coordinator
|
-- send acknowledgement to coordinator
|
||||||
@ -449,7 +449,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.acks.ascram = true
|
self.acks.ascram = true
|
||||||
self.sDB.control_state = false
|
self.sDB.control_state = false
|
||||||
elseif ack == false then
|
elseif ack == false then
|
||||||
log.debug(log_header .. " automatic SCRAM failed!")
|
log.debug(log_tag .. " automatic SCRAM failed!")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.RPS_STATUS then
|
elseif pkt.type == RPLC_TYPE.RPS_STATUS then
|
||||||
-- RPS status packet received, copy data
|
-- RPS status packet received, copy data
|
||||||
@ -459,10 +459,10 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
-- copied in RPS status data OK
|
-- copied in RPS status data OK
|
||||||
else
|
else
|
||||||
-- error copying RPS status data
|
-- error copying RPS status data
|
||||||
log.error(log_header .. "failed to parse RPS status packet data")
|
log.error(log_tag .. "failed to parse RPS status packet data")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC RPS status packet length mismatch")
|
log.debug(log_tag .. "RPLC RPS status packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.RPS_ALARM then
|
elseif pkt.type == RPLC_TYPE.RPS_ALARM then
|
||||||
-- RPS alarm
|
-- RPS alarm
|
||||||
@ -472,10 +472,10 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
-- copied in RPS status data OK
|
-- copied in RPS status data OK
|
||||||
else
|
else
|
||||||
-- error copying RPS status data
|
-- error copying RPS status data
|
||||||
log.error(log_header .. "failed to parse RPS alarm status data")
|
log.error(log_tag .. "failed to parse RPS alarm status data")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC RPS alarm packet length mismatch")
|
log.debug(log_tag .. "RPLC RPS alarm packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.RPS_RESET then
|
elseif pkt.type == RPLC_TYPE.RPS_RESET then
|
||||||
-- RPS reset acknowledgement
|
-- RPS reset acknowledgement
|
||||||
@ -485,7 +485,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.sDB.rps_tripped = false
|
self.sDB.rps_tripped = false
|
||||||
self.sDB.rps_trip_cause = "ok"
|
self.sDB.rps_trip_cause = "ok"
|
||||||
elseif ack == false then
|
elseif ack == false then
|
||||||
log.debug(log_header .. "RPS reset failed")
|
log.debug(log_tag .. "RPS reset failed")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- send acknowledgement to coordinator
|
-- send acknowledgement to coordinator
|
||||||
@ -498,7 +498,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
-- RPS auto control reset acknowledgement
|
-- RPS auto control reset acknowledgement
|
||||||
local ack = _get_ack(pkt)
|
local ack = _get_ack(pkt)
|
||||||
if not ack then
|
if not ack then
|
||||||
log.debug(log_header .. "RPS auto reset failed")
|
log.debug(log_tag .. "RPS auto reset failed")
|
||||||
end
|
end
|
||||||
elseif pkt.type == RPLC_TYPE.AUTO_BURN_RATE then
|
elseif pkt.type == RPLC_TYPE.AUTO_BURN_RATE then
|
||||||
if pkt.length == 1 then
|
if pkt.length == 1 then
|
||||||
@ -506,18 +506,18 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
|
|
||||||
if ack == PLC_AUTO_ACK.FAIL then
|
if ack == PLC_AUTO_ACK.FAIL then
|
||||||
self.acks.burn_rate = false
|
self.acks.burn_rate = false
|
||||||
log.debug(log_header .. "RPLC automatic burn rate set fail")
|
log.debug(log_tag .. "RPLC automatic burn rate set fail")
|
||||||
elseif ack == PLC_AUTO_ACK.DIRECT_SET_OK or ack == PLC_AUTO_ACK.RAMP_SET_OK or ack == PLC_AUTO_ACK.ZERO_DIS_OK then
|
elseif ack == PLC_AUTO_ACK.DIRECT_SET_OK or ack == PLC_AUTO_ACK.RAMP_SET_OK or ack == PLC_AUTO_ACK.ZERO_DIS_OK then
|
||||||
self.acks.burn_rate = true
|
self.acks.burn_rate = true
|
||||||
else
|
else
|
||||||
self.acks.burn_rate = false
|
self.acks.burn_rate = false
|
||||||
log.debug(log_header .. "RPLC automatic burn rate ack unknown")
|
log.debug(log_tag .. "RPLC automatic burn rate ack unknown")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "RPLC automatic burn rate ack packet length mismatch")
|
log.debug(log_tag .. "RPLC automatic burn rate ack packet length mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported RPLC packet type " .. pkt.type)
|
log.debug(log_tag .. "handler received unsupported RPLC packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then
|
elseif pkt.scada_frame.protocol() == PROTOCOL.SCADA_MGMT then
|
||||||
---@cast pkt mgmt_frame
|
---@cast pkt mgmt_frame
|
||||||
@ -530,7 +530,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
self.last_rtt = srv_now - srv_start
|
self.last_rtt = srv_now - srv_start
|
||||||
|
|
||||||
if self.last_rtt > 750 then
|
if self.last_rtt > 750 then
|
||||||
log.warning(log_header .. "PLC KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)")
|
log.warning(log_tag .. "PLC KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log.debug(log_header .. "PLC RTT = " .. self.last_rtt .. "ms")
|
-- log.debug(log_header .. "PLC RTT = " .. self.last_rtt .. "ms")
|
||||||
@ -538,13 +538,17 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
|
|
||||||
databus.tx_plc_rtt(reactor_id, self.last_rtt)
|
databus.tx_plc_rtt(reactor_id, self.last_rtt)
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA keep alive packet length mismatch")
|
log.debug(log_tag .. "SCADA keep alive packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == MGMT_TYPE.CLOSE then
|
elseif pkt.type == MGMT_TYPE.CLOSE then
|
||||||
-- close the session
|
-- close the session
|
||||||
_close()
|
_close()
|
||||||
|
elseif pkt.type == MGMT_TYPE.ESTABLISH then
|
||||||
|
-- something is wrong, kill the session
|
||||||
|
_close()
|
||||||
|
log.warning(log_tag .. "terminated session due to an unexpected ESTABLISH packet")
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
log.debug(log_tag .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -639,7 +643,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
_close()
|
_close()
|
||||||
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
||||||
println("connection to reactor " .. reactor_id .. " PLC closed by server")
|
println("connection to reactor " .. reactor_id .. " PLC closed by server")
|
||||||
log.info(log_header .. "session closed by server")
|
log.info(log_tag .. "session closed by server")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
@ -696,7 +700,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
_send(RPLC_TYPE.RPS_AUTO_RESET, {})
|
_send(RPLC_TYPE.RPS_AUTO_RESET, {})
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.error(log_header .. "unsupported command received in in_queue (this is a bug)", true)
|
log.error(log_tag .. "unsupported command received in in_queue (this is a bug)", true)
|
||||||
end
|
end
|
||||||
elseif message.qtype == mqueue.TYPE.DATA then
|
elseif message.qtype == mqueue.TYPE.DATA then
|
||||||
-- instruction with body
|
-- instruction with body
|
||||||
@ -745,14 +749,14 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.error(log_header .. "unsupported data command received in in_queue (this is a bug)", true)
|
log.error(log_tag .. "unsupported data command received in in_queue (this is a bug)", true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- max 100ms spent processing queue
|
-- max 100ms spent processing queue
|
||||||
if util.time() - handle_start > 100 then
|
if util.time() - handle_start > 100 then
|
||||||
log.warning(log_header .. "exceeded 100ms queue process limit")
|
log.warning(log_tag .. "exceeded 100ms queue process limit")
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -760,7 +764,7 @@ function plc.new_session(id, s_addr, i_seq_num, reactor_id, in_queue, out_queue,
|
|||||||
-- exit if connection was closed
|
-- exit if connection was closed
|
||||||
if not self.connected then
|
if not self.connected then
|
||||||
println("connection to reactor " .. reactor_id .. " PLC closed by remote host")
|
println("connection to reactor " .. reactor_id .. " PLC closed by remote host")
|
||||||
log.info(log_header .. "session closed by remote host")
|
log.info(log_tag .. "session closed by remote host")
|
||||||
return self.connected
|
return self.connected
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,7 +40,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
-- print a log message to the terminal as long as the UI isn't running
|
-- 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
|
local function println(message) if not fp_ok then util.println_ts(message) end end
|
||||||
|
|
||||||
local log_header = "pdg_session(" .. id .. "): "
|
local log_tag = "pdg_session(" .. id .. "): "
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
-- connection properties
|
-- connection properties
|
||||||
@ -95,7 +95,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
local function _handle_packet(pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
||||||
log.warning(log_header .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
log.warning(log_tag .. "sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
||||||
@ -116,7 +116,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
self.last_rtt = srv_now - srv_start
|
self.last_rtt = srv_now - srv_start
|
||||||
|
|
||||||
if self.last_rtt > 750 then
|
if self.last_rtt > 750 then
|
||||||
log.warning(log_header .. "PDG KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)")
|
log.warning(log_tag .. "PDG KEEP_ALIVE round trip time > 750ms (" .. self.last_rtt .. "ms)")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- log.debug(log_header .. "PDG RTT = " .. self.last_rtt .. "ms")
|
-- log.debug(log_header .. "PDG RTT = " .. self.last_rtt .. "ms")
|
||||||
@ -124,11 +124,15 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
|
|
||||||
databus.tx_pdg_rtt(id, self.last_rtt)
|
databus.tx_pdg_rtt(id, self.last_rtt)
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA keep alive packet length mismatch")
|
log.debug(log_tag .. "SCADA keep alive packet length mismatch")
|
||||||
end
|
end
|
||||||
elseif pkt.type == MGMT_TYPE.CLOSE then
|
elseif pkt.type == MGMT_TYPE.CLOSE then
|
||||||
-- close the session
|
-- close the session
|
||||||
_close()
|
_close()
|
||||||
|
elseif pkt.type == MGMT_TYPE.ESTABLISH then
|
||||||
|
-- something is wrong, kill the session
|
||||||
|
_close()
|
||||||
|
log.warning(log_tag .. "terminated session due to an unexpected ESTABLISH packet")
|
||||||
elseif pkt.type == MGMT_TYPE.DIAG_TONE_GET then
|
elseif pkt.type == MGMT_TYPE.DIAG_TONE_GET then
|
||||||
-- get the state of alarm tones
|
-- get the state of alarm tones
|
||||||
_send_mgmt(MGMT_TYPE.DIAG_TONE_GET, facility.get_alarm_tones())
|
_send_mgmt(MGMT_TYPE.DIAG_TONE_GET, facility.get_alarm_tones())
|
||||||
@ -145,13 +149,13 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
local allow_testing, test_tone_states = facility.diag_set_test_tone(pkt.data[1], pkt.data[2])
|
local allow_testing, test_tone_states = facility.diag_set_test_tone(pkt.data[1], pkt.data[2])
|
||||||
_send_mgmt(MGMT_TYPE.DIAG_TONE_SET, { allow_testing, test_tone_states })
|
_send_mgmt(MGMT_TYPE.DIAG_TONE_SET, { allow_testing, test_tone_states })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA diag tone set packet data type mismatch")
|
log.debug(log_tag .. "SCADA diag tone set packet data type mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA diag tone set packet length mismatch")
|
log.debug(log_tag .. "SCADA diag tone set packet length mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "DIAG_TONE_SET is blocked without HMAC for security")
|
log.debug(log_tag .. "DIAG_TONE_SET is blocked without HMAC for security")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not valid then _send_mgmt(MGMT_TYPE.DIAG_TONE_SET, { false }) end
|
if not valid then _send_mgmt(MGMT_TYPE.DIAG_TONE_SET, { false }) end
|
||||||
@ -168,18 +172,18 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
local allow_testing, test_alarm_states = facility.diag_set_test_alarm(pkt.data[1], pkt.data[2])
|
local allow_testing, test_alarm_states = facility.diag_set_test_alarm(pkt.data[1], pkt.data[2])
|
||||||
_send_mgmt(MGMT_TYPE.DIAG_ALARM_SET, { allow_testing, test_alarm_states })
|
_send_mgmt(MGMT_TYPE.DIAG_ALARM_SET, { allow_testing, test_alarm_states })
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA diag alarm set packet data type mismatch")
|
log.debug(log_tag .. "SCADA diag alarm set packet data type mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "SCADA diag alarm set packet length mismatch")
|
log.debug(log_tag .. "SCADA diag alarm set packet length mismatch")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "DIAG_ALARM_SET is blocked without HMAC for security")
|
log.debug(log_tag .. "DIAG_ALARM_SET is blocked without HMAC for security")
|
||||||
end
|
end
|
||||||
|
|
||||||
if not valid then _send_mgmt(MGMT_TYPE.DIAG_ALARM_SET, { false }) end
|
if not valid then _send_mgmt(MGMT_TYPE.DIAG_ALARM_SET, { false }) end
|
||||||
else
|
else
|
||||||
log.debug(log_header .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
log.debug(log_tag .. "handler received unsupported SCADA_MGMT packet type " .. pkt.type)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -205,7 +209,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
_close()
|
_close()
|
||||||
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
_send_mgmt(MGMT_TYPE.CLOSE, {})
|
||||||
println("connection to pocket diag session " .. id .. " closed by server")
|
println("connection to pocket diag session " .. id .. " closed by server")
|
||||||
log.info(log_header .. "session closed by server")
|
log.info(log_tag .. "session closed by server")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
@ -236,7 +240,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
|
|
||||||
-- max 100ms spent processing queue
|
-- max 100ms spent processing queue
|
||||||
if util.time() - handle_start > 100 then
|
if util.time() - handle_start > 100 then
|
||||||
log.warning(log_header .. "exceeded 100ms queue process limit")
|
log.warning(log_tag .. "exceeded 100ms queue process limit")
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -244,7 +248,7 @@ function pocket.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout,
|
|||||||
-- exit if connection was closed
|
-- exit if connection was closed
|
||||||
if not self.connected then
|
if not self.connected then
|
||||||
println("connection to pocket diag session " .. id .. " closed by remote host")
|
println("connection to pocket diag session " .. id .. " closed by remote host")
|
||||||
log.info(log_header .. "session closed by remote host")
|
log.info(log_tag .. "session closed by remote host")
|
||||||
return self.connected
|
return self.connected
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -242,7 +242,7 @@ function rtu.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout, ad
|
|||||||
local function _handle_packet(pkt)
|
local function _handle_packet(pkt)
|
||||||
-- check sequence number
|
-- check sequence number
|
||||||
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
if self.r_seq_num ~= pkt.scada_frame.seq_num() then
|
||||||
log.warning(log_tag .. "sequence out-of-order: last = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
log.warning(log_tag .. "sequence out-of-order: next = " .. self.r_seq_num .. ", new = " .. pkt.scada_frame.seq_num())
|
||||||
return
|
return
|
||||||
else
|
else
|
||||||
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
self.r_seq_num = pkt.scada_frame.seq_num() + 1
|
||||||
@ -283,6 +283,10 @@ function rtu.new_session(id, s_addr, i_seq_num, in_queue, out_queue, timeout, ad
|
|||||||
elseif pkt.type == MGMT_TYPE.CLOSE then
|
elseif pkt.type == MGMT_TYPE.CLOSE then
|
||||||
-- close the session
|
-- close the session
|
||||||
_close()
|
_close()
|
||||||
|
elseif pkt.type == MGMT_TYPE.ESTABLISH then
|
||||||
|
-- something is wrong, kill the session
|
||||||
|
_close()
|
||||||
|
log.warning(log_tag .. "terminated session due to an unexpected ESTABLISH packet")
|
||||||
elseif pkt.type == MGMT_TYPE.RTU_ADVERT then
|
elseif pkt.type == MGMT_TYPE.RTU_ADVERT then
|
||||||
-- RTU advertisement
|
-- RTU advertisement
|
||||||
log.debug(log_tag .. "received updated advertisement")
|
log.debug(log_tag .. "received updated advertisement")
|
||||||
|
@ -22,7 +22,7 @@ local supervisor = require("supervisor.supervisor")
|
|||||||
|
|
||||||
local svsessions = require("supervisor.session.svsessions")
|
local svsessions = require("supervisor.session.svsessions")
|
||||||
|
|
||||||
local SUPERVISOR_VERSION = "v1.5.0"
|
local SUPERVISOR_VERSION = "v1.5.1"
|
||||||
|
|
||||||
local println = util.println
|
local println = util.println
|
||||||
local println_ts = util.println_ts
|
local println_ts = util.println_ts
|
||||||
|
Loading…
Reference in New Issue
Block a user