mirror of
https://github.com/MikaylaFischler/cc-mek-scada.git
synced 2024-08-30 18:22:34 +00:00
supervisor PLC session closing, re-requesting status cache if missing
This commit is contained in:
parent
fe5059dd51
commit
e253a7b4ff
@ -7,6 +7,11 @@ local PROTOCOLS = comms.PROTOCOLS
|
|||||||
local RPLC_TYPES = comms.RPLC_TYPES
|
local RPLC_TYPES = comms.RPLC_TYPES
|
||||||
local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES
|
local SCADA_MGMT_TYPES = comms.SCADA_MGMT_TYPES
|
||||||
|
|
||||||
|
local print = util.print
|
||||||
|
local println = util.println
|
||||||
|
local print_ts = util.print_ts
|
||||||
|
local println_ts = util.println_ts
|
||||||
|
|
||||||
-- retry time constants in ms
|
-- retry time constants in ms
|
||||||
local INITIAL_WAIT = 1500
|
local INITIAL_WAIT = 1500
|
||||||
local RETRY_PERIOD = 1000
|
local RETRY_PERIOD = 1000
|
||||||
@ -38,6 +43,7 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
r_seq_num = nil,
|
r_seq_num = nil,
|
||||||
connected = true,
|
connected = true,
|
||||||
received_struct = false,
|
received_struct = false,
|
||||||
|
received_status_cache = false,
|
||||||
plc_conn_watchdog = util.new_watchdog(3),
|
plc_conn_watchdog = util.new_watchdog(3),
|
||||||
last_rtt = 0,
|
last_rtt = 0,
|
||||||
-- periodic messages
|
-- periodic messages
|
||||||
@ -48,6 +54,7 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
-- when to next retry one of these requests
|
-- when to next retry one of these requests
|
||||||
retry_times = {
|
retry_times = {
|
||||||
struct_req = (util.time() + 500),
|
struct_req = (util.time() + 500),
|
||||||
|
status_req = (util.time() + 500),
|
||||||
scram_req = 0,
|
scram_req = 0,
|
||||||
enable_req = 0,
|
enable_req = 0,
|
||||||
burn_rate_req = 0,
|
burn_rate_req = 0,
|
||||||
@ -257,6 +264,7 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
local status = pcall(_copy_status, pkt.data[6])
|
local status = pcall(_copy_status, pkt.data[6])
|
||||||
if status then
|
if status then
|
||||||
-- copied in status data OK
|
-- copied in status data OK
|
||||||
|
self.received_status_cache = true
|
||||||
else
|
else
|
||||||
-- error copying status data
|
-- error copying status data
|
||||||
log._error(log_header .. "failed to parse status packet data")
|
log._error(log_header .. "failed to parse status packet data")
|
||||||
@ -365,18 +373,6 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
-- get the session database
|
-- get the session database
|
||||||
local get_db = function () return self.sDB end
|
local get_db = function () return self.sDB end
|
||||||
|
|
||||||
-- close the connection
|
|
||||||
local close = function ()
|
|
||||||
self.plc_conn_watchdog.cancel()
|
|
||||||
self.connected = false
|
|
||||||
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
|
||||||
end
|
|
||||||
|
|
||||||
-- check if a timer matches this session's watchdog
|
|
||||||
local check_wd = function (timer)
|
|
||||||
return timer == self.plc_conn_watchdog.get_timer()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- get the reactor structure
|
-- get the reactor structure
|
||||||
local get_struct = function ()
|
local get_struct = function ()
|
||||||
if self.received_struct then
|
if self.received_struct then
|
||||||
@ -386,6 +382,29 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- get the reactor structure
|
||||||
|
local get_status = function ()
|
||||||
|
if self.received_status_cache then
|
||||||
|
return self.sDB.mek_status
|
||||||
|
else
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- check if a timer matches this session's watchdog
|
||||||
|
local check_wd = function (timer)
|
||||||
|
return timer == self.plc_conn_watchdog.get_timer()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- close the connection
|
||||||
|
local close = function ()
|
||||||
|
self.plc_conn_watchdog.cancel()
|
||||||
|
self.connected = false
|
||||||
|
_send_mgmt(SCADA_MGMT_TYPES.CLOSE, {})
|
||||||
|
println("connection to reactor " .. self.for_reactor .. " PLC closed by server")
|
||||||
|
log._info(log_header .. "session closed by server")
|
||||||
|
end
|
||||||
|
|
||||||
-- iterate the session
|
-- iterate the session
|
||||||
local iterate = function ()
|
local iterate = function ()
|
||||||
if self.connected then
|
if self.connected then
|
||||||
@ -442,6 +461,8 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
|
|
||||||
-- exit if connection was closed
|
-- exit if connection was closed
|
||||||
if not self.connected then
|
if not self.connected then
|
||||||
|
self.plc_conn_watchdog.cancel()
|
||||||
|
println("connection to reactor " .. self.for_reactor .. " PLC closed by remote host")
|
||||||
log._info(log_header .. "session closed by remote host")
|
log._info(log_header .. "session closed by remote host")
|
||||||
return self.connected
|
return self.connected
|
||||||
end
|
end
|
||||||
@ -479,6 +500,15 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- status cache request retry
|
||||||
|
|
||||||
|
if not self.received_status_cache then
|
||||||
|
if rtimes.status_req - util.time() <= 0 then
|
||||||
|
_send(RPLC_TYPES.MEK_STATUS, {})
|
||||||
|
rtimes.status_req = util.time() + RETRY_PERIOD
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- SCRAM request retry
|
-- SCRAM request retry
|
||||||
|
|
||||||
if not self.acks.scram then
|
if not self.acks.scram then
|
||||||
@ -522,9 +552,10 @@ function new_session(id, for_reactor, in_queue, out_queue)
|
|||||||
return {
|
return {
|
||||||
get_id = get_id,
|
get_id = get_id,
|
||||||
get_db = get_db,
|
get_db = get_db,
|
||||||
close = close,
|
|
||||||
check_wd = check_wd,
|
|
||||||
get_struct = get_struct,
|
get_struct = get_struct,
|
||||||
|
get_status = get_status,
|
||||||
|
check_wd = check_wd,
|
||||||
|
close = close,
|
||||||
iterate = iterate
|
iterate = iterate
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -91,6 +91,22 @@ function establish_plc_session(local_port, remote_port, for_reactor)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- cleanly close a session
|
||||||
|
local function _shutdown(session)
|
||||||
|
session.open = false
|
||||||
|
session.instance.close()
|
||||||
|
|
||||||
|
-- send packets in out queue (namely the close packet)
|
||||||
|
while session.out_queue.ready() do
|
||||||
|
local msg = session.out_queue.pop()
|
||||||
|
if msg.qtype == mqueue.TYPE.PACKET then
|
||||||
|
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
log._debug("closed session " .. session.instance.get_id() .. " on remote port " .. session.r_port)
|
||||||
|
end
|
||||||
|
|
||||||
-- check if a watchdog timer event matches that of one of the provided sessions
|
-- check if a watchdog timer event matches that of one of the provided sessions
|
||||||
local function _check_watchdogs(sessions, timer_event)
|
local function _check_watchdogs(sessions, timer_event)
|
||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
@ -98,9 +114,8 @@ local function _check_watchdogs(sessions, timer_event)
|
|||||||
if session.open then
|
if session.open then
|
||||||
local triggered = session.instance.check_wd(timer_event)
|
local triggered = session.instance.check_wd(timer_event)
|
||||||
if triggered then
|
if triggered then
|
||||||
log._debug("watchdog closing session " .. session.instance.get_id() .. " on remote port " .. session.r_port)
|
log._debug("watchdog closing session " .. session.instance.get_id() .. " on remote port " .. session.r_port .. "...")
|
||||||
session.open = false
|
_shutdown(session)
|
||||||
session.instance.close()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -134,7 +149,6 @@ local function _iterate(sessions)
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
session.open = false
|
session.open = false
|
||||||
session.instance.close()
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -189,18 +203,7 @@ local function _close(sessions)
|
|||||||
for i = 1, #sessions do
|
for i = 1, #sessions do
|
||||||
local session = sessions[i]
|
local session = sessions[i]
|
||||||
if session.open then
|
if session.open then
|
||||||
session.open = false
|
_shutdown(session)
|
||||||
session.instance.close()
|
|
||||||
|
|
||||||
-- send packets in out queue (namely the close packet)
|
|
||||||
while session.out_queue.ready() do
|
|
||||||
local msg = session.out_queue.pop()
|
|
||||||
if msg.qtype == mqueue.TYPE.PACKET then
|
|
||||||
self.modem.transmit(session.r_port, session.l_port, msg.message.raw_sendable())
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
log._debug("closed session " .. session.instance.get_id() .. " on remote port " .. session.r_port)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -18,7 +18,7 @@ os.loadAPI("session/svsessions.lua")
|
|||||||
|
|
||||||
os.loadAPI("supervisor.lua")
|
os.loadAPI("supervisor.lua")
|
||||||
|
|
||||||
local SUPERVISOR_VERSION = "alpha-v0.1.12"
|
local SUPERVISOR_VERSION = "alpha-v0.2.0"
|
||||||
|
|
||||||
local print = util.print
|
local print = util.print
|
||||||
local println = util.println
|
local println = util.println
|
||||||
|
Loading…
Reference in New Issue
Block a user