#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 self = {
|
||||
checking_wl = true,
|
||||
wd_modem = nil, ---@type Modem|nil
|
||||
wl_modem = nil, ---@type Modem|nil
|
||||
|
||||
nic = nil, ---@type nic
|
||||
net_listen = false,
|
||||
sv_addr = comms.BROADCAST,
|
||||
sv_seq_num = util.time_ms() * 10,
|
||||
|
||||
self_check_pass = true,
|
||||
|
||||
self_check_wireless = true,
|
||||
|
||||
settings = nil, ---@type rtu_config
|
||||
|
||||
run_test_btn = nil, ---@type PushButton
|
||||
@@ -59,10 +63,9 @@ local function send_sv(msg_type, msg)
|
||||
local pkt = comms.mgmt_packet()
|
||||
|
||||
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.sv_seq_num = self.sv_seq_num + 1
|
||||
end
|
||||
|
||||
-- handle an establish message from the supervisor
|
||||
@@ -78,10 +81,7 @@ local function handle_packet(packet)
|
||||
local est_ack = packet.data[1]
|
||||
|
||||
if est_ack== ESTABLISH_ACK.ALLOW then
|
||||
self.self_check_msg(nil, true, "")
|
||||
self.sv_addr = packet.scada_frame.src_addr()
|
||||
send_sv(MGMT_TYPE.CLOSE, {})
|
||||
if self.self_check_pass then check_complete() end
|
||||
-- OK
|
||||
elseif est_ack == ESTABLISH_ACK.DENY then
|
||||
error_msg = "error: supervisor connection denied"
|
||||
elseif est_ack == ESTABLISH_ACK.BAD_VERSION then
|
||||
@@ -98,18 +98,20 @@ local function handle_packet(packet)
|
||||
end
|
||||
|
||||
self.net_listen = false
|
||||
self.run_test_btn.enable()
|
||||
|
||||
if error_msg then
|
||||
self.self_check_msg(nil, false, error_msg)
|
||||
else
|
||||
self.self_check_msg(nil, true, "")
|
||||
end
|
||||
|
||||
util.push_event("conn_test_complete", error_msg == nil)
|
||||
end
|
||||
|
||||
-- handle supervisor connection failure
|
||||
local function handle_timeout()
|
||||
self.net_listen = false
|
||||
self.run_test_btn.enable()
|
||||
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")
|
||||
util.push_event("conn_test_complete", false)
|
||||
end
|
||||
|
||||
|
||||
@@ -129,10 +131,18 @@ local function self_check()
|
||||
self.self_check_pass = true
|
||||
|
||||
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)
|
||||
|
||||
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")
|
||||
|
||||
-- check redstone configurations
|
||||
@@ -211,27 +221,37 @@ local function self_check()
|
||||
end
|
||||
end
|
||||
|
||||
if valid_cfg and modem then
|
||||
self.self_check_msg("> check supervisor connection...")
|
||||
if valid_cfg then
|
||||
self.checking_wl = true
|
||||
|
||||
-- init mac as needed
|
||||
if cfg.AuthKey and string.len(cfg.AuthKey) >= 8 then
|
||||
network.init_mac(cfg.AuthKey)
|
||||
if cfg.WirelessModem and self.wl_modem then
|
||||
self.self_check_msg("> check wireless supervisor connection...")
|
||||
|
||||
-- init mac as needed
|
||||
if cfg.AuthKey and string.len(cfg.AuthKey) >= 8 then
|
||||
network.init_mac(cfg.AuthKey)
|
||||
else
|
||||
network.deinit_mac()
|
||||
end
|
||||
|
||||
comms.set_trusted_range(cfg.TrustedRange)
|
||||
|
||||
self.nic = network.nic(self.wl_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)
|
||||
elseif cfg.WiredModem and self.wd_modem then
|
||||
-- skip to wired
|
||||
util.push_event("conn_test_complete", true)
|
||||
else
|
||||
network.deinit_mac()
|
||||
self.self_check_msg("> no modem, can't test supervisor connection", false)
|
||||
end
|
||||
|
||||
self.nic = network.nic(modem)
|
||||
|
||||
self.nic.closeAll()
|
||||
self.nic.open(cfg.RTU_Channel)
|
||||
|
||||
self.sv_addr = comms.BROADCAST
|
||||
self.net_listen = true
|
||||
|
||||
send_sv(MGMT_TYPE.ESTABLISH, { comms.version, "0.0.0", DEVICE_TYPE.RTU, {} })
|
||||
|
||||
tcd.dispatch_unique(8, handle_timeout)
|
||||
else
|
||||
if self.self_check_pass then check_complete() end
|
||||
self.run_test_btn.enable()
|
||||
@@ -315,4 +335,44 @@ function check.receive_sv(side, sender, reply_to, message, distance)
|
||||
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
|
||||
|
||||
@@ -359,6 +359,8 @@ function configurator.configure(ask_config)
|
||||
display.handle_paste(param1)
|
||||
elseif event == "modem_message" then
|
||||
check.receive_sv(param1, param2, param3, param4, param5)
|
||||
elseif event == "conn_test_complete" then
|
||||
check.conn_test_callback(param1)
|
||||
elseif event == "peripheral_detach" then
|
||||
---@diagnostic disable-next-line: discard-returns
|
||||
ppm.handle_unmount(param1)
|
||||
|
||||
@@ -282,25 +282,31 @@ function supervisor.comms(_version, fp_ok, facility)
|
||||
-- drop if not listening
|
||||
elseif comms_v ~= comms.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
|
||||
|
||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.BAD_VERSION)
|
||||
elseif dev_type == DEVICE_TYPE.RTU then
|
||||
if packet.length == 4 then
|
||||
-- this is an RTU advertisement for a new session
|
||||
local rtu_advert = packet.data[4]
|
||||
local s_id = svsessions.establish_rtu_session(nic, src_addr, i_seq_num, rtu_advert, firmware_v)
|
||||
if firmware_v ~= comms.CONN_TEST_FWV then
|
||||
-- this is an RTU advertisement for a new session
|
||||
local rtu_advert = packet.data[4]
|
||||
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"))
|
||||
log.info(util.c("RTU_GW_ESTABLISH: RTU_GW (",firmware_v, ") [@", src_addr, "] connected with session ID ", s_id, " on ", nic.phy_name()))
|
||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.ALLOW)
|
||||
println(util.c("RTU (", firmware_v, ") [@", src_addr, "] \xbb connected"))
|
||||
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)
|
||||
else
|
||||
-- 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("RTU_GW_ESTABLISH: packet length mismatch")
|
||||
log.debug(util.c("RTU_GW_ESTABLISH: [@", src_addr, "] packet length mismatch"))
|
||||
_send_establish(nic, packet.scada_frame, ESTABLISH_ACK.DENY)
|
||||
end
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user