#642 RTU gateway connection test
This commit is contained in:
@@ -27,13 +27,17 @@ local ESTABLISH_ACK = comms.ESTABLISH_ACK
|
|||||||
local MGMT_TYPE = comms.MGMT_TYPE
|
local MGMT_TYPE = comms.MGMT_TYPE
|
||||||
|
|
||||||
local self = {
|
local self = {
|
||||||
|
checking_wl = true,
|
||||||
|
wd_modem = nil, ---@type Modem|nil
|
||||||
|
wl_modem = nil, ---@type Modem|nil
|
||||||
|
|
||||||
nic = nil, ---@type nic
|
nic = nil, ---@type nic
|
||||||
net_listen = false,
|
net_listen = false,
|
||||||
sv_addr = comms.BROADCAST,
|
|
||||||
sv_seq_num = util.time_ms() * 10,
|
|
||||||
|
|
||||||
self_check_pass = true,
|
self_check_pass = true,
|
||||||
|
|
||||||
|
self_check_wireless = true,
|
||||||
|
|
||||||
settings = nil, ---@type rtu_config
|
settings = nil, ---@type rtu_config
|
||||||
|
|
||||||
run_test_btn = nil, ---@type PushButton
|
run_test_btn = nil, ---@type PushButton
|
||||||
@@ -59,10 +63,9 @@ local function send_sv(msg_type, msg)
|
|||||||
local pkt = comms.mgmt_packet()
|
local pkt = comms.mgmt_packet()
|
||||||
|
|
||||||
pkt.make(msg_type, msg)
|
pkt.make(msg_type, msg)
|
||||||
s_pkt.make(self.sv_addr, self.sv_seq_num, PROTOCOL.SCADA_MGMT, pkt.raw_sendable())
|
s_pkt.make(comms.BROADCAST, util.time_ms() * 10, PROTOCOL.SCADA_MGMT, pkt.raw_sendable())
|
||||||
|
|
||||||
self.nic.transmit(self.settings.SVR_Channel, self.settings.RTU_Channel, s_pkt)
|
self.nic.transmit(self.settings.SVR_Channel, self.settings.RTU_Channel, s_pkt)
|
||||||
self.sv_seq_num = self.sv_seq_num + 1
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle an establish message from the supervisor
|
-- handle an establish message from the supervisor
|
||||||
@@ -78,10 +81,7 @@ local function handle_packet(packet)
|
|||||||
local est_ack = packet.data[1]
|
local est_ack = packet.data[1]
|
||||||
|
|
||||||
if est_ack== ESTABLISH_ACK.ALLOW then
|
if est_ack== ESTABLISH_ACK.ALLOW then
|
||||||
self.self_check_msg(nil, true, "")
|
-- OK
|
||||||
self.sv_addr = packet.scada_frame.src_addr()
|
|
||||||
send_sv(MGMT_TYPE.CLOSE, {})
|
|
||||||
if self.self_check_pass then check_complete() end
|
|
||||||
elseif est_ack == ESTABLISH_ACK.DENY then
|
elseif est_ack == ESTABLISH_ACK.DENY then
|
||||||
error_msg = "error: supervisor connection denied"
|
error_msg = "error: supervisor connection denied"
|
||||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||||
@@ -98,18 +98,20 @@ local function handle_packet(packet)
|
|||||||
end
|
end
|
||||||
|
|
||||||
self.net_listen = false
|
self.net_listen = false
|
||||||
self.run_test_btn.enable()
|
|
||||||
|
|
||||||
if error_msg then
|
if error_msg then
|
||||||
self.self_check_msg(nil, false, error_msg)
|
self.self_check_msg(nil, false, error_msg)
|
||||||
|
else
|
||||||
|
self.self_check_msg(nil, true, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
util.push_event("conn_test_complete", error_msg == nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- handle supervisor connection failure
|
-- handle supervisor connection failure
|
||||||
local function handle_timeout()
|
local function handle_timeout()
|
||||||
self.net_listen = false
|
self.net_listen = false
|
||||||
self.run_test_btn.enable()
|
util.push_event("conn_test_complete", false)
|
||||||
self.self_check_msg(nil, false, "make sure your supervisor is running, your channels are correct, trusted ranges are set properly (if enabled), facility keys match (if set), and if you are using wireless modems rather than ender modems, that your devices are close together in the same dimension")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
@@ -129,10 +131,18 @@ local function self_check()
|
|||||||
self.self_check_pass = true
|
self.self_check_pass = true
|
||||||
|
|
||||||
local cfg = self.settings
|
local cfg = self.settings
|
||||||
local modem = ppm.get_wireless_modem()
|
self.wd_modem = ppm.get_modem(cfg.WiredModem)
|
||||||
|
self.wl_modem = ppm.get_wireless_modem()
|
||||||
local valid_cfg = rtu.validate_config(cfg)
|
local valid_cfg = rtu.validate_config(cfg)
|
||||||
|
|
||||||
self.self_check_msg("> check wireless/ender modem connected...", modem ~= nil, "you must connect an ender or wireless modem to the RTU gateway")
|
if cfg.WiredModem then
|
||||||
|
self.self_check_msg("> check wired comms modem connected...", self.wd_modem, "please connect the wired comms modem " .. cfg.WiredModem)
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfg.WirelessModem then
|
||||||
|
self.self_check_msg("> check wireless/ender modem connected...", self.wl_modem, "please connect an ender or wireless modem for wireless comms")
|
||||||
|
end
|
||||||
|
|
||||||
self.self_check_msg("> check gateway configuration...", valid_cfg, "go through Configure Gateway and apply settings to set any missing settings and repair any corrupted ones")
|
self.self_check_msg("> check gateway configuration...", valid_cfg, "go through Configure Gateway and apply settings to set any missing settings and repair any corrupted ones")
|
||||||
|
|
||||||
-- check redstone configurations
|
-- check redstone configurations
|
||||||
@@ -211,8 +221,11 @@ local function self_check()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if valid_cfg and modem then
|
if valid_cfg then
|
||||||
self.self_check_msg("> check supervisor connection...")
|
self.checking_wl = true
|
||||||
|
|
||||||
|
if cfg.WirelessModem and self.wl_modem then
|
||||||
|
self.self_check_msg("> check wireless supervisor connection...")
|
||||||
|
|
||||||
-- init mac as needed
|
-- init mac as needed
|
||||||
if cfg.AuthKey and string.len(cfg.AuthKey) >= 8 then
|
if cfg.AuthKey and string.len(cfg.AuthKey) >= 8 then
|
||||||
@@ -221,17 +234,24 @@ local function self_check()
|
|||||||
network.deinit_mac()
|
network.deinit_mac()
|
||||||
end
|
end
|
||||||
|
|
||||||
self.nic = network.nic(modem)
|
comms.set_trusted_range(cfg.TrustedRange)
|
||||||
|
|
||||||
|
self.nic = network.nic(self.wl_modem)
|
||||||
|
|
||||||
self.nic.closeAll()
|
self.nic.closeAll()
|
||||||
self.nic.open(cfg.RTU_Channel)
|
self.nic.open(cfg.RTU_Channel)
|
||||||
|
|
||||||
self.sv_addr = comms.BROADCAST
|
|
||||||
self.net_listen = true
|
self.net_listen = true
|
||||||
|
|
||||||
send_sv(MGMT_TYPE.ESTABLISH, { comms.version, "0.0.0", DEVICE_TYPE.RTU, {} })
|
send_sv(MGMT_TYPE.ESTABLISH, { comms.version, comms.CONN_TEST_FWV, DEVICE_TYPE.RTU, {} })
|
||||||
|
|
||||||
tcd.dispatch_unique(8, handle_timeout)
|
tcd.dispatch_unique(8, handle_timeout)
|
||||||
|
elseif cfg.WiredModem and self.wd_modem then
|
||||||
|
-- skip to wired
|
||||||
|
util.push_event("conn_test_complete", true)
|
||||||
|
else
|
||||||
|
self.self_check_msg("> no modem, can't test supervisor connection", false)
|
||||||
|
end
|
||||||
else
|
else
|
||||||
if self.self_check_pass then check_complete() end
|
if self.self_check_pass then check_complete() end
|
||||||
self.run_test_btn.enable()
|
self.run_test_btn.enable()
|
||||||
@@ -315,4 +335,44 @@ function check.receive_sv(side, sender, reply_to, message, distance)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- handle completed connection tests
|
||||||
|
---@param pass boolean
|
||||||
|
function check.conn_test_callback(pass)
|
||||||
|
local cfg = self.settings
|
||||||
|
|
||||||
|
if self.checking_wl then
|
||||||
|
if not pass then
|
||||||
|
self.self_check_msg(nil, false, "make sure your supervisor is running, listening on the wireless interface, your channels are correct, trusted ranges are set properly (if enabled), facility keys match (if set), and if you are using wireless modems rather than ender modems, that your devices are close together in the same dimension")
|
||||||
|
end
|
||||||
|
|
||||||
|
if cfg.WiredModem and self.wd_modem then
|
||||||
|
self.checking_wl = false
|
||||||
|
self.self_check_msg("> check wired supervisor connection...")
|
||||||
|
|
||||||
|
comms.set_trusted_range(0)
|
||||||
|
|
||||||
|
self.nic = network.nic(self.wd_modem)
|
||||||
|
|
||||||
|
self.nic.closeAll()
|
||||||
|
self.nic.open(cfg.RTU_Channel)
|
||||||
|
|
||||||
|
self.net_listen = true
|
||||||
|
|
||||||
|
send_sv(MGMT_TYPE.ESTABLISH, { comms.version, comms.CONN_TEST_FWV, DEVICE_TYPE.RTU, {} })
|
||||||
|
|
||||||
|
tcd.dispatch_unique(8, handle_timeout)
|
||||||
|
else
|
||||||
|
if self.self_check_pass then check_complete() end
|
||||||
|
self.run_test_btn.enable()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
if not pass then
|
||||||
|
self.self_check_msg(nil, false, "make sure your supervisor is running, listening on the wired interface, the wire is intact, and your channels are correct")
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.self_check_pass then check_complete() end
|
||||||
|
self.run_test_btn.enable()
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
return check
|
return check
|
||||||
|
|||||||
@@ -359,6 +359,8 @@ function configurator.configure(ask_config)
|
|||||||
display.handle_paste(param1)
|
display.handle_paste(param1)
|
||||||
elseif event == "modem_message" then
|
elseif event == "modem_message" then
|
||||||
check.receive_sv(param1, param2, param3, param4, param5)
|
check.receive_sv(param1, param2, param3, param4, param5)
|
||||||
|
elseif event == "conn_test_complete" then
|
||||||
|
check.conn_test_callback(param1)
|
||||||
elseif event == "peripheral_detach" then
|
elseif event == "peripheral_detach" then
|
||||||
---@diagnostic disable-next-line: discard-returns
|
---@diagnostic disable-next-line: discard-returns
|
||||||
ppm.handle_unmount(param1)
|
ppm.handle_unmount(param1)
|
||||||
|
|||||||
@@ -282,25 +282,31 @@ function supervisor.comms(_version, fp_ok, facility)
|
|||||||
-- drop if not listening
|
-- drop if not listening
|
||||||
elseif comms_v ~= comms.version then
|
elseif comms_v ~= comms.version then
|
||||||
if last_ack ~= ESTABLISH_ACK.BAD_VERSION then
|
if last_ack ~= ESTABLISH_ACK.BAD_VERSION then
|
||||||
log.info(util.c("dropping RTU_GW establish packet with incorrect comms version v", comms_v, " (expected v", comms.version, ")"))
|
log.info(util.c("RTU_GW_ESTABLISH: [@", src_addr, "] dropping RTU_GW establish packet with incorrect comms version v", comms_v, " (expected v", comms.version, ")"))
|
||||||
end
|
end
|
||||||
|
|
||||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.BAD_VERSION)
|
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.BAD_VERSION)
|
||||||
elseif dev_type == DEVICE_TYPE.RTU then
|
elseif dev_type == DEVICE_TYPE.RTU then
|
||||||
if packet.length == 4 then
|
if packet.length == 4 then
|
||||||
|
if firmware_v ~= comms.CONN_TEST_FWV then
|
||||||
-- this is an RTU advertisement for a new session
|
-- this is an RTU advertisement for a new session
|
||||||
local rtu_advert = packet.data[4]
|
local rtu_advert = packet.data[4]
|
||||||
local s_id = svsessions.establish_rtu_session(nic, src_addr, i_seq_num, rtu_advert, firmware_v)
|
local s_id = svsessions.establish_rtu_session(nic, src_addr, i_seq_num, rtu_advert, firmware_v)
|
||||||
|
|
||||||
println(util.c("RTU (", firmware_v, ") [@", src_addr, "] \xbb connected"))
|
println(util.c("RTU (", firmware_v, ") [@", src_addr, "] \xbb connected"))
|
||||||
log.info(util.c("RTU_GW_ESTABLISH: RTU_GW (",firmware_v, ") [@", src_addr, "] connected with session ID ", s_id, " on ", nic.phy_name()))
|
log.info(util.c("RTU_GW_ESTABLISH: [@", src_addr, "] RTU_GW (",firmware_v, ") connected with session ID ", s_id, " on ", nic.phy_name()))
|
||||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.ALLOW)
|
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.ALLOW)
|
||||||
else
|
else
|
||||||
log.debug("RTU_GW_ESTABLISH: packet length mismatch")
|
-- valid, but this was just a test
|
||||||
|
log.info(util.c("RTU_GW_ESTABLISH: RTU_GW [@", src_addr, "] sending connection test success response on ", nic.phy_name()))
|
||||||
|
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.ALLOW)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
log.debug(util.c("RTU_GW_ESTABLISH: [@", src_addr, "] packet length mismatch"))
|
||||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.DENY)
|
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.DENY)
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
log.debug(util.c("illegal establish packet for device ", dev_type, " on RTU channel"))
|
log.debug(util.c("RTU_GW_ESTABLISH: [@", src_addr, "] illegal establish packet for device ", dev_type, " on RTU channel"))
|
||||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.DENY)
|
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.DENY)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user