wireless-regdb: add package containing the wireless regulatory database
authorFelix Fietkau <nbd@nbd.name>
Sun, 5 Nov 2017 21:34:33 +0000 (22:34 +0100)
committerFelix Fietkau <nbd@nbd.name>
Thu, 16 Nov 2017 14:23:32 +0000 (15:23 +0100)
Installs to /lib/firmware for newer cfg80211 versions

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/firmware/wireless-regdb/Makefile [new file with mode: 0644]
package/firmware/wireless-regdb/patches/100-regdb-write-firmware-file-format-version-code-20.patch [new file with mode: 0644]
package/firmware/wireless-regdb/patches/500-world-regd-5GHz.patch [new file with mode: 0644]

diff --git a/package/firmware/wireless-regdb/Makefile b/package/firmware/wireless-regdb/Makefile
new file mode 100644 (file)
index 0000000..fa732b2
--- /dev/null
@@ -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 <nbd@nbd.name>
+
+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 (file)
index 0000000..0c5c63f
--- /dev/null
@@ -0,0 +1,251 @@
+From: Johannes Berg <johannes.berg@intel.com>
+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 <johannes.berg@intel.com>
+---
+ 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 (file)
index 0000000..9baba80
--- /dev/null
@@ -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 <nbd@nbd.name>
+---
+--- 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