diff --git a/luci-app-passwall/Makefile b/luci-app-passwall/Makefile
index aef31787..b901bce5 100644
--- a/luci-app-passwall/Makefile
+++ b/luci-app-passwall/Makefile
@@ -8,7 +8,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=26.7.1
-PKG_RELEASE:=178
+PKG_RELEASE:=179
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua b/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua
index eeeab750..e2025548 100644
--- a/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua
+++ b/luci-app-passwall/luasrc/model/cbi/passwall/client/socks_config.lua
@@ -81,23 +81,14 @@ o = s:option(Flag, "enable_autoswitch", translate("Auto Switch"))
o.default = 0
o.rmempty = false
-o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds"))
-o.datatype = "min(10)"
-o.default = 30
+o = s:option(ListValue, "backup_node_add_mode", translate("Backup Node Addition Method"))
o:depends("enable_autoswitch", true)
+o.default = "manual"
+o:value("manual", translate("Manual"))
+o:value("batch", translate("Batch"))
-o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
-o.datatype = "min(1)"
-o.default = 3
-o:depends("enable_autoswitch", true)
-
-o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
-o.datatype = "min(1)"
-o.default = 1
-o:depends("enable_autoswitch", true)
-
o = s:option(DynamicList, "autoswitch_backup_node", translate("List of backup nodes"))
-o:depends("enable_autoswitch", true)
+o:depends("backup_node_add_mode", "manual")
o.template = appname .. "/cbi/nodes_dynamiclist"
o.group = {}
o.write = function(self, section, value)
@@ -119,6 +110,44 @@ for i, v in pairs(nodes_table) do
socks_node.group[#socks_node.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
end
+o = s:option(MultiValue, "backup_node_group", translate("Select Group"))
+o:depends("backup_node_add_mode", "batch")
+o.widget = "checkbox"
+o:value("default", translate("default"))
+local groups = {}
+m.uci:foreach(appname, "nodes", function(s)
+ if s.group and s.group ~= "" then
+ groups[s.group] = true
+ end
+end)
+for k, v in pairs(groups) do
+ o:value(api.UrlEncode(k), k)
+end
+
+o = s:option(Value, "backup_node_match_rule", translate("Node Matching Rules"))
+o:depends("backup_node_add_mode", "batch")
+local descrStr = "Example: ^A && B && !C && D$
"
+descrStr = descrStr .. "This means the node remark must start with A (^), include B, exclude C (!), and end with D ($).
"
+descrStr = descrStr .. "Conditions are joined by && (AND), and their order does not affect the result.
"
+descrStr = descrStr .. "Multiple groups can be separated by || (OR), matching succeeds if any group matches.
"
+descrStr = descrStr .. "Example: A && B || C && D means (A AND B) OR (C AND D)."
+o.description = translate(descrStr)
+
+o = s:option(Value, "autoswitch_testing_time", translate("How often to test"), translate("Units:seconds"))
+o.datatype = "min(10)"
+o.default = 30
+o:depends("enable_autoswitch", true)
+
+o = s:option(Value, "autoswitch_connect_timeout", translate("Timeout seconds"), translate("Units:seconds"))
+o.datatype = "min(1)"
+o.default = 3
+o:depends("enable_autoswitch", true)
+
+o = s:option(Value, "autoswitch_retry_num", translate("Timeout retry num"))
+o.datatype = "min(1)"
+o.default = 1
+o:depends("enable_autoswitch", true)
+
o = s:option(Flag, "autoswitch_restore_switch", translate("Restore Switch"), translate("When detects main node is available, switch back to the main node."))
o:depends("enable_autoswitch", true)
@@ -135,6 +164,6 @@ o:depends("enable_autoswitch", true)
o = s:option(DummyValue, "btn")
o.template = appname .. "/socks_auto_switch/btn"
-o:depends("enable_autoswitch", true)
+o:depends("backup_node_add_mode", "manual")
return m
diff --git a/luci-app-passwall/luasrc/passwall/api.lua b/luci-app-passwall/luasrc/passwall/api.lua
index 7a2ebdc4..111f34cc 100644
--- a/luci-app-passwall/luasrc/passwall/api.lua
+++ b/luci-app-passwall/luasrc/passwall/api.lua
@@ -1598,6 +1598,56 @@ function match_node_rule(name, rule)
return false
end
+local normal_nodes = {}
+function get_batch_nodes(node)
+ if #normal_nodes == 0 then
+ for k, e in ipairs(get_valid_nodes()) do
+ if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then
+ normal_nodes[#normal_nodes + 1] = {
+ id = e[".name"],
+ remarks = e["remarks"],
+ group = e["group"]
+ }
+ end
+ end
+ end
+ if not node.node_group or node.node_group == "" then return {} end
+ local nodes = {}
+ for g in node.node_group:gmatch("%S+") do
+ g = UrlDecode(g)
+ for k, v in pairs(normal_nodes) do
+ local gn = (v.group and v.group ~= "") and v.group or "default"
+ if gn:lower() == g:lower() and match_node_rule(v.remarks, node.node_match_rule) then
+ nodes[#nodes + 1] = v.id
+ end
+ end
+ end
+ return nodes
+end
+
+function get_socks_backup_nodes(id)
+ id = trim(id)
+ if id == "" then return "" end
+ local socks = uci:get_all(appname, id)
+ local nodes
+ if socks.backup_node_add_mode and socks.backup_node_add_mode == "batch" then
+ local node = {}
+ node.node_group = socks.backup_node_group
+ node.node_match_rule = socks.backup_node_match_rule
+ nodes = get_batch_nodes(node)
+ else
+ nodes = socks.autoswitch_backup_node
+ end
+ local backup_nodes, seen = {}, {}
+ for _, v in ipairs(nodes or {}) do
+ if v ~= socks.node and not seen[v] then
+ seen[v] = true
+ table.insert(backup_nodes, v)
+ end
+ end
+ return table.concat(backup_nodes, " ")
+end
+
function get_core(field, candidates)
local v = uci:get(appname, "@global_subscribe[0]", field)
if v and v ~= "" then
diff --git a/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/luci-app-passwall/luasrc/passwall/util_sing-box.lua
index 53dafe3e..f4d08d60 100644
--- a/luci-app-passwall/luasrc/passwall/util_sing-box.lua
+++ b/luci-app-passwall/luasrc/passwall/util_sing-box.lua
@@ -1285,33 +1285,6 @@ function gen_config(var)
return result
end
- local nodes_list = {}
- function get_urltest_batch_nodes(_node)
- if #nodes_list == 0 then
- for k, e in ipairs(api.get_valid_nodes()) do
- if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then
- nodes_list[#nodes_list + 1] = {
- id = e[".name"],
- remarks = e["remarks"],
- group = e["group"]
- }
- end
- end
- end
- if not _node.node_group or _node.node_group == "" then return {} end
- local nodes = {}
- for g in _node.node_group:gmatch("%S+") do
- g = api.UrlDecode(g)
- for k, v in pairs(nodes_list) do
- local gn = (v.group and v.group ~= "") and v.group or "default"
- if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then
- nodes[#nodes + 1] = v.id
- end
- end
- end
- return nodes
- end
-
function get_node_by_id(node_id)
if not node_id or node_id == "" or node_id == "nil" then return nil end
if node_id:find("Socks_") then
@@ -1333,7 +1306,7 @@ function gen_config(var)
-- new urltest
local ut_nodes
if _node.node_add_mode and _node.node_add_mode == "batch" then
- ut_nodes = get_urltest_batch_nodes(_node)
+ ut_nodes = api.get_batch_nodes(_node)
else
ut_nodes = _node.urltest_node
end
diff --git a/luci-app-passwall/luasrc/passwall/util_xray.lua b/luci-app-passwall/luasrc/passwall/util_xray.lua
index cc320701..66920df6 100644
--- a/luci-app-passwall/luasrc/passwall/util_xray.lua
+++ b/luci-app-passwall/luasrc/passwall/util_xray.lua
@@ -1016,33 +1016,6 @@ function gen_config(var)
end
end
- local nodes_list = {}
- function get_balancer_batch_nodes(_node)
- if #nodes_list == 0 then
- for k, e in ipairs(api.get_valid_nodes()) do
- if e.node_type == "normal" and (not e.chain_proxy or e.chain_proxy == "") then
- nodes_list[#nodes_list + 1] = {
- id = e[".name"],
- remarks = e["remarks"],
- group = e["group"]
- }
- end
- end
- end
- if not _node.node_group or _node.node_group == "" then return {} end
- local nodes = {}
- for g in _node.node_group:gmatch("%S+") do
- g = api.UrlDecode(g)
- for k, v in pairs(nodes_list) do
- local gn = (v.group and v.group ~= "") and v.group or "default"
- if gn:lower() == g:lower() and api.match_node_rule(v.remarks, _node.node_match_rule) then
- nodes[#nodes + 1] = v.id
- end
- end
- end
- return nodes
- end
-
function gen_loopback(outbound_tag, loopback_dst)
if not outbound_tag or outbound_tag == "" then return nil end
local inbound_tag = loopback_dst and "lo-to-" .. loopback_dst or outbound_tag .. "-lo"
@@ -1074,7 +1047,7 @@ function gen_config(var)
-- new balancer
local blc_nodes
if _node.node_add_mode and _node.node_add_mode == "batch" then
- blc_nodes = get_balancer_batch_nodes(_node)
+ blc_nodes = api.get_batch_nodes(_node)
else
blc_nodes = _node.balancing_node
end
diff --git a/luci-app-passwall/po/zh-cn/passwall.po b/luci-app-passwall/po/zh-cn/passwall.po
index 6189be51..68f6484b 100644
--- a/luci-app-passwall/po/zh-cn/passwall.po
+++ b/luci-app-passwall/po/zh-cn/passwall.po
@@ -517,6 +517,9 @@ msgstr "负载均衡"
msgid "Node Addition Method"
msgstr "节点添加方式"
+msgid "Backup Node Addition Method"
+msgstr "后备节点添加方式"
+
msgid "Manual"
msgstr "手动"
diff --git a/luci-app-passwall/root/usr/share/passwall/app.sh b/luci-app-passwall/root/usr/share/passwall/app.sh
index d8a083ca..d037b806 100755
--- a/luci-app-passwall/root/usr/share/passwall/app.sh
+++ b/luci-app-passwall/root/usr/share/passwall/app.sh
@@ -998,7 +998,6 @@ start_socks() {
local http_port=$(config_n_get $id http_port 0)
local http_config_file="HTTP2SOCKS_${id}.json"
local enable_autoswitch=$(config_n_get $id enable_autoswitch 0)
- [ "$enable_autoswitch" = "1" ] && [ -z "$(config_n_get $id autoswitch_backup_node)" ] && enable_autoswitch=0
local no_rec=0
[ "$enable_autoswitch" = "1" ] && no_rec=1
NO_REC_PROCESS=$no_rec $APP_PATH/app.sh run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
diff --git a/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh b/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh
index 38d9b773..6ba3baad 100755
--- a/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh
+++ b/luci-app-passwall/root/usr/share/passwall/socks_auto_switch.sh
@@ -164,14 +164,15 @@ start() {
retry_num=$(config_n_get $id autoswitch_retry_num 1)
restore_switch=$(config_n_get $id autoswitch_restore_switch 0)
probe_url=$(config_n_get $id autoswitch_probe_url "https://www.google.com/generate_204")
- backup_node=$(config_n_get $id autoswitch_backup_node)
+ backup_node=$(lua_api "get_socks_backup_nodes(\"${id}\")")
if [ -n "$backup_node" ]; then
- backup_node=$(echo "$backup_node" | tr -s ' ' '\n' | uniq | tr -s '\n' ' ')
backup_node_num=$(printf "%s\n" "$backup_node" | wc -w)
+ echolog " - Socks切换检测:端口[${socks_port}] 后备节点数量:${backup_node_num}"
if [ "$backup_node_num" -eq 1 ]; then
[ "$main_node" = "$backup_node" ] && return
fi
else
+ echolog " - Socks切换检测:端口[${socks_port}] 后备节点数量:0"
return
fi
while [ -n "$backup_node" ]; do
diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile
index 9df331b5..441f3820 100644
--- a/luci-app-passwall2/Makefile
+++ b/luci-app-passwall2/Makefile
@@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=26.7.12
-PKG_RELEASE:=61
+PKG_RELEASE:=62
PKG_PO_VERSION:=$(PKG_VERSION)
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua
index e2335a41..21d387cd 100644
--- a/luci-app-passwall2/luasrc/passwall2/util_xray.lua
+++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua
@@ -922,10 +922,10 @@ function gen_config(var)
fragment_table = {
type = "fragment",
settings = {
- packets = xray_settings.fragment_packets,
- lengths = #lengths > 0 and lengths or nil,
- delays = #delays > 0 and delays or nil,
- maxSplit = xray_settings.fragment_maxSplit
+ packets = xray_settings.fragment_packets or "tlshello",
+ lengths = #lengths > 0 and lengths or {"3-5","6-8","10-20"},
+ delays = #delays > 0 and delays or {"10-20"},
+ maxSplit = xray_settings.fragment_maxSplit or "3-6"
}
}
end
diff --git a/luci-app-wechatpush/Makefile b/luci-app-wechatpush/Makefile
index e428574f..e5dd0fb4 100755
--- a/luci-app-wechatpush/Makefile
+++ b/luci-app-wechatpush/Makefile
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-wechatpush
PKG_VERSION:=3.6.12
-PKG_RELEASE:=5
+PKG_RELEASE:=6
PKG_MAINTAINER:=tty228
PKG_CONFIG_DEPENDS:= \
diff --git a/luci-app-wechatpush/po/zh_Hans/wechatpush.po b/luci-app-wechatpush/po/zh_Hans/wechatpush.po
index 4860004d..d975e859 100644
--- a/luci-app-wechatpush/po/zh_Hans/wechatpush.po
+++ b/luci-app-wechatpush/po/zh_Hans/wechatpush.po
@@ -1342,6 +1342,15 @@ msgstr "设备状态变化"
msgid "Traffic in 1 minute:"
msgstr "一分钟内流量:"
+msgid "Upload Traffic:"
+msgstr "上传流量:"
+
+msgid "Download Traffic:"
+msgstr "下载流量:"
+
+msgid "Signal Strength:"
+msgstr "dBm:"
+
msgid "Whitelist add failed, IP format error"
msgstr "白名单添加失败,IP 格式错误"
diff --git a/luci-app-wechatpush/root/usr/share/wechatpush/wechatpush b/luci-app-wechatpush/root/usr/share/wechatpush/wechatpush
index 1791f944..132f860a 100755
--- a/luci-app-wechatpush/root/usr/share/wechatpush/wechatpush
+++ b/luci-app-wechatpush/root/usr/share/wechatpush/wechatpush
@@ -123,6 +123,40 @@ read_config() {
cron
}
+get_signal_dbm() {
+ local mac="$1"
+ local device
+ local wxjk_dbm
+
+ [ -z "$mac" ] && return 1
+ echo "$mac" | grep -qE "^([0-9A-Fa-f]{2}:){5}[0-9A-Fa-f]{2}$" || return 1
+
+ for device in /sys/class/net/*; do
+ device=$(basename "$device")
+ [ -d "/sys/class/net/$device/wireless" ] || continue
+ iwinfo "$device" info >/dev/null 2>&1 || continue
+
+ wxjk_dbm=$(iwinfo "$device" assoclist 2>/dev/null | awk -v mac="$mac" '
+ index(tolower($0), tolower(mac)) {
+ line = tolower($0)
+ if (match(line, /-?[0-9]+[[:space:]]*dbm/)) {
+ val = substr(line, RSTART, RLENGTH)
+ gsub(/[[:space:]]*dbm/, "", val)
+ print val
+ } else {
+ print "__SEEN__"
+ }
+ exit
+ }
+ ')
+
+ [ "$wxjk_dbm" = "__SEEN__" ] && return 1
+ [ -n "$wxjk_dbm" ] && echo "$wxjk_dbm" | awk '{ $1=$1 };1' && return 0
+ done
+
+ return 1
+}
+
# 初始化
init() {
# 检测程序开关
@@ -968,9 +1002,22 @@ usage() {
elif [ $1 == "get" ]; then
[ ! -f "${dir}/usage.db" ] && [ -z "$3" ] && echo $(bytes_for_humans "0") && return
[ ! -f "${dir}/usage.db" ] && [ -n "$3" ] && echo "0" && return
- [ -z "$total_n" ] && total_n=$(cat ${dir}/usage.db | head -n1 | grep "total" | sed 's/,/\n/g' | awk '/total/{print NR}') 2>/dev/null
+ [ -z "$total_n" ] && total_n=$(head -n1 "${dir}/usage.db" | sed 's/,/\n/g' | awk '$0=="total"{print NR; exit}') 2>/dev/null
+ [ -z "$in_n" ] && in_n=$(head -n1 "${dir}/usage.db" | sed 's/,/\n/g' | awk '$0=="in"{print NR; exit}') 2>/dev/null
+ [ -z "$out_n" ] && out_n=$(head -n1 "${dir}/usage.db" | sed 's/,/\n/g' | awk '$0=="out"{print NR; exit}') 2>/dev/null
[ -z "$total_n" ] && total_n="6"
- [ -n "$2" ] && local tmptotal=$(cat ${dir}/usage.db | sed 's/,,,/,0,0,/g' | sed 's/,,/,0,/g' | sed 's/,/ /g' | grep -i -w ${2} | awk "{print "'$'$total_n"}" | grep -v "^$" | sort -u | head -n1) 2>/dev/null
+ local selected_n="$total_n"
+ case "$4" in
+ in) selected_n="$in_n" ;;
+ out) selected_n="$out_n" ;;
+ total|"") selected_n="$total_n" ;;
+ *) selected_n="$total_n" ;;
+ esac
+ case "$4" in
+ in|out) [ -z "$selected_n" ] && return ;;
+ *) [ -z "$selected_n" ] && selected_n="$total_n" ;;
+ esac
+ [ -n "$2" ] && local tmptotal=$(cat "${dir}/usage.db" | sed 's/,,,/,0,0,/g' | sed 's/,,/,0,/g' | sed 's/,/ /g' | awk -v key="$2" -v column="$selected_n" '{for (i=1; i<=NF; i++) if (tolower($i)==tolower(key)) {print $column; exit}}' | grep -v "^$" | sort -u | head -n1) 2>/dev/null
[ -z "$tmptotal" ] && local tmptotal="0"
[ -z "$3" ] && echo $(bytes_for_humans "${tmptotal}") || echo "$tmptotal"
# 剔除
@@ -979,6 +1026,44 @@ usage() {
fi
}
+get_usage_stats() {
+ local mac="$1"
+ local has_direction="0"
+
+ if [ ! -f "/usr/sbin/wrtbwmon" ] || [ -z "$mac" ] || [ ! -f "${dir}/usage.db" ]; then
+ echo "0 0 0 0"
+ return
+ fi
+
+ [ -z "$total_n" ] && total_n=$(head -n1 "${dir}/usage.db" | sed 's/,/\n/g' | awk '$0=="total"{print NR; exit}') 2>/dev/null
+ [ -z "$in_n" ] && in_n=$(head -n1 "${dir}/usage.db" | sed 's/,/\n/g' | awk '$0=="in"{print NR; exit}') 2>/dev/null
+ [ -z "$out_n" ] && out_n=$(head -n1 "${dir}/usage.db" | sed 's/,/\n/g' | awk '$0=="out"{print NR; exit}') 2>/dev/null
+ [ -z "$total_n" ] && total_n="6"
+ [ -n "$in_n" ] && [ -n "$out_n" ] && has_direction="1"
+
+ awk -F, -v key="$mac" -v total_col="$total_n" -v in_col="$in_n" -v out_col="$out_n" -v has_direction="$has_direction" '
+ {
+ for (i = 1; i <= NF; i++) {
+ if (tolower($i) == tolower(key)) {
+ total = $total_col + 0
+ in_bytes = 0
+ out_bytes = 0
+ if (has_direction == "1") {
+ in_bytes = $in_col + 0
+ out_bytes = $out_col + 0
+ }
+ print total, in_bytes, out_bytes, has_direction
+ found = 1
+ exit
+ }
+ }
+ }
+ END {
+ if (!found) print 0, 0, 0, has_direction
+ }
+ ' "${dir}/usage.db" 2>/dev/null
+}
+
# ------------------------------------
# 需要经常调用的偷懒类
#
@@ -1829,7 +1914,13 @@ ${str_linefeed}${str_tab} - $(translate "Client IP:")${str_space}${str_space}${s
${str_linefeed}${str_tab} - $(translate "Client MAC:")${str_space}${str_space}${str_space}${str_space}${mac}\
${str_linefeed}${str_tab} - $(translate "Network Interface:")${str_space}${str_space}${str_space}${str_space}${str_space}${interface}"
- log_change "${disturb_text} $(translate "New device %s %s connected" "$name" "$ip")"
+ local up_dbm=$(get_signal_dbm "$mac")
+ [ -n "$up_dbm" ] && content="${content}\
+${str_linefeed}${str_tab} - $(translate "Signal Strength:")${str_space}${str_space}${up_dbm} dBm"
+
+ local up_log=$(translate "New device %s %s connected" "$name" "$ip")
+ [ -n "$up_dbm" ] && up_log="${up_log} dbm:${up_dbm}"
+ log_change "${disturb_text} ${up_log}"
[ -n "$title" ] && echo "$title" >"${dir}/title"
[ -n "$content" ] && echo -n "$content" >>"${dir}/content"
@@ -2065,16 +2156,24 @@ get_client_usage() {
if [ "$(($(date +%s) - $get_client_usage_time))" -ge "60" ]; then
>${dir}/client_usage_aliases
for mac in $MACLIST; do
- echo "$mac" $(usage get ${mac} bytes) >>${dir}/client_usage_aliases
- [ -f "${dir}/old_client_usage_aliases" ] && get_client_usage_bytes=$(cat ${dir}/old_client_usage_aliases | grep -i -w $mac | awk '{print $2}' | grep -v "^$" | sort -u | head -n1) || continue
+ local cur_total cur_in cur_out cur_has_direction
+ read -r cur_total cur_in cur_out cur_has_direction <<<"$(get_usage_stats "$mac")"
+ echo "$mac ${cur_total} ${cur_in} ${cur_out} ${cur_has_direction}" >>${dir}/client_usage_aliases
+ [ -f "${dir}/old_client_usage_aliases" ] || continue
+ local old_line=$(awk -v key="$mac" 'tolower($1)==tolower(key){print; exit}' "${dir}/old_client_usage_aliases" 2>/dev/null)
+ [ -z "$old_line" ] && continue
- [ -z "$get_client_usage_bytes" ] && get_client_usage_bytes="0"
- if [ "$(($(usage get ${mac} bytes) - $get_client_usage_bytes))" -ge "$client_usage_max" ]; then
+ local old_mac prev_total prev_in prev_out old_has_direction
+ read -r old_mac prev_total prev_in prev_out old_has_direction <<<"$old_line"
+ [ -z "$prev_total" ] && prev_total="0"
+ local delta_total=$((cur_total - prev_total))
+ [ "$delta_total" -lt "0" ] && continue
+ if [ "$delta_total" -ge "$client_usage_max" ]; then
local ip=$(jq -r --arg mac "$mac" '.devices[] | select((.mac | ascii_downcase) == ($mac | ascii_downcase) and .status == "online") | .ip' "$devices_json")
local ip_name=$(getname ${ip} ${mac})
- local tmp_usage=$(bytes_for_humans $(expr $(usage get ${mac} bytes) - ${get_client_usage_bytes}))
+ local tmp_usage=$(bytes_for_humans "$delta_total")
local time_up=$(jq -r --arg mac "$mac" '.devices[] | select((.mac | ascii_downcase) == ($mac | ascii_downcase) and .status == "online") | .uptime' "$devices_json")
- local ip_total=$(usage get $mac) && [ -n "$ip_total" ] && local ip_total="${str_linefeed}${str_tab} - $(translate "Total Traffic:") ${str_space}${str_space}${str_space}${str_space}${ip_total}"
+ local ip_total=$(bytes_for_humans "$cur_total") && [ -n "$ip_total" ] && local ip_total="${str_linefeed}${str_tab} - $(translate "Total Traffic:") ${str_space}${str_space}${str_space}${str_space}${ip_total}"
local time1=$(date +%s)
local time1=$(time_for_humans $(expr ${time1} - ${time_up}))
@@ -2088,14 +2187,31 @@ get_client_usage() {
local content_title="${str_splitline}${str_title_start}$(translate "Device abnormal traffic")${str_title_end}"
fi
+ local detail_upload=""
+ local detail_download=""
+ if [ "$cur_has_direction" = "1" ] && [ "$old_has_direction" = "1" ]; then
+ [ -z "$prev_in" ] && prev_in="0"
+ [ -z "$prev_out" ] && prev_out="0"
+ local delta_in=$((cur_in - prev_in))
+ local delta_out=$((cur_out - prev_out))
+ [ "$delta_in" -lt "0" ] && delta_in="0"
+ [ "$delta_out" -lt "0" ] && delta_out="0"
+ detail_upload="${str_linefeed}${str_tab} - $(translate "Upload Traffic:")${str_space}${str_space}$(bytes_for_humans "$delta_out")"
+ detail_download="${str_linefeed}${str_tab} - $(translate "Download Traffic:")${str_space}$(bytes_for_humans "$delta_in")"
+ fi
+
+ local detail_dbm=""
+ local wxjk_dbm=$(get_signal_dbm "$mac")
+ [ -n "$wxjk_dbm" ] && detail_dbm="${str_linefeed}${str_tab} - $(translate "Signal Strength:")${str_space}${str_space}${wxjk_dbm} dBm"
+
content="\
${content}\
${content_title}\
${str_linefeed}${str_tab} - $(translate "Client Name:")${str_space}${str_space}${str_space}${str_space}${str_space}${ip_name}\
${str_linefeed}${str_tab} - $(translate "Client IP:")${str_space}${str_space}${str_space}${str_space}${ip}\
${str_linefeed}${str_tab} - $(translate "Client MAC:")${str_space}${str_space}${str_space}${str_space}${mac}${ip_total}\
-${str_linefeed}${str_tab} - $(translate "Traffic in 1 minute:")${str_space}${str_space}${str_space}${tmp_usage}\
-${str_linefeed}${str_tab} - $(translate "Uptime:")${str_space}${str_space}${str_space}${str_space}${time1}"
+${str_linefeed}${str_tab} - $(translate "Traffic in 1 minute:")${str_space}${str_space}${str_space}${tmp_usage}${detail_upload}${detail_download}\
+${str_linefeed}${str_tab} - $(translate "Uptime:")${str_space}${str_space}${str_space}${str_space}${time1}${detail_dbm}"
fi
done
cat ${dir}/client_usage_aliases >${dir}/old_client_usage_aliases
@@ -2657,7 +2773,13 @@ ${str_linefeed}${str_tab} - $(translate "Client IP:")${str_space}${str_space}${s
${str_linefeed}${str_tab} - $(translate "Client MAC:")${str_space}${str_space}${str_space}${str_space}${mac}${ip_total}\
${str_linefeed}${str_tab} - $(translate "Uptime:")${str_space}${str_space}${str_space}${str_space}${time1}"
- log_change "${disturb_text} $(translate "Device %s %s disconnected" "$name" "$ip")"
+ local down_dbm=$(get_signal_dbm "$mac")
+ [ -n "$down_dbm" ] && content="${content}\
+${str_linefeed}${str_tab} - $(translate "Signal Strength:")${str_space}${str_space}${down_dbm} dBm"
+
+ local down_log=$(translate "Device %s %s disconnected" "$name" "$ip")
+ [ -n "$down_dbm" ] && down_log="${down_log} dbm:${down_dbm}"
+ log_change "${disturb_text} ${down_log}"
done
silent_run LockFile lock
diff --git a/rtl8189es/Makefile b/rtl8189es/Makefile
index 0e4d42a4..94ac1cdd 100644
--- a/rtl8189es/Makefile
+++ b/rtl8189es/Makefile
@@ -5,12 +5,12 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=rtl8189es
-PKG_RELEASE:=2
+PKG_RELEASE:=3
PKG_SOURCE_URL:=https://github.com/jwrdegoede/rtl8189ES_linux.git
PKG_SOURCE_PROTO:=git
PKG_SOURCE_DATE:=2025-09-27
-PKG_SOURCE_VERSION:=36d917d5069f25f4c36b8b4d8b17b5d02e9116e9
+PKG_SOURCE_VERSION:=2d9a8afb5d12de1cfc4ab5ad3d1a61e1937629bd
PKG_MIRROR_HASH:=skip
PKG_BUILD_PARALLEL:=1