Improve initial node setup (#1590)

* Improve the initial nrvam setup

* More fallbacks

* Rebuild the initial setup and upgrade of a node.
This is mostly about removing duplicated effort and data, which should
make it easier to add things in the future.

* Re-setup and repair the node on each reboot.
By running this every time we reboot, we have a chance to repair problems in the configuration
automatically. We can detect changes and force a reboot only when necessary.

* Improve startup and upgrade

* Remove debug delays

* Move after telnet (for emergency access)

* Ignore ubootenv file when diffing
This commit is contained in:
Tim Wilkinson 2024-10-08 21:08:01 -07:00 committed by GitHub
parent 189845fa7f
commit 976c3ec1e1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
26 changed files with 381 additions and 512 deletions

View File

@ -33,9 +33,9 @@
*/
%}
{%
if ((auth.isFirstUse || !config.authenable) && request.env.REQUEST_METHOD === "POST") {
if (!(configuration.isConfigured() && config.authenable) && request.env.REQUEST_METHOD === "POST") {
print(_R("reboot-firstuse-ram"));
response.upgrade = `/usr/local/bin/aredn_sysupgrade -n -q ${request.args.firmwarefile}`;
response.reboot = `/usr/local/bin/aredn_sysupgrade -n -q ${request.args.firmwarefile}`;
return;
}
%}

View File

@ -33,11 +33,11 @@
*/
%}
{%
import * as xuci from "uci";
if ((auth.isFirstUse || !config.authenable) && request.env.REQUEST_METHOD === "PUT") {
system(`/usr/local/bin/firstuse-setup '${request.args.name}' '${request.args.passwd}'`);
response.reboot = true;
if (!(configuration.isConfigured() && config.authenable) && request.env.REQUEST_METHOD === "PUT") {
system(`/usr/local/bin/setpasswd '${request.args.passwd}'`);
configuration.setName(request.args.name);
configuration.setConfigured("1");
response.reboot = "/sbin/reboot";
print(_R("reboot-firstuse"));
return;
}

View File

@ -104,11 +104,9 @@
}
}
fo.close();
configuration.setUpgrade("1");
if (system("/bin/tar -czf /tmp/arednsysupgradebackup.tgz -T /tmp/sysupgradefilelist > /dev/null 2>&1") < 0) {
fs.unlink("/tmp/arednsysupgradebackup.tgz");
}
configuration.setUpgrade("0");
fs.unlink("/tmp/sysupgradefilelist");
}
fi.close();
@ -175,7 +173,7 @@
print(`<div id="dialog-messages-error" hx-swap-oob="true">ERROR: ${upgrade.error}</div>`);
}
else {
response.upgrade = upgrade.upgrade;
response.reboot = upgrade.upgrade;
print(_R("reboot-firmware"));
}
}
@ -191,7 +189,7 @@
restoreServices();
}
else {
response.upgrade = upgrade.upgrade;
response.reboot = upgrade.upgrade;
print(_R("reboot-firmware"));
}
}
@ -388,7 +386,7 @@
restoreServices();
}
else {
response.upgrade = upgrade.upgrade;
response.reboot = upgrade.upgrade;
uhttpd.send(`event: close\r\ndata: ${sprintf("%J", { v:_R("reboot-firmware")})}\r\n\r\n`);
}
return;

View File

@ -33,7 +33,7 @@
*/
%}
{%
response.reboot = true;
response.reboot = "/sbin/reboot";
const address = configuration.getSettingAsString("wifi_ip", request.env.HTTP_HOST);
%}
<title>{{configuration.getName()}} rebooting</title>

View File

@ -34,7 +34,7 @@
%}
{%
configuration.reset();
const address = configuration.getSettingAsString("wifi_ip", "192.168.1.1");
const address = configuration.getDefaultIP();
%}
<div id="all" hx-swap-oob="true">
<div class="reboot">

View File

