aredn/files/usr/local/bin/aredn_init

236 lines
6.6 KiB
Lua
Executable File

#! /usr/bin/lua
--[[
Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2021, 2024 Tim Wilkinson
See Contributors file for additional contributors
This does the low-level setup of the node, upgrades new setup values,
and repairs any configuration damage it detects.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation version 3 of the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Additional Terms:
Additional use restrictions exist on the AREDN® trademark and logo.
See AREDNLicense.txt for more info.
Attributions to the AREDN® Project must be retained in the source code.
If importing this code into a new or existing project attribution
to the AREDN® project must be added to the source code.
You must not misrepresent the origin of the material contained within.
Modified versions must be modified to attribute to the original source
and be marked in reasonable ways as differentiate it from the original
version
--]]
require("aredn.utils")
require("aredn.info")
require("aredn.hardware")
require("uci")
require("iwinfo")
local name = aredn.info.get_nvram("node")
local mac2 = aredn.info.get_nvram("mac2")
local dtdmac = aredn.info.get_nvram("dtdmac")
local wifi_mac = aredn.info.get_nvram("wifimac")
local cfg = {}
local wifi_enable
--
-- Setup the nvram
--
if wifi_mac == "" or mac2 == "" then
local hardware_mac
if aredn.hardware.has_wifi() then
local phy
for i = 1,5
do
for _, wlan in ipairs({ "wlan0", "wlan1" })
do
local f = io.popen("iwinfo " .. wlan .. " info")
if f then
for line in f:lines()
do
phy = line:match("PHY name:%s*([a-z0-4]+)")
if phy then
break
end
end
f:close()
end
if phy then
break
end
end
if phy then
for line in io.lines("/sys/class/ieee80211/" .. phy .. "/macaddress")
do
local m = line:match("(%w%w:%w%w:%w%w:%w%w:%w%w:%w%w)")
if m then
hardware_mac = m
break
end
end
end
if hardware_mac then
break
end
sleep(5)
end
else
-- Disable wifi
wifi_enable = 0
end
if not hardware_mac then
-- Fallback, create a random mac address instead
hardware_mac = capture([[hexdump -n5 -e'/5 "02" 5/1 ":%02X"' /dev/urandom]]):match("^(%S+)")
end
if wifi_mac == "" then
aredn.info.set_nvram("wifimac", hardware_mac)
end
if mac2 == "" then
local a, b, c = hardware_mac:match("%w%w:%w%w:%w%w:(%w%w):(%w%w):(%w%w)")
mac2 = string.format("%d.%d.%d", tonumber(a, 16), tonumber(b, 16), tonumber(c, 16))
aredn.info.set_nvram("mac2", mac2)
end
end
if dtdmac == "" then
local a, b, c
for i = 1,5
do
a, b, c = aredn.hardware.get_interface_mac(aredn.hardware.get_iface_name("lan")):match("%w%w:%w%w:%w%w:(%w%w):(%w%w):(%w%w)")
if a then
break
end
sleep(5)
end
if a then
dtdmac = string.format("%d.%d.%d", tonumber(a, 16), tonumber(b, 16), tonumber(c, 16))
else
dtdmac = mac2
end
if dtdmac == mac2 then
a = tonumber(a, 16) + 1
if a > 255 then
a = 0
end
dtdmac = string.format("%d.%d.%d", a, tonumber(b, 16), tonumber(c, 16))
end
aredn.info.set_nvram("dtdmac", dtdmac)
end
if name == "" then
name = "NOCALL"
aredn.info.set_nvram("node", name)
end
--
-- Configure and repair _setup
--
-- Load the defaults
local keys = {}
for line in io.lines("/etc/config.mesh/_setup.default")
do
if not (line:match("^%s*#") or line:match("^%s*$")) then
line = line:gsub("<NODE>", name):gsub("<MAC2>", mac2):gsub("<DTDMAC>", dtdmac)
local k, v = line:match("^(%S+)%s*=%s*(.*)%s*$")
cfg[k] = v
-- add default config key
keys[#keys + 1] = k
end
end
-- Override with the current config
local all = uci.cursor("/etc/config.mesh"):get_all("setup", "globals") or {}
for k, v in pairs(all)
do
if not k:match("^%.") then
cfg[k] = v
end
end
-- Override wifi setting
if wifi_enable == 0 then
cfg.wifi_enable = wifi_enable
end
-- Radio
if aredn.hardware.get_radio_count() > 0 and cfg.wifi_intf == "" then
local wifi_intf = "wlan0"
local defaultwifi = aredn.hardware.get_default_channel(wifi_intf)
cfg.wifi_intf = wifi_intf
cfg.wifi_channel = defaultwifi.channel
cfg.wifi_chanbw = defaultwifi.bandwidth
end
-- DHCP
if cfg.dmz_mode == "" then
local dmz_dhcp_base, net = ("1" .. decimal_to_ip((ip_to_decimal("10." .. mac2) * 8) % 0x1000000)):match("(%d+%.%d+%.%d+%.)(%d+)")
cfg.dmz_mode = 3
cfg.dmz_lan_ip = dmz_dhcp_base .. (tonumber(net) + 1)
cfg.dmz_dhcp_start = 2
cfg.dmz_dhcp_end = 6
cfg.dmz_lan_mask = "255.255.255.248"
end
-- And save
local c = uci.cursor("/etc/config.mesh")
io.open("/etc/config.mesh/setup", "a"):close()
if not c:get("setup", "globals") then
c:set("setup", "globals", "globals")
end
table.sort(keys)
for _, key in ipairs(keys)
do
local v = cfg[key]
if v then
c:set("setup", "globals", key, v)
end
end
c:commit("setup")
-- set variables in special conditions
if cfg.dmz_mode == "0" or cfg.wan_proto == "disabled" then
c:set("aredn", "@wan[0]", "olsrd_gw", "0")
c:commit("aredn")
end
-- end special condition overrides
-- If this was an upgrade, make sure to remove the carried configutation so we dont apply it again
os.remove("/sysupgrade.tgz")
-- If the node has been configured by the user we can complete the setup
if aredn.info.get_nvram("configured") ~= "0" then
os.execute("/usr/local/bin/node-setup")
-- Reboot when necessary
if nixio.fs.stat("/tmp/reboot-required") then
print "Rebooting node"
os.execute("/sbin/mount_root done")
os.execute("/bin/sync")
os.execute("/sbin/reboot")
end
end