From 39d87b7949be82d89d89dc38a54afaa2325218be Mon Sep 17 00:00:00 2001 From: ben Date: Sun, 17 Sep 2023 04:38:37 +0000 Subject: [PATCH] first commit --- Makefile | 13 + README.md | 0 luasrc/controller/easymesh.lua | 15 + luasrc/model/cbi/easymesh.lua | 127 +++++++++ po/zh-cn/easymesh.po | 89 ++++++ po/zh_Hans | 1 + root/etc/config/easymesh | 3 + root/etc/init.d/easymesh | 261 ++++++++++++++++++ root/etc/uci-defaults/luci-easymesh | 11 + .../share/rpcd/acl.d/luci-app-easymesh.json | 11 + 10 files changed, 531 insertions(+) create mode 100755 Makefile create mode 100644 README.md create mode 100755 luasrc/controller/easymesh.lua create mode 100755 luasrc/model/cbi/easymesh.lua create mode 100755 po/zh-cn/easymesh.po create mode 120000 po/zh_Hans create mode 100755 root/etc/config/easymesh create mode 100755 root/etc/init.d/easymesh create mode 100755 root/etc/uci-defaults/luci-easymesh create mode 100644 root/usr/share/rpcd/acl.d/luci-app-easymesh.json diff --git a/Makefile b/Makefile new file mode 100755 index 0000000..2d12595 --- /dev/null +++ b/Makefile @@ -0,0 +1,13 @@ +# +#-- Copyright (C) 2021 dz +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI Support for easymesh +LUCI_DEPENDS:= +kmod-cfg80211 +batctl-default +kmod-batman-adv +wpad-mesh-openssl +dawn +PKG_VERSION:=2.0 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/luasrc/controller/easymesh.lua b/luasrc/controller/easymesh.lua new file mode 100755 index 0000000..fb861ab --- /dev/null +++ b/luasrc/controller/easymesh.lua @@ -0,0 +1,15 @@ +-- Copyright (C) 2021 dz + +module("luci.controller.easymesh", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/easymesh") then + return + end + + local page + + page = entry({"admin", "network", "easymesh"}, cbi("easymesh"), _("EASY MESH"), 60) + page.dependent = true + page.acl_depends = { "luci-app-easymesh" } +end diff --git a/luasrc/model/cbi/easymesh.lua b/luasrc/model/cbi/easymesh.lua new file mode 100755 index 0000000..e8be5f9 --- /dev/null +++ b/luasrc/model/cbi/easymesh.lua @@ -0,0 +1,127 @@ +-- Copyright (C) 2021 dz + +local m,s,o +local sys = require "luci.sys" +local uci = require "luci.model.uci".cursor() + +m = Map("easymesh") + +function detect_Node() + local data = {} + local lps = luci.util.execi(" batctl n 2>/dev/null | tail +2 | sed 's/^[ ][ ]*//g' | sed 's/[ ][ ]*/ /g' | sed 's/$/ /g' ") + for value in lps do + local row = {} + local pos = string.find(value, " ") + local IFA = string.sub(value, 1, pos - 1) + local value = string.sub(value, pos + 1, string.len(value)) + pos = string.find(value, " ") + local pos = string.find(value, " ") + local Neighbora = string.sub(value, 1, pos - 1) + local value = string.sub(value, pos + 1, string.len(value)) + pos = string.find(value, " ") + local pos = string.find(value, " ") + local lastseena = string.sub(value, 1, pos - 1) + local value = string.sub(value, pos + 1, string.len(value)) + pos = string.find(value, " ") + row["IF"] = IFA + row["Neighbor"] = Neighbora + row["lastseen"] = lastseena + table.insert(data, row) + end + return data +end +local Nodes = luci.sys.exec("batctl n 2>/dev/null| tail +3 | wc -l") +local Node = detect_Node() +v = m:section(Table, Node, "" ,"" .. translate("Active node") .. ":" .. Nodes .. "") +v:option(DummyValue, "IF", translate("IF")) +v:option(DummyValue, "Neighbor", translate("Neighbor")) +v:option(DummyValue, "lastseen", translate("lastseen")) + +-- Basic +s = m:section(TypedSection, "easymesh", translate("Settings"), translate("General Settings")) +s.anonymous = true + +---- Eanble +o = s:option(Flag, "enabled", translate("Enable"), translate("Enable or disable EASY MESH")) +o.default = 0 +o.rmempty = false + +o = s:option(ListValue, "role", translate("role")) +o:value("off", translate("off")) +o:value("server", translate("host MESH")) +o:value("client", translate("son MESH")) +o.rmempty = false + +apRadio = s:option(ListValue, "apRadio", translate("MESH Radio device"), translate("The radio device which MESH use")) +uci:foreach("wireless", "wifi-device", + function(s) + apRadio:value(s['.name']) + end) +apRadio:value("all", translate("ALL")) +o.default = "radio0" +o.rmempty = false + +---- mesh +o = s:option(Value, "mesh_id", translate("MESH ID")) +o.default = "easymesh" +o.description = translate("MESH ID") + +enable = s:option(Flag, "encryption", translate("Encryption"), translate("")) +enable.default = 0 +enable.rmempty = false + +o = s:option(Value, "key", translate("Key")) +o.default = "easymesh" +o:depends("encryption", 1) + +---- kvr +enable = s:option(Flag, "kvr", translate("K/V/R"), translate("")) +enable.default = 1 +enable.rmempty = false + +o = s:option(Value, "mobility_domain", translate("Mobility Domain"), translate("4-character hexadecimal ID")) +o.default = "4f57" +o.datatype = "and(hexstring,rangelength(4,4))" +o:depends("kvr", 1) + +o = s:option(Value, "rssi_val", translate("Threshold for an good RSSI")) +o.default = "-60" +o.atatype = "range(-1,-120)" +o:depends("kvr", 1) + +o = s:option(Value, "low_rssi_val", translate("Threshold for an bad RSSI")) +o.default = "-88" +o.atatype = "range(-1,-120)" +o:depends("kvr", 1) + +---- 802.11F +--enable = s:option(Flag, "iapp", translate("inter-access point protocol"), translate("Wireless Access Points (APs) running on different vendors can communicate with each other")) +--enable.default = 0 +--enable.rmempty = false + +---- ap_mode +enable = s:option(Flag, "ap_mode", translate("AP MODE Enable"), translate("Enable or disable AP MODE")) +enable.default = 0 +enable.rmempty = false + +o = s:option(Value, "ipaddr", translate("IPv4-Address")) +o.default = "192.168.1.10" +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("IPv4 gateway")) +o.default = "192.168.1.1" +o.datatype = "ip4addr" +o:depends("ap_mode", 1) + +o = s:option(Value, "dns", translate("Use custom DNS servers")) +o.default = "192.168.1.1" +o.datatype = "ip4addr" +o:depends("ap_mode", 1) + +return m diff --git a/po/zh-cn/easymesh.po b/po/zh-cn/easymesh.po new file mode 100755 index 0000000..dc99d6a --- /dev/null +++ b/po/zh-cn/easymesh.po @@ -0,0 +1,89 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8\n" + +msgid "easymesh" +msgstr "easymesh" + +msgid "Active node" +msgstr "活动节点" + +msgid "IF" +msgstr "IF" + +msgid "Neighbor" +msgstr "节点邻居设备" + +msgid "lastseen" +msgstr "上次连接延时" + +msgid "EASY MESH" +msgstr "简单MESH" + +msgid "Settings" +msgstr "设置" + +msgid "General Settings" +msgstr "基本设置" + +msgid "Enable" +msgstr "启用" + +msgid "role" +msgstr "角色" + +msgid "off" +msgstr "关闭" + +msgid "host MESH" +msgstr "主MESH" + +msgid "son MESH" +msgstr "子MESH" + +msgid "MESH Radio device" +msgstr "MESH无线设备" + +msgid "The radio device which MESH use" +msgstr "使用MESH组网的无线设备" + +msgid "AUTO" +msgstr "自动" + +msgid "Enable or disable EASY MESH" +msgstr "启用或禁用简单MESH" + +msgid "Encryption" +msgstr "加密" + +msgid "Key" +msgstr "密码" + +msgid "inter-access point protocol" +msgstr "接入点内部协议" + +msgid "Wireless Access Points (APs) running on different vendors can communicate with each other" +msgstr "运行在不同供应商的无线访问点(AP)可以相互交流" + +msgid "Threshold for an good RSSI" +msgstr "快速漫游接入值" + +msgid "Threshold for an bad RSSI" +msgstr "快速漫游踢出值" + +msgid "AP MODE Enable" +msgstr "启用AP模式" + +msgid "Enable or disable AP MODE" +msgstr "启用或禁用AP模式" + +msgid "IPv4-Address" +msgstr "IPv4 地址" + +msgid "IPv4 netmask" +msgstr "IPv4 子网掩码" + +msgid "IPv4 gateway" +msgstr "IPv4 网关" + +msgid "Use custom DNS servers" +msgstr "使用自定义的 DNS 服务器" diff --git a/po/zh_Hans b/po/zh_Hans new file mode 120000 index 0000000..41451e4 --- /dev/null +++ b/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/root/etc/config/easymesh b/root/etc/config/easymesh new file mode 100755 index 0000000..3446d21 --- /dev/null +++ b/root/etc/config/easymesh @@ -0,0 +1,3 @@ + +config easymesh 'config' + option enabled '0' diff --git a/root/etc/init.d/easymesh b/root/etc/init.d/easymesh new file mode 100755 index 0000000..d142534 --- /dev/null +++ b/root/etc/init.d/easymesh @@ -0,0 +1,261 @@ +#!/bin/sh /etc/rc.common +START=99 +STOP=70 + +load_easymesh_config() { + enable=$(uci -q get easymesh.config.enabled) + mesh_bat0=$(uci -q get network.bat0) + ap_mode=$(uci -q get easymesh.config.ap_mode) + lan=$(uci -q get network.lan.ifname) + ipaddr=$(uci -q get easymesh.config.ipaddr) + netmask=$(uci -q get easymesh.config.netmask) + gateway=$(uci -q get easymesh.config.gateway) + dns=$(uci -q get easymesh.config.dns) + ap_ipaddr=$(uci -q get network.lan.ipaddr) + ap_ipaddr1=$(sed -n '1p' /etc/easymesh 2>/dev/null) + apRadio=$(uci -q get easymesh.config.apRadio) + kvr=$(uci -q get easymesh.config.kvr) + iapp=$(uci -q get easymesh.config.iapp) + brlan=$(uci -q get network.@device[0].name) + role=$(uci -q get easymesh.config.role) +} + +ap_mode_stop() { + ap_ipaddr=$(uci -q get network.lan.ipaddr) + ap_ipaddr1=$(sed -n '1p' /etc/easymesh 2>/dev/null) + dns1=$(sed -n '2p' /etc/easymesh 2>/dev/null) + if [ "$ap_ipaddr" = "$ap_ipaddr1" ]; then + uci -q delete network.lan.gateway + uci -q del_list network.lan.dns=$dns1 + uci commit network + + echo "" >/etc/easymesh + + uci -q delete dhcp.lan.dynamicdhcp + uci -q delete dhcp.lan.ignore + uci commit dhcp + + /etc/init.d/odhcpd enable && /etc/init.d/odhcpd start + /etc/init.d/firewall enable && /etc/init.d/firewall start >/dev/null 2>&1 + fi +} + +add_wifi_mesh() { + mesh_nwi_mesh=$(uci -q get network.nwi_mesh_${apall}) + mesh_apRadio=$(uci -q get wireless.mesh_${apall}.device) + mesh_mesh=$(uci -q get wireless.mesh_${apall}) + mesh_id=$(uci -q get easymesh.config.mesh_id) + mobility_domain=$(uci -q get easymesh.config.mobility_domain) + key=$(uci -q get easymesh.config.key) + encryption=$(uci -q get easymesh.config.encryption) + + if [ "$mesh_nwi_mesh" != "interface" ]; then + uci set network.nwi_mesh_$apall=interface + uci set network.nwi_mesh_$apall.proto='batadv_hardif' + uci set network.nwi_mesh_$apall.master='bat0' + uci set network.nwi_mesh_$apall.mtu='1536' + uci commit network + fi + + if [ "$mesh_mesh" != "wifi-iface" ]; then + uci set wireless.mesh_$apall=wifi-iface + uci set wireless.mesh_$apall.device=$apall + uci set wireless.mesh_$apall.ifname=mesh_${apall} + uci set wireless.mesh_$apall.network=nwi_mesh_${apall} + uci set wireless.mesh_$apall.mode='mesh' + uci set wireless.mesh_$apall.mesh_id=$mesh_id + uci set wireless.mesh_$apall.mesh_fwding='0' + uci set wireless.mesh_$apall.mesh_ttl='1' + uci set wireless.mesh_$apall.mcast_rate='24000' + uci set wireless.mesh_$apall.disabled='0' + uci commit wireless + fi + + if [ "$mesh_mesh" = "wifi-iface" ]; then + if [ "$mesh_apRadio" != "$apall" ]; then + uci set wireless.mesh_$apall.device=$apall + uci commit wireless + fi + fi + + if [ "$encryption" != 1 ]; then + uci set wireless.mesh_$apall.encryption='none' + uci commit wireless + else + uci set wireless.mesh_$apall.encryption='sae' + uci set wireless.mesh_$apall.key=$key + uci commit wireless + fi +} + +add_kvr() { + kvr=$(uci -q get easymesh.config.kvr) + mobility_domain=$(uci -q get easymesh.config.mobility_domain) + iapp=$(uci -q get easymesh.config.iapp) + for apall in $(uci -X show wireless | grep wifi-device | awk -F'[.=]' '{print $2}'); do + if [ "$kvr" = 1 ]; then + uci set wireless.default_$apall.ieee80211k='1' + uci set wireless.default_$apall.rrm_neighbor_report='1' + uci set wireless.default_$apall.rrm_beacon_report='1' + uci set wireless.default_$apall.ieee80211v='1' + uci set wireless.default_$apall.bss_transition='1' + uci set wireless.default_$apall.ieee80211r='1' + uci set wireless.default_$apall.encryption='psk2+ccmp' + uci set wireless.default_$apall.mobility_domain=$mobility_domain + uci set wireless.default_$apall.ft_over_ds='1' + uci set wireless.default_$apall.ft_psk_generate_local='1' + uci commit wireless + else + uci -q delete wireless.default_$apall.ieee80211k + uci -q delete wireless.default_$apall.ieee80211v + uci -q delete wireless.default_$apall.ieee80211r + uci commit wireless + fi + if [ "$iapp" = 1 ]; then + uci set wireless.default_$apall.iapp_interface='br-lan' + uci commit wireless + else + uci -q delete wireless.default_$apall.iapp_interface + uci commit wireless + fi + done +} + +add_dawn() { + kvr=$(uci -q get easymesh.config.kvr) + rssi_val=$(uci -q get easymesh.config.rssi_val) + low_rssi_val=$(uci -q get easymesh.config.low_rssi_val) + + if [ "$kvr" = 1 ]; then + uci set dawn.@metric[0].rssi_val=$rssi_val + uci set dawn.@metric[0].low_rssi_val=$low_rssi_val + uci commit dawn + /etc/init.d/dawn enable && /etc/init.d/dawn start + else + /etc/init.d/dawn stop && /etc/init.d/dawn disable + fi +} + +set_easymesh() { + load_easymesh_config + if [ "$enable" = 1 ]; then + if [ "$mesh_bat0" != "interface" ]; then + uci set network.bat0=interface + uci set network.bat0.proto='batadv' + uci set network.bat0.routing_algo='BATMAN_IV' + uci set network.bat0.aggregated_ogms='1' + uci set network.bat0.ap_isolation='0' + uci set network.bat0.bonding='0' + uci set network.bat0.bridge_loop_avoidance='1' + uci set network.bat0.distributed_arp_table='1' + uci set network.bat0.fragmentation='1' + # uci set network.bat0.gw_bandwidth='10000/2000' + # uci set network.bat0.gw_sel_class='20' + uci set network.bat0.hop_penalty='30' + uci set network.bat0.isolation_mark='0x00000000/0x00000000' + uci set network.bat0.log_level='0' + uci set network.bat0.multicast_fanout='16' + uci set network.bat0.multicast_mode='1' + uci set network.bat0.network_coding='0' + uci set network.bat0.orig_interval='1000' + + if [ "$role" = "server" ]; then + uci set network.bat0.gw_mode='server' + elif [ "$role" = "client" ]; then + uci set network.bat0.gw_mode='client' + else + uci set network.bat0.gw_mode='off' + fi + + if [ "$brlan" = "br-lan" ]; then + uci add_list network.@device[0].ports='bat0' + else + uci set network.lan.ifname="${lan} bat0" + fi + uci commit network + fi + + if [ "$apRadio" = "all" ]; then + for apall in $(uci -X show wireless | grep wifi-device | awk -F'[.=]' '{print $2}'); do + add_wifi_mesh + done + else + apall=$apRadio + add_wifi_mesh + fi + + add_kvr + add_dawn + + if [ "$ap_mode" = 1 ]; then + if [ "$ap_ipaddr" != "$ipaddr" ]; then + uci set network.lan.ipaddr=$ipaddr + uci set network.lan.netmask=$netmask + uci set network.lan.gateway=$gateway + uci add_list network.lan.dns=$dns + uci commit network + + echo "" >/etc/easymesh + echo "$ipaddr" >/etc/easymesh + echo "$dns" >>/etc/easymesh + + uci set dhcp.lan.dynamicdhcp='0' + uci set dhcp.lan.ignore='1' + uci -q delete dhcp.lan.ra + uci -q delete dhcp.lan.dhcpv6 + uci -q delete dhcp.lan.ra_management + uci commit dhcp + + /etc/init.d/odhcpd stop && /etc/init.d/odhcpd disable + /etc/init.d/firewall stop && /etc/init.d/firewall disable >/dev/null 2>&1 + fi + else + ap_mode_stop + fi + else + if [ "$mesh_bat0" = "interface" ]; then + uci -q delete network.bat0 + if [ "$brlan" = "br-lan" ]; then + uci -q del_list network.@device[0].ports='bat0' + else + sed -i 's/ bat0//' /etc/config/network + fi + uci commit network + fi + + for apall in $(uci -X show wireless | grep wifi-device | awk -F'[.=]' '{print $2}'); do + mesh_nwi_mesh=$(uci -q get network.nwi_mesh_${apall}) + mesh_mesh=$(uci -q get wireless.mesh_${apall}) + + if [ "$mesh_nwi_mesh" = "interface" ]; then + uci -q delete network.nwi_mesh_$apall + uci commit network + fi + + if [ "$mesh_mesh" = "wifi-iface" ]; then + uci -q delete wireless.mesh_$apall + uci commit wireless + fi + done + + add_kvr + add_dawn + + if [ "$ap_mode" = 1 ]; then + ap_mode_stop + fi + fi + /etc/init.d/network restart +} + +start() { + return 0 +} + +stop() { + return 0 +} + +restart() { + set_easymesh +} diff --git a/root/etc/uci-defaults/luci-easymesh b/root/etc/uci-defaults/luci-easymesh new file mode 100755 index 0000000..92b0774 --- /dev/null +++ b/root/etc/uci-defaults/luci-easymesh @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@easymesh[-1] + add ucitrack easymesh + set ucitrack.@easymesh[-1].init=easymesh + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/root/usr/share/rpcd/acl.d/luci-app-easymesh.json b/root/usr/share/rpcd/acl.d/luci-app-easymesh.json new file mode 100644 index 0000000..4d43594 --- /dev/null +++ b/root/usr/share/rpcd/acl.d/luci-app-easymesh.json @@ -0,0 +1,11 @@ +{ + "luci-app-easymesh": { + "description": "Grant UCI access for luci-app-easymesh", + "read": { + "uci": [ "easymesh" ] + }, + "write": { + "uci": [ "easymesh" ] + } + } +} \ No newline at end of file