From 782dcaa7005b1b27b4fd8c813739ec0be774182f Mon Sep 17 00:00:00 2001 From: AmadeusGhost <42570690+AmadeusGhost@users.noreply.github.com> Date: Tue, 14 Apr 2020 10:39:11 +0800 Subject: [PATCH 1/3] wireless-regdb: bump to latest --- package/firmware/wireless-regdb/Makefile | 12 +- ...regdb-fix-compatibility-with-python2.patch | 58 ++ ...firmware-file-format-version-code-20.patch | 115 ---- .../patches/500-world-regd-5GHz.patch | 2 +- .../600-custom-fix-txpower-and-dfs.patch | 42 -- ...-regdb-fix-compatibility-with-python.patch | 615 ------------------ 6 files changed, 65 insertions(+), 779 deletions(-) create mode 100644 package/firmware/wireless-regdb/patches/010-regdb-fix-compatibility-with-python2.patch delete mode 100644 package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch delete mode 100644 package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch delete mode 100644 package/firmware/wireless-regdb/patches/700-regdb-fix-compatibility-with-python.patch diff --git a/package/firmware/wireless-regdb/Makefile b/package/firmware/wireless-regdb/Makefile index 47d36ea66b..26f470af44 100644 --- a/package/firmware/wireless-regdb/Makefile +++ b/package/firmware/wireless-regdb/Makefile @@ -1,21 +1,21 @@ include $(TOPDIR)/rules.mk PKG_NAME:=wireless-regdb +PKG_VERSION:=2019.06.03 -PKG_SOURCE_PROTO:=git -PKG_SOURCE_URL:=https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git -PKG_SOURCE_DATE:=2017-10-20 -PKG_SOURCE_VERSION:=4343d359ed5e7404de8803a74df186457b26ab79 -PKG_MIRROR_HASH:=5f5b669f32ae36cb65b1d99efbbbfd42c2983cda32f6448346e3e54ffaba3889 +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz +PKG_SOURCE_URL:=@KERNEL/software/network/wireless-regdb/ +PKG_HASH:=cd917ed86b63ce8d93947979f1f18948f03a4ac0ad89ec25227b36ac00dc54bf PKG_MAINTAINER:=Felix Fietkau include $(INCLUDE_DIR)/package.mk define Package/wireless-regdb + PKGARCH:=all SECTION:=firmware CATEGORY:=Firmware - URL:=$(patsubst pub/scm,cgit,$(PKG_SOURCE_URL)) + URL:=https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git/ TITLE:=Wireless Regulatory Database endef diff --git a/package/firmware/wireless-regdb/patches/010-regdb-fix-compatibility-with-python2.patch b/package/firmware/wireless-regdb/patches/010-regdb-fix-compatibility-with-python2.patch new file mode 100644 index 0000000000..81f50f5dc0 --- /dev/null +++ b/package/firmware/wireless-regdb/patches/010-regdb-fix-compatibility-with-python2.patch @@ -0,0 +1,58 @@ +From 651e39dee8605995b736b6056c6f7dc5c5a9c948 Mon Sep 17 00:00:00 2001 +From: Johannes Berg +Date: Thu, 22 Aug 2019 21:46:27 +0200 +Subject: [PATCH] regdb: fix compatibility with python2 + +Various changes in the commit mentioned below broke +compatibility with python2. Restore it in a way that +makes it worth with both versions. + +Fixes: f3c4969c2485 ("wireless-regdb: make scripts compatible with Python 3") +Signed-off-by: Johannes Berg +Signed-off-by: Seth Forshee +--- + db2bin.py | 2 +- + db2fw.py | 2 +- + dbparse.py | 3 +-- + 3 files changed, 3 insertions(+), 4 deletions(-) + +--- a/db2bin.py ++++ b/db2bin.py +@@ -118,7 +118,7 @@ reg_country_ptr.set() + for alpha2 in countrynames: + coll = countries[alpha2] + # struct regdb_file_reg_country +- output.write(struct.pack('>BBxBI', alpha2[0], alpha2[1], coll.dfs_region, reg_rules_collections[coll.permissions])) ++ output.write(struct.pack('>2sxBI', alpha2, coll.dfs_region, reg_rules_collections[coll.permissions])) + + + if len(sys.argv) > 3: +--- a/db2fw.py ++++ b/db2fw.py +@@ -85,7 +85,7 @@ countrynames = list(countries) + countrynames.sort() + for alpha2 in countrynames: + coll = countries[alpha2] +- output.write(struct.pack('>BB', alpha2[0], alpha2[1])) ++ output.write(struct.pack('>2s', alpha2)) + country_ptrs[alpha2] = PTR(output) + output.write(b'\x00' * 4) + +--- a/dbparse.py ++++ b/dbparse.py +@@ -1,6 +1,5 @@ + #!/usr/bin/env python + +-from builtins import bytes + from functools import total_ordering + import sys, math + from math import ceil, log +@@ -359,7 +358,7 @@ class DBParser(object): + for cname in cnames: + if len(cname) != 2: + self._warn("country '%s' not alpha2" % cname) +- cname = bytes(cname, 'ascii') ++ cname = cname.encode('ascii') + if not cname in self._countries: + self._countries[cname] = Country(dfs_region, comments=self._comments) + self._current_countries[cname] = self._countries[cname] diff --git a/package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch b/package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch deleted file mode 100644 index 0a2f6c8fa6..0000000000 --- a/package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch +++ /dev/null @@ -1,115 +0,0 @@ -From: Johannes Berg -Date: Mon, 9 Oct 2017 11:50:57 +0200 -Subject: [PATCH] regdb: write firmware file format (version code 20) - -TODO: clean up the Makefile stuff ... - -Signed-off-by: Johannes Berg ---- - create mode 100755 db2fw.py - ---- a/Makefile -+++ b/Makefile -@@ -1,7 +1,5 @@ - # Install prefix - PREFIX ?= /usr --CRDA_PATH ?= $(PREFIX)/lib/crda --CRDA_KEY_PATH ?= $(CRDA_PATH)/pubkeys - - MANDIR ?= $(PREFIX)/share/man/ - -@@ -30,39 +28,47 @@ REGDB_AUTHOR ?= $(shell if [ -f $(DISTRO - fi) - - REGDB_PRIVKEY ?= ~/.wireless-regdb-$(REGDB_AUTHOR).key.priv.pem --REGDB_PUBKEY ?= $(REGDB_AUTHOR).key.pub.pem -- --REGDB_UPSTREAM_PUBKEY ?= sforshee.key.pub.pem -+REGDB_PUBCERT ?= $(REGDB_AUTHOR).x509.pem - - REGDB_CHANGED = $(shell $(SHA1SUM) -c --status sha1sum.txt >/dev/null 2>&1; \ - if [ $$? -ne 0 ]; then \ -- echo maintainer-clean $(REGDB_PUBKEY); \ -+ echo maintainer-clean $(REGDB_PUBCERT); \ - fi) - - .PHONY: all clean mrproper install maintainer-clean install-distro-key - --all: $(REGDB_CHANGED) regulatory.bin sha1sum.txt -+all: $(REGDB_CHANGED) regulatory.db.p7s sha1sum.txt - - clean: - @rm -f *.pyc *.gz - - maintainer-clean: clean -- @rm -f regulatory.bin -+ @rm -f regulatory.db regulatory.db.p7s - - mrproper: clean maintainer-clean -- @echo Removed public key, regulatory.bin and compresed man pages -- @rm -f $(REGDB_PUBKEY) .custom -+ @echo Removed public key, regulatory.db* and compressed man pages -+ @rm -f $(REGDB_PUBCERT) .custom - --regulatory.bin: db.txt $(REGDB_PRIVKEY) $(REGDB_PUBKEY) -- @echo Generating $@ digitally signed by $(REGDB_AUTHOR)... -- ./db2bin.py regulatory.bin db.txt $(REGDB_PRIVKEY) -+regulatory.db: db.txt db2fw.py -+ @echo "Generating $@" -+ ./db2fw.py regulatory.db db.txt -+ -+regulatory.db.p7s: regulatory.db $(REGDB_PRIVKEY) $(REGDB_PUBCERT) -+ @echo "Signing regulatory.db (by $(REGDB_AUTHOR))..." -+ @openssl smime -sign \ -+ -signer $(REGDB_PUBCERT) \ -+ -inkey $(REGDB_PRIVKEY) \ -+ -in $< -nosmimecap -binary \ -+ -outform DER -out $@ - - sha1sum.txt: db.txt - sha1sum $< > $@ - --$(REGDB_PUBKEY): $(REGDB_PRIVKEY) -- @echo "Generating public key for $(REGDB_AUTHOR)..." -- openssl rsa -in $(REGDB_PRIVKEY) -out $(REGDB_PUBKEY) -pubout -outform PEM -+$(REGDB_PUBCERT): $(REGDB_PRIVKEY) -+ @echo "Generating certificate for $(REGDB_AUTHOR)..." -+ @openssl req -config regulatory.openssl.conf \ -+ -key $(REGDB_PRIVKEY) -days 36500 -utf8 -nodes -batch \ -+ -x509 -outform PEM -out $(REGDB_PUBCERT) - @echo $(REGDB_PUBKEY) > .custom - - -@@ -97,16 +103,7 @@ install-distro-key: maintainer-clean $(D - # make maintainer-clean - # make - # sudo make install --install: regulatory.bin.5.gz -- install -m 755 -d $(DESTDIR)/$(CRDA_PATH) -- install -m 755 -d $(DESTDIR)/$(CRDA_KEY_PATH) -- if [ -f .custom ]; then \ -- install -m 644 -t $(DESTDIR)/$(CRDA_KEY_PATH)/ $(shell cat .custom); \ -- fi -- install -m 644 -t $(DESTDIR)/$(CRDA_KEY_PATH)/ $(REGDB_UPSTREAM_PUBKEY) -- install -m 644 -t $(DESTDIR)/$(CRDA_PATH)/ regulatory.bin -+install: regulatory.db.5.gz -+ install -m 644 -t $(DESTDIR)/$(CRDA_PATH)/ regulatory.db - install -m 755 -d $(DESTDIR)/$(MANDIR)/man5/ -- install -m 644 -t $(DESTDIR)/$(MANDIR)/man5/ regulatory.bin.5.gz -- --uninstall: -- rm -rf $(DESTDIR)/$(CRDA_PATH)/ -+ install -m 644 -t $(DESTDIR)/$(MANDIR)/man5/ regulatory.db.5.gz ---- a/README -+++ b/README -@@ -18,8 +18,8 @@ python module is used by the web viewer - implemented as a MoinMoin macro (and used on http://wireless.kernel.org) - to allow viewing the database for verification. - --The dbparse module is also used by db2bin.py, the `compiler', which --compiles and signs the binary database. -+The dbparse module is also used by db2bin.py and db2fw.py, the `compilers' -+that compile the database to its binary formats. - - For more information, please see the CRDA git repository: - \ No newline at end of file diff --git a/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch b/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch index 9baba808bc..ae38f93537 100644 --- a/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch +++ b/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch @@ -5,7 +5,7 @@ Signed-off-by: Felix Fietkau --- --- a/db.txt +++ b/db.txt -@@ -6,7 +6,7 @@ country 00: +@@ -16,7 +16,7 @@ country 00: # Channel 14. Only JP enables this and for 802.11b only (2474 - 2494 @ 20), (20), NO-IR, NO-OFDM # Channel 36 - 48 diff --git a/package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch b/package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch deleted file mode 100644 index b1c9124449..0000000000 --- a/package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 7eb6313910023f1be6015a8cd9e1b380ae01af64 Mon Sep 17 00:00:00 2001 -From: Chen Minqiang -Date: Sun, 7 Jan 2018 14:38:36 +0800 -Subject: [PATCH] custom fix txpower and dfs - ---- - db.txt | 12 ++++++------ - 1 file changed, 6 insertions(+), 6 deletions(-) - -diff --git a/db.txt b/db.txt -index 75dc0a3..24989ad 100644 ---- a/db.txt -+++ b/db.txt -@@ -277,9 +277,9 @@ country CL: DFS-JP - (5735 - 5835 @ 80), (20) - - country CN: DFS-FCC -- (2402 - 2482 @ 40), (20) -- (5170 - 5250 @ 80), (23), AUTO-BW -- (5250 - 5330 @ 80), (23), DFS, AUTO-BW -+ (2402 - 2482 @ 40), (30) -+ (5170 - 5250 @ 80), (30), AUTO-BW -+ (5250 - 5330 @ 80), (30), AUTO-BW - (5735 - 5835 @ 80), (30) - # 60 GHz band channels 1,4: 28dBm, channels 2,3: 44dBm - # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf -@@ -1238,9 +1238,9 @@ country UG: DFS-FCC - country US: DFS-FCC - (2402 - 2472 @ 40), (30) - # 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients -- (5170 - 5250 @ 80), (23), AUTO-BW -- (5250 - 5330 @ 80), (23), DFS, AUTO-BW -- (5490 - 5730 @ 160), (23), DFS -+ (5170 - 5250 @ 80), (30), AUTO-BW -+ (5250 - 5330 @ 80), (30), AUTO-BW -+ (5490 - 5730 @ 160), (30) - (5735 - 5835 @ 80), (30) - # 60g band - # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255 --- -2.7.4 - diff --git a/package/firmware/wireless-regdb/patches/700-regdb-fix-compatibility-with-python.patch b/package/firmware/wireless-regdb/patches/700-regdb-fix-compatibility-with-python.patch deleted file mode 100644 index 6e72a9ed1b..0000000000 --- a/package/firmware/wireless-regdb/patches/700-regdb-fix-compatibility-with-python.patch +++ /dev/null @@ -1,615 +0,0 @@ -diff --git a/db2bin.py b/db2bin.py ---- a/db2bin.py -+++ b/db2bin.py -@@ -1,6 +1,6 @@ - #!/usr/bin/env python - --from cStringIO import StringIO -+from io import BytesIO, open - import struct - import hashlib - from dbparse import DBParser -@@ -10,21 +10,21 @@ - VERSION = 19 - - if len(sys.argv) < 3: -- print 'Usage: %s output-file input-file [key-file]' % sys.argv[0] -+ print('Usage: %s output-file input-file [key-file]' % sys.argv[0]) - sys.exit(2) - - def create_rules(countries): - result = {} -- for c in countries.itervalues(): -+ for c in countries.values(): - for rule in c.permissions: - result[rule] = 1 -- return result.keys() -+ return list(result) - - def create_collections(countries): - result = {} -- for c in countries.itervalues(): -+ for c in countries.values(): - result[c.permissions] = 1 -- return result.keys() -+ return list(result) - - - def be32(output, val): -@@ -49,21 +49,25 @@ - return self._offset - - p = DBParser() --countries = p.parse(file(sys.argv[2])) -+countries = p.parse(open(sys.argv[2], 'r', encoding='utf-8')) -+ -+countrynames = list(countries) -+countrynames.sort() -+ - power = [] - bands = [] --for c in countries.itervalues(): -- for perm in c.permissions: -+for alpha2 in countrynames: -+ for perm in countries[alpha2].permissions: - if not perm.freqband in bands: - bands.append(perm.freqband) - if not perm.power in power: - power.append(perm.power) - rules = create_rules(countries) --rules.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband)) -+rules.sort() - collections = create_collections(countries) --collections.sort(cmp=lambda x, y: cmp(x[0].freqband, y[0].freqband)) -+collections.sort() - --output = StringIO() -+output = BytesIO() - - # struct regdb_file_header - be32(output, MAGIC) -@@ -104,19 +108,17 @@ - # struct regdb_file_reg_rules_collection - coll = list(coll) - be32(output, len(coll)) -- coll.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband)) -+ coll.sort() - for regrule in coll: - be32(output, reg_rules[regrule]) - - # update country pointer now! - reg_country_ptr.set() - --countrynames = countries.keys() --countrynames.sort() - for alpha2 in countrynames: - coll = countries[alpha2] - # struct regdb_file_reg_country -- output.write(struct.pack('>ccxBI', str(alpha2[0]), str(alpha2[1]), coll.dfs_region, reg_rules_collections[coll.permissions])) -+ output.write(struct.pack('>2sxBI', alpha2, coll.dfs_region, reg_rules_collections[coll.permissions])) - - - if len(sys.argv) > 3: -@@ -141,5 +143,5 @@ - else: - siglen.set(0) - --outfile = open(sys.argv[1], 'w') -+outfile = open(sys.argv[1], 'wb') - outfile.write(output.getvalue()) -diff --git a/dbparse.py b/dbparse.py ---- a/dbparse.py -+++ b/dbparse.py -@@ -1,6 +1,9 @@ - #!/usr/bin/env python - -+from functools import total_ordering - import sys, math -+from math import ceil, log -+from collections import defaultdict, OrderedDict - - # must match enum nl80211_reg_rule_flags - -@@ -25,6 +28,40 @@ - 'DFS-JP': 3, - } - -+@total_ordering -+ -+class WmmRule(object): -+ -+ def __init__(self, vo_c, vi_c, be_c, bk_c, vo_ap, vi_ap, be_ap, bk_ap): -+ self.vo_c = vo_c -+ self.vi_c = vi_c -+ self.be_c = be_c -+ self.bk_c = bk_c -+ self.vo_ap = vo_ap -+ self.vi_ap = vi_ap -+ self.be_ap = be_ap -+ self.bk_ap = bk_ap -+ -+ def _as_tuple(self): -+ return (self.vo_c, self.vi_c, self.be_c, self.bk_c, -+ self.vo_ap, self.vi_ap, self.be_ap, self.bk_ap) -+ -+ def __eq__(self, other): -+ if other is None: -+ return False -+ return (self._as_tuple() == other._as_tuple()) -+ -+ def __ne__(self, other): -+ return not (self == other) -+ -+ def __lt__(self, other): -+ if other is None: -+ return False -+ return (self._as_tuple() < other._as_tuple()) -+ -+ def __hash__(self): -+ return hash(self._as_tuple()) -+ - class FreqBand(object): - def __init__(self, start, end, bw, comments=None): - self.start = start -@@ -32,41 +69,49 @@ - self.maxbw = bw - self.comments = comments or [] - -- def __cmp__(self, other): -- s = self -- o = other -- if not isinstance(o, FreqBand): -- return False -- return cmp((s.start, s.end, s.maxbw), (o.start, o.end, o.maxbw)) -+ def _as_tuple(self): -+ return (self.start, self.end, self.maxbw) -+ -+ def __eq__(self, other): -+ return (self._as_tuple() == other._as_tuple()) -+ -+ def __ne__(self, other): -+ return not (self == other) -+ -+ def __lt__(self, other): -+ return (self._as_tuple() < other._as_tuple()) - - def __hash__(self): -- s = self -- return hash((s.start, s.end, s.maxbw)) -+ return hash(self._as_tuple()) - - def __str__(self): - return '' % ( - self.start, self.end, self.maxbw) - -+@total_ordering - class PowerRestriction(object): - def __init__(self, max_ant_gain, max_eirp, comments = None): - self.max_ant_gain = max_ant_gain - self.max_eirp = max_eirp - self.comments = comments or [] - -- def __cmp__(self, other): -- s = self -- o = other -- if not isinstance(o, PowerRestriction): -- return False -- return cmp((s.max_ant_gain, s.max_eirp), -- (o.max_ant_gain, o.max_eirp)) -+ def _as_tuple(self): -+ return (self.max_ant_gain, self.max_eirp) - -- def __str__(self): -- return '' -+ def __eq__(self, other): -+ return (self._as_tuple() == other._as_tuple()) -+ -+ def __ne__(self, other): -+ return not (self == other) -+ -+ def __lt__(self, other): -+ return (self._as_tuple() < other._as_tuple()) - - def __hash__(self): -- s = self -- return hash((s.max_ant_gain, s.max_eirp)) -+ return hash(self._as_tuple()) -+ -+ def __str__(self): -+ return '' - - class DFSRegionError(Exception): - def __init__(self, dfs_region): -@@ -76,12 +121,15 @@ - def __init__(self, flag): - self.flag = flag - -+@total_ordering - class Permission(object): -- def __init__(self, freqband, power, flags): -+ def __init__(self, freqband, power, flags, wmmrule): - assert isinstance(freqband, FreqBand) - assert isinstance(power, PowerRestriction) -+ assert isinstance(wmmrule, WmmRule) or wmmrule is None - self.freqband = freqband - self.power = power -+ self.wmmrule = wmmrule - self.flags = 0 - for flag in flags: - if not flag in flag_definitions: -@@ -90,26 +138,33 @@ - self.textflags = flags - - def _as_tuple(self): -- return (self.freqband, self.power, self.flags) -+ return (self.freqband, self.power, self.flags, self.wmmrule) - -- def __cmp__(self, other): -- if not isinstance(other, Permission): -- return False -- return cmp(self._as_tuple(), other._as_tuple()) -+ def __eq__(self, other): -+ return (self._as_tuple() == other._as_tuple()) -+ -+ def __ne__(self, other): -+ return not (self == other) -+ -+ def __lt__(self, other): -+ return (self._as_tuple() < other._as_tuple()) - - def __hash__(self): - return hash(self._as_tuple()) - -+ def __str__(self): -+ return str(self.freqband) + str(self.power) + str(self.wmmrule) -+ - class Country(object): - def __init__(self, dfs_region, permissions=None, comments=None): - self._permissions = permissions or [] - self.comments = comments or [] -- self.dfs_region = 0 -+ self.dfs_region = 0 - -- if dfs_region: -- if not dfs_region in dfs_regions: -- raise DFSRegionError(dfs_region) -- self.dfs_region = dfs_regions[dfs_region] -+ if dfs_region: -+ if not dfs_region in dfs_regions: -+ raise DFSRegionError(dfs_region) -+ self.dfs_region = dfs_regions[dfs_region] - - def add(self, perm): - assert isinstance(perm, Permission) -@@ -233,6 +288,61 @@ - self._powerrev[p] = pname - self._powerline[pname] = self._lineno - -+ def _parse_wmmrule(self, line): -+ regions = line[:-1].strip() -+ if not regions: -+ self._syntax_error("'wmmrule' keyword must be followed by region") -+ -+ regions = regions.split(',') -+ -+ self._current_regions = {} -+ for region in regions: -+ if region in self._wmm_rules: -+ self._warn("region %s was added already to wmm rules" % region) -+ self._current_regions[region] = 1 -+ self._comments = [] -+ -+ def _validate_input(self, cw_min, cw_max, aifsn, cot): -+ if cw_min < 1: -+ self._syntax_error("Invalid cw_min value (%d)" % cw_min) -+ if cw_max < 1: -+ self._syntax_error("Invalid cw_max value (%d)" % cw_max) -+ if cw_min > cw_max: -+ self._syntax_error("Inverted contention window (%d - %d)" % -+ (cw_min, cw_max)) -+ if not (bin(cw_min + 1).count('1') == 1 and cw_min < 2**15): -+ self._syntax_error("Invalid cw_min value should be power of 2 - 1 (%d)" -+ % cw_min) -+ if not (bin(cw_max + 1).count('1') == 1 and cw_max < 2**15): -+ self._syntax_error("Invalid cw_max value should be power of 2 - 1 (%d)" -+ % cw_max) -+ if aifsn < 1: -+ self._syntax_error("Invalid aifsn value (%d)" % aifsn) -+ if cot < 0: -+ self._syntax_error("Invalid cot value (%d)" % cot) -+ -+ -+ def _validate_size(self, var, bytcnt): -+ return bytcnt < ceil(len(bin(var)[2:]) / 8.0) -+ -+ def _parse_wmmrule_item(self, line): -+ bytcnt = (2.0, 2.0, 1.0, 2.0) -+ try: -+ ac, cval = line.split(':') -+ if not ac: -+ self._syntax_error("wmm item must have ac prefix") -+ except ValueError: -+ self._syntax_error("access category must be followed by colon") -+ p = tuple([int(v.split('=', 1)[1]) for v in cval.split(',')]) -+ self._validate_input(*p) -+ for v, b in zip(p, bytcnt): -+ if self._validate_size(v, b): -+ self._syntax_error("unexpected input size expect %d got %d" -+ % (b, v)) -+ -+ for r in self._current_regions: -+ self._wmm_rules[r][ac] = p -+ - def _parse_country(self, line): - try: - cname, cvals= line.split(':', 1) -@@ -248,6 +358,7 @@ - for cname in cnames: - if len(cname) != 2: - self._warn("country '%s' not alpha2" % cname) -+ cname = cname.encode('ascii') - if not cname in self._countries: - self._countries[cname] = Country(dfs_region, comments=self._comments) - self._current_countries[cname] = self._countries[cname] -@@ -290,6 +401,15 @@ - line = line.split(',') - pname = line[0] - flags = line[1:] -+ w = None -+ if flags and 'wmmrule' in flags[-1]: -+ try: -+ region = flags.pop().split('=', 1)[1] -+ if region not in self._wmm_rules.keys(): -+ self._syntax_error("No wmm rule for %s" % region) -+ except IndexError: -+ self._syntax_error("flags is empty list or no region was found") -+ w = WmmRule(*self._wmm_rules[region].values()) - - if not bname in self._bands: - self._syntax_error("band does not exist") -@@ -303,10 +423,10 @@ - b = self._bands[bname] - p = self._power[pname] - try: -- perm = Permission(b, p, flags) -- except FlagError, e: -+ perm = Permission(b, p, flags, w) -+ except FlagError as e: - self._syntax_error("Invalid flag '%s'" % e.flag) -- for cname, c in self._current_countries.iteritems(): -+ for cname, c in self._current_countries.items(): - if perm in c: - self._warn('Rule "%s, %s" added to "%s" twice' % ( - bname, pname, cname)) -@@ -315,6 +435,7 @@ - - def parse(self, f): - self._current_countries = None -+ self._current_regions = None - self._bands = {} - self._power = {} - self._countries = {} -@@ -326,6 +447,7 @@ - self._powerdup = {} - self._bandline = {} - self._powerline = {} -+ self._wmm_rules = defaultdict(lambda: OrderedDict()) - - self._comments = [] - -@@ -337,6 +459,7 @@ - self._comments.append(line[1:].strip()) - line = line.replace(' ', '').replace('\t', '') - if not line: -+ self._current_regions = None - self._comments = [] - line = line.split('#')[0] - if not line: -@@ -344,23 +467,35 @@ - if line[0:4] == 'band': - self._parse_band(line[4:]) - self._current_countries = None -+ self._current_regions = None - self._comments = [] - elif line[0:5] == 'power': - self._parse_power(line[5:]) - self._current_countries = None -+ self._current_regions = None - self._comments = [] - elif line[0:7] == 'country': - self._parse_country(line[7:]) - self._comments = [] -+ self._current_regions = None - elif self._current_countries is not None: -+ self._current_regions = None - self._parse_country_item(line) - self._comments = [] -+ elif line[0:7] == 'wmmrule': -+ self._parse_wmmrule(line[7:]) -+ self._current_countries = None -+ self._comments = [] -+ elif self._current_regions is not None: -+ self._parse_wmmrule_item(line) -+ self._current_countries = None -+ self._comments = [] - else: - self._syntax_error("Expected band, power or country definition") - - countries = self._countries - bands = {} -- for k, v in self._bands.iteritems(): -+ for k, v in self._bands.items(): - if k in self._bands_used: - bands[self._banddup[k]] = v - continue -@@ -369,7 +504,7 @@ - self._lineno = self._bandline[k] - self._warn('Unused band definition "%s"' % k) - power = {} -- for k, v in self._power.iteritems(): -+ for k, v in self._power.items(): - if k in self._power_used: - power[self._powerdup[k]] = v - continue -diff --git /dev/null b/db2fw.py ---- /dev/null -+++ b/db2fw.py -@@ -0,0 +1,158 @@ -+#!/usr/bin/env python -+ -+from io import BytesIO, open -+import struct -+import hashlib -+from dbparse import DBParser -+import sys -+from math import log -+ -+MAGIC = 0x52474442 -+VERSION = 20 -+ -+if len(sys.argv) < 3: -+ print('Usage: %s output-file input-file' % sys.argv[0]) -+ sys.exit(2) -+ -+def create_rules(countries): -+ result = {} -+ for c in countries.values(): -+ for rule in c.permissions: -+ result[rule] = 1 -+ return list(result) -+ -+def create_collections(countries): -+ result = {} -+ for c in countries.values(): -+ result[(c.permissions, c.dfs_region)] = 1 -+ return list(result) -+ -+def create_wmms(countries): -+ result = {} -+ for c in countries.values(): -+ for rule in c.permissions: -+ if rule.wmmrule is not None: -+ result[rule.wmmrule] = 1 -+ return list(result) -+ -+def be32(output, val): -+ output.write(struct.pack('>I', val)) -+def be16(output, val): -+ output.write(struct.pack('>H', val)) -+ -+class PTR(object): -+ def __init__(self, output): -+ self._output = output -+ self._pos = output.tell() -+ be16(output, 0) -+ self._written = False -+ -+ def set(self, val=None): -+ if val is None: -+ val = self._output.tell() -+ assert val & 3 == 0 -+ self._offset = val -+ pos = self._output.tell() -+ self._output.seek(self._pos) -+ be16(self._output, val >> 2) -+ self._output.seek(pos) -+ self._written = True -+ -+ def get(self): -+ return self._offset -+ -+ @property -+ def written(self): -+ return self._written -+ -+p = DBParser() -+countries = p.parse(open(sys.argv[2], 'r', encoding='utf-8')) -+rules = create_rules(countries) -+rules.sort() -+collections = create_collections(countries) -+collections.sort() -+wmms = create_wmms(countries) -+wmms.sort() -+ -+output = BytesIO() -+ -+# struct regdb_file_header -+be32(output, MAGIC) -+be32(output, VERSION) -+ -+country_ptrs = {} -+countrynames = list(countries) -+countrynames.sort() -+for alpha2 in countrynames: -+ coll = countries[alpha2] -+ output.write(struct.pack('>2s', alpha2)) -+ country_ptrs[alpha2] = PTR(output) -+output.write(b'\x00' * 4) -+ -+wmmdb = {} -+for w in wmms: -+ assert output.tell() & 3 == 0 -+ wmmdb[w] = output.tell() >> 2 -+ for r in w._as_tuple(): -+ ecw = int(log(r[0] + 1, 2)) << 4 | int(log(r[1] + 1, 2)) -+ ac = (ecw, r[2],r[3]) -+ output.write(struct.pack('>BBH', *ac)) -+ -+reg_rules = {} -+flags = 0 -+for reg_rule in rules: -+ freq_range, power_rule, wmm_rule = reg_rule.freqband, reg_rule.power, reg_rule.wmmrule -+ reg_rules[reg_rule] = output.tell() -+ assert power_rule.max_ant_gain == 0 -+ flags = 0 -+ # convert to new rule flags -+ assert reg_rule.flags & ~0x899 == 0 -+ if reg_rule.flags & 1<<0: -+ flags |= 1<<0 -+ if reg_rule.flags & 1<<3: -+ flags |= 1<<1 -+ if reg_rule.flags & 1<<4: -+ flags |= 1<<2 -+ if reg_rule.flags & 1<<7: -+ flags |= 1<<3 -+ if reg_rule.flags & 1<<11: -+ flags |= 1<<4 -+ rule_len = 16 -+ cac_timeout = 0 # TODO -+ if not (flags & 1<<2): -+ cac_timeout = 0 -+ if cac_timeout or wmm_rule: -+ rule_len += 2 -+ if wmm_rule is not None: -+ rule_len += 2 -+ output.write(struct.pack('>BBHIII', rule_len, flags, int(power_rule.max_eirp * 100), -+ int(freq_range.start * 1000), int(freq_range.end * 1000), int(freq_range.maxbw * 1000), -+ )) -+ if rule_len > 16: -+ output.write(struct.pack('>H', cac_timeout)) -+ -+ if rule_len > 18: -+ be16(output, wmmdb[wmm_rule]) -+ -+ while rule_len % 4: -+ output.write('\0') -+ rule_len += 1 -+ -+for coll in collections: -+ for alpha2 in countrynames: -+ if (countries[alpha2].permissions, countries[alpha2].dfs_region) == coll: -+ assert not country_ptrs[alpha2].written -+ country_ptrs[alpha2].set() -+ slen = 3 -+ output.write(struct.pack('>BBBx', slen, len(list(coll[0])), coll[1])) -+ coll = list(coll[0]) -+ for regrule in coll: -+ be16(output, reg_rules[regrule] >> 2) -+ if len(coll) % 2: -+ be16(output, 0) -+ -+for alpha2 in countrynames: -+ assert country_ptrs[alpha2].written -+ -+outfile = open(sys.argv[1], 'wb') -+outfile.write(output.getvalue()) From b10fadf9190960585cf23ebf9d248ab96631fa29 Mon Sep 17 00:00:00 2001 From: Chen Minqiang Date: Wed, 23 Jan 2019 23:03:56 +0800 Subject: [PATCH 2/3] wireless-regdb: custom fix txpower and dfs Edit: enable 160MHz BW in channel 36~64 --- .../600-custom-fix-txpower-and-dfs.patch | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch diff --git a/package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch b/package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch new file mode 100644 index 0000000000..f4ebb0dfa1 --- /dev/null +++ b/package/firmware/wireless-regdb/patches/600-custom-fix-txpower-and-dfs.patch @@ -0,0 +1,26 @@ +--- a/db.txt ++++ b/db.txt +@@ -291,9 +291,8 @@ country CL: DFS-JP + (5735 - 5835 @ 80), (20) + + country CN: DFS-FCC +- (2402 - 2482 @ 40), (20) +- (5170 - 5250 @ 80), (23), AUTO-BW +- (5250 - 5330 @ 80), (23), DFS, AUTO-BW ++ (2402 - 2482 @ 40), (30) ++ (5170 - 5330 @ 160), (30), AUTO-BW + (5735 - 5835 @ 80), (30) + # 60 GHz band channels 1,4: 28dBm, channels 2,3: 44dBm + # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf +@@ -1284,9 +1283,8 @@ country UG: DFS-FCC + country US: DFS-FCC + (2402 - 2472 @ 40), (30) + # 5.15 ~ 5.25 GHz: 30 dBm for master mode, 23 dBm for clients +- (5170 - 5250 @ 80), (23), AUTO-BW +- (5250 - 5330 @ 80), (23), DFS, AUTO-BW +- (5490 - 5730 @ 160), (23), DFS ++ (5170 - 5330 @ 160), (30), AUTO-BW ++ (5490 - 5730 @ 160), (30) + (5735 - 5835 @ 80), (30) + # 60g band + # reference: section IV-D https://docs.fcc.gov/public/attachments/FCC-16-89A1.pdf From a5e61fd196958814c3fbe0b44aa4adf0af76eaf2 Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Tue, 14 Apr 2020 19:36:08 +0800 Subject: [PATCH 3/3] tcpping: add necessary dependency This fix project-openwrt/openwrt#132. --- package/lean/tcpping/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/lean/tcpping/Makefile b/package/lean/tcpping/Makefile index 72e79e5b15..0760d6758b 100644 --- a/package/lean/tcpping/Makefile +++ b/package/lean/tcpping/Makefile @@ -15,7 +15,7 @@ include $(INCLUDE_DIR)/package.mk define Package/tcpping SECTION:=net CATEGORY:=Network - DEPENDS:=+libnet-1.2.x + DEPENDS:=+libnet-1.2.x +libpcap TITLE:=Ping look-alike that uses TCP SYN packets to get around firewalls and ICMP blackholes endef