From 5f6047bcba6aae5f0d079d77f5b2f9ed401f27c8 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 12 Sep 2026 10:51:28 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=97=BD=20Sync=202026-09-12=2010:51:28?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- linkease-common-bin/Makefile | 4 +- linkease/Makefile | 4 +- linkeasefull/Makefile | 6 +- luci-app-fwlive/Makefile | 4 +- .../luci-static/resources/fwlive/constants.js | 2 +- .../usr/libexec/fwlive-is-firewall-event.awk | 124 +++++++++++++++++ .../usr/libexec/fwlive-is-firewall-event.sh | 125 +----------------- .../root/usr/libexec/fwlive-log-filter.sh | 10 +- luci-app-wwand/Makefile | 74 +++++++++-- luci-proto-wwand/Makefile | 12 +- wwand/Makefile | 16 ++- 11 files changed, 228 insertions(+), 153 deletions(-) create mode 100755 luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.awk diff --git a/linkease-common-bin/Makefile b/linkease-common-bin/Makefile index 89a3a7d5..a75ad91b 100644 --- a/linkease-common-bin/Makefile +++ b/linkease-common-bin/Makefile @@ -12,7 +12,7 @@ PKG_ARCH_LINKEASE:=$(ARCH) PKG_NAME:=linkease-common-bin # use PKG_SOURCE_DATE instead of PKG_VERSION for compitable PKG_SOURCE_DATE:=1.7.5 -PKG_RELEASE:=31 +PKG_RELEASE:=32 ARCH_HEXCODE:= ifeq ($(ARCH),x86_64) @@ -28,7 +28,7 @@ else ifeq ($(ARCH),mipsel) ARCH_HEXCODE=1b0c endif -PKG_SOURCE_VERSION:=d795d92450b318f7ae72ae04dd2694761b453919 +PKG_SOURCE_VERSION:=4bb94bc5fe4da6d98dfcd730f40fe15f0d71ec4a PKG_SOURCE:=linkease-common-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE).tar.gz PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/linkease-runtime-v$(PKG_SOURCE_DATE)/ PKG_BUILD_DIR:=$(BUILD_DIR)/linkease-common-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE) diff --git a/linkease/Makefile b/linkease/Makefile index db4e2ed2..9d399f3e 100644 --- a/linkease/Makefile +++ b/linkease/Makefile @@ -12,7 +12,7 @@ PKG_ARCH_LINKEASE:=$(ARCH) PKG_NAME:=linkease # use PKG_SOURCE_DATE instead of PKG_VERSION for compitable PKG_SOURCE_DATE:=1.7.5 -PKG_RELEASE:=34 +PKG_RELEASE:=35 ARCH_HEXCODE:= ifeq ($(ARCH),x86_64) @@ -28,7 +28,7 @@ else ifeq ($(ARCH),mipsel) ARCH_HEXCODE=1b0c endif -PKG_SOURCE_VERSION:=d795d92450b318f7ae72ae04dd2694761b453919 +PKG_SOURCE_VERSION:=4bb94bc5fe4da6d98dfcd730f40fe15f0d71ec4a PKG_SOURCE:=linkease-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE).tar.gz PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/linkease-runtime-v$(PKG_SOURCE_DATE)/ PKG_BUILD_DIR:=$(BUILD_DIR)/linkease-bin-$(PKG_SOURCE_DATE)-linux-$(PKG_ARCH_LINKEASE) diff --git a/linkeasefull/Makefile b/linkeasefull/Makefile index 6e084489..f96ac021 100644 --- a/linkeasefull/Makefile +++ b/linkeasefull/Makefile @@ -10,8 +10,8 @@ PKG_ARCH_LINKEASE:=$(ARCH) PKG_NAME:=linkeasefull # use PKG_SOURCE_DATE instead of PKG_VERSION for compitable -PKG_SOURCE_DATE:=3.0.19 -PKG_RELEASE:=33 +PKG_SOURCE_DATE:=3.0.20 +PKG_RELEASE:=34 ARCH_HEXCODE:= ifeq ($(ARCH),x86_64) @@ -24,7 +24,7 @@ LINKEASE_RUNTIME_ARCH:=arm64 PKG_HASH:=skip endif -PKG_SOURCE_VERSION:=d795d92450b318f7ae72ae04dd2694761b453919 +PKG_SOURCE_VERSION:=4bb94bc5fe4da6d98dfcd730f40fe15f0d71ec4a PKG_SOURCE:=linkease-runtime-$(PKG_SOURCE_DATE)-linux-$(LINKEASE_RUNTIME_ARCH).tar.gz PKG_SOURCE_URL:=https://github.com/istoreos/istoreos-app-hub/releases/download/linkeasefull-runtime-v$(PKG_SOURCE_DATE)/ PKG_BUILD_DIR:=$(BUILD_DIR)/linkease-runtime-$(PKG_SOURCE_DATE)-linux-$(LINKEASE_RUNTIME_ARCH) diff --git a/luci-app-fwlive/Makefile b/luci-app-fwlive/Makefile index 0cb13678..cd1aba68 100644 --- a/luci-app-fwlive/Makefile +++ b/luci-app-fwlive/Makefile @@ -11,8 +11,8 @@ LUCI_DESCRIPTION:=Live firewall log table (nftables/fw4 and iptables LOG) with f LUCI_DEPENDS:=+luci-base +logd +jsonfilter LUCI_PKGARCH:=all -PKG_VERSION:=0.1.40 -PKG_RELEASE:=11 +PKG_VERSION:=0.1.41 +PKG_RELEASE:=12 # Reproducible build: honor SOURCE_DATE_EPOCH from the build environment (set by docker-sdk.sh / CI). ifdef SOURCE_DATE_EPOCH diff --git a/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js b/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js index c83beb97..3d791364 100644 --- a/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js +++ b/luci-app-fwlive/htdocs/luci-static/resources/fwlive/constants.js @@ -9,7 +9,7 @@ */ return baseclass.extend({ /* Keep in sync with openwrt-feed/luci-app-fwlive/Makefile PKG_VERSION. */ - APP_VERSION: '0.1.40', + APP_VERSION: '0.1.41', ROW_LIMIT_OPTIONS: [25, 50, 100, 250, 500, 1000, 2000], DEFAULT_ROW_LIMIT: 100, /* Row pass/deny tint (#40): classic green/red default; accessible teal/orange */ diff --git a/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.awk b/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.awk new file mode 100755 index 00000000..367dcc56 --- /dev/null +++ b/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.awk @@ -0,0 +1,124 @@ +# SPDX-License-Identifier: Apache-2.0 +# Copyright 2025-2026 Lucas Albers +# +# GENERATED FILE — do not edit. Run: ./scripts/gen-all.sh +# source: core/fwlive-log.js CLASSIFY_SPEC +# Standalone awk program loaded by fwlive-is-firewall-event.sh. + +function normalize(s, keys, n, i, k) { + n = split("IN OUT SRC DST PROTO SPT DPT LEN MAC TYPE CODE TTL TOS PREC DF", keys, " ") + for (i = 1; i <= n; i++) { + k = keys[i] + while (match(s, "[^[:space:]]" k "=")) + s = substr(s, 1, RSTART) " " substr(s, RSTART + 1) + } + return s +} +function trim(s) { + sub(/^[[:space:]]+/, "", s) + sub(/[[:space:]]+$/, "", s) + return s +} +function has_kv(s, key) { + return s ~ "(^|[^A-Za-z0-9_])" key "=" +} +function has_hint(s, lc) { + lc = tolower(s) + return lc ~ "(^|[^a-z0-9_])(fw4|nft|iptables|kernel|firewall)([^a-z0-9_]|$)" +} +function non_fw_prefix(s, lc) { + lc = tolower(s) + return lc ~ "^(dnsmasq|procd|ubusd|netifd|odhcpd|logd|dropbear|uhttpd|hostapd|wpad)([^a-z0-9_]|$)" +} +function detect_action(s, words, n, i, w, wl, lc, start, pos, before, afterc, best, bestpos) { + n = split("ACCEPT ALLOW PASS DROP REJECT DENY BLOCK", words, " ") + lc = tolower(s) + best = "" + bestpos = length(s) + 1 + for (i = 1; i <= n; i++) { + w = words[i] + wl = tolower(w) + start = 1 + while (start <= length(lc) && match(substr(lc, start), wl)) { + pos = start + RSTART - 1 + before = (pos == 1) ? " " : substr(lc, pos - 1, 1) + afterc = substr(lc, pos + length(wl), 1) + if (before !~ /[a-z0-9_]/ && (afterc == "" || afterc !~ /[a-z0-9_]/)) { + if (pos < bestpos) { bestpos = pos; best = w } + break + } + start = pos + 1 + } + } + return best == "" ? "UNKNOWN" : best +} +function json_unhex4(h, n, i, c, v) { + n = 0 + h = tolower(h) + for (i = 1; i <= 4; i++) { + c = substr(h, i, 1) + v = index("0123456789abcdef", c) + if (v == 0) return -1 + n = n * 16 + v - 1 + } + return n +} +function json_get_msg(obj, s, i, c, esc, out, hex, n) { + if (!match(obj, /"msg"[[:space:]]*:[[:space:]]*"/)) return "" + s = substr(obj, RSTART + RLENGTH) + out = "" + esc = 0 + for (i = 1; i <= length(s); i++) { + c = substr(s, i, 1) + if (esc) { + if (c == "n") out = out "\n" + else if (c == "t") out = out "\t" + else if (c == "r") out = out "\r" + else if (c == "b") out = out "\b" + else if (c == "f") out = out "\f" + else if (c == "u") { + hex = substr(s, i + 1, 4) + n = (length(hex) == 4) ? json_unhex4(hex) : -1 + if (n >= 1 && n <= 255) out = out sprintf("%c", n) + else if (n < 0) out = out "u" + if (n >= 0) i += 4 + } else out = out c + esc = 0 + } else if (c == "\\") { + esc = 1 + } else if (c == "\"") { + return out + } else { + out = out c + } + } + return out +} +function is_fw(s, action) { + s = trim(normalize(s)) + if (s == "") return 0 + if (non_fw_prefix(s)) return 0 + action = detect_action(s) + if (has_kv(s, "SRC") && has_kv(s, "DST")) return 1 + if ((has_kv(s, "IN") || has_kv(s, "OUT")) && (has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO") || has_kv(s, "SPT") || has_kv(s, "DPT"))) return 1 + if (action != "UNKNOWN" && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "PROTO") || has_kv(s, "SRC") || has_kv(s, "DST"))) return 1 + if (has_hint(s) && action != "UNKNOWN") return 1 + if (has_hint(s) && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO"))) return 1 + return 0 +} +BEGIN { if (MODE != "json") ORS = "" } +{ + if (MODE == "json") { + msg = json_get_msg($0) + if (is_fw(msg)) { + if (out_n++) printf "," + printf "%s", $0 + } + next + } + buf = (NR == 1) ? $0 : buf "\n" $0 +} +END { + if (MODE != "json") + print is_fw(buf) ? 1 : 0 +} diff --git a/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.sh b/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.sh index 8e202242..f19f672a 100755 --- a/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.sh +++ b/luci-app-fwlive/root/usr/libexec/fwlive-is-firewall-event.sh @@ -7,127 +7,12 @@ # Sourced library: do not add set -euo here (callers own strict mode, #291 C3). # One awk process classifies a batch (MODE=json) or one message (default). +# The caller sets FILTER_DIR when this file is sourced. Resolve the asset +# once, not once per classification call. +CLASSIFY_AWK="${FILTER_DIR:-${0%/*}}/fwlive-is-firewall-event.awk" + _fwlive_run_classify() { - awk -v MODE="${1:-msg}" "$(cat <<'AWK' -function normalize(s, keys, n, i, k) { - n = split("IN OUT SRC DST PROTO SPT DPT LEN MAC TYPE CODE TTL TOS PREC DF", keys, " ") - for (i = 1; i <= n; i++) { - k = keys[i] - while (match(s, "[^[:space:]]" k "=")) - s = substr(s, 1, RSTART) " " substr(s, RSTART + 1) - } - return s -} -function trim(s) { - sub(/^[[:space:]]+/, "", s) - sub(/[[:space:]]+$/, "", s) - return s -} -function has_kv(s, key) { - return s ~ "(^|[^A-Za-z0-9_])" key "=" -} -function has_hint(s, lc) { - lc = tolower(s) - return lc ~ "(^|[^a-z0-9_])(fw4|nft|iptables|kernel|firewall)([^a-z0-9_]|$)" -} -function non_fw_prefix(s, lc) { - lc = tolower(s) - return lc ~ "^(dnsmasq|procd|ubusd|netifd|odhcpd|logd|dropbear|uhttpd|hostapd|wpad)([^a-z0-9_]|$)" -} -function detect_action(s, words, n, i, w, wl, lc, start, pos, before, afterc, best, bestpos) { - n = split("ACCEPT ALLOW PASS DROP REJECT DENY BLOCK", words, " ") - lc = tolower(s) - best = "" - bestpos = length(s) + 1 - for (i = 1; i <= n; i++) { - w = words[i] - wl = tolower(w) - start = 1 - while (start <= length(lc) && match(substr(lc, start), wl)) { - pos = start + RSTART - 1 - before = (pos == 1) ? " " : substr(lc, pos - 1, 1) - afterc = substr(lc, pos + length(wl), 1) - if (before !~ /[a-z0-9_]/ && (afterc == "" || afterc !~ /[a-z0-9_]/)) { - if (pos < bestpos) { bestpos = pos; best = w } - break - } - start = pos + 1 - } - } - return best == "" ? "UNKNOWN" : best -} -function json_unhex4(h, n, i, c, v) { - n = 0 - h = tolower(h) - for (i = 1; i <= 4; i++) { - c = substr(h, i, 1) - v = index("0123456789abcdef", c) - if (v == 0) return -1 - n = n * 16 + v - 1 - } - return n -} -function json_get_msg(obj, s, i, c, esc, out, hex, n) { - if (!match(obj, /"msg"[[:space:]]*:[[:space:]]*"/)) return "" - s = substr(obj, RSTART + RLENGTH) - out = "" - esc = 0 - for (i = 1; i <= length(s); i++) { - c = substr(s, i, 1) - if (esc) { - if (c == "n") out = out "\n" - else if (c == "t") out = out "\t" - else if (c == "r") out = out "\r" - else if (c == "b") out = out "\b" - else if (c == "f") out = out "\f" - else if (c == "u") { - hex = substr(s, i + 1, 4) - n = (length(hex) == 4) ? json_unhex4(hex) : -1 - if (n >= 1 && n <= 255) out = out sprintf("%c", n) - else if (n < 0) out = out "u" - if (n >= 0) i += 4 - } else out = out c - esc = 0 - } else if (c == "\\") { - esc = 1 - } else if (c == "\"") { - return out - } else { - out = out c - } - } - return out -} -function is_fw(s, action) { - s = trim(normalize(s)) - if (s == "") return 0 - if (non_fw_prefix(s)) return 0 - action = detect_action(s) - if (has_kv(s, "SRC") && has_kv(s, "DST")) return 1 - if ((has_kv(s, "IN") || has_kv(s, "OUT")) && (has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO") || has_kv(s, "SPT") || has_kv(s, "DPT"))) return 1 - if (action != "UNKNOWN" && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "PROTO") || has_kv(s, "SRC") || has_kv(s, "DST"))) return 1 - if (has_hint(s) && action != "UNKNOWN") return 1 - if (has_hint(s) && (has_kv(s, "IN") || has_kv(s, "OUT") || has_kv(s, "SRC") || has_kv(s, "DST") || has_kv(s, "PROTO"))) return 1 - return 0 -} -BEGIN { if (MODE != "json") ORS = "" } -{ - if (MODE == "json") { - msg = json_get_msg($0) - if (is_fw(msg)) { - if (out_n++) printf "," - printf "%s", $0 - } - next - } - buf = (NR == 1) ? $0 : buf "\n" $0 -} -END { - if (MODE != "json") - print is_fw(buf) ? 1 : 0 -} -AWK -)" + awk -v MODE="${1:-msg}" -f "$CLASSIFY_AWK" } is_firewall_event_msg() { diff --git a/luci-app-fwlive/root/usr/libexec/fwlive-log-filter.sh b/luci-app-fwlive/root/usr/libexec/fwlive-log-filter.sh index c8f41459..5c2458fd 100755 --- a/luci-app-fwlive/root/usr/libexec/fwlive-log-filter.sh +++ b/luci-app-fwlive/root/usr/libexec/fwlive-log-filter.sh @@ -25,8 +25,12 @@ FILTER_DIR="$(cd "$(dirname "$0")" && pwd)" # shellcheck disable=SC1091 # classifier is a sibling file next to this script . "$FILTER_DIR/fwlive-is-firewall-event.sh" -input="$(cat)" -[ -n "$input" ] || input='{"log":[]}' +# The classifier is a package asset, not generated at request time. Fail +# closed if an incomplete install or a damaged package removed it (#321). +if [ ! -r "$CLASSIFY_AWK" ]; then + printf '%s' '{"log":[],"error":"classifier_missing"}' + exit 1 +fi printf '%s' '{"log":[' # Prefer stdin over -s: Linux MAX_ARG_STRLEN is 128KiB; a raised logd ring @@ -34,5 +38,5 @@ printf '%s' '{"log":[' # while this script still printed {"log":[]} and exited 0 (#234). # jsonfilter miss / empty @.log is not fatal; must still close JSON (#220). # set -e + pipefail cannot apply to this pipeline (#291 C3). -printf '%s' "$input" | jsonfilter -e '@.log[*]' 2>/dev/null | _fwlive_filter_json_entries || true +jsonfilter -e '@.log[*]' 2>/dev/null | _fwlive_filter_json_entries || true printf '%s' ']}' diff --git a/luci-app-wwand/Makefile b/luci-app-wwand/Makefile index 3923aedb..5a79e0c1 100644 --- a/luci-app-wwand/Makefile +++ b/luci-app-wwand/Makefile @@ -3,8 +3,10 @@ # the Modems editor, live settings, and the shared resources (wwand.bands / # wwand.modemopts / wwand.simlist) reused by the proto handler. # -# Sources live in https://github.com/ddimension/luci-app-wwand — bump -# PKG_SOURCE_VERSION (and PKG_SOURCE_DATE) to pick up new source commits. +# Sources live in https://github.com/ddimension/luci-app-wwand, tagged vX.Y.Z +# together with wwand. Pin a new commit with +# `scripts/bump-source.sh luci-app-wwand `: it derives PKG_VERSION +# (X.Y.Z at a tag, X.Y.Z_pN after it), PKG_RELEASE and the mirror hash. # # NOTE: built from a git PKG_SOURCE, so it does NOT use luci.mk — luci.mk's # htdocs/root install is gated on those dirs living next to the Makefile @@ -15,12 +17,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-wwand -PKG_RELEASE:=17 +PKG_VERSION:=1.6.6_p3 +PKG_RELEASE:=18 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/ddimension/luci-app-wwand.git -PKG_SOURCE_VERSION:=db03f95603aa70ef3682d462cfe476f935374392 -PKG_SOURCE_DATE:=2026-09-11 +PKG_SOURCE_VERSION:=4676454a1a8356de565fc02e44f66a6813c66b09 PKG_MIRROR_HASH:=skip PKG_LICENSE:=GPL-2.0-only @@ -44,16 +46,68 @@ endef define Build/Compile endef +define Package/luci-app-wwand-statistics + SECTION:=luci + CATEGORY:=LuCI + SUBMENU:=3. Applications + TITLE:=wwand graphs for luci-app-statistics + DEPENDS:=+luci-app-statistics +wwand + PKGARCH:=all +endef + +define Package/luci-app-wwand-statistics/description + RRD graph definitions for the data `wwandctl collectd` feeds into collectd: + signal strength, band power, quality, SINR, modem temperature and state, one + line per radio technology. + + Split out because it drops a file into luci-app-statistics' own resource tree, + which is only meaningful when that app is installed — luci-app-statistics + lists that directory at runtime, so nothing over there has to know about us. + + Feeding it needs no extra package at all: + + config statistics 'collectd_exec' + option enable '1' + + config collectd_exec_input + option cmdline '/usr/bin/wwandctl collectd' +endef + +# Named, not globbed. The same rule the wwand package follows for its ucode +# sources: a wildcard install silently ships whatever happens to be in the tree, +# so a file added for one package lands in another — which is exactly how the +# statistics graph definition would have been installed on boxes with no +# luci-app-statistics. A new resource has to be added here, and that is the +# point of listing them. +LUCI_WWAND_VIEW:=modems.js settings.js status.js +LUCI_WWAND_RES:=bands.js esim.js format.js graph.js mccmnc.js modemopts.js \ + modemsid.js netsel.js rpc.js signal.svg simlist.js + define Package/luci-app-wwand/install - $(INSTALL_DIR) $(1)/www/luci-static/resources - $(CP) $(PKG_BUILD_DIR)/htdocs/luci-static/resources/* \ - $(1)/www/luci-static/resources/ + $(INSTALL_DIR) $(1)/www/luci-static/resources/view/wwand + $(INSTALL_DIR) $(1)/www/luci-static/resources/wwand + for f in $(LUCI_WWAND_VIEW); do \ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/htdocs/luci-static/resources/view/wwand/$$$$f \ + $(1)/www/luci-static/resources/view/wwand/ ; \ + done + for f in $(LUCI_WWAND_RES); do \ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/htdocs/luci-static/resources/wwand/$$$$f \ + $(1)/www/luci-static/resources/wwand/ ; \ + done $(INSTALL_DIR) $(1)/usr/share/luci/menu.d - $(INSTALL_DATA) $(PKG_BUILD_DIR)/root/usr/share/luci/menu.d/*.json \ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/root/usr/share/luci/menu.d/luci-app-wwand.json \ $(1)/usr/share/luci/menu.d/ $(INSTALL_DIR) $(1)/usr/share/rpcd/acl.d - $(INSTALL_DATA) $(PKG_BUILD_DIR)/root/usr/share/rpcd/acl.d/*.json \ + $(INSTALL_DATA) $(PKG_BUILD_DIR)/root/usr/share/rpcd/acl.d/luci-app-wwand.json \ $(1)/usr/share/rpcd/acl.d/ endef +define Package/luci-app-wwand-statistics/install + $(INSTALL_DIR) $(1)/www/luci-static/resources/statistics/rrdtool/definitions + $(INSTALL_DATA) \ + $(PKG_BUILD_DIR)/htdocs/luci-static/resources/statistics/rrdtool/definitions/wwand.js \ + $(1)/www/luci-static/resources/statistics/rrdtool/definitions/ +endef + $(eval $(call BuildPackage,luci-app-wwand)) +$(eval $(call BuildPackage,luci-app-wwand-statistics)) diff --git a/luci-proto-wwand/Makefile b/luci-proto-wwand/Makefile index 3a16835e..11cf4a97 100644 --- a/luci-proto-wwand/Makefile +++ b/luci-proto-wwand/Makefile @@ -5,8 +5,10 @@ # file collision, good-citizen coexistence), and interfaces are moved to # `proto wwand` via the migration list in the LuCI modem page. # -# Sources live in https://github.com/ddimension/luci-proto-wwand — bump -# PKG_SOURCE_VERSION (and PKG_SOURCE_DATE) to pick up new source commits. +# Sources live in https://github.com/ddimension/luci-proto-wwand, tagged vX.Y.Z +# together with wwand. Pin a new commit with +# `scripts/bump-source.sh luci-proto-wwand `: it derives PKG_VERSION +# (X.Y.Z at a tag, X.Y.Z_pN after it), PKG_RELEASE and the mirror hash. # # NOTE: this is built from a git PKG_SOURCE, so it does NOT use luci.mk. luci.mk # gates its htdocs/root install on those directories living NEXT TO the Makefile @@ -18,12 +20,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-proto-wwand -PKG_RELEASE:=9 +PKG_VERSION:=1.6.6_p1 +PKG_RELEASE:=10 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/ddimension/luci-proto-wwand.git -PKG_SOURCE_VERSION:=a094000b65d69b1b8048f6c6523fc6457980f33e -PKG_SOURCE_DATE:=2026-09-10 +PKG_SOURCE_VERSION:=6e214de502bae28cb4badb82f4a8c0674b760aa8 PKG_MIRROR_HASH:=skip PKG_LICENSE:=GPL-2.0-only diff --git a/wwand/Makefile b/wwand/Makefile index 7dbe7085..75c32b70 100644 --- a/wwand/Makefile +++ b/wwand/Makefile @@ -37,18 +37,24 @@ # CONFIG_WWAND_UCODE_SOURCE. # # NOTE: the split needs the ucode source that lazy-loads every backend -# (qmi_lazy.uc + the backend-neutral daemon). Bump PKG_SOURCE_VERSION (and -# PKG_SOURCE_DATE / PKG_MIRROR_HASH) to a wwand commit that includes them. +# (qmi_lazy.uc + the backend-neutral daemon), i.e. a wwand commit that +# includes them. +# +# Version: PKG_VERSION is the wwand release the pinned commit belongs to — +# X.Y.Z for the tag vX.Y.Z (what stable ships), X.Y.Z_pN for N commits after +# it (main). Do not bump by hand: `scripts/bump-source.sh wwand ` +# sets PKG_SOURCE_VERSION, PKG_VERSION, PKG_RELEASE and PKG_MIRROR_HASH +# together. include $(TOPDIR)/rules.mk PKG_NAME:=wwand -PKG_RELEASE:=31 +PKG_VERSION:=1.6.6_p16 +PKG_RELEASE:=32 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://github.com/ddimension/wwand.git -PKG_SOURCE_VERSION:=c27f72e6c35d055d7abbf13eacfbc3bf2e9780a4 -PKG_SOURCE_DATE:=2026-09-11 +PKG_SOURCE_VERSION:=78e295b05c360787631f914e389d7394c092ba4a PKG_MIRROR_HASH:=skip PKG_LICENSE:=GPL-2.0-only