Merge branch 'main' into ben_main

main
Jason Hawks 10 months ago
commit 595f84ba61

@ -7,8 +7,7 @@ include $(TOPDIR)/rules.mk
LUCI_TITLE:=LuCI Support for easymesh LUCI_TITLE:=LuCI Support for easymesh
LUCI_DEPENDS:= +kmod-cfg80211 +batctl-default +kmod-batman-adv +dawn +bash LUCI_DEPENDS:= +kmod-cfg80211 +batctl-default +kmod-batman-adv +dawn +bash
PKG_VERSION:=2.8.5 PKG_VERSION:=2.8.8
PKG_RELEASE:=0
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk

@ -13,34 +13,28 @@ m = Map("easymesh",
function detect_Node() function detect_Node()
local data = {} local data = {}
local lps = luci.util.execi(" batctl n 2>/dev/null | tail +2 | sed 's/^[ ][ ]*//g' | sed 's/[ ][ ]*/ /g' | sed 's/$/ /g' ") -- Streamline the command to retrieve node information
for value in lps do local lps = luci.util.execi("batctl n 2>/dev/null | tail +2 | sed 's/^[ ]*//;s/[ ]*/ /g'")
local row = {}
local pos = string.find(value, " ") for line in lps do
local IFA = string.sub(value, 1, pos - 1) -- Split the line into parts using pattern matching
local value = string.sub(value, pos + 1, string.len(value)) local ifa, neighbor, lastseen = string.match(line, "(%S+) (%S+) (%S+)")
pos = string.find(value, " ")
local pos = string.find(value, " ") if ifa and neighbor and lastseen then
local Neighbora = string.sub(value, 1, pos - 1) -- Construct the row and add it to the data table
local value = string.sub(value, pos + 1, string.len(value)) local row = {["IF"] = ifa, ["Neighbor"] = neighbor, ["lastseen"] = lastseen}
pos = string.find(value, " ") table.insert(data, row)
local pos = string.find(value, " ") end
local lastseena = string.sub(value, 1, pos - 1) end
local value = string.sub(value, pos + 1, string.len(value)) return data
pos = string.find(value, " ")
row["IF"] = IFA
row["Neighbor"] = Neighbora
row["lastseen"] = lastseena
table.insert(data, row)
end
return data
end end
function get_verbose_hw_info(iface)
function get_verbose_hw_info(iface)
local type = iwinfo.type(iface) local type = iwinfo.type(iface)
if not type then if not type then
return "Unknown interface" return "Generic"
end end
local driver = iwinfo[type] local driver = iwinfo[type]
@ -48,46 +42,41 @@ end
return "Driver not supported" return "Driver not supported"
end end
-- Get the hardware name (e.g., "Generic MAC80211")
local hw_name = driver.hardware_name and driver.hardware_name(iface) local hw_name = driver.hardware_name and driver.hardware_name(iface)
if not hw_name or hw_name == "" then if not hw_name or hw_name == "" then
hw_name = "Unknown hardware" hw_name = "Unknown hardware"
end end
-- Get the list of supported modes (e.g., "802.11bgnac") local hw_modes = driver.hwmodelist and driver.hwmodelist(iface)
local hw_modes_tbl = driver.hwmodelist and driver.hwmodelist(iface) local supported_modes = {}
local hw_modes_str = "" if hw_modes then
if hw_modes_tbl then for mode, supported in pairs(hw_modes) do
local hw_modes = {} if supported then
for mode, _ in pairs(hw_modes_tbl) do table.insert(supported_modes, mode)
table.insert(hw_modes, mode) end
end end
hw_modes_str = table.concat(hw_modes, "/")
else
hw_modes_str = "No mode information"
end end
-- Combine the hardware name with the supported modes if #supported_modes == 0 then
local verbose_info = hw_name .. hw_modes_str supported_modes_str = "No mode information"
else
supported_modes_str = table.concat(supported_modes, "/")
end
local verbose_info = hw_name .. " (" .. supported_modes_str .. ")"
return verbose_info return verbose_info
end end
local Nodes = luci.sys.exec("batctl n 2>/dev/null| tail +3 | wc -l") local Nodes = luci.sys.exec("batctl n 2>/dev/null| tail +3 | wc -l")
local Node = detect_Node() local Node = detect_Node()
v = m:section(Table, Node, "" ,"<b>" .. translate("Active node") .. "" .. Nodes .. "</b>") v = m:section(Table, Node, translate("Active Nodes") ,"<b>" .. translate("Number of Active Nodes: ") .. Nodes .. "</b>")
v:option(DummyValue, "IF", translate("IF")) v:option(DummyValue, "IF", translate("Interface"))
v:option(DummyValue, "Neighbor", translate("Neighbor")) v:option(DummyValue, "Neighbor", translate("Neighbor Nodes"))
v:option(DummyValue, "lastseen", translate("lastseen")) v:option(DummyValue, "lastseen", translate("Last Seen Timestamp"))
-- Basic -- Basic
s = m:section(TypedSection, "easymesh", translate("Mesh Gateway & Node WiFi Settings"), translate("Choose Mesh Gateway or Mesh Node WiFi Settings: Begin by completing this section on your mesh server and nodes. Ensure each radio's WiFi network name is consistent. For example: easymesh_AC, easymesh_N.")) s = m:section(TypedSection, "easymesh", translate("Mesh Settings"))
s.anonymous = true s.anonymous = true
---- Eanble
o = s:option(Flag, "enabled", translate("Enable"), translate("Enable or disable Easy Mesh"))
o.default = 0
o.rmempty = false
-- Connection Type Dropdown -- Connection Type Dropdown
--o = s:option(ListValue, "backbone", translate("Connection Type"), translate("Choose if Node or Gateway is connected to internet by LAN or WiFi")) --o = s:option(ListValue, "backbone", translate("Connection Type"), translate("Choose if Node or Gateway is connected to internet by LAN or WiFi"))
--o:value("lan", translate("LAN")) --o:value("lan", translate("LAN"))
@ -109,16 +98,22 @@ o.rmempty = false
--app.rmempty = true --app.rmempty = true
s:tab("setup", translate("Basic Setup")) s:tab("setup", translate("Basic Setup"))
s:tab("apmode", translate("AP Mode"))
s:tab("advanced", translate("Advanced Settings")) s:tab("advanced", translate("Advanced Settings"))
---- Eanble
o = s:taboption("setup", Flag, "enabled", translate("Enable Mesh Network"), translate("Toggle this switch to activate or deactivate the Mesh Network on this device according to the settings specified in this configuration. Make sure to configure all necessary settings before enabling the Mesh Network. Changes will apply when you click Save and Apply"))
o.default = 0
-- Move basic settings under the "Setup" tab -- Move basic settings under the "Setup" tab
o = s:taboption("setup", ListValue, "role", translate("Mesh Mode")) o = s:taboption("setup", ListValue, "role", translate("Mesh Mode"), translate('<p style="text-align: justify; padding: 0;"><strong>Choose the role this device will play in your mesh network. There are two options available:</strong></p> <p style="text-align: justify; padding: 0;"><strong>1. Server:</strong> If you select this option, this device will act as the Mesh Gateway Server. The server manages the routing of data in the network and handles connections to the internet. It is the central point of your mesh network.</p> <p style="text-align: justify; padding: 0;"><strong>2. Node:</strong> The device functions as a Mesh Node if this option is selected. Nodes connect to the Mesh Gateway Server and other nodes to extend the range of the network. Nodes can also route traffic between each other to increase network efficiency.</p> <p style="text-align: justify; padding: 0;"><strong>Remember to set up the Mesh Gateway Server first before setting up the nodes.</strong></p>'))
o:value("off", translate("Node"))
o:value("server", translate("Server")) o:value("server", translate("Server"))
o:value("client", translate("Client (advanced)")) o:value("off", translate("Node"))
o.rmempty = false o.default = "server"
--o:value("client", translate("Client (advanced)"))
apRadio = s:taboption("setup", ListValue, "apRadio", translate("Mesh Radio")) apRadio = s:taboption("setup", MultiValue, "apRadio", translate("Mesh Radio(s)"), translate('<p style="text-align: justify; padding: 0;">Select one or multiple radio interfaces to be used for the mesh network. Each selected radio interface will be configured to participate in the mesh network, extending its range and improving its resilience. By using multiple radios, your mesh network can balance the network load and handle a larger number of connected devices.</p>'))
uci:foreach("wireless", "wifi-device", uci:foreach("wireless", "wifi-device",
function(s) function(s)
@ -127,40 +122,37 @@ uci:foreach("wireless", "wifi-device",
local desc = string.format("%s (%s)", iface, hw_modes) local desc = string.format("%s (%s)", iface, hw_modes)
apRadio:value(iface, desc) -- Display radio interface with its hardware modes apRadio:value(iface, desc) -- Display radio interface with its hardware modes
end) end)
apRadio:value("all", translate("ALL"))
apRadio.default = "radio0" apRadio.default = "radio0"
apRadio.rmempty = false apRadio.widget = "select"
o = s:taboption("setup", Value, "mesh_id", translate("Mesh SSID")) o = s:taboption("setup", Value, "mesh_id", translate("Mesh SSID"))
o.default = "easymesh_AC" o.default = "easymesh_AC"
enable = s:taboption("setup", Flag, "encryption", translate("Encryption WIP DROPDOWN"), translate("")) encryption = s:taboption("setup", Flag, "encryption", translate("Enable Password"), translate(""))
enable.default = 0 encryption.default = 0
enable.rmempty = false
o = s:taboption("setup", Value, "key", translate("Key")) o = s:taboption("setup", Value, "key", translate("Mesh Password"))
o.default = "easymesh" o.default = "easymesh"
o:depends("encryption", 1) o:depends("encryption", 1)
o.password = true
-- Move K/V/R settings to the "Advanced" tab
enable_kvr = s:taboption("advanced", Flag, "kvr", translate("K/V/R"), translate("Enable Key Value Roaming")) enable_kvr = s:taboption("advanced", Flag, "kvr", translate("K/V/R"), translate("Enable Key Value Roaming"))
enable_kvr.default = 1 enable_kvr.default = 1
enable_kvr.rmempty = false
mobility_domain = s:taboption("advanced", Value, "mobility_domain", translate("Mobility Domain"), translate("4-character hexadecimal ID")) mobility_domain = s:taboption("advanced", Value, "mobility_domain", translate("Mobility Domain"), translate("4-character hexadecimal ID"))
mobility_domain.default = "4f57" mobility_domain.default = "4f57"
mobility_domain.datatype = "and(hexstring,rangelength(4,4))" --mobility_domain.datatype = "and(hexstring,rangelength(4,4))"
mobility_domain:depends("kvr", 1)
rssi_val = s:taboption("advanced", Value, "rssi_val", translate("Threshold for a good RSSI")) rssi_val = s:taboption("advanced", Value, "rssi_val", translate("Threshold for a good RSSI"))
rssi_val.default = "-60" rssi_val.default = "-60"
rssi_val.datatype = "range(-1,-120)" --rssi_val.datatype = "range(-1,-120)"
rssi_val:depends("kvr", 1)
low_rssi_val = s:taboption("advanced", Value, "low_rssi_val", translate("Threshold for a bad RSSI")) low_rssi_val = s:taboption("advanced", Value, "low_rssi_val", translate("Threshold for a bad RSSI"))
low_rssi_val.default = "-88" low_rssi_val.default = "-88"
low_rssi_val.datatype = "range(-1,-120)" --low_rssi_val.datatype = "range(-1,-120)"
low_rssi_val:depends("kvr", 1)
---- Apply MESH settings ---- Apply MESH settings
@ -179,31 +171,11 @@ low_rssi_val:depends("kvr", 1)
--enable.rmempty = false --enable.rmempty = false
-- NodeMode -- NodeMode
s = m:section(TypedSection, "easymesh", translate("Enable Router as DHCP Mesh Node"), translate("Set up Easy Mesh WiFi on your server and nodes first. All mesh nodes will utilize your mesh server for DHCP. ")) -- s = m:section(TypedSection, "easymesh", translate("Enable Router as DHCP Mesh Node"), translate("Set up Easy Mesh WiFi on your server and nodes first. All mesh nodes will utilize your mesh server for DHCP. "))
s.anonymous = true -- s.anonymous = true
---- ap_mode ---- ap_mode
enable = s:option(Flag, "ap_mode", translate("Enable as DHCP Mesh Node"), translate("Important: Setup your mesh WiFi network before enabling.")) o = s:taboption("apmode", Value, "hostname", translate("Node Hostname"))
enable.default = 0
enable.rmempty = false
---- ip address
--o = s:option(Value, "ipaddr", translate("Static IP Address"))
--o.default = "192.168.8.2"
--o.datatype = "ip4addr"
--o:depends("ap_mode", 1)
o = s:option(Value, "dns", translate("Mesh Gateway IP Address"))
o.default = "192.168.8.1"
o.datatype = "ip4addr"
o:depends("ap_mode", 1)
o = s:option(Value, "netmask", translate("IPv4 netmask"))
o.default = "255.255.255.0"
o.datatype = "ip4addr"
o:depends("ap_mode", 1)
o = s:option(Value, "gateway", translate("Set Hostname for this Mesh Node"))
o.default = "node2" o.default = "node2"
o:value("node2", "node2") o:value("node2", "node2")
o:value("node3", "node3") o:value("node3", "node3")
@ -214,29 +186,52 @@ o:value("node7", "node7")
o:value("node8", "node8") o:value("node8", "node8")
o:value("node9", "node9") o:value("node9", "node9")
o.datatype = "string" o.datatype = "string"
o:depends("ap_mode", 1) o:depends("role", "off")
-- IP Mode (DHCP or Static)
ipmode = s:taboption("apmode", ListValue, "ipmode", translate("IP Mode"), translate("Choose if the node uses DHCP or a Static IP"))
ipmode:value("dhcp", translate("DHCP"))
ipmode:value("static", translate("Static"))
ipmode.default = "dhcp"
ipmode:depends("role", "off")
-- Static IP address
o = s:taboption("apmode", Value, "ipaddr", translate("Static IP Address"))
o.default = "192.168.70.254"
o.datatype = "ip4addr"
o:depends({ipmode="static",role="off"})
-- MESH Node Control: apply mesh settings -- DNS (Mesh Gateway IP Address)
ctrl = m:section(TypedSection, "easymesh", "Click Save Then Enable or Disable Your Mesh WiFi settings") o = s:taboption("apmode", Value, "gateway", translate("Mesh Gateway IP Address"))
ctrl.anonymous = true o.default = "192.168.70.1"
ctrl.addremove = false o.datatype = "ip4addr"
o:depends({ipmode="static",role="off"})
-- IPv4 netmask
o = s:taboption("apmode", Value, "netmask", translate("IPv4 netmask"))
o.default = "255.255.255.0"
o.datatype = "ip4addr"
o:depends({ipmode="static",role="off"})
btnStart = ctrl:option(Button, "_btn_start", translate("Enable Easy Mesh")) -- IPv4 netmask
function btnStart.write() o = s:taboption("apmode", Value, "dns", translate("DNS Server"))
io.popen("/easymesh/easymesh.sh start") o.default = "192.168.70.1"
end o.datatype = "ip4addr"
o:depends({ipmode="static",role="off"})
btnStop = ctrl:option(Button, "_btn_stop", translate("Disable Easy Mesh")) btnAPMode = s:taboption("apmode", Button, "_btn_apmode", translate("Enable Dumb AP Mode"), translate("WARNING: THIS WILL CHANGE THIS NODE'S IP ADDRESS, YOU WILL LOOSE ACCESS TO THIS UI"))
function btnStop.write() function btnAPMode.write()
io.popen("/easymesh/easymesh.sh stop") io.popen("/easymesh/easymesh.sh dumbap &")
end end
btnAPMode:depends("role", "off")
function o.write(self, section, value) m.on_before_apply = function(self)
Flag.write(self, section, value) local enabled = m:formvalue("cbid.easymesh.config.enabled")
-- Run init start if enabled and enabled == "1" then
-- luci.sys.call("uci commit") io.popen("/easymesh/easymesh.sh enable &")
-- luci.sys.call("/etc/init.d/easymesh start &") else
io.popen("/easymesh/easymesh.sh disable &")
end
end end
return m return m

@ -1,38 +1,234 @@
#!/bin/bash #!/bin/bash
clear_old_networks() { # Dumb AP Mode Block
# Get the mesh name from UCI config set_apmode() {
MESH_NAME=$(uci -q get easymesh.config.mesh_id) # Backup our configs
rm /etc/config/*.meshbak
cp /etc/config/wireless /etc/config/wireless.meshbak
cp /etc/config/network /etc/config/network.meshbak
cp /etc/config/dhcp /etc/config/dhcp.meshbak
cp /etc/config/system /etc/config/system.meshbak
cp /etc/config/firewall /etc/config/firewall.meshbak
uci set easymesh.config.ap_mode_enabled=1
# Disabling and stopping services not needed
for service in firewall dnsmasq odhcpd; do
if /etc/init.d/$service enabled; then
echo "Disabling and stopping $service..."
/etc/init.d/$service disable >/dev/null 2>&1
/etc/init.d/$service stop >/dev/null 2>&1
else
echo "$service is not enabled, skipping..."
fi
done
if [ $(uci -q get easymesh.config.ipmode) == "static" ]; then
# Set static IP
uci set network.lan.proto='static'
uci set network.lan.ipaddr=$(uci -q get easymesh.config.ipaddr)
uci set network.lan.netmask=$(uci -q get easymesh.config.netmask)
uci set network.lan.gateway=$(uci -q get easymesh.config.gateway)
uci set network.lan.dns=$(uci -q get easymesh.config.dns)
else
# Set LAN interface to DHCP client
uci del network.lan.ipaddr
uci del network.lan.netmask
uci set network.lan.proto='dhcp'
fi
# Get all the radios and go through them one by one to remove old networks and interfaces with the same mesh name # Delete wan interfaces
for CURRENT_RADIO in $(uci -X show wireless | grep wifi-device | awk -F'[.=]' '{print $2}'); do uci del network.wan
echo "Clearing old networks for radio: $CURRENT_RADIO" uci del network.wan6
# Use awk to parse the 'uci show wireless' output and find the matching section # Set firewall disabled
matched_section=$(uci show wireless | awk -F. -v radio="$CURRENT_RADIO" -v ssid="$MESH_NAME" ' uci del firewall.lan.network
$0 ~ /^wireless\.wifinet[0-9]+\.device=/ && $3 ~ radio { device_section=$2 } uci del firewall.wan.network
$0 ~ /^wireless\.wifinet[0-9]+\.ssid=/ && $3 ~ ssid && device_section == $2 { print $2; exit }
')
# Check if a matching section was found # Just in case, set lan to be ignored by dhcp
if [ -n "$matched_section" ]; then uci set dhcp.lan.ignore='1'
echo "The matching wireless interface section is: $matched_section - deleting it" uci del dhcp.wan
uci delete wireless.$matched_section
fi # Fix this for proper variable name
HOSTNAME=$(uci -q get easymesh.config.hostname)
# Set netmask and gateway (assuming $netmask and $dns didn't break more stuff)
uci set system.@system[0].hostname=$HOSTNAME
# Find and delete existing mesh network interfaces with the specified MESH_NAME on the current radio # Retrieve the list of ports for network.@device[0]
EXISTING_MESH=$(uci show wireless | grep -w "mesh_id='$MESH_NAME'" | grep ".$CURRENT_RADIO." | cut -d'.' -f1-2) LAN_PORTS=$(uci get network.@device[0].ports)
for section in $EXISTING_MESH; do
uci delete $section # Check if 'wan' is already in the list of ports
echo "The matching wireless interface section is: $section - deleting it" if echo "$LAN_PORTS" | grep -q -w 'wan'; then
echo "'wan' is already in the list of ports for lan."
else
echo "'wan' is not in the list. Adding it to lan ports..."
uci add_list network.@device[0].ports='wan'
fi
# Get the radio to be used for mesh from the config
AP_RADIO=$(uci -q get easymesh.config.apRadio)
# Our config set mesh_id that we are looking for
MESH_ID=$(uci -q get easymesh.config.mesh_id)
# Check if MESH_NAME and AP_RADIO are set, if so find set our network
if [ ! -z "$AP_RADIO" ] && [ ! -z "$MESH_ID" ]; then
# Loop through the radios and update the network settings
for radio in $AP_RADIO; do
# Get the number from the radio name
radio_num="${radio#radio}"
echo "Checking wireless networks on radio${radio_num} for ssid '$MESH_ID'"
# Loop through all the wireless interfaces associated with the current radio
uci show wireless | grep "wireless\.wifinet${radio_num}" | grep '\.ssid=' | while read -r ssid_line; do
# Extract the interface identifier
wifinet=$(echo "$ssid_line" | cut -d'.' -f2)
# Extract the ssid value
interface_ssid=$(echo "$ssid_line" | cut -d'=' -f2 | tr -d "'")
if [ "$interface_ssid" = "$MESH_ID" ]; then
echo "Found target SSID '$MESH_ID' on wireless wifinet ${wifinet} on radio ${radio}"
# Get the current network setting for this wifinet
current_network=$(uci get "wireless.${wifinet}.network")
echo "Current network setting for ${wifinet}: ${current_network}"
# Check if 'private_router_batman' is part of the current network setting
if echo "$current_network" | grep -qv 'private_router_batman'; then
# 'private_router_batman' is not in the network setting, so we add it
new_network="${current_network} private_router_batman"
uci set "wireless.${wifinet}.network=${new_network}"
echo "Added 'private_router_batman' to the network setting for ${wifinet}."
uci commit wireless
else
echo "'private_router_batman' is already in the network setting for ${wifinet}."
fi
else
echo "SSID '$interface_ssid' on wireless wifinet ${wifinet} does not match target SSID '$MESH_ID'. Skipping..."
fi
done
done done
fi
# Commit changes to wireless # Commit changes to make sure the wireless configuration is updated
uci commit uci commit
done
# Restart wireless
wifi reload
# Tell openwrt to reload the configs
reload_config
/etc/init.d/network reload
} }
create_bat0() { disable_apmode() {
# Config Count Must Match 5
local CONFIG_COUNT=0
# Check our configs exist, then restore them
[ -f /etc/config/wireless.meshbak ] && {
CONFIG_COUNT=$((CONFIG_COUNT+1))
}
[ -f /etc/config/network.meshbak ] && {
CONFIG_COUNT=$((CONFIG_COUNT+1))
}
[ -f /etc/config/dhcp.meshbak ] && {
CONFIG_COUNT=$((CONFIG_COUNT+1))
}
[ -f /etc/config/system.meshbak ] && {
CONFIG_COUNT=$((CONFIG_COUNT+1))
}
[ -f /etc/config/firewall.meshbak ] && {
CONFIG_COUNT=$((CONFIG_COUNT+1))
}
# Check if we have 5 configs to restore
if [ $CONFIG_COUNT -eq 5 ]; then
echo "Restoring configs from backup..."
echo "Existing configs will be moved to /etc/config/*.dumbap for reference."
rm /etc/config/*.dumbap
mv /etc/config/dhcp /etc/config/dhcp.dumbap
mv /etc/config/network /etc/config/network.dumbap
mv /etc/config/wireless /etc/config/wireless.dumbap
mv /etc/config/system /etc/config/system.dumbap
mv /etc/config/firewall /etc/config/firewall.dumbap
mv /etc/config/dhcp.meshbak /etc/config/dhcp
mv /etc/config/network.meshbak /etc/config/network
mv /etc/config/wireless.meshbak /etc/config/wireless
mv /etc/config/system.meshbak /etc/config/system
mv /etc/config/firewall.meshbak /etc/config/firewall
# Enable and start services not needed
for service in firewall dnsmasq odhcpd; do
if /etc/init.d/$service disabled; then
echo "Enabling and starting $service..."
/etc/init.d/$service enable
/etc/init.d/$service start
else
echo "$service is not disabled, skipping..."
fi
done
# Reload all the system configs
reload_config
/etc/init.d/network reload
wifi reload
else
echo "Unable to restore configs as none were found."
fi
}
clear_by_mesh_id() {
# Passed mesh_id to clear, allows us to multipurpose this function
MESH_ID_TO_CLEAR=$1
# Get the radio to be used for mesh from the config
AP_RADIO=$(uci -q get easymesh.config.apRadio)
# Check if MESH_NAME is not empty
if [ -z "$MESH_ID_TO_CLEAR" ]; then
echo "No mesh_id passed to remove from wireless."
return;
fi
# Get the output from uci show wireless
uci_output=$(uci show wireless)
# Find the mesh network with the matching mesh_id and delete it
mesh_id=$(echo "$uci_output" | grep -o "wireless\.mesh_radio[0-9]*\.mesh_id='$MESH_ID_TO_CLEAR'")
if [ ! -z "$mesh_id" ]; then
# Extract the number from the interface name
mesh_radio=$(echo "$mesh_id" | grep -o "radio[0-9]*")
# Loop through radios and delete the mesh networks
for radio in $AP_RADIO; do
# Delete the network
uci del wireless.mesh_$radio
echo "Deleted mesh network with mesh_id '$MESH_ID_TO_CLEAR' on $radio"
done
fi
# Find the wireless network with the matching ssid and delete it
ssid=$(echo "$uci_output" | grep -o "wireless\.wifinet[0-9]*\.ssid='$MESH_ID_TO_CLEAR'")
if [ ! -z "$ssid" ]; then
# Loop through radios and delete the wireless networks
for radio in $AP_RADIO; do
# Get the number from the radio name
radio_num="${radio#radio}"
# Delete the network
uci del wireless.wifinet$radio_num
echo "Deleted wireless network with ssid '$MESH_ID_TO_CLEAR' on radio$radio_num"
done
fi
# Commit changes to make sure the wireless configuration is updated
uci commit wireless
# Restart wireless to apply changes
wifi reload
echo "Wireless interfaces reloaded."
}
create_batman_network() {
# Check if bat0 already exists # Check if bat0 already exists
if uci -q get network.bat0 >/dev/null; then if uci -q get network.bat0 >/dev/null; then
echo "bat0 interface already exists." echo "bat0 interface already exists."
@ -73,15 +269,28 @@ create_bat0() {
echo "Old bat0 interface deleted from lan network." echo "Old bat0 interface deleted from lan network."
fi fi
# Add 'bat0' to the list of ports for 'br-lan' uci commit network
uci add_list network.@device[0].ports='bat0' fi
echo "bat0 has been added to the lan network."
# Check if network.private_router_batman already exists
if uci -q get network.private_router_batman >/dev/null; then
echo "network.private_router_batman interface already exists."
else
# Get the LAN bridge name
LAN_NAME=$(uci -q get network.@device[0].name)
# Setup our Private Router Batman Interface
uci set network.private_router_batman=interface
uci set network.private_router_batman.proto='batadv_hardif'
uci set network.private_router_batman.master='bat0'
uci set network.private_router_batman.device="$LAN_NAME"
uci set network.private_router_batman.mtu='1536'
uci commit network uci commit network
fi fi
} }
find_radios() { process_radios() {
# Get the radio to be used for mesh from the config # Get the radio to be used for mesh from the config
AP_RADIO=$(uci -q get easymesh.config.apRadio) AP_RADIO=$(uci -q get easymesh.config.apRadio)
@ -91,28 +300,11 @@ find_radios() {
exit 1 exit 1
fi fi
# Check to make sure if "all" is passed or a single radio # Loop through the selected radios
if [ "$AP_RADIO" == "all" ]; then for CURRENT_RADIO in $AP_RADIO; do
# Get the list of wifi devices echo "Setting up mesh networks for: $CURRENT_RADIO"
WIFI_RADIOS=$(uci -X show wireless | awk -F'[.=]' '/wifi-device/ {print $2}' | tr '\n' ' ') setup_mesh_radio $CURRENT_RADIO
else done
# Set the radio to the one passed in the config
WIFI_RADIOS=$AP_RADIO
fi
}
process_radios() {
# Check if WIFI_RADIOS contains more than one radio
if [[ $WIFI_RADIOS =~ [[:space:]] ]]; then
# Loop through all the radios and set them up
for radio in $WIFI_RADIOS; do
echo "Multiple Radio Setup, Current Radio: $radio"
setup_mesh_radio $radio
done
else
echo "Calling Single Radio Setup: $WIFI_RADIOS"
setup_mesh_radio $WIFI_RADIOS
fi
} }
# This is called from the process_radios function and is passed the radio to be used for mesh # This is called from the process_radios function and is passed the radio to be used for mesh
@ -126,18 +318,12 @@ setup_mesh_radio() {
# Commit changes to wireless # Commit changes to wireless
uci commit wireless uci commit wireless
uci set network.nwi_mesh_$CURRENT_RADIO=interface uci set wireless.mesh_$CURRENT_RADIO='wifi-iface'
uci set network.nwi_mesh_$CURRENT_RADIO.proto='batadv_hardif' uci set wireless.mesh_$CURRENT_RADIO.device="$CURRENT_RADIO"
uci set network.nwi_mesh_$CURRENT_RADIO.master='bat0' uci set wireless.mesh_$CURRENT_RADIO.ifname="mesh_$CURRENT_RADIO"
uci set network.nwi_mesh_$CURRENT_RADIO.device='bat0' uci set wireless.mesh_$CURRENT_RADIO.network='private_router_batman'
uci set network.nwi_mesh_$CURRENT_RADIO.mtu='1536'
uci set wireless.mesh_$CURRENT_RADIO=wifi-iface
uci set wireless.mesh_$CURRENT_RADIO.device=$CURRENT_RADIO
uci set wireless.mesh_$CURRENT_RADIO.ifname=mesh_$CURRENT_RADIO
uci set wireless.mesh_$CURRENT_RADIO.network=nwi_mesh_$CURRENT_RADIO
uci set wireless.mesh_$CURRENT_RADIO.mode='mesh' uci set wireless.mesh_$CURRENT_RADIO.mode='mesh'
uci set wireless.mesh_$CURRENT_RADIO.mesh_id=$MESH_NAME uci set wireless.mesh_$CURRENT_RADIO.mesh_id="$MESH_NAME"
uci set wireless.mesh_$CURRENT_RADIO.mesh_fwding='0' uci set wireless.mesh_$CURRENT_RADIO.mesh_fwding='0'
uci set wireless.mesh_$CURRENT_RADIO.mesh_rssi_threshold='0' uci set wireless.mesh_$CURRENT_RADIO.mesh_rssi_threshold='0'
uci set wireless.mesh_$CURRENT_RADIO.mesh_ttl='1' uci set wireless.mesh_$CURRENT_RADIO.mesh_ttl='1'
@ -163,7 +349,6 @@ setup_mesh_radio() {
ENCRYPTION_ENABLED=$(uci -q get easymesh.config.encryption) ENCRYPTION_ENABLED=$(uci -q get easymesh.config.encryption)
# Setup the interface for the mesh network # Setup the interface for the mesh network
uci set wireless.mesh_$CURRENT_RADIO.disabled='0'
uci set wireless.wifinet$RADIO_NUM=wifi-iface uci set wireless.wifinet$RADIO_NUM=wifi-iface
uci set wireless.wifinet$RADIO_NUM.device=$CURRENT_RADIO uci set wireless.wifinet$RADIO_NUM.device=$CURRENT_RADIO
uci set wireless.wifinet$RADIO_NUM.mode='ap' uci set wireless.wifinet$RADIO_NUM.mode='ap'
@ -172,9 +357,16 @@ setup_mesh_radio() {
uci set wireless.wifinet$RADIO_NUM.mobility_domain=$MOBILITY_DOMAIN uci set wireless.wifinet$RADIO_NUM.mobility_domain=$MOBILITY_DOMAIN
uci set wireless.wifinet$RADIO_NUM.ft_over_ds='0' uci set wireless.wifinet$RADIO_NUM.ft_over_ds='0'
uci set wireless.wifinet$RADIO_NUM.ft_psk_generate_local='0' uci set wireless.wifinet$RADIO_NUM.ft_psk_generate_local='0'
uci set wireless.wifinet$RADIO_NUM.network='lan'
uci set wireless.wifinet$RADIO_NUM.disabled=0 uci set wireless.wifinet$RADIO_NUM.disabled=0
# Check if ap_mode_enabled is enabled, if so add private_router_batman to the network
# otherwise just add lan
if [ "$(uci -q get easymesh.config.ap_mode_enabled)" = 1 ]; then
uci set wireless.wifinet$RADIO_NUM.network='lan'
else
uci set wireless.wifinet$RADIO_NUM.network='lan private_router_batman'
fi
# Get the encryption key from the config # Get the encryption key from the config
NETWORK_KEY=$(uci -q get easymesh.config.key) NETWORK_KEY=$(uci -q get easymesh.config.key)
@ -213,22 +405,6 @@ setup_mesh_radio() {
uci commit wireless uci commit wireless
fi fi
# Check if we need to setup iapp
ENABLE_IAPP=$(uci -q get easymesh.config.iapp)
if [ "$ENABLE_IAPP" = 1 ]; then
# Get the LAN interface name
LAN_NAME=$(uci -q get network.@device[0].name)
# If LAN_NAME is not empty, set the iapp interface
if [ ! -z "$LAN_NAME" ]; then
uci set wireless.wifinet$RADIO_NUM.iapp_interface="$LAN_NAME"
uci commit wireless
fi
else
uci -q delete wireless.wifinet$RADIO_NUM.iapp_interface
uci commit wireless
fi
# If KVR is enabled, setup DAWN # If KVR is enabled, setup DAWN
if [ "$ENABLE_KVR" = 1 ]; then if [ "$ENABLE_KVR" = 1 ]; then
RSSI=$(uci -q get easymesh.config.rssi_val) RSSI=$(uci -q get easymesh.config.rssi_val)
@ -246,207 +422,89 @@ setup_mesh_radio() {
} }
restart_and_reload() { restart_and_reload() {
# Enable all the radios and commit the changes at once # Get the radio to be used for mesh from the config
for radio in $(uci -X show wireless | grep wifi-device | awk -F'[.=]' '{print $2}'); do AP_RADIO=$(uci -q get easymesh.config.apRadio)
# Check if AP_RADIO is empty, if so exit
if [ -z "$AP_RADIO" ]; then
echo "No radio specified in the config, exiting."
exit 1
fi
# Enable radios
for radio in $AP_RADIO; do
echo "Enabling $radio..." echo "Enabling $radio..."
uci set wireless.$radio.disabled=0 uci set wireless.$radio.disabled=0
done done
uci commit
echo "All radios enabled."
# Apply the wireless configuration changes uci commit wireless
wifi reload
# Reload wifi to apply changes without restarting all interfaces
wifi up
echo "Wireless interfaces reloaded." echo "Wireless interfaces reloaded."
# Apply network configuration changes # Apply network configuration changes
# Note: Only use reload_config if you have made changes to the network config
# and need to apply them. Otherwise, you can skip this step.
reload_config reload_config
echo "Network configuration reloaded." echo "Network configuration reloaded."
/etc/init.d/network reload /etc/init.d/network reload
/etc/init.d/network restart
} }
disable_easymesh() { disable_batman_interfaces() {
# Delete the bat0 interface # Delete the bat0 interface
if [ "$(uci -q get network.bat0)" = "interface" ]; then if [ "$(uci -q get network.bat0)" = "interface" ]; then
uci del network.bat0 uci del network.bat0
fi fi
# Get the current list of ports for the 'br-lan' interface # Delete the private_router_batman network interface
LAN_PORTS=$(uci -q get network.@device[0].ports) if [ "$(uci -q get network.private_router_batman)" = "interface" ]; then
# Check if 'bat0' is already in the list of ports for 'br-lan' uci del network.private_router_batman
if echo "$LAN_PORTS" | grep -q 'bat0'; then
uci del_list network.@device[0].ports='bat0'
echo "Old bat0 interface deleted from lan network."
fi fi
# Get the list of wifi devices uci commit network
WIFI_RADIOS=$(uci -X show wireless | awk -F'[.=]' '/wifi-device/ {print $2}' | tr '\n' ' ')
# Loop through all the radios and delete the network interfaces
for CURRENT_RADIO in $WIFI_RADIOS; do
echo "Handling removal of mesh networks for: $CURRENT_RADIO"
if [ "$(uci -q get network.nwi_mesh_$CURRENT_RADIO)" = "interface" ]; then
uci del network.nwi_mesh_$CURRENT_RADIO
uci commit network
fi
done
uci commit
reload_config reload_config
echo "Network configuration reloaded."
/etc/init.d/network reload /etc/init.d/network reload
/etc/init.d/network restart echo "Network configuration reloaded."
} }
set_apmode() { # Enable easymesh
AP_MODE=$(uci -q get easymesh.config.ap_mode) enable_easymesh() {
if [ "$AP_MODE" = 1 ]; then # Clear old radios then set "old values"
# Set a flag to indicate that we are in AP mode clear_by_mesh_id "$(uci -q get easymesh.config.mesh_id)"
# When we go to disable easymesh, we will check this flag and if it was set we restore settings clear_by_mesh_id "$(uci -q get easymesh.config.old_mesh_id)"
uci set easymesh.config.ap_mode_enabled=1 uci set easymesh.config.old_mesh_id="$(uci -q get easymesh.config.mesh_id)"
create_batman_network
# Backup our configs process_radios
rm /etc/config/*.meshbak restart_and_reload
cp /etc/config/wireless /etc/config/wireless.meshbak # Set at end to be sure it worked
cp /etc/config/network /etc/config/network.meshbak uci set easymesh.config.running=1
cp /etc/config/dhcp /etc/config/dhcp.meshbak }
# Generate a random IP in the same subnet for fun
# ip_base=$(echo "$dns" | cut -d'.' -f1-3) # Get the first three octets of the DNS IP
# last_octet=$((RANDOM % 254 + 1)) # Generate a random value for the last octet between 1 and 254
# nodeip="${ip_base}.${last_octet}" # Concatenate the base IP with the new last octet
# Disabling and stopping services not needed
for service in firewall dnsmasq odhcpd; do
if /etc/init.d/$service enabled; then
echo "Disabling and stopping $service..."
/etc/init.d/$service disable
/etc/init.d/$service stop
else
echo "$service is not enabled, skipping..."
fi
done
# Set LAN interface to DHCP client
uci del network.lan.ipaddr
uci del network.lan.netmask
uci set network.lan.proto='dhcp'
uci del network.wan
uci del network.wan6
# Fix firewall to be disabled
uci del firewall.lan.network
uci del firewall.wan.network
# Fix dhcp to be disabled
uci set dhcp.lan.ignore='1'
uci del dhcp.wan
# Fix this for proper variable name
HOSTNAME=$(uci -q get easymesh.config.gateway)
# Set netmask and gateway (assuming $netmask and $dns didn't break more stuff)
uci set system.@system[0].hostname=$HOSTNAME
# Retrieve the list of ports for network.@device[0]
LAN_PORTS=$(uci get network.@device[0].ports)
# Check if 'wan' is already in the list of ports
if echo "$LAN_PORTS" | grep -q -w 'wan'; then
echo "'wan' is already in the list of ports for lan."
else
echo "'wan' is not in the list. Adding it to lan ports..."
uci add_list network.@device[0].ports='wan'
fi
# Find all radios we are using in our setup
find_radios
#### COME BACK TO THIS ####
# # Check if WIFI_RADIOS contains more than one radio
# if [[ $WIFI_RADIOS =~ [[:space:]] ]]; then
# # Loop through all the radios add nwimesh to the that network
# for cur_radio in $WIFI_RADIOS; do
# echo "Multiple Radio Setup, Current Radio: $radio"
# # Extact the radio number from the radio name
# wifi_num="${cur_radio#radio}"
# uci set wireless.wifinet${wifi_num}.network="lan nwi_mesh_${cur_radio}"
# done
# else
# echo "Calling Single Radio Setup: $WIFI_RADIOS"
# # Extact the radio number from the radio name
# wifi_num="${WIFI_RADIOS#radio}"
# uci set wireless.wifinet${wifi_num}.network="lan nwi_mesh_${WIFI_RADIOS}"
# fi
uci commit
# Tell openwrt to reload the configs
reload_config
else
# Set a flag to indicate that we are in AP mode
uci set easymesh.config.ap_mode_enabled=0
# Restore our configs
[ -f /etc/config/wireless.meshbak ] && {
mv /etc/config/wireless /etc/config/wireless.dumbap
cp /etc/config/wireless.meshbak /etc/config/wireless
}
[ -f /etc/config/network.meshbak ] && {
mv /etc/config/network /etc/config/network.dumbap
cp /etc/config/network.meshbak /etc/config/network
}
[ -f /etc/config/dhcp.meshbak ] && {
mv /etc/config/dhcp /etc/config/dhcp.dumbap
cp /etc/config/dhcp.meshbak /etc/config/dhcp
}
# Enable and start services not needed
for service in firewall dnsmasq odhcpd; do
if /etc/init.d/$service disabled; then
echo "Enabling and starting $service..."
/etc/init.d/$service enable
/etc/init.d/$service start
else
echo "$service is not disabled, skipping..."
fi
done
reload_config # Disable easymesh
/etc/init.d/network reload disable_easymesh() {
fi # Clear old radios then set "old values"
clear_by_mesh_id "$(uci -q get easymesh.config.mesh_id)"
clear_by_mesh_id "$(uci -q get easymesh.config.old_mesh_id)"
uci del easymesh.config.old_mesh_id
disable_batman_interfaces
# Set at end to be sure it worked
uci del easymesh.config.running
} }
# ENABLED=$(uci -q get easymesh.config.enabled) if [ "$1" = "enable" ]; then
# if [ "$ENABLED" = 1 ]; then enable_easymesh
# clear_old_networks exit 0
# create_bat0 elif [ "$1" = "disable" ]; then
# find_radios
# process_radios
# restart_and_reload
# else
# clear_old_networks
# disable_easymesh
# fi
# We accept the parameters: start, stop and apmode
# start: Enables easymesh
# stop: Disables easymesh
# apmode: Sets the device to AP mode
if [ "$1" = "start" ]; then
clear_old_networks
create_bat0
find_radios
process_radios
restart_and_reload
elif [ "$1" = "stop" ]; then
clear_old_networks
disable_easymesh disable_easymesh
# elif [ "$1" = "apmode" ]; then exit 0
# set_apmode elif [ "$1" = "dumbap" ]; then
set_apmode
exit 0
elif [ "$1" = "undumb" ]; then
disable_apmode
exit 0
else else
echo "Invalid parameter passed." echo "Invalid argument. Please use 'start', 'stop' or 'dumbap'"
exit 1
fi fi

Loading…
Cancel
Save