@ -309,7 +309,6 @@ const uciMeshMethods =
};
const auth = {
isFirstUse: false,
isAdmin: false,
key: null,
age: 315360000, // 10 years
@ -403,11 +402,9 @@ global.handle_request = function(env)
const page = path[1] || "status";
const secured = index(path[2], "/e/") === 0;
auth.isFirstUse = !!fs.access("/etc/config/unconfigured");
if (path[2] == "" || secured) {
let tpath;
if (auth.isFirstUse) {
if (!configuration.isConfigured()) {
tpath = `${config.application}/main/firstuse-ram.ut`;
const f = fs.open("/proc/mounts");
if (f) {
@ -602,10 +599,7 @@ global.handle_request = function(env)
);
}
if (response.reboot) {
system("(sleep 2; exec /sbin/reboot)&");
}
if (response.upgrade) {
system(`(sleep 2; ${response.upgrade})&`);
system(`(sleep 2; ${response.reboot})&`);
}
return;
}

View File

@ -1,5 +1,16 @@
# This file contains a list of files to retain over a sysupgrade with "Keep Settings" in the GUI.
# This list will be used instead of the list normally used by sysupgrade.
/etc/config/aredn
/etc/config/dhcp
/etc/config/dropbear
/etc/config/firewall
/etc/config/network
/etc/config/olsrd
/etc/config/snmpd
/etc/config/system
/etc/config/uhttpd
/etc/config/vtun
/etc/config/wireless
/etc/config.mesh/_setup
/etc/config.mesh/_setup.dhcp.dmz
/etc/config.mesh/_setup.dhcp.nat

View File

@ -1,40 +1 @@
wifi_proto = static
wifi_ip = 10.<MAC2>
wifi_mask = 255.0.0.0
wifi_ssid = AREDN
wifi_mode = adhoc
wifi_txpower = 19
wifi_channel = 1
wifi_chanbw = 20
wifi_distance = 0
wifi_country = 00
wifi_enable = 1
wifi2_enable = 0
wifi2_ssid = NoCall-AREDN
wifi2_channel = 36
wifi2_encryption =
wifi2_key =
wifi2_hwmode = 11a
wifi3_enable = 0
wifi3_ssid =
wifi3_key =
wifi3_hwmode = 11a
dmz_mode = 3
lan_proto = static
lan_ip = 172.27.0.1
lan_mask = 255.255.255.0
lan_dhcp = 1
dhcp_start = 5
dhcp_end = 25
dhcp_limit = 20
olsrd_bridge = 0
wan_proto = dhcp
wan_dns1 = 8.8.8.8
wan_dns2 = 8.8.4.4
dtdlink_ip=10.<DTDMAC>
time_zone = UTC
time_zone_name = UTC
ntp_server = us.pool.ntp.org
ntp_server2 = time.cloudflare.com
description_node =
compat_version = 1.0
# Populated from _setup.default

View File

@ -10,45 +10,41 @@ wifi_chanbw = 20
wifi_distance = 0
wifi_country = 00
wifi_enable = 1
wifi2_enable = 0
wifi2_ssid = NoCAll-AREDN
wifi2_ssid = NoCall-AREDN
wifi2_channel = 36
wifi2_encryption = none
wifi2_key =
wifi2_hwmode = 11a
wifi3_enable = 0
wifi3_ssid =
wifi3_key =
wifi3_hwmode = 11a
dmz_mode = 3
lan_proto = static
lan_ip = 172.27.0.1
lan_mask = 255.255.255.0
lan_dhcp = 1
dhcp_start = 5
dhcp_end = 25
dhcp_limit = 20
dmz_mode =
dmz_lan_ip =
dmz_dhcp_start =
dmz_dhcp_end =
dmz_dhcp_limit =
dmz_lan_mask =
olsrd_bridge = 0
wan_proto = dhcp
wan_dns1 = 8.8.8.8
wan_dns2 = 8.8.4.4
wan_intf =
wan_ip = 192.168.0.2
wan_mask = 255.255.255.0
wan_gw = 192.168.0.1
dtdlink_ip = 10.<DTDMAC>
time_zone = UTC
time_zone_name = UTC
ntp_server = us.pool.ntp.org
ntp_server2 = time.cloudflare.com
description_node =
compat_version = 1.0

10
files/etc/config.mesh/rpcd Executable file
View File

@ -0,0 +1,10 @@
config rpcd
option socket /var/run/ubus/ubus.sock
option timeout 30
config login
option username 'root'
option password '$p$root'
list read '*'
list write '*'

View File

@ -1,42 +0,0 @@
config agent
option agentaddress UDP:161
config com2sec public
option secname ro
option source default
option community public
config group public_v1
option group public
option version v1
option secname ro
config group public_v2c
option group public
option version v2c
option secname ro
config group public_usm
option group public
option version usm
option secname ro
config view all
option viewname all
option type included
option oid .1
config access public_access
option group public
option context none
option version any
option level noauth
option prefix exact
option read all
option write none
option notify none
config system
option sysLocation 'Deployed'
option sysContact 'N0CALL'
option sysName 'N0CALL'

View File

@ -1,9 +1,5 @@
#!/bin/sh
configmode=$(uci -q -c /etc/local/uci/ get hsmmmesh.settings.config)
if [ "$configmode" != "mesh" ] ; then exit 0; fi
xlink=$(uci -q -c /etc/config.mesh/ show xlink | grep "ifname='${DEVICE}'")
# This section will generate rtnetlink errors when the rule doesn't exist.

View File

@ -4,11 +4,6 @@
START=99
boot() {
[ -x /usr/local/bin/aredn_postupgrade ] && /usr/local/bin/aredn_postupgrade
# setup nvram variables
[ -x /usr/local/bin/nvram-setup ] && /usr/local/bin/nvram-setup
# run mode specific setup
[ -x /etc/config/local ] && /etc/config/local
[ -x /etc/local/services ] && /etc/local/services

7
files/etc/init.d/upgrade Executable file
View File

@ -0,0 +1,7 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2006 OpenWrt.org
START=55
boot() {
/usr/local/bin/aredn_init
}

View File

@ -118,9 +118,8 @@ apply_uci_config() {
}
start() {
# only if vtun is installed and ind mesh mode
configmode=$(uci -q -c /etc/local/uci/ get hsmmmesh.settings.config)
if [ -x "/usr/sbin/vtund" -a "$configmode" = "mesh" ]
# only if vtun is installed
if [ -x "/usr/sbin/vtund" ]
then
apply_uci_config
config_load vtun

View File

@ -98,8 +98,7 @@ apply_uci_config() {
start() {
configmode=$(uci -q -c /etc/local/uci/ get hsmmmesh.settings.config)
if [ -x "/usr/sbin/vtund" -a "$configmode" = "mesh" ]
if [ -x "/usr/sbin/vtund" ]
then
apply_uci_config

View File

@ -1,6 +1,7 @@
config settings settings
option config ""
option node ""
option tactical ""
option mac2 ""
option boot_wait ""
config settings 'settings'
option node ''
option tactical ''
option mac2 ''
option dtdmac ''
option wifimac ''
option configured '0'

View File

@ -0,0 +1,5 @@
#! /bin/sh
if [ "$(uci -c /etc/local/uci -q get hsmmmesh.settings.configured)" = "" ]; then
uci -c /etc/local/uci -q set hsmmmesh.settings.configured=1
uci -c /etc/local/uci -q commit hsmmmesh
fi

234
files/usr/local/bin/aredn_init Executable file
View File

@ -0,0 +1,234 @@
#! /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 = {}
--
-- 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
os.execute("sed -i -e 's/wifi_enable = 1/wifi_enable = 0/' /etc/config.mesh/_setup")
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
for line in io.lines("/etc/config.mesh/_setup")
do
if not (line:match("^%s*#") or line:match("^%s*$")) then
local k, v = line:match("^(%S+)%s*=%s*(.*)%s*$")
if cfg[k] then
cfg[k] = v
end
end
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+)")
net = tonumber(net)
local dmz_lan_ip = dmz_dhcp_base .. (net + 1)
local dmz_dhcp_start = net + 2
local dmz_dhcp_limit = 5 -- dmz_mode == 3
local dmz_dhcp_end = dmz_dhcp_start + dmz_dhcp_limit - 1
cfg.dmz_mode = 3
cfg.dmz_dhcp_end = dmz_dhcp_end
cfg.dmz_dhcp_limit = dmz_dhcp_limit
cfg.dmz_dhcp_start = dmz_dhcp_start
cfg.dmz_lan_ip = dmz_dhcp_base .. (net + 1)
cfg.dmz_lan_mask = "255.255.255.248"
end
-- And save
table.sort(keys)
local f = io.open("/etc/config.mesh/_setup", "w")
if not f then
print "Failed to update /etc/config.mesh/_setup"
os.exit(-1)
end
for _, key in ipairs(keys)
do
local v = cfg[key]
if v then
f:write(key .. " = " .. v .. "\n")
end
end
f:close()
-- set variables in special conditions
if cfg.dmz_mode == "0" or cfg.wan_proto == "disabled" then
local c = uci.cursor("/etc/config.mesh")
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/reboot")
end
end

View File

@ -1,129 +0,0 @@
#! /usr/bin/lua
--[[
Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2021 Tim Wilkinson
See Contributors file for additional contributors
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")
local needsrun = aredn.info.get_nvram("nodeupgraded")
if needsrun == "" or needsrun == "0" then
print "Node not upgraded, exiting"
os.exit(0)
end
local config = aredn.info.get_nvram("config")
if config ~= "mesh" then
print "This node was previously configured in non-mesh mode and is no longer implemented. Returning to 'firstboot'."
local f = io.popen("firstboot -y && reboot")
f:read("*a")
f:close()
os.exit(1)
end
local node = aredn.info.get_nvram("node")
local mac2 = mac_to_ip(aredn.hardware.get_interface_mac(aredn.hardware.get_iface_name("wifi")), 0)
local dtdmac = mac_to_ip(aredn.hardware.get_interface_mac(aredn.hardware.get_iface_name("lan")), 0)
local cfg = {}
local defaultcfg = {}
local tmp = io.open("/tmp/.mesh_setup", "w")
if not tmp then
print "Failed to create temp file"
os.exit(-1)
end
for line in io.lines("/etc/config.mesh/_setup")
do
if not (line:match("^%s*#") or line:match("^%s*$")) then
local k, v = line:match("^(%S+)%s*=%s*(.*)%s*$")
cfg[k] = v
end
end
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>", node):gsub("<MAC2>", mac2):gsub("<DTDMAC>", dtdmac)
local k, v = line:match("^(%S+)%s*=%s*(.*)%s*$")
defaultcfg[k] = v
end
end
-- set variables in special conditions
if cfg.dmz_mode == "0" or cfg.wan_proto == "disabled" then
local c = uci.cursor("/etc/config.mesh")
c:set("aredn", "@wan[0]", "olsrd_gw", "0")
c:commit("aredn")
end
-- end special condition overrides
local keys = {}
for k, v in pairs(defaultcfg)
do
keys[#keys + 1] = k
end
table.sort(keys)
for _, key in ipairs(keys)
do
local v = cfg[key]
if v then
tmp:write(key .. " = " .. v .. "\n")
else
tmp:write(key .. " = " .. defaultcfg[key] .. "\n")
end
end
-- specific settings for variables that are not in the default config but are added by the system
for _, key in ipairs({ 'dmz_dhcp_end', 'dmz_dhcp_limit', 'dmz_dhcp_start', 'dmz_lan_ip', 'dmz_lan_mask', 'wifi_rxant', 'wifi_txant', 'wan_gw', 'wan_ip', 'wan_mask', 'wan_intf' })
do
local v = cfg[key]
if v then
tmp:write(key .. " = " .. v .. "\n")
end
end
tmp:close()
filecopy("/tmp/.mesh_setup", "/etc/config.mesh/_setup")
os.remove("/tmp/.mesh_setup")
os.execute("/usr/local/bin/node-setup")
aredn.info.set_nvram("nodeupgraded", "0")
print "Rebooting node"
os.execute("reboot >/dev/null 2>&1")

View File

@ -1,108 +0,0 @@
#! /usr/bin/lua
--[[
Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2024 Tim Wilkinson
See Contributors file for additional contributors
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("uci")
require("aredn.utils")
require("aredn.hardware")
local c = uci.cursor("/etc/local/uci")
if #arg ~= 2 then
io.stderr:write("Usage: firstuse <node name> <password>\n")
os.exit(-1)
end
local name = arg[1]
local passwd = arg[2]:gsub("'", "\\'")
-- Set the password
io.popen("{ echo '" .. passwd .. "'; sleep 1; echo '" .. passwd .. "'; } | passwd 2>&1"):read("*a")
-- Set the node name
c:set("hsmmmesh", "settings", "node", name)
c:commit("hsmmmesh")
-- Initial configuration
local mac2 = c:get("hsmmmesh", "settings", "mac2")
local dtdmac = c:get("hsmmmesh", "settings", "dtdmac")
local defaultwifi = null;
if aredn.hardware.get_radio_count() > 0 then
defaultwifi = aredn.hardware.get_default_channel("wlan0")
end
local lines = {}
for line in io.lines("/etc/config.mesh/_setup")
do
line = line:gsub("<NODE>", name):gsub("<MAC2>", mac2):gsub("<DTDMAC>", dtdmac)
if defaultwifi then
if line:match("^wifi_channel") then
line = "wifi_channel = " .. defaultwifi.channel
elseif line:match("^wifi_chanbw") then
line = "wifi_chanbw = " .. defaultwifi.bandwidth
elseif line:match("^wifi_intf") then
line = ""
end
end
lines[#lines + 1] = line
end
if defaultwifi then
lines[#lines + 1] = "wifi_intf = wlan0"
end
-- dhcp dmz
local dmz_dhcp_base, net = ("1" .. decimal_to_ip((ip_to_decimal("10." .. mac2) * 8) % 0x1000000)):match("(%d+%.%d+%.%d+%.)(%d+)")
net = tonumber(net)
local dmz_lan_ip = dmz_dhcp_base .. (tonumber(net) + 1)
local dmz_dhcp_start = net + 2
local dmz_dhcp_limit = 5 -- dmz_mode == 3
local dmz_dhcp_end = dmz_dhcp_start + dmz_dhcp_limit - 1
lines[#lines + 1] = "dmz_dhcp_end = " .. dmz_dhcp_end
lines[#lines + 1] = "dmz_dhcp_limit = " .. dmz_dhcp_limit
lines[#lines + 1] = "dmz_dhcp_start = " .. dmz_dhcp_start
lines[#lines + 1] = "dmz_lan_ip = " .. dmz_dhcp_base .. (net + 1)
lines[#lines + 1] = "dmz_lan_mask = 255.255.255.248"
local f = io.open("/etc/config.mesh/_setup", "w")
for _, line in ipairs(lines)
do
f:write(line .. "\n")
end
f:close()
os.execute("/usr/local/bin/node-setup")
c:set("hsmmmesh", "settings", "nodeupgraded", "0")
c:commit("hsmmmesh")

View File

@ -0,0 +1,54 @@
#! /usr/bin/lua
--[[
Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2024 Tim Wilkinson
See Contributors file for additional contributors
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("uci")
if #arg ~= 2 then
io.stderr:write("Usage: firstuse <node name> <password>\n")
os.exit(-1)
end
local name = arg[1]
local passwd = arg[2]:gsub("'", "\\'")
-- Set the password
os.execute("/usr/local/bin/setpasswd '" .. passwd .. "'")
-- Set the node name
local c = uci.cursor("/etc/local/uci")
c:set("hsmmmesh", "settings", "node", name)
c:set("hsmmmesh", "settings", "configured", "1")
c:commit("hsmmmesh")

View File

@ -1325,9 +1325,13 @@ for file in nixio.fs.glob("/etc/config/*")
do
if not nfiles[nixio.fs.basename(file)] then
nixio.fs.remove(file)
if file == "/etc/config/ubootenv" then
-- Ignore
else
changes.reboot = true
end
end
end
for file, _ in pairs(nfiles)
do
local ffile = "/tmp/new_config/" .. file
@ -1427,7 +1431,6 @@ do
end
nixio.fs.rmdir("/tmp/new_config")
aredn.info.set_nvram("config", "mesh")
aredn.info.set_nvram("node", node)
aredn.info.set_nvram("tactical", tactical)

View File

@ -1,133 +0,0 @@
#! /usr/bin/lua
--[[
Part of AREDN® -- Used for creating Amateur Radio Emergency Data Networks
Copyright (C) 2021 Tim Wilkinson
Original Perl Copyright (C) 2015 Conrad Lara
See Contributors file for additional contributors
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
--]]
-- do the initial setup of the essential nvram variables
-- node - node name
-- mac2 - last 3 bytes of wifi mac address in the form ddd.ddd.ddd
-- wifi_mac - full mac address of wireless card in the form hh:hh:hh:hh:hh:hh
--
-- intended to run every boot but it should only actually do anything
-- on the first boot
require("aredn.utils")
require("iwinfo")
require("aredn.hardware")
require('aredn.info')
local wifi_mac = aredn.info.get_nvram("wifimac")
local mac2 = aredn.info.get_nvram("mac2")
local node = aredn.info.get_nvram("node")
local dtdmac = aredn.info.get_nvram("dtdmac")
local hardware_mac
if wifi_mac == "" or mac2 == "" then
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
end
if not hardware_mac then
if not aredn.hardware.has_wifi() then
-- Non wifi device, create a random mac address instead
hardware_mac = capture([[hexdump -n5 -e'/5 "02" 5/1 ":%02X"' /dev/random]]):match("^(%S+)")
-- Disable wifi
os.execute("sed -i -e 's/wifi_enable = 1/wifi_enable = 0/' /etc/config.mesh/_setup")
else
io.stderr:write("ERROR: hardware mac not found\n")
os.exit(-1)
end
end
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
if node == "" then
aredn.info.set_nvram("node", "NOCALL-" .. mac2:gsub("%.", "-"))
end
if dtdmac == "" then
local 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)")
dtdmac = string.format("%d.%d.%d", tonumber(a, 16), tonumber(b, 16), tonumber(c, 16))
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

View File

@ -191,13 +191,31 @@ export function getFirmwareVersion()
return firmwareVersion;
};
export function setUpgrade(v)
export function isConfigured()
{
initCursor();
cursor.set("hsmmmesh", "settings", "nodeupgraded", v);
return cursor.get("hsmmmesh", "settings", "configured") !== "0";
};
export function setConfigured(v)
{
initCursor();
cursor.set("hsmmmesh", "settings", "configured", v);
cursor.commit("hsmmmesh");
};
export function getDefaultIP()
{
initCursor();
const mac2 = cursor.get("hsmmmesh", "settings", "mac2");
if (mac2) {
return `10.${mac2}`;
}
else {
return "192.168.1.1";
}
};
export function setPassword(passwd)
{
fs.writefile("/tmp/newpassword", passwd);
@ -365,7 +383,7 @@ export function commitChanges()
removeConfig(currentConfig);
if (fs.access("/tmp/newpassword")) {
const pw = fs.readfile("/tmp/newpassword");
system(`{ echo '${pw}'; sleep 1; echo '${pw}'; } | passwd > /dev/null 2>&1`);
system(`/usr/local/bin/setpasswd '${pw}'`);
fs.unlink("/tmp/newpassword");
}
const n = fs.popen("exec /usr/local/bin/node-setup");