refactor(esp_wifi): migrate regulatory tools to esp-pylib

Replace ad-hoc print/raise patterns in reg_parse.py and reg2fw.py with
esp_pylib.logger log.warn/log.die and install_exception_reporting().

Signed-off-by: Chen Yudong <chenyudong@espressif.com>
This commit is contained in:
Chen Yudong
2026-07-01 09:28:11 +08:00
parent 9d263e3725
commit b8a23f8a0e
3 changed files with 26 additions and 21 deletions
+1 -1
View File
@@ -6,5 +6,5 @@
`esp_wifi_regulatory.c` is generated from `esp_wifi_regulatory.txt` by using the `reg2fw.py` script. `esp_wifi_regulatory.c` is generated from `esp_wifi_regulatory.txt` by using the `reg2fw.py` script.
- Generate `esp_wifi_regulatory.c` - Generate `esp_wifi_regulatory.c`
- `cd ~/esp-idf/components/esp_wifi/regulatory` - `cd ${IDF_PATH}/components/esp_wifi/regulatory`
- `python reg2fw.py` - `python reg2fw.py`
+14 -8
View File
@@ -5,8 +5,10 @@ import os
from datetime import datetime from datetime import datetime
from typing import TextIO from typing import TextIO
from esp_pylib.logger import log
from reg_parse import DBParser from reg_parse import DBParser
from reg_parse import Regdomain from reg_parse import Regdomain
from rich.markup import escape
# Not a valid ISO 3166-1 alpha-2 code; marks end of regdomain_table for linear scans (matches wifi_regdomain_t.cn[2]). # Not a valid ISO 3166-1 alpha-2 code; marks end of regdomain_table for linear scans (matches wifi_regdomain_t.cn[2]).
REGDOMAIN_TABLE_SENTINEL_CC = '##' REGDOMAIN_TABLE_SENTINEL_CC = '##'
@@ -95,7 +97,7 @@ def main() -> None:
mtime = os.path.getmtime(file_path) mtime = os.path.getmtime(file_path)
copyright_year = datetime.fromtimestamp(mtime).year copyright_year = datetime.fromtimestamp(mtime).year
except FileNotFoundError: except FileNotFoundError:
raise Exception(f'File {file_path} not found') log.die(f'File {file_path} not found')
reg.simplify_countries(regdomains) reg.simplify_countries(regdomains)
reg.simplify_countries_2g(regdomains) reg.simplify_countries_2g(regdomains)
@@ -111,11 +113,11 @@ def main() -> None:
max_rules_count = max_rules_country[1] max_rules_count = max_rules_country[1]
max_rules_countries = [cc for cc, count in country_rules_count.items() if count == max_rules_count] max_rules_countries = [cc for cc, count in country_rules_count.items() if count == max_rules_count]
print('\n=== Regulatory Statistics ===') log.print('\n=== Regulatory Statistics ===')
print(f'Total supported countries: {total_countries}') log.print(f'Total supported countries: {total_countries}')
print(f'Country(ies) with most rules: {", ".join(max_rules_countries)}') log.print(f'Country(ies) with most rules: {", ".join(max_rules_countries)}')
print(f'Maximum number of rules: {max_rules_count}') log.print(f'Maximum number of rules: {max_rules_count}')
print('=' * 30 + '\n') log.print('=' * 30 + '\n')
type_list = list(reg.typical_regulatory.keys()) type_list = list(reg.typical_regulatory.keys())
perm_list = list(reg.typical_regulatory.values()) perm_list = list(reg.typical_regulatory.values())
@@ -124,8 +126,9 @@ def main() -> None:
perm_list_2g = list(reg.typical_regulatory_2g.values()) perm_list_2g = list(reg.typical_regulatory_2g.values())
output_file = 'esp_wifi_regulatory.c' output_file = 'esp_wifi_regulatory.c'
output_file_path = os.path.join(directory, output_file)
with open(output_file, 'w') as cfile: with open(output_file_path, 'w') as cfile:
cfile.write('/*\n') cfile.write('/*\n')
cfile.write(f' * SPDX-FileCopyrightText: 2025-{copyright_year} Espressif Systems (Shanghai) CO LTD\n') cfile.write(f' * SPDX-FileCopyrightText: 2025-{copyright_year} Espressif Systems (Shanghai) CO LTD\n')
cfile.write(' *\n') cfile.write(' *\n')
@@ -143,8 +146,11 @@ def main() -> None:
write_regulatory_data(cfile, reg, type_list_2g, perm_list_2g, filter_5g=False) write_regulatory_data(cfile, reg, type_list_2g, perm_list_2g, filter_5g=False)
cfile.write('#endif // CONFIG_SOC_WIFI_SUPPORT_5G\n') cfile.write('#endif // CONFIG_SOC_WIFI_SUPPORT_5G\n')
print(f'{output_file} generated successfully.') log.print(f'{escape(output_file)} generated successfully.')
if __name__ == '__main__': if __name__ == '__main__':
from esp_pylib.excepthook import install_exception_reporting
install_exception_reporting()
main() main()
+10 -11
View File
@@ -23,14 +23,15 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import math import math
import sys
from collections import OrderedDict from collections import OrderedDict
from collections import defaultdict from collections import defaultdict
from collections.abc import Callable
from functools import total_ordering from functools import total_ordering
from math import ceil from math import ceil
from typing import TextIO from typing import TextIO
from esp_pylib.logger import log
from rich.markup import escape
flag_definitions: dict[str, int] = { flag_definitions: dict[str, int] = {
'NO-OFDM': 1 << 0, 'NO-OFDM': 1 << 0,
'NO-CCK': 1 << 1, 'NO-CCK': 1 << 1,
@@ -291,13 +292,8 @@ class Country:
permissions_2g = property(_get_permissions_2g_tuple) permissions_2g = property(_get_permissions_2g_tuple)
class MySyntaxError(Exception):
pass
class DBParser: class DBParser:
def __init__(self, warn: Callable[[str], None] | None = None) -> None: def __init__(self) -> None:
self._warn_callout = warn or sys.stderr.write
self._lineno: int = 0 self._lineno: int = 0
self._comments: list[str] = [] self._comments: list[str] = []
self._banddup: dict[str, str] = {} self._banddup: dict[str, str] = {}
@@ -361,10 +357,10 @@ class DBParser:
def _syntax_error(self, txt: str | None = None) -> None: def _syntax_error(self, txt: str | None = None) -> None:
txt = f' ({txt})' if txt else '' txt = f' ({txt})' if txt else ''
raise MySyntaxError(f'Syntax error in line {self._lineno}{txt}') log.die(f'Syntax error in line {self._lineno}{escape(txt)}')
def _warn(self, txt: str) -> None: def _warn(self, txt: str) -> None:
self._warn(f'Warning (line {self._lineno}): {txt}\n') log.warn(f'line {self._lineno}: {escape(txt)}')
def channel_to_freq(self, channel: int) -> int: def channel_to_freq(self, channel: int) -> int:
if channel == 14: if channel == 14:
@@ -561,7 +557,10 @@ class DBParser:
self._warn(f"country '{cname}' not alpha2") self._warn(f"country '{cname}' not alpha2")
cname_bytes = cname.encode('ascii') cname_bytes = cname.encode('ascii')
if cname_bytes not in self._countries: if cname_bytes not in self._countries:
self._countries[cname_bytes] = Country(dfs_region, comments=self._comments) try:
self._countries[cname_bytes] = Country(dfs_region, comments=self._comments)
except DFSRegionError as e:
self._syntax_error(f'Invalid DFS region {e.dfs_region}')
self._current_countries[cname_bytes] = self._countries[cname_bytes] self._current_countries[cname_bytes] = self._countries[cname_bytes]
self._comments = [] self._comments = []