2022-01-13 15:23:56 +00:00
|
|
|
--
|
2023-04-12 16:40:13 +00:00
|
|
|
-- SCADA System Access on a Pocket Computer
|
2022-05-14 17:32:42 +00:00
|
|
|
--
|
|
|
|
|
2024-06-14 00:34:39 +00:00
|
|
|
---@diagnostic disable-next-line: undefined-global
|
2024-06-14 16:20:53 +00:00
|
|
|
local _is_pocket_env = pocket or periphemu -- luacheck: ignore pocket
|
2024-06-14 00:34:39 +00:00
|
|
|
|
2022-05-14 17:32:42 +00:00
|
|
|
require("/initenv").init_env()
|
2023-02-19 17:54:02 +00:00
|
|
|
|
2023-07-29 22:16:59 +00:00
|
|
|
local crash = require("scada-common.crash")
|
|
|
|
local log = require("scada-common.log")
|
2024-06-13 16:45:44 +00:00
|
|
|
local mqueue = require("scada-common.mqueue")
|
2023-07-29 22:16:59 +00:00
|
|
|
local network = require("scada-common.network")
|
|
|
|
local ppm = require("scada-common.ppm")
|
|
|
|
local util = require("scada-common.util")
|
2023-02-19 17:54:02 +00:00
|
|
|
|
2024-02-19 19:07:26 +00:00
|
|
|
local configure = require("pocket.configure")
|
2023-07-29 22:16:59 +00:00
|
|
|
local iocontrol = require("pocket.iocontrol")
|
|
|
|
local pocket = require("pocket.pocket")
|
|
|
|
local renderer = require("pocket.renderer")
|
2024-06-13 16:45:44 +00:00
|
|
|
local threads = require("pocket.threads")
|
2023-04-12 16:40:13 +00:00
|
|
|
|
2024-06-29 16:29:28 +00:00
|
|
|
local POCKET_VERSION = "v0.10.2-alpha"
|
2023-02-19 17:54:02 +00:00
|
|
|
|
|
|
|
local println = util.println
|
|
|
|
local println_ts = util.println_ts
|
|
|
|
|
2024-06-14 00:34:39 +00:00
|
|
|
-- check environment (allows Pocket or CraftOS-PC)
|
|
|
|
if not _is_pocket_env then
|
|
|
|
println("You can only use this application on a pocket computer.")
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2023-04-12 16:40:13 +00:00
|
|
|
----------------------------------------
|
2024-02-19 19:07:26 +00:00
|
|
|
-- get configuration
|
2023-04-12 16:40:13 +00:00
|
|
|
----------------------------------------
|
|
|
|
|
2024-02-19 19:07:26 +00:00
|
|
|
if not pocket.load_config() then
|
|
|
|
-- try to reconfigure (user action)
|
|
|
|
local success, error = configure.configure(true)
|
|
|
|
if success then
|
2024-03-06 01:17:52 +00:00
|
|
|
if not pocket.load_config() then
|
|
|
|
println("failed to load a valid configuration, please reconfigure")
|
|
|
|
return
|
|
|
|
end
|
2024-02-19 19:07:26 +00:00
|
|
|
else
|
2024-03-06 01:17:52 +00:00
|
|
|
println("configuration error: " .. error)
|
|
|
|
return
|
2024-02-19 19:07:26 +00:00
|
|
|
end
|
|
|
|
end
|
2023-04-12 16:40:13 +00:00
|
|
|
|
2024-02-19 19:07:26 +00:00
|
|
|
local config = pocket.config
|
2023-04-12 16:40:13 +00:00
|
|
|
|
|
|
|
----------------------------------------
|
|
|
|
-- log init
|
|
|
|
----------------------------------------
|
|
|
|
|
2024-02-19 19:07:26 +00:00
|
|
|
log.init(config.LogPath, config.LogMode, config.LogDebug)
|
2023-04-12 16:40:13 +00:00
|
|
|
|
|
|
|
log.info("========================================")
|
|
|
|
log.info("BOOTING pocket.startup " .. POCKET_VERSION)
|
|
|
|
log.info("========================================")
|
|
|
|
|
|
|
|
crash.set_env("pocket", POCKET_VERSION)
|
2024-03-23 04:49:19 +00:00
|
|
|
crash.dbg_log_env()
|
2023-04-12 16:40:13 +00:00
|
|
|
|
|
|
|
----------------------------------------
|
|
|
|
-- main application
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
local function main()
|
|
|
|
----------------------------------------
|
|
|
|
-- system startup
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
-- mount connected devices
|
|
|
|
ppm.mount_all()
|
|
|
|
|
2024-04-13 20:18:27 +00:00
|
|
|
-- record version for GUI
|
|
|
|
iocontrol.get_db().version = POCKET_VERSION
|
|
|
|
|
2024-06-13 16:45:44 +00:00
|
|
|
----------------------------------------
|
|
|
|
-- memory allocation
|
|
|
|
----------------------------------------
|
|
|
|
|
|
|
|
-- shared memory across threads
|
|
|
|
---@class pkt_shared_memory
|
|
|
|
local __shared_memory = {
|
|
|
|
-- pocket system state flags
|
|
|
|
---@class pkt_state
|
|
|
|
pkt_state = {
|
|
|
|
ui_ok = false,
|
2024-06-14 21:42:03 +00:00
|
|
|
ui_error = nil,
|
2024-06-13 16:45:44 +00:00
|
|
|
shutdown = false
|
|
|
|
},
|
|
|
|
|
|
|
|
-- core pocket devices
|
|
|
|
pkt_dev = {
|
|
|
|
modem = ppm.get_wireless_modem()
|
|
|
|
},
|
|
|
|
|
|
|
|
-- system objects
|
|
|
|
pkt_sys = {
|
|
|
|
nic = nil, ---@type nic
|
|
|
|
pocket_comms = nil, ---@type pocket_comms
|
|
|
|
sv_wd = nil, ---@type watchdog
|
2024-06-14 01:43:56 +00:00
|
|
|
api_wd = nil, ---@type watchdog
|
|
|
|
nav = nil ---@type pocket_nav
|
2024-06-13 16:45:44 +00:00
|
|
|
},
|
|
|
|
|
|
|
|
-- message queues
|
|
|
|
q = {
|
|
|
|
mq_render = mqueue.new()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
local smem_dev = __shared_memory.pkt_dev
|
|
|
|
local smem_sys = __shared_memory.pkt_sys
|
|
|
|
|
|
|
|
local pkt_state = __shared_memory.pkt_state
|
|
|
|
|
2023-04-12 16:40:13 +00:00
|
|
|
----------------------------------------
|
2024-06-14 01:43:56 +00:00
|
|
|
-- setup system
|
2023-04-12 16:40:13 +00:00
|
|
|
----------------------------------------
|
|
|
|
|
2024-06-27 23:57:43 +00:00
|
|
|
smem_sys.nav = pocket.init_nav(__shared_memory)
|
2024-06-14 16:10:04 +00:00
|
|
|
|
2023-06-25 18:00:18 +00:00
|
|
|
-- message authentication init
|
2024-02-19 19:07:26 +00:00
|
|
|
if type(config.AuthKey) == "string" and string.len(config.AuthKey) > 0 then
|
|
|
|
network.init_mac(config.AuthKey)
|
2023-06-25 18:00:18 +00:00
|
|
|
end
|
|
|
|
|
2023-07-29 22:16:59 +00:00
|
|
|
iocontrol.report_link_state(iocontrol.LINK_STATE.UNLINKED)
|
2023-04-18 17:47:06 +00:00
|
|
|
|
2023-04-12 16:40:13 +00:00
|
|
|
-- get the communications modem
|
2024-06-13 16:45:44 +00:00
|
|
|
if smem_dev.modem == nil then
|
2023-04-12 16:40:13 +00:00
|
|
|
println("startup> wireless modem not found: please craft the pocket computer with a wireless modem")
|
2023-04-16 23:50:16 +00:00
|
|
|
log.fatal("startup> no wireless modem on startup")
|
2023-04-12 16:40:13 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2023-04-16 23:50:16 +00:00
|
|
|
-- create connection watchdogs
|
2024-06-13 16:45:44 +00:00
|
|
|
smem_sys.sv_wd = util.new_watchdog(config.ConnTimeout)
|
|
|
|
smem_sys.sv_wd.cancel()
|
|
|
|
smem_sys.api_wd = util.new_watchdog(config.ConnTimeout)
|
|
|
|
smem_sys.api_wd.cancel()
|
2023-04-16 23:50:16 +00:00
|
|
|
log.debug("startup> conn watchdogs created")
|
2023-04-12 16:40:13 +00:00
|
|
|
|
2023-06-25 16:59:38 +00:00
|
|
|
-- create network interface then setup comms
|
2024-06-13 16:45:44 +00:00
|
|
|
smem_sys.nic = network.nic(smem_dev.modem)
|
2024-06-14 16:10:04 +00:00
|
|
|
smem_sys.pocket_comms = pocket.comms(POCKET_VERSION, smem_sys.nic, smem_sys.sv_wd, smem_sys.api_wd, smem_sys.nav)
|
2023-04-16 23:50:16 +00:00
|
|
|
log.debug("startup> comms init")
|
2023-04-12 16:40:13 +00:00
|
|
|
|
2024-06-14 16:10:04 +00:00
|
|
|
-- init I/O control
|
2024-06-14 01:43:56 +00:00
|
|
|
iocontrol.init_core(smem_sys.pocket_comms, smem_sys.nav)
|
2023-07-29 22:16:59 +00:00
|
|
|
|
2023-04-12 16:40:13 +00:00
|
|
|
----------------------------------------
|
|
|
|
-- start the UI
|
|
|
|
----------------------------------------
|
|
|
|
|
2024-06-13 16:45:44 +00:00
|
|
|
local ui_message
|
|
|
|
pkt_state.ui_ok, ui_message = renderer.try_start_ui()
|
|
|
|
if not pkt_state.ui_ok then
|
|
|
|
println(util.c("UI error: ", ui_message))
|
|
|
|
log.error(util.c("startup> GUI render failed with error ", ui_message))
|
2023-04-12 16:40:13 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
----------------------------------------
|
2024-06-13 16:45:44 +00:00
|
|
|
-- start system
|
2023-04-12 16:40:13 +00:00
|
|
|
----------------------------------------
|
|
|
|
|
2024-06-13 16:45:44 +00:00
|
|
|
if pkt_state.ui_ok then
|
|
|
|
-- init threads
|
|
|
|
local main_thread = threads.thread__main(__shared_memory)
|
|
|
|
local render_thread = threads.thread__render(__shared_memory)
|
|
|
|
|
|
|
|
log.info("startup> completed")
|
|
|
|
|
|
|
|
-- run threads
|
|
|
|
parallel.waitForAll(main_thread.p_exec, render_thread.p_exec)
|
2023-04-12 16:40:13 +00:00
|
|
|
|
2023-04-30 03:48:50 +00:00
|
|
|
renderer.close_ui()
|
2024-06-14 21:42:03 +00:00
|
|
|
|
|
|
|
if not pkt_state.ui_ok then
|
2024-06-14 21:49:43 +00:00
|
|
|
println(util.c("UI crashed with error: ", pkt_state.ui_error))
|
2024-06-14 21:42:03 +00:00
|
|
|
end
|
2024-06-13 16:45:44 +00:00
|
|
|
else
|
|
|
|
println_ts("UI creation failed")
|
2023-04-30 03:48:50 +00:00
|
|
|
end
|
2023-04-12 16:40:13 +00:00
|
|
|
|
|
|
|
println_ts("exited")
|
|
|
|
log.info("exited")
|
|
|
|
end
|
|
|
|
|
|
|
|
if not xpcall(main, crash.handler) then
|
|
|
|
pcall(renderer.close_ui)
|
|
|
|
crash.exit()
|
2023-04-21 01:01:41 +00:00
|
|
|
else
|
|
|
|
log.close()
|
2023-04-12 16:40:13 +00:00
|
|
|
end
|