From a8d751c243b9d840b97293b289adddb0df438358 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Sun, 5 Nov 2017 22:34:33 +0100 Subject: [PATCH] wireless-regdb: add package containing the wireless regulatory database Installs to /lib/firmware for newer cfg80211 versions Signed-off-by: Felix Fietkau --- package/firmware/wireless-regdb/Makefile | 31 +++ ...firmware-file-format-version-code-20.patch | 251 ++++++++++++++++++ .../patches/500-world-regd-5GHz.patch | 16 ++ 3 files changed, 298 insertions(+) create mode 100644 package/firmware/wireless-regdb/Makefile create mode 100644 package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch create mode 100644 package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch diff --git a/package/firmware/wireless-regdb/Makefile b/package/firmware/wireless-regdb/Makefile new file mode 100644 index 00000000000..fa732b2d388 --- /dev/null +++ b/package/firmware/wireless-regdb/Makefile @@ -0,0 +1,31 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=wireless-regdb + +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:=b827bf760de57b907df159c8d38d7c3fb5b4a691781114c47739e20bffb3a312 + +PKG_MAINTAINER:=Felix Fietkau + +include $(INCLUDE_DIR)/package.mk + +define Package/wireless-regdb + SECTION:=firmware + CATEGORY:=Firmware + URL:=$(patsubst pub/scm,cgit,$(PKG_SOURCE_URL)) + TITLE:=Wireless Regulatory Database +endef + +define Build/Compile + python $(PKG_BUILD_DIR)/db2fw.py $(PKG_BUILD_DIR)/regulatory.db $(PKG_BUILD_DIR)/db.txt +endef + +define Package/wireless-regdb/install + $(INSTALL_DIR) $(1)/lib/firmware + $(CP) $(PKG_BUILD_DIR)/regulatory.db $(1)/lib/firmware/ +endef + +$(eval $(call BuildPackage,wireless-regdb)) 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 new file mode 100644 index 00000000000..0c5c63fc5f6 --- /dev/null +++ b/package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch @@ -0,0 +1,251 @@ +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: + +--- /dev/null ++++ b/db2fw.py +@@ -0,0 +1,133 @@ ++#!/usr/bin/env python ++ ++from cStringIO import StringIO ++import struct ++import hashlib ++from dbparse import DBParser ++import sys ++ ++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.itervalues(): ++ for rule in c.permissions: ++ result[rule] = 1 ++ return result.keys() ++ ++def create_collections(countries): ++ result = {} ++ for c in countries.itervalues(): ++ result[(c.permissions, c.dfs_region)] = 1 ++ return result.keys() ++ ++ ++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(file(sys.argv[2])) ++rules = create_rules(countries) ++rules.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband)) ++collections = create_collections(countries) ++collections.sort(cmp=lambda x, y: cmp(x[0][0].freqband, y[0][0].freqband)) ++ ++output = StringIO() ++ ++# struct regdb_file_header ++be32(output, MAGIC) ++be32(output, VERSION) ++ ++country_ptrs = {} ++countrynames = countries.keys() ++countrynames.sort() ++for alpha2 in countrynames: ++ coll = countries[alpha2] ++ output.write(struct.pack('>cc', str(alpha2[0]), str(alpha2[1]))) ++ country_ptrs[alpha2] = PTR(output) ++output.write('\x00' * 4) ++ ++reg_rules = {} ++flags = 0 ++for reg_rule in rules: ++ freq_range, power_rule = reg_rule.freqband, reg_rule.power ++ 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: ++ rule_len += 2 ++ output.write(struct.pack('>BBHIII', rule_len, flags, power_rule.max_eirp * 100, ++ freq_range.start * 1000, freq_range.end * 1000, freq_range.maxbw * 1000, ++ )) ++ if cac_timeout: ++ output.write(struct.pack('>H', cac_timeout)) ++ 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], 'w') ++outfile.write(output.getvalue()) diff --git a/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch b/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch new file mode 100644 index 00000000000..9baba808bca --- /dev/null +++ b/package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch @@ -0,0 +1,16 @@ +Remove the NO-IR flag from channels 36-48 on the World domain, +to make it usable for AP mode. + +Signed-off-by: Felix Fietkau +--- +--- a/db.txt ++++ b/db.txt +@@ -6,7 +6,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 +- (5170 - 5250 @ 80), (20), NO-IR, AUTO-BW ++ (5170 - 5250 @ 80), (20), AUTO-BW + # Channel 52 - 64 + (5250 - 5330 @ 80), (20), NO-IR, DFS, AUTO-BW + # Channel 100 - 144