From bbafcfb069edac1f17782d535f29aea77fb6e905 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=97=D1=83=D0=B1?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 21 Aug 2026 19:00:09 +0300 Subject: [PATCH 1/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20opt-in=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D1=8C=20?= =?UTF-8?q?BJ=20regdb?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.sh | 33 ++++++--- .../0001-wireless-regdb-run-customizer.patch | 9 ++- scripts/customize-wireless-regdb.py | 70 ++++++------------- scripts/verify-custom-regdb.sh | 25 ++++--- 4 files changed, 63 insertions(+), 74 deletions(-) diff --git a/build.sh b/build.sh index 92defee..6d89ce9 100755 --- a/build.sh +++ b/build.sh @@ -5,6 +5,13 @@ PROJECT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$PROJECT_DIR/scripts/versions.env" BUILDROOT="${BUILDROOT:-$PROJECT_DIR/.work/openwrt}" JOBS="${JOBS:-$(nproc)}" +CUSTOM_WIRELESS_REGDB="${CUSTOM_WIRELESS_REGDB:-0}" + +case "$CUSTOM_WIRELESS_REGDB" in + 0|1) ;; + *) echo "CUSTOM_WIRELESS_REGDB must be 0 or 1" >&2; exit 2;; +esac +export CUSTOM_WIRELESS_REGDB require() { command -v "$1" >/dev/null || { echo "missing required command: $1" >&2; exit 1; }; } require git @@ -25,14 +32,18 @@ fi REGDB_PACKAGE_DIR="$BUILDROOT/package/firmware/wireless-regdb" REGDB_PATCH="$PROJECT_DIR/patches/openwrt/0001-wireless-regdb-run-customizer.patch" -install -D -m 0755 "$PROJECT_DIR/scripts/customize-wireless-regdb.py" "$REGDB_PACKAGE_DIR/customize-wireless-regdb.py" -if git -C "$BUILDROOT" apply --reverse --check "$REGDB_PATCH" 2>/dev/null; then - : -elif git -C "$BUILDROOT" apply --check "$REGDB_PATCH" 2>/dev/null; then - git -C "$BUILDROOT" apply "$REGDB_PATCH" -else - echo "wireless-regdb customization patch does not apply to the pinned OpenWrt source" >&2 - exit 1 +if [[ "$CUSTOM_WIRELESS_REGDB" = 1 ]]; then + install -D -m 0755 "$PROJECT_DIR/scripts/customize-wireless-regdb.py" "$REGDB_PACKAGE_DIR/customize-wireless-regdb.py" + if git -C "$BUILDROOT" apply --ignore-space-change --reverse --check "$REGDB_PATCH" 2>/dev/null; then + : + elif git -C "$BUILDROOT" apply --ignore-space-change --check "$REGDB_PATCH" 2>/dev/null; then + git -C "$BUILDROOT" apply --ignore-space-change "$REGDB_PATCH" + else + echo "wireless-regdb customization patch does not apply to the pinned OpenWrt source" >&2 + exit 1 + fi +elif git -C "$BUILDROOT" apply --ignore-space-change --reverse --check "$REGDB_PATCH" 2>/dev/null; then + git -C "$BUILDROOT" apply --ignore-space-change --reverse "$REGDB_PATCH" fi if ! grep -Fqx "src-git-full awg $AMNEZIAWG_FEED_REPOSITORY^$AMNEZIAWG_FEED_COMMIT" "$BUILDROOT/feeds.conf.default"; then @@ -99,12 +110,14 @@ AMNEZIAWG_VERSION=$AMNEZIAWG_KERNEL_MODULE_VERSION AMNEZIAWG_COMMIT=$AMNEZIAWG_FEED_COMMIT PODKOP_VERSION=$PODKOP_VERSION PODKOP_COMMIT=$PODKOP_COMMIT -CUSTOM_WIRELESS_REGDB=1 +CUSTOM_WIRELESS_REGDB=$CUSTOM_WIRELESS_REGDB EOF make download -j"$JOBS" make -j"$JOBS" V=s popd >/dev/null -BUILDROOT="$BUILDROOT" bash "$PROJECT_DIR/scripts/verify-custom-regdb.sh" +if [[ "$CUSTOM_WIRELESS_REGDB" = 1 ]]; then + BUILDROOT="$BUILDROOT" bash "$PROJECT_DIR/scripts/verify-custom-regdb.sh" +fi BUILDROOT="$BUILDROOT" "$PROJECT_DIR/scripts/collect-artifacts.sh" BUILDROOT="$BUILDROOT" "$PROJECT_DIR/scripts/verify-build.sh" diff --git a/patches/openwrt/0001-wireless-regdb-run-customizer.patch b/patches/openwrt/0001-wireless-regdb-run-customizer.patch index 166f7a6..a6f0304 100644 --- a/patches/openwrt/0001-wireless-regdb-run-customizer.patch +++ b/patches/openwrt/0001-wireless-regdb-run-customizer.patch @@ -2,12 +2,15 @@ diff --git a/package/firmware/wireless-regdb/Makefile b/package/firmware/wireles index d895d98..7db582a 100644 --- a/package/firmware/wireless-regdb/Makefile +++ b/package/firmware/wireless-regdb/Makefile -@@ -23,6 +23,8 @@ define Package/wireless-regdb +@@ -23,6 +23,11 @@ define Package/wireless-regdb endef define Build/Compile -+ $(STAGING_DIR_HOST)/bin/$(PYTHON) $(CURDIR)/customize-wireless-regdb.py $(PKG_BUILD_DIR)/db.txt $(PKG_BUILD_DIR)/db.txt.custom -+ mv $(PKG_BUILD_DIR)/db.txt.custom $(PKG_BUILD_DIR)/db.txt ++ @if [ "$(CUSTOM_WIRELESS_REGDB)" = "1" ]; then \\ ++ cp $(PKG_BUILD_DIR)/db.txt $(PKG_BUILD_DIR)/db.txt.stock; \\ ++ $(STAGING_DIR_HOST)/bin/$(PYTHON) $(CURDIR)/customize-wireless-regdb.py $(PKG_BUILD_DIR)/db.txt $(PKG_BUILD_DIR)/db.txt.custom; \\ ++ mv $(PKG_BUILD_DIR)/db.txt.custom $(PKG_BUILD_DIR)/db.txt; \\ ++ fi $(STAGING_DIR_HOST)/bin/$(PYTHON) $(PKG_BUILD_DIR)/db2fw.py $(PKG_BUILD_DIR)/regulatory.db $(PKG_BUILD_DIR)/db.txt endef diff --git a/scripts/customize-wireless-regdb.py b/scripts/customize-wireless-regdb.py index 572d20b..01e11b6 100644 --- a/scripts/customize-wireless-regdb.py +++ b/scripts/customize-wireless-regdb.py @@ -1,9 +1,9 @@ #!/usr/bin/env python3 -"""Replace every country regulatory block with the Flint 2 custom template. +"""Append an opt-in BJ profile without changing existing wireless-regdb rules. The OpenWrt wireless-regdb package still performs the actual db.txt -> -regulatory.db compilation with its pinned db2fw.py. This helper only rewrites -its textual input immediately before that compile step. +regulatory.db compilation with its pinned db2fw.py. This helper preserves all +existing country profiles and only appends BJ when that country is absent. """ from __future__ import annotations @@ -29,48 +29,22 @@ ) COUNTRY_RE = re.compile(r"^country\s+([A-Z0-9]{2}):.*$") -TOP_LEVEL_RE = re.compile(r"^(?:country\s+[A-Z0-9]{2}:|wmmrule\s+)") -def is_comment(line: str) -> bool: - return line.lstrip().startswith("#") +def transform(lines: list[str]) -> tuple[list[str], bool]: + """Return the unchanged source, adding BJ only if it does not exist.""" + countries = [COUNTRY_RE.match(line.rstrip("\n")) for line in lines] + if any(match and match.group(1) == "BJ" for match in countries): + return lines, False - -def transform(lines: list[str]) -> tuple[list[str], int]: - out: list[str] = [] - countries = 0 - i = 0 - - while i < len(lines): - line = lines[i] - - if is_comment(line): - i += 1 - continue - - match = COUNTRY_RE.match(line.rstrip("\n")) - if match: - cc = match.group(1) - countries += 1 - out.append(f"country {cc}:\n") - out.extend(f"{rule}\n" for rule in TEMPLATE_LINES) - out.append("\n") - - # Consume the complete original country body. This deliberately - # also discards blank/comment lines inside the block so a source - # update cannot leave an orphaned regulatory rule behind. - i += 1 - while i < len(lines): - candidate = lines[i] - if TOP_LEVEL_RE.match(candidate): - break - i += 1 - continue - - out.append(line) - i += 1 - - return out, countries + out = list(lines) + if out and not out[-1].endswith("\n"): + out[-1] = f"{out[-1]}\n" + if out and out[-1].strip(): + out.append("\n") + out.append("country BJ:\n") + out.extend(f"{rule}\n" for rule in TEMPLATE_LINES) + return out, True def main() -> int: @@ -81,19 +55,15 @@ def main() -> int: input_path = Path(sys.argv[1]) output_path = Path(sys.argv[2]) original = input_path.read_text(encoding="utf-8").splitlines(keepends=True) - transformed, country_count = transform(original) - - if country_count < 1: - print("wireless-regdb customization failed: no country blocks found", file=sys.stderr) - return 1 + transformed, added = transform(original) rendered = "".join(transformed) - if "(5150 - 5350 @ 160), (36)" not in rendered or "(5925 - 7125 @ 320), (36)" not in rendered: - print("wireless-regdb customization failed: template validation failed", file=sys.stderr) + if "country BJ:\n" not in rendered or " (5150 - 5350 @ 160), (36)\n" not in rendered or " (5925 - 7125 @ 320), (36)\n" not in rendered: + print("wireless-regdb customization failed: BJ template validation failed", file=sys.stderr) return 1 output_path.write_text(rendered, encoding="utf-8") - print(f"customized wireless-regdb: replaced {country_count} country blocks") + print(f"customized wireless-regdb: {'added' if added else 'retained'} country BJ") return 0 diff --git a/scripts/verify-custom-regdb.sh b/scripts/verify-custom-regdb.sh index 3b9b412..71601fa 100644 --- a/scripts/verify-custom-regdb.sh +++ b/scripts/verify-custom-regdb.sh @@ -9,25 +9,28 @@ fail() { echo "CUSTOM REGDB VERIFY FAILED: $*" >&2; exit 1; } grep -qx 'CONFIG_PACKAGE_wireless-regdb=y' "$BUILDROOT/.config" || fail "wireless-regdb package is not selected" DB_TXT="$(find "$BUILDROOT/build_dir" -type f -path '*/wireless-regdb-*/db.txt' -print -quit)" +STOCK_DB_TXT="$(find "$BUILDROOT/build_dir" -type f -path '*/wireless-regdb-*/db.txt.stock' -print -quit)" REGDB="$(find "$BUILDROOT/build_dir" -type f -path '*/root-mediatek/lib/firmware/regulatory.db' -print -quit)" MANIFEST="$(find "$BUILDROOT/bin/targets/mediatek/filogic" -maxdepth 1 -type f -name '*gl-mt6000*.manifest' -print -quit)" test -n "$DB_TXT" || fail "customized wireless-regdb db.txt was not found" +test -n "$STOCK_DB_TXT" || fail "stock wireless-regdb db.txt snapshot was not found" test -s "$REGDB" || fail "regulatory.db is absent from the root filesystem" test -n "$MANIFEST" || fail "firmware manifest was not found" -grep -Fq '(2400 - 2483.5 @ 40), (36)' "$DB_TXT" || fail "2.4 GHz custom rule is absent" -grep -Fq '(5150 - 5350 @ 160), (36)' "$DB_TXT" || fail "5 GHz custom rule is absent" -grep -Fq '(5470 - 5730 @ 160), (36)' "$DB_TXT" || fail "upper 5 GHz custom rule is absent" -grep -Fq '(5925 - 7125 @ 320), (36)' "$DB_TXT" || fail "6 GHz custom rule is absent" -grep -Fq '(57000 - 71000 @ 2160), (44)' "$DB_TXT" || fail "60 GHz custom rule is absent" +extract_country() { + awk -v header="country $1:" '$0 == header { inside = 1 } inside { if ($0 ~ /^country [A-Z0-9][A-Z0-9]:/ && $0 != header) exit; print }' "$2" +} -grep -q '^wireless-regdb - ' "$MANIFEST" || fail "wireless-regdb is absent from firmware manifest" +grep -qx 'country BJ:' "$DB_TXT" || fail "country BJ is absent" +stock_world="$(extract_country 00 "$STOCK_DB_TXT")" +custom_world="$(extract_country 00 "$DB_TXT")" +test -n "$stock_world" || fail "stock country 00 is absent" +test -n "$custom_world" || fail "custom country 00 is absent" +diff -u <(printf '%s\n' "$stock_world") <(printf '%s\n' "$custom_world") >/dev/null || fail "country 00 was modified" +extract_country BJ "$DB_TXT" | grep -Fxq ' (5150 - 5350 @ 160), (36)' || fail "BJ 5150-5350 rule is absent" +extract_country BJ "$DB_TXT" | grep -Fxq ' (5925 - 7125 @ 320), (36)' || fail "BJ 5925-7125 rule is absent" -# The customizer intentionally removes country DFS-region suffixes. Spot-check -# a few common domains to catch accidental fallback to the stock source. -for cc in RU US DE; do - grep -qx "country $cc:" "$DB_TXT" || fail "country $cc was not customized" -done +grep -q '^wireless-regdb - ' "$MANIFEST" || fail "wireless-regdb is absent from firmware manifest" printf 'CUSTOM REGDB VERIFY PASSED: %s (%s bytes)\n' "$REGDB" "$(stat -c '%s' "$REGDB")" From 518577b3119791dc0dcc4d7ea9cdb958b8baf9ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D0=B4=D1=80=D0=B5=D0=B9=20=D0=97=D1=83=D0=B1?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=BA=D0=BE?= Date: Fri, 21 Aug 2026 23:08:57 +0300 Subject: [PATCH 2/2] =?UTF-8?q?=D0=A3=D1=81=D0=B8=D0=BB=D0=B5=D0=BD=D0=B0?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D1=8F=20BJ?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/customize-wireless-regdb.py | 6 +++--- scripts/verify-custom-regdb.sh | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/scripts/customize-wireless-regdb.py b/scripts/customize-wireless-regdb.py index 01e11b6..71a2229 100644 --- a/scripts/customize-wireless-regdb.py +++ b/scripts/customize-wireless-regdb.py @@ -40,8 +40,6 @@ def transform(lines: list[str]) -> tuple[list[str], bool]: out = list(lines) if out and not out[-1].endswith("\n"): out[-1] = f"{out[-1]}\n" - if out and out[-1].strip(): - out.append("\n") out.append("country BJ:\n") out.extend(f"{rule}\n" for rule in TEMPLATE_LINES) return out, True @@ -58,7 +56,9 @@ def main() -> int: transformed, added = transform(original) rendered = "".join(transformed) - if "country BJ:\n" not in rendered or " (5150 - 5350 @ 160), (36)\n" not in rendered or " (5925 - 7125 @ 320), (36)\n" not in rendered: + if "country BJ:\n" not in rendered or ( + added and any(f"{rule}\n" not in rendered for rule in TEMPLATE_LINES) + ): print("wireless-regdb customization failed: BJ template validation failed", file=sys.stderr) return 1 diff --git a/scripts/verify-custom-regdb.sh b/scripts/verify-custom-regdb.sh index 71601fa..9b737fb 100644 --- a/scripts/verify-custom-regdb.sh +++ b/scripts/verify-custom-regdb.sh @@ -19,9 +19,33 @@ test -s "$REGDB" || fail "regulatory.db is absent from the root filesystem" test -n "$MANIFEST" || fail "firmware manifest was not found" extract_country() { - awk -v header="country $1:" '$0 == header { inside = 1 } inside { if ($0 ~ /^country [A-Z0-9][A-Z0-9]:/ && $0 != header) exit; print }' "$2" + awk -v country="$1" ' + $0 ~ ("^country " country ":") { inside = 1 } + inside { + if ($0 ~ /^country [A-Z0-9][A-Z0-9]:/ && $0 !~ ("^country " country ":")) exit + print + } + ' "$2" } +country_codes() { + awk '/^country [A-Z0-9][A-Z0-9]:/ { print substr($2, 1, 2) }' "$1" +} + +stock_countries="$(country_codes "$STOCK_DB_TXT")" +if grep -Fxq 'BJ' <<< "$stock_countries"; then + expected_countries="$stock_countries" +else + expected_countries="${stock_countries}"$'\nBJ' +fi +custom_countries="$(country_codes "$DB_TXT")" +diff -u <(printf '%s\n' "$expected_countries") <(printf '%s\n' "$custom_countries") >/dev/null || fail "country list was modified unexpectedly" + +while IFS= read -r country; do + test -n "$country" || continue + diff -u <(extract_country "$country" "$STOCK_DB_TXT") <(extract_country "$country" "$DB_TXT") >/dev/null || fail "country $country was modified" +done <<< "$stock_countries" + grep -qx 'country BJ:' "$DB_TXT" || fail "country BJ is absent" stock_world="$(extract_country 00 "$STOCK_DB_TXT")" custom_world="$(extract_country 00 "$DB_TXT")"