├── .gitignore ├── LICENSE ├── Makefile ├── README ├── db.txt ├── db2bin.py ├── dbparse.py ├── debian-example ├── changelog ├── compat ├── control ├── copyright ├── docs └── rules ├── linville.key.pub.pem ├── regulatory.bin ├── regulatory.bin.5 ├── sha1sum.txt ├── web └── Regulatory.py └── wireless-regdb.spec /.gitignore: -------------------------------------------------------------------------------- 1 | key.priv.pem 2 | dbparse.pyc 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2008, Luis R. Rodriguez 2 | Copyright (c) 2008, Johannes Berg 3 | Copyright (c) 2008, Michael Green 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | 17 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Install prefix 2 | PREFIX ?= /usr 3 | CRDA_PATH ?= $(PREFIX)/lib/crda 4 | CRDA_KEY_PATH ?= $(CRDA_PATH)/pubkeys 5 | 6 | MANDIR ?= $(PREFIX)/share/man/ 7 | 8 | SHA1SUM ?= /usr/bin/sha1sum 9 | LSB_RELEASE ?= /usr/bin/lsb_release 10 | WHOAMI ?= /usr/bin/whoami 11 | 12 | # Distro name: Ubuntu, Debian, Fedora, if not present you get 13 | # "custom-distro", if your distribution does not have the LSB stuff, 14 | # then set this variable when calling make if you don't want "custom-distro" 15 | LSB_ID ?= $(shell if [ -f $(LSB_RELEASE) ]; then \ 16 | $(LSB_RELEASE) -i -s; \ 17 | else \ 18 | echo custom-distro; \ 19 | fi) 20 | 21 | DISTRO_PRIVKEY ?= ~/.wireless-regdb-$(LSB_ID).key.priv.pem 22 | DISTRO_PUBKEY ?= ~/.wireless-regdb-$(LSB_ID).key.priv.pem 23 | 24 | REGDB_AUTHOR ?= $(shell if [ -f $(DISTRO_PRIVKEY) ]; then \ 25 | echo $(LSB_ID) ; \ 26 | elif [ -f $(WHOAMI) ]; then \ 27 | $(WHOAMI); \ 28 | else \ 29 | echo custom-user; \ 30 | fi) 31 | 32 | REGDB_PRIVKEY ?= ~/.wireless-regdb-$(REGDB_AUTHOR).key.priv.pem 33 | REGDB_PUBKEY ?= $(REGDB_AUTHOR).key.pub.pem 34 | 35 | REGDB_UPSTREAM_PUBKEY ?= linville.key.pub.pem 36 | 37 | REGDB_CHANGED = $(shell $(SHA1SUM) -c --status sha1sum.txt >/dev/null 2>&1; \ 38 | if [ $$? -ne 0 ]; then \ 39 | echo maintainer-clean $(REGDB_PUBKEY); \ 40 | fi) 41 | 42 | .PHONY: all clean mrproper install maintainer-clean install-distro-key 43 | 44 | all: $(REGDB_CHANGED) regulatory.bin sha1sum.txt 45 | 46 | clean: 47 | @rm -f *.pyc *.gz 48 | 49 | maintainer-clean: clean 50 | @rm -f regulatory.bin 51 | 52 | mrproper: clean maintainer-clean 53 | @echo Removed public key, regulatory.bin and compresed man pages 54 | @rm -f $(REGDB_PUBKEY) .custom 55 | 56 | regulatory.bin: db.txt $(REGDB_PRIVKEY) $(REGDB_PUBKEY) 57 | @echo Generating $@ digitally signed by $(REGDB_AUTHOR)... 58 | ./db2bin.py regulatory.bin db.txt $(REGDB_PRIVKEY) 59 | 60 | sha1sum.txt: db.txt 61 | sha1sum $< > $@ 62 | 63 | $(REGDB_PUBKEY): $(REGDB_PRIVKEY) 64 | @echo "Generating public key for $(REGDB_AUTHOR)..." 65 | openssl rsa -in $(REGDB_PRIVKEY) -out $(REGDB_PUBKEY) -pubout -outform PEM 66 | @echo $(REGDB_PUBKEY) > .custom 67 | 68 | 69 | $(REGDB_PRIVKEY): 70 | @echo "Generating private key for $(REGDB_AUTHOR)..." 71 | openssl genrsa -out $(REGDB_PRIVKEY) 2048 72 | 73 | ifneq ($(shell test -e $(DISTRO_PRIVKEY) && echo yes),yes) 74 | $(DISTRO_PRIVKEY): 75 | @echo "Generating private key for $(LSB_ID) packager..." 76 | openssl genrsa -out $(DISTRO_PRIVKEY) 2048 77 | endif 78 | 79 | install-distro-key: maintainer-clean $(DISTRO_PRIVKEY) 80 | 81 | %.gz: % 82 | gzip < $< > $@ 83 | 84 | # Users should just do: 85 | # sudo make install 86 | # 87 | # Developers should do: 88 | # make maintainer-clean 89 | # make 90 | # sudo make install 91 | # 92 | # Distributions packagers should do only once: 93 | # make install-distro-key 94 | # This will create a private key for you and install it into 95 | # ~/.wireless-regdb-$(LSB_ID).key.priv.pem 96 | # To make new releaes just do: 97 | # make maintainer-clean 98 | # make 99 | # sudo make install 100 | install: regulatory.bin.5.gz 101 | install -m 755 -d $(DESTDIR)/$(CRDA_PATH) 102 | install -m 755 -d $(DESTDIR)/$(CRDA_KEY_PATH) 103 | if [ -f .custom ]; then \ 104 | install -m 644 -t $(DESTDIR)/$(CRDA_KEY_PATH)/ $(shell cat .custom); \ 105 | fi 106 | @# In linville we trust 107 | install -m 644 -t $(DESTDIR)/$(CRDA_KEY_PATH)/ $(REGDB_UPSTREAM_PUBKEY) 108 | install -m 644 -t $(DESTDIR)/$(CRDA_PATH)/ regulatory.bin 109 | install -m 755 -d $(DESTDIR)/$(MANDIR)/man5/ 110 | install -m 644 -t $(DESTDIR)/$(MANDIR)/man5/ regulatory.bin.5.gz 111 | 112 | uninstall: 113 | rm -rf $(DESTDIR)/$(CRDA_PATH)/ 114 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | This repository contains the plain text version of the regulatory 2 | database file I maintain for use with Central Regulatory Database 3 | Agent daemon. Also included is the compiled binary version of this 4 | file signed with my RSA key. This represents a good faith attempt 5 | to capture regulatory information that is correct at the time of its last 6 | modification. This information is provided to you with no warranty 7 | either expressed or implied. 8 | 9 | Also included are the tools used to compile and sign the regulatory.bin 10 | file as well as a MoinMoin macro used for viewing the database. 11 | 12 | TECHNICAL INFORMATION 13 | ======================= 14 | 15 | The regulatory information in `db.txt' is stored in a human-readable 16 | format which can be read using the `dbparse.py' python module. This 17 | python module is used by the web viewer (Regulatory.py) which is 18 | implemented as a MoinMoin macro (and used on http://wireless.kernel.org) 19 | to allow viewing the database for verification. 20 | 21 | The dbparse module is also used by db2bin.py, the `compiler', which 22 | compiles and signs the binary database. 23 | 24 | For more information, please see the CRDA git repository: 25 | 26 | git://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/crda.git 27 | 28 | John W. Linville 29 | 17 November 2008 30 | -------------------------------------------------------------------------------- /db.txt: -------------------------------------------------------------------------------- 1 | # This is the world regulatory domain 2 | country 00: 3 | (2402 - 2472 @ 40), (20) 4 | # Channel 12 - 13. 5 | (2457 - 2482 @ 40), (20), NO-IR 6 | # Channel 14. Only JP enables this and for 802.11b only 7 | (2474 - 2494 @ 20), (20), NO-IR 8 | # Channel 36 - 48 9 | (5170 - 5250 @ 80), (20), NO-IR 10 | # NB: 5260 MHz - 5700 MHz requies DFS 11 | # Channel 149 - 165 12 | (5735 - 5835 @ 80), (20), NO-IR 13 | # IEEE 802.11ad (60GHz), channels 1..3 14 | (57240 - 63720 @ 2160), (0) 15 | 16 | 17 | country AD: 18 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 19 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 20 | 21 | country AE: DFS-FCC 22 | (2402 - 2482 @ 40), (20) 23 | (5170 - 5250 @ 80), (17) 24 | (5250 - 5330 @ 80), (24), DFS 25 | (5490 - 5730 @ 80), (24), DFS 26 | (5735 - 5835 @ 80), (30) 27 | 28 | country AL: DFS-ETSI 29 | (2402 - 2482 @ 40), (20) 30 | (5170 - 5250 @ 80), (20.00) 31 | (5250 - 5330 @ 80), (20.00), DFS 32 | (5490 - 5710 @ 80), (27.00), DFS 33 | 34 | country AM: DFS-ETSI 35 | (2402 - 2482 @ 40), (20) 36 | (5170 - 5250 @ 80), (18) 37 | (5250 - 5330 @ 80), (18), DFS 38 | 39 | country AN: DFS-ETSI 40 | (2402 - 2482 @ 40), (20) 41 | (5170 - 5250 @ 80), (20) 42 | (5250 - 5330 @ 80), (20), DFS 43 | (5490 - 5710 @ 80), (27), DFS 44 | 45 | country AR: DFS-FCC 46 | (2402 - 2482 @ 40), (20) 47 | (5170 - 5250 @ 80), (17) 48 | (5250 - 5330 @ 80), (24), DFS 49 | (5490 - 5730 @ 80), (24), DFS 50 | (5735 - 5835 @ 80), (30) 51 | 52 | country AT: DFS-ETSI 53 | (2402 - 2482 @ 40), (20) 54 | (5170 - 5250 @ 80), (20) 55 | (5250 - 5330 @ 80), (20), DFS 56 | (5490 - 5710 @ 80), (27), DFS 57 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 58 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 59 | 60 | country AU: 61 | (2402 - 2482 @ 40), (20) 62 | (5170 - 5250 @ 80), (17) 63 | (5250 - 5330 @ 80), (24), DFS 64 | (5490 - 5710 @ 80), (24), DFS 65 | (5735 - 5835 @ 80), (30) 66 | 67 | country AW: DFS-ETSI 68 | (2402 - 2482 @ 40), (20) 69 | (5170 - 5250 @ 80), (20) 70 | (5250 - 5330 @ 80), (20), DFS 71 | (5490 - 5710 @ 80), (27), DFS 72 | 73 | country AZ: DFS-ETSI 74 | (2402 - 2482 @ 40), (20) 75 | (5170 - 5250 @ 80), (18) 76 | (5250 - 5330 @ 80), (18), DFS 77 | 78 | country BA: DFS-ETSI 79 | (2402 - 2482 @ 40), (20) 80 | (5170 - 5250 @ 80), (20) 81 | (5250 - 5330 @ 80), (20), DFS 82 | (5490 - 5710 @ 80), (27), DFS 83 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 84 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 85 | 86 | country BB: DFS-FCC 87 | (2402 - 2482 @ 40), (20) 88 | (5170 - 5250 @ 80), (23) 89 | (5250 - 5330 @ 80), (23), DFS 90 | (5735 - 5835 @ 80), (30) 91 | 92 | country BD: DFS-JP 93 | (2402 - 2482 @ 40), (20) 94 | (5735 - 5835 @ 80), (30) 95 | 96 | country BE: DFS-ETSI 97 | (2402 - 2482 @ 40), (20) 98 | (5170 - 5250 @ 80), (20) 99 | (5250 - 5330 @ 80), (20), DFS 100 | (5490 - 5710 @ 80), (27), DFS 101 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 102 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 103 | 104 | country BG: DFS-ETSI 105 | (2402 - 2482 @ 40), (20) 106 | (5170 - 5250 @ 80), (20) 107 | (5250 - 5330 @ 80), (20), DFS 108 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 109 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 110 | 111 | country BH: DFS-JP 112 | (2402 - 2482 @ 40), (20) 113 | (5170 - 5250 @ 80), (20) 114 | (5250 - 5330 @ 80), (20), DFS 115 | (5735 - 5835 @ 80), (20) 116 | 117 | country BL: 118 | (2402 - 2482 @ 40), (20) 119 | (5170 - 5250 @ 40), (18) 120 | (5250 - 5330 @ 40), (18), DFS 121 | 122 | country BN: DFS-JP 123 | (2402 - 2482 @ 40), (20) 124 | (5170 - 5250 @ 80), (20) 125 | (5250 - 5330 @ 80), (20), DFS 126 | (5735 - 5835 @ 80), (20) 127 | 128 | country BO: DFS-JP 129 | (2402 - 2482 @ 40), (30) 130 | (5735 - 5835 @ 80), (30) 131 | 132 | country BR: DFS-FCC 133 | (2402 - 2482 @ 40), (20) 134 | (5170 - 5250 @ 80), (17) 135 | (5250 - 5330 @ 80), (24), DFS 136 | (5490 - 5730 @ 80), (24), DFS 137 | (5735 - 5835 @ 80), (30) 138 | 139 | country BY: DFS-ETSI 140 | (2402 - 2482 @ 40), (20) 141 | (5170 - 5250 @ 80), (20) 142 | (5250 - 5330 @ 80), (20), DFS 143 | (5490 - 5710 @ 80), (27), DFS 144 | 145 | country BZ: DFS-JP 146 | (2402 - 2482 @ 40), (30) 147 | (5735 - 5835 @ 80), (30) 148 | 149 | country CA: DFS-FCC 150 | (2402 - 2472 @ 40), (30) 151 | (5170 - 5250 @ 80), (17) 152 | (5250 - 5330 @ 80), (24), DFS 153 | (5490 - 5730 @ 80), (24), DFS 154 | (5735 - 5835 @ 80), (30) 155 | 156 | country CH: DFS-ETSI 157 | (2402 - 2482 @ 40), (20) 158 | (5170 - 5250 @ 80), (20) 159 | (5250 - 5330 @ 80), (20), DFS 160 | (5490 - 5710 @ 80), (27), DFS 161 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 162 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 163 | 164 | country CL: DFS-JP 165 | (2402 - 2482 @ 40), (20) 166 | (5170 - 5250 @ 80), (20) 167 | (5250 - 5330 @ 80), (20), DFS 168 | (5735 - 5835 @ 80), (20) 169 | 170 | country CN: DFS-FCC 171 | (2402 - 2482 @ 40), (20) 172 | (5170 - 5250 @ 80), (23) 173 | (5250 - 5330 @ 80), (23), DFS 174 | (5735 - 5835 @ 80), (30) 175 | # 60 gHz band channels 1,4: 28dBm, channels 2,3: 44dBm 176 | # ref: http://www.miit.gov.cn/n11293472/n11505629/n11506593/n11960250/n11960606/n11960700/n12330791.files/n12330790.pdf 177 | (57240 - 59400 @ 2160), (28) 178 | (59400 - 63720 @ 2160), (44) 179 | (63720 - 65880 @ 2160), (28) 180 | 181 | country CO: DFS-FCC 182 | (2402 - 2482 @ 40), (20) 183 | (5170 - 5250 @ 80), (17) 184 | (5250 - 5330 @ 80), (24), DFS 185 | (5490 - 5730 @ 80), (24), DFS 186 | (5735 - 5835 @ 80), (30) 187 | 188 | country CR: DFS-FCC 189 | (2402 - 2482 @ 40), (20) 190 | (5170 - 5250 @ 80), (17) 191 | (5250 - 5330 @ 80), (24), DFS 192 | (5490 - 5730 @ 80), (24), DFS 193 | (5735 - 5835 @ 80), (30) 194 | 195 | country CY: DFS-ETSI 196 | (2402 - 2482 @ 40), (20) 197 | (5170 - 5250 @ 80), (20) 198 | (5250 - 5330 @ 80), (20), DFS 199 | (5490 - 5710 @ 80), (27), DFS 200 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 201 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 202 | 203 | # Data from http://www.ctu.eu/164/download/VOR/VOR-12-08-2005-34.pdf 204 | # and http://www.ctu.eu/164/download/VOR/VOR-12-05-2007-6-AN.pdf 205 | # Power at 5250 - 5350 MHz and 5470 - 5725 MHz can be doubled if TPC is 206 | # implemented. 207 | country CZ: DFS-ETSI 208 | (2400 - 2483.5 @ 40), (100 mW) 209 | (5150 - 5250 @ 80), (200 mW), NO-OUTDOOR 210 | (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR 211 | (5470 - 5725 @ 80), (500 mW), DFS 212 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 213 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 214 | 215 | # Data from "Frequenznutzungsplan" (as published in April 2008), downloaded from 216 | # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38448/publicationFile/2659/Frequenznutzungsplan2008_Id17448pdf.pdf 217 | # For the 5GHz range also see 218 | # http://www.bundesnetzagentur.de/cae/servlet/contentblob/38216/publicationFile/6579/WLAN5GHzVfg7_2010_28042010pdf.pdf 219 | # The values have been reduced by a factor of 2 (3db) for non TPC devices 220 | # (in other words: devices with TPC can use twice the tx power of this table). 221 | # Note that the docs do not require TPC for 5150--5250; the reduction to 222 | # 100mW thus is not strictly required -- however the conservative 100mW 223 | # limit is used here as the non-interference with radar and satellite 224 | # apps relies on the attenuation by the building walls only in the 225 | # absence of DFS; the neighbour countries have 100mW limit here as well. 226 | 227 | country DE: DFS-ETSI 228 | # entries 279004 and 280006 229 | (2400 - 2483.5 @ 40), (100 mW) 230 | # entry 303005, 304002 and 305002 231 | (5150 - 5350 @ 80), (100 mW), NO-OUTDOOR 232 | # entries 308002, 309001 and 310003 233 | (5470 - 5725 @ 80), (500 mW), DFS 234 | # For ITS-G5 evaluation 235 | (5850 - 5925 @ 20), (100 mW), NO-CCK, OCB-ONLY 236 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 237 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 238 | 239 | country DK: DFS-ETSI 240 | (2402 - 2482 @ 40), (20) 241 | (5170 - 5250 @ 80), (20) 242 | (5250 - 5330 @ 80), (20), DFS 243 | (5490 - 5710 @ 80), (27), DFS 244 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 245 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 246 | 247 | country DO: DFS-FCC 248 | (2402 - 2472 @ 40), (30) 249 | (5170 - 5250 @ 80), (17) 250 | (5250 - 5330 @ 80), (23), DFS 251 | (5735 - 5835 @ 80), (30) 252 | 253 | country DZ: DFS-JP 254 | (2402 - 2482 @ 40), (20) 255 | (5170.000 - 5250.000 @ 80.000), (23.00) 256 | (5250.000 - 5330.000 @ 80.000), (23.00), DFS 257 | (5490.000 - 5670.000 @ 80.000), (23.00), DFS 258 | 259 | country EC: DFS-FCC 260 | (2402 - 2482 @ 40), (20) 261 | (5170 - 5250 @ 80), (17) 262 | (5250 - 5330 @ 80), (24), DFS 263 | (5490 - 5730 @ 80), (24), DFS 264 | (5735 - 5835 @ 80), (30) 265 | 266 | country EE: DFS-ETSI 267 | (2402 - 2482 @ 40), (20) 268 | (5170 - 5250 @ 80), (20) 269 | (5250 - 5330 @ 80), (20), DFS 270 | (5490 - 5710 @ 80), (27), DFS 271 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 272 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 273 | 274 | country EG: DFS-ETSI 275 | (2402 - 2482 @ 40), (20) 276 | (5170 - 5250 @ 80), (20) 277 | (5250 - 5330 @ 80), (20), DFS 278 | 279 | country ES: DFS-ETSI 280 | (2400 - 2483.5 @ 40), (100 mW) 281 | (5150 - 5250 @ 80), (100 mW), NO-OUTDOOR 282 | (5250 - 5350 @ 80), (100 mW), NO-OUTDOOR 283 | (5470 - 5725 @ 80), (500 mW), DFS 284 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 285 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 286 | 287 | country FI: DFS-ETSI 288 | (2402 - 2482 @ 40), (20) 289 | (5170 - 5250 @ 80), (20) 290 | (5250 - 5330 @ 80), (20), DFS 291 | (5490 - 5710 @ 80), (27), DFS 292 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 293 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 294 | 295 | country FR: DFS-ETSI 296 | (2402 - 2482 @ 40), (20) 297 | (5170 - 5250 @ 80), (20) 298 | (5250 - 5330 @ 80), (20), DFS 299 | (5490 - 5710 @ 80), (27), DFS 300 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 301 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 302 | 303 | country GE: DFS-ETSI 304 | (2402 - 2482 @ 40), (20) 305 | (5170 - 5250 @ 80), (18) 306 | (5250 - 5330 @ 80), (18), DFS 307 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 308 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 309 | 310 | country GB: DFS-ETSI 311 | (2402 - 2482 @ 40), (20) 312 | (5170 - 5250 @ 80), (20) 313 | (5250 - 5330 @ 80), (20), DFS 314 | (5490 - 5710 @ 80), (27), DFS 315 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 316 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 317 | 318 | country GD: DFS-FCC 319 | (2402 - 2472 @ 40), (30) 320 | (5170 - 5250 @ 80), (17) 321 | (5250 - 5330 @ 80), (24), DFS 322 | (5490 - 5730 @ 80), (24), DFS 323 | (5735 - 5835 @ 80), (30) 324 | 325 | country GR: DFS-ETSI 326 | (2402 - 2482 @ 40), (20) 327 | (5170 - 5250 @ 80), (20) 328 | (5250 - 5330 @ 80), (20), DFS 329 | (5490 - 5710 @ 80), (27), DFS 330 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 331 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 332 | 333 | country GL: DFS-ETSI 334 | (2402 - 2482 @ 40), (20) 335 | (5170 - 5250 @ 80), (20) 336 | (5250 - 5330 @ 80), (20), DFS 337 | (5490 - 5710 @ 80), (27), DFS 338 | 339 | country GT: DFS-FCC 340 | (2402 - 2472 @ 40), (30) 341 | (5170 - 5250 @ 80), (17) 342 | (5250 - 5330 @ 80), (23), DFS 343 | (5735 - 5835 @ 80), (30) 344 | 345 | country GU: DFS-FCC 346 | (2402 - 2472 @ 40), (30) 347 | (5170 - 5250 @ 80), (17) 348 | (5250 - 5330 @ 80), (24), DFS 349 | (5490 - 5730 @ 80), (24), DFS 350 | (5735 - 5835 @ 80), (30) 351 | 352 | country HN: DFS-FCC 353 | (2402 - 2482 @ 40), (20) 354 | (5170 - 5250 @ 80), (17) 355 | (5250 - 5330 @ 80), (24), DFS 356 | (5490 - 5730 @ 80), (24), DFS 357 | (5735 - 5835 @ 80), (30) 358 | 359 | country HK: 360 | (2402 - 2482 @ 40), (20) 361 | (5170 - 5250 @ 80), (17) 362 | (5250 - 5330 @ 80), (24), DFS 363 | (5490 - 5710 @ 80), (24), DFS 364 | (5735 - 5835 @ 80), (30) 365 | 366 | country HR: DFS-ETSI 367 | (2402 - 2482 @ 40), (20) 368 | (5170 - 5250 @ 80), (20) 369 | (5250 - 5330 @ 80), (20), DFS 370 | (5490 - 5710 @ 80), (27), DFS 371 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 372 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 373 | 374 | country HT: DFS-ETSI 375 | (2402 - 2482 @ 40), (20) 376 | (5170 - 5250 @ 80), (20) 377 | (5250 - 5330 @ 80), (20), DFS 378 | (5490 - 5710 @ 80), (27), DFS 379 | 380 | country HU: DFS-ETSI 381 | (2402 - 2482 @ 40), (20) 382 | (5170 - 5250 @ 80), (20) 383 | (5250 - 5330 @ 80), (20), DFS 384 | (5490 - 5710 @ 80), (27), DFS 385 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 386 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 387 | 388 | country ID: DFS-JP 389 | # ref: http://www.postel.go.id/content/ID/regulasi/standardisasi/kepdir/bwa%205,8%20ghz.pdf 390 | (2402 - 2482 @ 40), (20) 391 | (5735 - 5815 @ 80), (23) 392 | 393 | country IE: DFS-ETSI 394 | (2402 - 2482 @ 40), (20) 395 | (5170 - 5250 @ 80), (20) 396 | (5250 - 5330 @ 80), (20), DFS 397 | (5490 - 5710 @ 80), (27), DFS 398 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 399 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 400 | 401 | country IL: DFS-ETSI 402 | (2402 - 2482 @ 40), (20) 403 | (5150 - 5350 @ 80), (200 mW), NO-OUTDOOR 404 | 405 | country IN: DFS-JP 406 | (2402 - 2482 @ 40), (20) 407 | (5170 - 5250 @ 80), (20) 408 | (5250 - 5330 @ 80), (20), DFS 409 | (5735 - 5835 @ 80), (20) 410 | 411 | country IS: DFS-ETSI 412 | (2402 - 2482 @ 40), (20) 413 | (5170 - 5250 @ 80), (20) 414 | (5250 - 5330 @ 80), (20), DFS 415 | (5490 - 5710 @ 80), (27), DFS 416 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 417 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 418 | 419 | country IR: DFS-JP 420 | (2402 - 2482 @ 40), (20) 421 | (5735 - 5835 @ 80), (30) 422 | 423 | country IT: DFS-ETSI 424 | (2402 - 2482 @ 40), (20) 425 | (5170 - 5250 @ 80), (20) 426 | (5250 - 5330 @ 80), (20), DFS 427 | (5490 - 5710 @ 80), (27), DFS 428 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 429 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 430 | 431 | country JM: DFS-FCC 432 | (2402 - 2482 @ 40), (20) 433 | (5170 - 5250 @ 80), (17) 434 | (5250 - 5330 @ 80), (24), DFS 435 | (5490 - 5730 @ 80), (24), DFS 436 | (5735 - 5835 @ 80), (30) 437 | 438 | country JP: DFS-JP 439 | (2402 - 2482 @ 40), (20) 440 | (2474 - 2494 @ 20), (20), NO-OFDM 441 | (4910 - 4990 @ 40), (23) 442 | (5030 - 5090 @ 40), (23) 443 | (5170 - 5250 @ 80), (20) 444 | (5250 - 5330 @ 80), (20), DFS 445 | (5490 - 5710 @ 160), (23), DFS 446 | 447 | country JO: DFS-JP 448 | (2402 - 2482 @ 40), (20) 449 | (5170 - 5250 @ 80), (23) 450 | (5735 - 5835 @ 80), (23) 451 | 452 | country KE: DFS-JP 453 | (2402 - 2482 @ 40), (20) 454 | (5170 - 5250 @ 80), (23) 455 | (5490 - 5570 @ 80), (30), DFS 456 | (5735 - 5775 @ 40), (23) 457 | 458 | country KH: DFS-ETSI 459 | (2402 - 2482 @ 40), (20) 460 | (5170 - 5250 @ 80), (20) 461 | (5250 - 5330 @ 80), (20), DFS 462 | (5490 - 5710 @ 80), (27), DFS 463 | 464 | country KP: DFS-JP 465 | (2402 - 2482 @ 40), (20) 466 | (5170 - 5250 @ 80), (20) 467 | (5250 - 5330 @ 80), (20), DFS 468 | (5490 - 5630 @ 80), (30), DFS 469 | (5735 - 5815 @ 80), (30) 470 | 471 | country KR: DFS-JP 472 | (2402 - 2482 @ 20), (20) 473 | (2402 - 2482 @ 40), (20) 474 | (5170 - 5250 @ 80), (20) 475 | (5250 - 5330 @ 80), (20), DFS 476 | (5490 - 5710 @ 80), (30), DFS 477 | (5735 - 5815 @ 80), (30) 478 | 479 | country KW: DFS-ETSI 480 | (2402 - 2482 @ 40), (20) 481 | (5170 - 5250 @ 80), (20) 482 | (5250 - 5330 @ 80), (20), DFS 483 | 484 | country KZ: 485 | (2402 - 2482 @ 40), (20) 486 | 487 | country LB: DFS-FCC 488 | (2402 - 2482 @ 40), (20) 489 | (5170 - 5250 @ 80), (17) 490 | (5250 - 5330 @ 80), (24), DFS 491 | (5490 - 5730 @ 80), (24), DFS 492 | (5735 - 5835 @ 80), (30) 493 | 494 | country LI: DFS-ETSI 495 | (2402 - 2482 @ 40), (20) 496 | (5170 - 5250 @ 80), (20) 497 | (5250 - 5330 @ 80), (20), DFS 498 | (5490 - 5710 @ 80), (27), DFS 499 | 500 | country LK: DFS-FCC 501 | (2402 - 2482 @ 40), (20) 502 | (5170 - 5250 @ 80), (17) 503 | (5250 - 5330 @ 80), (24), DFS 504 | (5490 - 5730 @ 80), (24), DFS 505 | (5735 - 5835 @ 80), (30) 506 | 507 | country LT: DFS-ETSI 508 | (2402 - 2482 @ 40), (20) 509 | (5170 - 5250 @ 80), (20) 510 | (5250 - 5330 @ 80), (20), DFS 511 | (5490 - 5710 @ 80), (27), DFS 512 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 513 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 514 | 515 | country LU: DFS-ETSI 516 | (2402 - 2482 @ 40), (20) 517 | (5170 - 5250 @ 80), (20) 518 | (5250 - 5330 @ 80), (20), DFS 519 | (5490 - 5710 @ 80), (27), DFS 520 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 521 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 522 | 523 | country LV: DFS-ETSI 524 | (2402 - 2482 @ 40), (20) 525 | (5170 - 5250 @ 80), (20) 526 | (5250 - 5330 @ 80), (20), DFS 527 | (5490 - 5710 @ 80), (27), DFS 528 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 529 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 530 | 531 | country MC: DFS-ETSI 532 | (2402 - 2482 @ 40), (20) 533 | (5170 - 5250 @ 80), (20) 534 | (5250 - 5330 @ 80), (20), DFS 535 | (5490 - 5710 @ 80), (27), DFS 536 | 537 | country MA: DFS-ETSI 538 | (2402 - 2482 @ 40), (20) 539 | (5170 - 5250 @ 80), (20) 540 | (5250 - 5330 @ 80), (20), DFS 541 | 542 | country MO: 543 | (2402 - 2482 @ 40), (20) 544 | (5170 - 5250 @ 40), (23) 545 | (5250 - 5330 @ 40), (23), DFS 546 | (5735 - 5835 @ 40), (30) 547 | 548 | country MK: DFS-ETSI 549 | (2402 - 2482 @ 40), (20) 550 | (5170 - 5250 @ 80), (20) 551 | (5250 - 5330 @ 80), (20), DFS 552 | (5490 - 5710 @ 80), (27), DFS 553 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 554 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 555 | 556 | country MT: DFS-ETSI 557 | (2402 - 2482 @ 40), (20) 558 | (5170 - 5250 @ 80), (20) 559 | (5250 - 5330 @ 80), (20), DFS 560 | (5490 - 5710 @ 80), (27), DFS 561 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 562 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 563 | 564 | country MY: DFS-FCC 565 | (2402 - 2482 @ 40), (20) 566 | (5170 - 5250 @ 80), (17) 567 | (5250 - 5330 @ 80), (23), DFS 568 | (5735 - 5835 @ 80), (30) 569 | 570 | country MX: DFS-FCC 571 | (2402 - 2482 @ 40), (20) 572 | (5170 - 5250 @ 80), (17) 573 | (5250 - 5330 @ 80), (24), DFS 574 | (5490 - 5730 @ 80), (24), DFS 575 | (5735 - 5835 @ 80), (30) 576 | 577 | country NL: DFS-ETSI 578 | (2402 - 2482 @ 40), (20) 579 | (5170 - 5330 @ 80), (20), NO-OUTDOOR 580 | (5490 - 5710 @ 80), (27), DFS 581 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 582 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 583 | 584 | country NO: DFS-ETSI 585 | (2402 - 2482 @ 40), (20) 586 | (5170 - 5250 @ 80), (20) 587 | (5250 - 5330 @ 80), (20), DFS 588 | (5490 - 5710 @ 80), (27), DFS 589 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 590 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 591 | 592 | country NP: DFS-JP 593 | (2402 - 2482 @ 40), (20) 594 | (5170 - 5250 @ 80), (20) 595 | (5250 - 5330 @ 80), (20), DFS 596 | (5735 - 5835 @ 80), (20) 597 | 598 | country NZ: DFS-FCC 599 | (2402 - 2482 @ 40), (30) 600 | (5170 - 5250 @ 80), (17) 601 | (5250 - 5330 @ 80), (24), DFS 602 | (5490 - 5730 @ 80), (24), DFS 603 | (5735 - 5835 @ 80), (30) 604 | 605 | country OM: DFS-ETSI 606 | (2402 - 2482 @ 40), (20) 607 | (5170 - 5250 @ 80), (20) 608 | (5250 - 5330 @ 80), (20), DFS 609 | (5490 - 5710 @ 80), (27), DFS 610 | 611 | country PA: DFS-FCC 612 | (2402 - 2472 @ 40), (30) 613 | (5170 - 5250 @ 80), (17) 614 | (5250 - 5330 @ 80), (23), DFS 615 | (5735 - 5835 @ 80), (30) 616 | 617 | country PE: DFS-FCC 618 | (2402 - 2482 @ 40), (20) 619 | (5170 - 5250 @ 80), (17) 620 | (5250 - 5330 @ 80), (24), DFS 621 | (5490 - 5730 @ 80), (24), DFS 622 | (5735 - 5835 @ 80), (30) 623 | 624 | country PG: DFS-FCC 625 | (2402 - 2482 @ 40), (20) 626 | (5170 - 5250 @ 80), (17) 627 | (5250 - 5330 @ 80), (24), DFS 628 | (5490 - 5730 @ 80), (24), DFS 629 | (5735 - 5835 @ 80), (30) 630 | 631 | country PH: DFS-FCC 632 | (2402 - 2482 @ 40), (20) 633 | (5170 - 5250 @ 80), (17) 634 | (5250 - 5330 @ 80), (24), DFS 635 | (5490 - 5730 @ 80), (24), DFS 636 | (5735 - 5835 @ 80), (30) 637 | 638 | country PK: DFS-JP 639 | (2402 - 2482 @ 40), (20) 640 | (5735 - 5835 @ 80), (30) 641 | 642 | country PL: DFS-ETSI 643 | (2402 - 2482 @ 40), (20) 644 | (5170 - 5250 @ 80), (20) 645 | (5250 - 5330 @ 80), (20), DFS 646 | (5490 - 5710 @ 80), (27), DFS 647 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 648 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 649 | 650 | country PT: DFS-ETSI 651 | (2402 - 2482 @ 40), (20) 652 | (5170 - 5250 @ 80), (20) 653 | (5250 - 5330 @ 80), (20), DFS 654 | (5490 - 5710 @ 80), (27), DFS 655 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 656 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 657 | 658 | country PR: DFS-FCC 659 | (2402 - 2472 @ 40), (30) 660 | (5170 - 5250 @ 80), (17) 661 | (5250 - 5330 @ 80), (24), DFS 662 | (5490 - 5730 @ 80), (24), DFS 663 | (5735 - 5835 @ 80), (30) 664 | 665 | country QA: DFS-JP 666 | (2402 - 2482 @ 40), (20) 667 | (5735 - 5835 @ 80), (30) 668 | 669 | country RO: DFS-ETSI 670 | (2402 - 2482 @ 40), (20) 671 | (5170 - 5250 @ 80), (20) 672 | (5250 - 5330 @ 80), (20), DFS 673 | (5490 - 5710 @ 80), (27), DFS 674 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 675 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 676 | 677 | 678 | # Source: 679 | # http://www.ratel.rs/upload/documents/Plan_namene/Plan_namene-sl_glasnik.pdf 680 | country RS: DFS-ETSI 681 | (2400 - 2483.5 @ 40), (100 mW) 682 | (5150 - 5350 @ 40), (200 mW), NO-OUTDOOR 683 | (5470 - 5725 @ 20), (1000 mW), DFS 684 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 685 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 686 | 687 | country RU: DFS-ETSI 688 | (2402 - 2482 @ 40), (20) 689 | (5170 - 5250 @ 80), (20) 690 | (5250 - 5330 @ 80), (20), DFS 691 | (5650 - 5730 @ 80), (30), DFS 692 | (5735 - 5835 @ 80), (30) 693 | 694 | country RW: DFS-FCC 695 | (2402 - 2482 @ 40), (20) 696 | (5170 - 5250 @ 80), (17) 697 | (5250 - 5330 @ 80), (24), DFS 698 | (5490 - 5730 @ 80), (24), DFS 699 | (5735 - 5835 @ 80), (30) 700 | 701 | country SA: DFS-ETSI 702 | (2402 - 2482 @ 40), (20) 703 | (5170 - 5250 @ 80), (20) 704 | (5250 - 5330 @ 80), (20), DFS 705 | (5490 - 5710 @ 80), (27), DFS 706 | 707 | country SE: DFS-ETSI 708 | (2402 - 2482 @ 40), (20) 709 | (5170 - 5250 @ 80), (20) 710 | (5250 - 5330 @ 80), (20), DFS 711 | (5490 - 5710 @ 80), (27), DFS 712 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 713 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 714 | 715 | country SG: DFS-FCC 716 | (2402 - 2482 @ 40), (20) 717 | (5170 - 5250 @ 80), (17) 718 | (5250 - 5330 @ 80), (24), DFS 719 | (5490 - 5730 @ 80), (24), DFS 720 | (5735 - 5835 @ 80), (30) 721 | 722 | country SI: DFS-ETSI 723 | (2402 - 2482 @ 40), (20) 724 | (5170 - 5250 @ 80), (20) 725 | (5250 - 5330 @ 80), (20), DFS 726 | (5490 - 5710 @ 80), (27), DFS 727 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 728 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 729 | 730 | country SK: DFS-ETSI 731 | (2402 - 2482 @ 40), (20) 732 | (5170 - 5250 @ 80), (20) 733 | (5250 - 5330 @ 80), (20), DFS 734 | (5490 - 5710 @ 80), (27), DFS 735 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 736 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 737 | 738 | country SV: DFS-FCC 739 | (2402 - 2482 @ 40), (20) 740 | (5170 - 5250 @ 80), (17) 741 | (5250 - 5330 @ 80), (23), DFS 742 | (5735 - 5835 @ 80), (30) 743 | 744 | country SY: 745 | (2402 - 2482 @ 40), (20) 746 | 747 | country TW: DFS-JP 748 | (2402 - 2472 @ 40), (30) 749 | (5270 - 5330 @ 40), (17), DFS 750 | (5490 - 5590 @ 80), (30), DFS 751 | (5650 - 5710 @ 40), (30), DFS 752 | (5735 - 5835 @ 80), (30) 753 | 754 | country TH: DFS-FCC 755 | (2402 - 2482 @ 40), (20) 756 | (5170 - 5250 @ 80), (17) 757 | (5250 - 5330 @ 80), (24), DFS 758 | (5490 - 5730 @ 80), (24), DFS 759 | (5735 - 5835 @ 80), (30) 760 | 761 | country TT: DFS-FCC 762 | (2402 - 2482 @ 40), (20) 763 | (5170 - 5250 @ 80), (17) 764 | (5250 - 5330 @ 80), (24), DFS 765 | (5490 - 5730 @ 80), (24), DFS 766 | (5735 - 5835 @ 80), (30) 767 | 768 | country TN: DFS-ETSI 769 | (2402 - 2482 @ 40), (20) 770 | (5170 - 5250 @ 80), (20) 771 | (5250 - 5330 @ 80), (20), DFS 772 | 773 | country TR: DFS-ETSI 774 | (2402 - 2482 @ 40), (20) 775 | (5170 - 5250 @ 80), (20) 776 | (5250 - 5330 @ 80), (20), DFS 777 | (5490 - 5710 @ 80), (27), DFS 778 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 779 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 780 | 781 | # Source: 782 | # #914 / 06 Sep 2007: http://www.ucrf.gov.ua/uk/doc/nkrz/1196068874 783 | # #1174 / 23 Oct 2008: http://www.nkrz.gov.ua/uk/activities/ruling/1225269361 784 | # (appendix 8) 785 | # Listed 5GHz range is a lowest common denominator for all related 786 | # rules in the referenced laws. Such a range is used because of 787 | # disputable definitions there. 788 | country UA: DFS-ETSI 789 | (2400 - 2483.5 @ 40), (20), NO-OUTDOOR 790 | (5150 - 5350 @ 40), (20), NO-OUTDOOR 791 | (5490 - 5670 @ 80), (20), DFS 792 | (5735 - 5835 @ 80), (20) 793 | # 60 gHz band channels 1-4, ref: Etsi En 302 567 794 | (57240 - 65880 @ 2160), (40), NO-OUTDOOR 795 | 796 | country US: DFS-FCC 797 | (2402 - 2472 @ 40), (30) 798 | (5170 - 5250 @ 80), (17) 799 | (5250 - 5330 @ 80), (23), DFS 800 | (5735 - 5835 @ 80), (30) 801 | # 60g band 802 | # reference: http://cfr.regstoday.com/47cfr15.aspx#47_CFR_15p255 803 | # channels 1,2,3, EIRP=40dBm(43dBm peak) 804 | (57240 - 63720 @ 2160), (40) 805 | 806 | country UY: DFS-FCC 807 | (2402 - 2482 @ 40), (20) 808 | (5170 - 5250 @ 80), (17) 809 | (5250 - 5330 @ 80), (24), DFS 810 | (5490 - 5730 @ 80), (24), DFS 811 | (5735 - 5835 @ 80), (30) 812 | 813 | country UZ: DFS-FCC 814 | (2402 - 2472 @ 40), (30) 815 | (5170 - 5250 @ 80), (17) 816 | (5250 - 5330 @ 80), (24), DFS 817 | (5490 - 5730 @ 80), (24), DFS 818 | (5735 - 5835 @ 80), (30) 819 | 820 | country VE: DFS-FCC 821 | (2402 - 2482 @ 40), (20) 822 | (5170 - 5250 @ 80), (17) 823 | (5250 - 5330 @ 80), (23), DFS 824 | (5735 - 5835 @ 80), (30) 825 | 826 | country VN: DFS-FCC 827 | (2402 - 2482 @ 40), (20) 828 | (5170 - 5250 @ 80), (17) 829 | (5250 - 5330 @ 80), (24), DFS 830 | (5490 - 5730 @ 80), (24), DFS 831 | (5735 - 5835 @ 80), (30) 832 | 833 | country YE: 834 | (2402 - 2482 @ 40), (20) 835 | 836 | country ZA: DFS-ETSI 837 | (2402 - 2482 @ 40), (20) 838 | (5170 - 5250 @ 80), (20) 839 | (5250 - 5330 @ 80), (20), DFS 840 | (5490 - 5710 @ 80), (27), DFS 841 | 842 | country ZW: DFS-ETSI 843 | (2402 - 2482 @ 40), (20) 844 | (5170 - 5250 @ 80), (20) 845 | (5250 - 5330 @ 80), (20), DFS 846 | (5490 - 5710 @ 80), (27), DFS 847 | 848 | -------------------------------------------------------------------------------- /db2bin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from cStringIO import StringIO 4 | import struct 5 | import hashlib 6 | from dbparse import DBParser 7 | import sys 8 | 9 | MAGIC = 0x52474442 10 | VERSION = 19 11 | 12 | if len(sys.argv) < 3: 13 | print 'Usage: %s output-file input-file [key-file]' % sys.argv[0] 14 | sys.exit(2) 15 | 16 | def create_rules(countries): 17 | result = {} 18 | for c in countries.itervalues(): 19 | for rule in c.permissions: 20 | result[rule] = 1 21 | return result.keys() 22 | 23 | def create_collections(countries): 24 | result = {} 25 | for c in countries.itervalues(): 26 | result[c.permissions] = 1 27 | return result.keys() 28 | 29 | 30 | def be32(output, val): 31 | output.write(struct.pack('>I', val)) 32 | 33 | class PTR(object): 34 | def __init__(self, output): 35 | self._output = output 36 | self._pos = output.tell() 37 | be32(output, 0xFFFFFFFF) 38 | 39 | def set(self, val=None): 40 | if val is None: 41 | val = self._output.tell() 42 | self._offset = val 43 | pos = self._output.tell() 44 | self._output.seek(self._pos) 45 | be32(self._output, val) 46 | self._output.seek(pos) 47 | 48 | def get(self): 49 | return self._offset 50 | 51 | p = DBParser() 52 | countries = p.parse(file(sys.argv[2])) 53 | power = [] 54 | bands = [] 55 | for c in countries.itervalues(): 56 | for perm in c.permissions: 57 | if not perm.freqband in bands: 58 | bands.append(perm.freqband) 59 | if not perm.power in power: 60 | power.append(perm.power) 61 | rules = create_rules(countries) 62 | rules.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband)) 63 | collections = create_collections(countries) 64 | collections.sort(cmp=lambda x, y: cmp(x[0].freqband, y[0].freqband)) 65 | 66 | output = StringIO() 67 | 68 | # struct regdb_file_header 69 | be32(output, MAGIC) 70 | be32(output, VERSION) 71 | reg_country_ptr = PTR(output) 72 | # add number of countries 73 | be32(output, len(countries)) 74 | siglen = PTR(output) 75 | 76 | power_rules = {} 77 | for pr in power: 78 | power_rules[pr] = output.tell() 79 | pr = [int(v * 100.0) for v in (pr.max_ant_gain, pr.max_eirp)] 80 | # struct regdb_file_power_rule 81 | output.write(struct.pack('>II', *pr)) 82 | 83 | freq_ranges = {} 84 | for fr in bands: 85 | freq_ranges[fr] = output.tell() 86 | fr = [int(f * 1000.0) for f in (fr.start, fr.end, fr.maxbw)] 87 | # struct regdb_file_freq_range 88 | output.write(struct.pack('>III', *fr)) 89 | 90 | 91 | reg_rules = {} 92 | for reg_rule in rules: 93 | freq_range, power_rule = reg_rule.freqband, reg_rule.power 94 | reg_rules[reg_rule] = output.tell() 95 | # struct regdb_file_reg_rule 96 | output.write(struct.pack('>III', freq_ranges[freq_range], power_rules[power_rule], 97 | reg_rule.flags)) 98 | 99 | 100 | reg_rules_collections = {} 101 | 102 | for coll in collections: 103 | reg_rules_collections[coll] = output.tell() 104 | # struct regdb_file_reg_rules_collection 105 | coll = list(coll) 106 | be32(output, len(coll)) 107 | coll.sort(cmp=lambda x, y: cmp(x.freqband, y.freqband)) 108 | for regrule in coll: 109 | be32(output, reg_rules[regrule]) 110 | 111 | # update country pointer now! 112 | reg_country_ptr.set() 113 | 114 | countrynames = countries.keys() 115 | countrynames.sort() 116 | for alpha2 in countrynames: 117 | coll = countries[alpha2] 118 | # struct regdb_file_reg_country 119 | output.write(struct.pack('>ccxBI', str(alpha2[0]), str(alpha2[1]), coll.dfs_region, reg_rules_collections[coll.permissions])) 120 | 121 | 122 | if len(sys.argv) > 3: 123 | # Load RSA only now so people can use this script 124 | # without having those libraries installed to verify 125 | # their SQL changes 126 | from M2Crypto import RSA 127 | 128 | # determine signature length 129 | key = RSA.load_key(sys.argv[3]) 130 | hash = hashlib.sha1() 131 | hash.update(output.getvalue()) 132 | sig = key.sign(hash.digest()) 133 | # write it to file 134 | siglen.set(len(sig)) 135 | # sign again 136 | hash = hashlib.sha1() 137 | hash.update(output.getvalue()) 138 | sig = key.sign(hash.digest()) 139 | 140 | output.write(sig) 141 | else: 142 | siglen.set(0) 143 | 144 | outfile = open(sys.argv[1], 'w') 145 | outfile.write(output.getvalue()) 146 | -------------------------------------------------------------------------------- /dbparse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | import sys, math 4 | 5 | # must match enum nl80211_reg_rule_flags 6 | 7 | flag_definitions = { 8 | 'NO-OFDM': 1<<0, 9 | 'NO-CCK': 1<<1, 10 | 'NO-INDOOR': 1<<2, 11 | 'NO-OUTDOOR': 1<<3, 12 | 'DFS': 1<<4, 13 | 'PTP-ONLY': 1<<5, 14 | 'PTMP-ONLY': 1<<6, 15 | 'NO-IR': 1<<7, 16 | # hole at bit 8 17 | # hole at bit 9. FIXME: Where is NO-HT40 defined? 18 | 'NO-HT40': 1<<10, 19 | 'OCB-ONLY': 1<<12, 20 | } 21 | 22 | dfs_regions = { 23 | 'DFS-FCC': 1, 24 | 'DFS-ETSI': 2, 25 | 'DFS-JP': 3, 26 | } 27 | 28 | class FreqBand(object): 29 | def __init__(self, start, end, bw, comments=None): 30 | self.start = start 31 | self.end = end 32 | self.maxbw = bw 33 | self.comments = comments or [] 34 | 35 | def __cmp__(self, other): 36 | s = self 37 | o = other 38 | if not isinstance(o, FreqBand): 39 | return False 40 | return cmp((s.start, s.end, s.maxbw), (o.start, o.end, o.maxbw)) 41 | 42 | def __hash__(self): 43 | s = self 44 | return hash((s.start, s.end, s.maxbw)) 45 | 46 | def __str__(self): 47 | return '' % ( 48 | self.start, self.end, self.maxbw) 49 | 50 | class PowerRestriction(object): 51 | def __init__(self, max_ant_gain, max_eirp, comments = None): 52 | self.max_ant_gain = max_ant_gain 53 | self.max_eirp = max_eirp 54 | self.comments = comments or [] 55 | 56 | def __cmp__(self, other): 57 | s = self 58 | o = other 59 | if not isinstance(o, PowerRestriction): 60 | return False 61 | return cmp((s.max_ant_gain, s.max_eirp), 62 | (o.max_ant_gain, o.max_eirp)) 63 | 64 | def __str__(self): 65 | return '' 66 | 67 | def __hash__(self): 68 | s = self 69 | return hash((s.max_ant_gain, s.max_eirp)) 70 | 71 | class DFSRegionError(Exception): 72 | def __init__(self, dfs_region): 73 | self.dfs_region = dfs_region 74 | 75 | class FlagError(Exception): 76 | def __init__(self, flag): 77 | self.flag = flag 78 | 79 | class Permission(object): 80 | def __init__(self, freqband, power, flags): 81 | assert isinstance(freqband, FreqBand) 82 | assert isinstance(power, PowerRestriction) 83 | self.freqband = freqband 84 | self.power = power 85 | self.flags = 0 86 | for flag in flags: 87 | if not flag in flag_definitions: 88 | raise FlagError(flag) 89 | self.flags |= flag_definitions[flag] 90 | self.textflags = flags 91 | 92 | def _as_tuple(self): 93 | return (self.freqband, self.power, self.flags) 94 | 95 | def __cmp__(self, other): 96 | if not isinstance(other, Permission): 97 | return False 98 | return cmp(self._as_tuple(), other._as_tuple()) 99 | 100 | def __hash__(self): 101 | return hash(self._as_tuple()) 102 | 103 | class Country(object): 104 | def __init__(self, dfs_region, permissions=None, comments=None): 105 | self._permissions = permissions or [] 106 | self.comments = comments or [] 107 | self.dfs_region = 0 108 | 109 | if dfs_region: 110 | if not dfs_region in dfs_regions: 111 | raise DFSRegionError(dfs_region) 112 | self.dfs_region = dfs_regions[dfs_region] 113 | 114 | def add(self, perm): 115 | assert isinstance(perm, Permission) 116 | self._permissions.append(perm) 117 | self._permissions.sort() 118 | 119 | def __contains__(self, perm): 120 | assert isinstance(perm, Permission) 121 | return perm in self._permissions 122 | 123 | def __str__(self): 124 | r = ['(%s, %s)' % (str(b), str(p)) for b, p in self._permissions] 125 | return '' % (', '.join(r)) 126 | 127 | def _get_permissions_tuple(self): 128 | return tuple(self._permissions) 129 | permissions = property(_get_permissions_tuple) 130 | 131 | class SyntaxError(Exception): 132 | pass 133 | 134 | class DBParser(object): 135 | def __init__(self, warn=None): 136 | self._warn_callout = warn or sys.stderr.write 137 | 138 | def _syntax_error(self, txt=None): 139 | txt = txt and ' (%s)' % txt or '' 140 | raise SyntaxError("Syntax error in line %d%s" % (self._lineno, txt)) 141 | 142 | def _warn(self, txt): 143 | self._warn_callout("Warning (line %d): %s\n" % (self._lineno, txt)) 144 | 145 | def _parse_band_def(self, bname, banddef, dupwarn=True): 146 | try: 147 | freqs, bw = banddef.split('@') 148 | bw = float(bw) 149 | except ValueError: 150 | bw = 20.0 151 | 152 | try: 153 | start, end = freqs.split('-') 154 | start = float(start) 155 | end = float(end) 156 | # The kernel will reject these, so might as well reject this 157 | # upon building it. 158 | if start <= 0: 159 | self._syntax_error("Invalid start freq (%d)" % start) 160 | if end <= 0: 161 | self._syntax_error("Invalid end freq (%d)" % end) 162 | if start > end: 163 | self._syntax_error("Inverted freq range (%d - %d)" % (start, end)) 164 | if start == end: 165 | self._syntax_error("Start and end freqs are equal (%d)" % start) 166 | except ValueError: 167 | self._syntax_error("band must have frequency range") 168 | 169 | b = FreqBand(start, end, bw, comments=self._comments) 170 | self._comments = [] 171 | self._banddup[bname] = bname 172 | if b in self._bandrev: 173 | if dupwarn: 174 | self._warn('Duplicate band definition ("%s" and "%s")' % ( 175 | bname, self._bandrev[b])) 176 | self._banddup[bname] = self._bandrev[b] 177 | self._bands[bname] = b 178 | self._bandrev[b] = bname 179 | self._bandline[bname] = self._lineno 180 | 181 | def _parse_band(self, line): 182 | try: 183 | bname, line = line.split(':', 1) 184 | if not bname: 185 | self._syntax_error("'band' keyword must be followed by name") 186 | except ValueError: 187 | self._syntax_error("band name must be followed by colon") 188 | 189 | if bname in flag_definitions: 190 | self._syntax_error("Invalid band name") 191 | 192 | self._parse_band_def(bname, line) 193 | 194 | def _parse_power(self, line): 195 | try: 196 | pname, line = line.split(':', 1) 197 | if not pname: 198 | self._syntax_error("'power' keyword must be followed by name") 199 | except ValueError: 200 | self._syntax_error("power name must be followed by colon") 201 | 202 | if pname in flag_definitions: 203 | self._syntax_error("Invalid power name") 204 | 205 | self._parse_power_def(pname, line) 206 | 207 | def _parse_power_def(self, pname, line, dupwarn=True): 208 | try: 209 | max_eirp = line 210 | if max_eirp == 'N/A': 211 | max_eirp = '0' 212 | max_ant_gain = float(0) 213 | def conv_pwr(pwr): 214 | if pwr.endswith('mW'): 215 | pwr = float(pwr[:-2]) 216 | return 10.0 * math.log10(pwr) 217 | else: 218 | return float(pwr) 219 | max_eirp = conv_pwr(max_eirp) 220 | except ValueError: 221 | self._syntax_error("invalid power data") 222 | 223 | p = PowerRestriction(max_ant_gain, max_eirp, 224 | comments=self._comments) 225 | self._comments = [] 226 | self._powerdup[pname] = pname 227 | if p in self._powerrev: 228 | if dupwarn: 229 | self._warn('Duplicate power definition ("%s" and "%s")' % ( 230 | pname, self._powerrev[p])) 231 | self._powerdup[pname] = self._powerrev[p] 232 | self._power[pname] = p 233 | self._powerrev[p] = pname 234 | self._powerline[pname] = self._lineno 235 | 236 | def _parse_country(self, line): 237 | try: 238 | cname, cvals= line.split(':', 1) 239 | dfs_region = cvals.strip() 240 | if not cname: 241 | self._syntax_error("'country' keyword must be followed by name") 242 | except ValueError: 243 | self._syntax_error("country name must be followed by colon") 244 | 245 | cnames = cname.split(',') 246 | 247 | self._current_countries = {} 248 | for cname in cnames: 249 | if len(cname) != 2: 250 | self._warn("country '%s' not alpha2" % cname) 251 | if not cname in self._countries: 252 | self._countries[cname] = Country(dfs_region, comments=self._comments) 253 | self._current_countries[cname] = self._countries[cname] 254 | self._comments = [] 255 | 256 | def _parse_country_item(self, line): 257 | if line[0] == '(': 258 | try: 259 | band, line = line[1:].split('),', 1) 260 | bname = 'UNNAMED %d' % self._lineno 261 | self._parse_band_def(bname, band, dupwarn=False) 262 | except: 263 | self._syntax_error("Badly parenthesised band definition") 264 | else: 265 | try: 266 | bname, line = line.split(',', 1) 267 | if not bname: 268 | self._syntax_error("country definition must have band") 269 | if not line: 270 | self._syntax_error("country definition must have power") 271 | except ValueError: 272 | self._syntax_error("country definition must have band and power") 273 | 274 | if line[0] == '(': 275 | items = line.split('),', 1) 276 | if len(items) == 1: 277 | pname = items[0] 278 | line = '' 279 | if not pname[-1] == ')': 280 | self._syntax_error("Badly parenthesised power definition") 281 | pname = pname[:-1] 282 | flags = [] 283 | else: 284 | pname = items[0] 285 | flags = items[1].split(',') 286 | power = pname[1:] 287 | pname = 'UNNAMED %d' % self._lineno 288 | self._parse_power_def(pname, power, dupwarn=False) 289 | else: 290 | line = line.split(',') 291 | pname = line[0] 292 | flags = line[1:] 293 | 294 | if not bname in self._bands: 295 | self._syntax_error("band does not exist") 296 | if not pname in self._power: 297 | self._syntax_error("power does not exist") 298 | self._bands_used[bname] = True 299 | self._power_used[pname] = True 300 | # de-duplicate so binary database is more compact 301 | bname = self._banddup[bname] 302 | pname = self._powerdup[pname] 303 | b = self._bands[bname] 304 | p = self._power[pname] 305 | try: 306 | perm = Permission(b, p, flags) 307 | except FlagError, e: 308 | self._syntax_error("Invalid flag '%s'" % e.flag) 309 | for cname, c in self._current_countries.iteritems(): 310 | if perm in c: 311 | self._warn('Rule "%s, %s" added to "%s" twice' % ( 312 | bname, pname, cname)) 313 | else: 314 | c.add(perm) 315 | 316 | def parse(self, f): 317 | self._current_countries = None 318 | self._bands = {} 319 | self._power = {} 320 | self._countries = {} 321 | self._bands_used = {} 322 | self._power_used = {} 323 | self._bandrev = {} 324 | self._powerrev = {} 325 | self._banddup = {} 326 | self._powerdup = {} 327 | self._bandline = {} 328 | self._powerline = {} 329 | 330 | self._comments = [] 331 | 332 | self._lineno = 0 333 | for line in f: 334 | self._lineno += 1 335 | line = line.strip() 336 | if line[0:1] == '#': 337 | self._comments.append(line[1:].strip()) 338 | line = line.replace(' ', '').replace('\t', '') 339 | if not line: 340 | self._comments = [] 341 | line = line.split('#')[0] 342 | if not line: 343 | continue 344 | if line[0:4] == 'band': 345 | self._parse_band(line[4:]) 346 | self._current_countries = None 347 | self._comments = [] 348 | elif line[0:5] == 'power': 349 | self._parse_power(line[5:]) 350 | self._current_countries = None 351 | self._comments = [] 352 | elif line[0:7] == 'country': 353 | self._parse_country(line[7:]) 354 | self._comments = [] 355 | elif self._current_countries is not None: 356 | self._parse_country_item(line) 357 | self._comments = [] 358 | else: 359 | self._syntax_error("Expected band, power or country definition") 360 | 361 | countries = self._countries 362 | bands = {} 363 | for k, v in self._bands.iteritems(): 364 | if k in self._bands_used: 365 | bands[self._banddup[k]] = v 366 | continue 367 | # we de-duplicated, but don't warn again about the dupes 368 | if self._banddup[k] == k: 369 | self._lineno = self._bandline[k] 370 | self._warn('Unused band definition "%s"' % k) 371 | power = {} 372 | for k, v in self._power.iteritems(): 373 | if k in self._power_used: 374 | power[self._powerdup[k]] = v 375 | continue 376 | # we de-duplicated, but don't warn again about the dupes 377 | if self._powerdup[k] == k: 378 | self._lineno = self._powerline[k] 379 | self._warn('Unused power definition "%s"' % k) 380 | return countries 381 | -------------------------------------------------------------------------------- /debian-example/changelog: -------------------------------------------------------------------------------- 1 | wireless-regdb (2009.01.15-1) unstable; urgency=low 2 | 3 | * Initial release 4 | 5 | -- Luis R. Rodriguez Thu, 22 Jan 2009 16:00:00 +0100 6 | -------------------------------------------------------------------------------- /debian-example/compat: -------------------------------------------------------------------------------- 1 | 5 2 | -------------------------------------------------------------------------------- /debian-example/control: -------------------------------------------------------------------------------- 1 | Source: wireless-regdb 2 | Section: admin 3 | Priority: optional 4 | Maintainer: Luis R. Rodriguez 5 | Build-Depends: cdbs, debhelper (>= 5), python 6 | Standards-Version: 3.7.3 7 | 8 | Package: wireless-regdb 9 | Architecture: all 10 | Depends: 11 | Suggests: crda 12 | Description: The Linux wireless regulatory database 13 | This package contains the wireless regulatory database used by all 14 | cfg80211 based Linux wireless drivers. The wireless database being 15 | used is maintained by John Linville, the Linux wireless kernel maintainer. 16 | -------------------------------------------------------------------------------- /debian-example/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by Luis Rodriguez on 2 | Thu, 22 Jan 2009 16:00:00 +0100. 3 | 4 | The wireless-regdb packages was downloaded from 5 | 6 | Copyright (c) 2008, Luis R. Rodriguez 7 | Copyright (c) 2008, Johannes Berg 8 | Copyright (c) 2008, Michael Green 9 | 10 | Permission to use, copy, modify, and/or distribute this software for any 11 | purpose with or without fee is hereby granted, provided that the above 12 | copyright notice and this permission notice appear in all copies. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 15 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 16 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 17 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 18 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 19 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 20 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /debian-example/docs: -------------------------------------------------------------------------------- 1 | README 2 | -------------------------------------------------------------------------------- /debian-example/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | 3 | include /usr/share/cdbs/1/rules/debhelper.mk 4 | 5 | PREFIX = /usr 6 | CRDA_LIB ?= $(PREFIX)/lib/crda 7 | 8 | install/wireless-regdb:: 9 | install -o 0 -g 0 -m 755 -d debian/$(cdbs_curpkg)/$(CRDA_LIB) 10 | install -o 0 -g 0 -m 644 regulatory.bin debian/$(cdbs_curpkg)/$(CRDA_LIB)/regulatory.bin 11 | -------------------------------------------------------------------------------- /linville.key.pub.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1leZcYjTXc4qLq1oN2Ak 3 | 8vLP85P5cFTrCpqdSI5W4VOwdaJB4TtaxU2fATcH/A2EsE3h1rOfzI0+fBV9DcOO 4 | qyID+zdILBMb8xK5Zv+78OkBGls/WzvDDVhdmn1TRHvRvmJy7cX1mCT56cnHrZM/ 5 | ZBaFwVfiD9TcqqisyF1sqE5+cMHTWRbxc1+rtojr0eGYrNfK20awlD5KVj6Ejzot 6 | r9EDWAsL1bH/kGfMdnputcyMapLQpRVruO/jEdjSmhAE/sj1tmHcAXBT6j5al4Oa 7 | LiBaWnP++rune7rjimwfzp0549/rupQUM7nAZRDLyzXj3J/KEci6dXtjonBUFqDY 8 | 4QIDAQAB 9 | -----END PUBLIC KEY----- 10 | -------------------------------------------------------------------------------- /regulatory.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CTU-IIG/802.11p-wireless-regdb/12b9b0017f7cae7a4c7f6706ed33034a790ab320/regulatory.bin -------------------------------------------------------------------------------- /regulatory.bin.5: -------------------------------------------------------------------------------- 1 | .TH regulatory.bin 5 "23 January 2009" "regulatory.bin" "Linux" 2 | .SH NAME 3 | regulatory.bin \- The Linux wireless regulatory database 4 | 5 | .ad l 6 | .in +8 7 | .ti -8 8 | 9 | .SS 10 | .SH Description 11 | .B regulatory.bin 12 | is the file used by the Linux wireless subsystem to keep its regulatory 13 | database information. It is read by 14 | .B crda 15 | upon the Linux kernel's request for regulatory information for a specific 16 | ISO / IEC 3166 alpha2 country code. The regulatory database is kept in 17 | a small binary format for size and code efficiency. The 18 | .B regulatory.bin 19 | file can be parsed and read in human format by using the 20 | .B regdbdump 21 | command. The 22 | .B regulatory.bin 23 | file should be updated upon regulatory changes or corrections. 24 | 25 | .SH Upkeeping 26 | The regulatory database is maintained by the community as such 27 | you are encouraged to send any corrections or updates to the 28 | linux-wireless mailing list: 29 | .B linux-wireless@vger.kernel.org 30 | 31 | .SH SEE ALSO 32 | .BR regdbdump (8) 33 | .BR crda (8) 34 | .BR iw (8) 35 | 36 | .BR http://wireless.kernel.org/en/developers/Regulatory/ 37 | 38 | -------------------------------------------------------------------------------- /sha1sum.txt: -------------------------------------------------------------------------------- 1 | dcce036e330cf160b677f3ec3d372020db204f92 db.txt 2 | -------------------------------------------------------------------------------- /web/Regulatory.py: -------------------------------------------------------------------------------- 1 | # -*- coding: iso-8859-1 -*- 2 | """ 3 | Regulatory Database 4 | 5 | @copyright: 2008 Johannes Berg 6 | @license: ISC, see LICENSE for details. 7 | """ 8 | 9 | import codecs, math 10 | from dbparse import DBParser, flag_definitions 11 | 12 | Dependencies = ["time"] 13 | 14 | def _country(macro, countries, code): 15 | result = [] 16 | 17 | f = macro.formatter 18 | 19 | result.extend([ 20 | f.heading(1, 1), 21 | f.text('Regulatory definition for %s' % _get_iso_code(code)), 22 | f.heading(0, 1), 23 | ]) 24 | 25 | try: 26 | country = countries[code] 27 | except: 28 | result.append(f.text('No information available')) 29 | return ''.join(result) 30 | 31 | 32 | if country.comments: 33 | result.extend([ 34 | f.preformatted(1), 35 | f.text('\n'.join(country.comments)), 36 | f.preformatted(0), 37 | ]) 38 | 39 | result.append(f.table(1)) 40 | result.extend([ 41 | f.table_row(1), 42 | f.table_cell(1), f.strong(1), 43 | f.text('Band [MHz]'), 44 | f.strong(0), f.table_cell(0), 45 | f.table_cell(1), f.strong(1), 46 | f.text('Max BW [MHz]'), 47 | f.strong(0), f.table_cell(0), 48 | f.table_cell(1), f.strong(1), 49 | f.text('Flags'), 50 | f.strong(0), f.table_cell(0), 51 | f.table_cell(1), f.strong(1), 52 | f.text('Max antenna gain [dBi]'), 53 | f.strong(0), f.table_cell(0), 54 | f.table_cell(1), f.strong(1), 55 | f.text('Max EIRP [dBm'), 56 | f.hardspace, 57 | f.text('(mW)]'), 58 | f.strong(0), f.table_cell(0), 59 | f.table_row(0), 60 | ]) 61 | 62 | for perm in country.permissions: 63 | def str_or_na(val, dBm=False): 64 | if val and not dBm: 65 | return '%.2f' % val 66 | elif val: 67 | return '%.2f (%.2f)' % (val, math.pow(10, val/10.0)) 68 | return 'N/A' 69 | result.extend([ 70 | f.table_row(1), 71 | f.table_cell(1), 72 | f.text('%.3f - %.3f' % (perm.freqband.start, perm.freqband.end)), 73 | f.table_cell(0), 74 | f.table_cell(1), 75 | f.text('%.3f' % (perm.freqband.maxbw,)), 76 | f.table_cell(0), 77 | f.table_cell(1), 78 | f.text(', '.join(perm.textflags)), 79 | f.table_cell(0), 80 | f.table_cell(1), 81 | f.text(str_or_na(perm.power.max_ant_gain)), 82 | f.table_cell(0), 83 | f.table_cell(1), 84 | f.text(str_or_na(perm.power.max_eirp, dBm=True)), 85 | f.table_cell(0), 86 | f.table_row(0), 87 | ]) 88 | 89 | result.append(f.table(0)) 90 | 91 | result.append(f.linebreak(0)) 92 | result.append(f.linebreak(0)) 93 | result.append(macro.request.page.link_to(macro.request, 'return to country list')) 94 | return ''.join(result) 95 | 96 | _iso_list = {} 97 | 98 | def _get_iso_code(code): 99 | if not _iso_list: 100 | for line in codecs.open('/usr/share/iso-codes/iso_3166.tab', encoding='utf-8'): 101 | line = line.strip() 102 | c, name = line.split('\t') 103 | _iso_list[c] = name 104 | return _iso_list.get(code, 'Unknown (%s)' % code) 105 | 106 | def macro_Regulatory(macro): 107 | _ = macro.request.getText 108 | request = macro.request 109 | f = macro.formatter 110 | 111 | country = request.form.get('alpha2', [None])[0] 112 | 113 | dbpath = '/tmp/db.txt' 114 | if hasattr(request.cfg, 'regdb_path'): 115 | dbpath = request.cfg.regdb_path 116 | 117 | result = [] 118 | 119 | if request.form.get('raw', [None])[0]: 120 | result.append(f.code_area(1, 'db-raw', show=1, start=1, step=1)) 121 | for line in open(dbpath): 122 | result.extend([ 123 | f.code_line(1), 124 | f.text(line.rstrip()), 125 | f.code_line(0), 126 | ]) 127 | result.append(f.code_area(0, 'db-raw')) 128 | result.append(macro.request.page.link_to(macro.request, 'return to country list')) 129 | return ''.join(result) 130 | 131 | warnings = [] 132 | countries = DBParser(warn=lambda x: warnings.append(x)).parse(open(dbpath)) 133 | 134 | if country: 135 | return _country(macro, countries, country) 136 | 137 | countries = countries.keys() 138 | countries = [(_get_iso_code(code), code) for code in countries] 139 | countries.sort() 140 | 141 | result.extend([ 142 | f.heading(1, 1), 143 | f.text('Countries'), 144 | f.heading(0, 1), 145 | ]) 146 | 147 | result.append(f.bullet_list(1)) 148 | for name, code in countries: 149 | result.extend([ 150 | f.listitem(1), 151 | request.page.link_to(request, name, querystr={'alpha2': code}), 152 | f.listitem(0), 153 | ]) 154 | result.append(f.bullet_list(0)) 155 | 156 | if warnings: 157 | result.append(f.heading(1, 2)) 158 | result.append(f.text("Warnings")) 159 | result.append(f.heading(0, 2)) 160 | result.append(f.preformatted(1)) 161 | result.extend(warnings) 162 | result.append(f.preformatted(0)) 163 | 164 | result.append(request.page.link_to(request, 'view raw database', querystr={'raw': 1})) 165 | 166 | return ''.join(result) 167 | -------------------------------------------------------------------------------- /wireless-regdb.spec: -------------------------------------------------------------------------------- 1 | Summary: Linux wireless regulatory database 2 | Name: wireless-regdb 3 | Version: 2009.01.15 4 | Release: 1 5 | License: ISC 6 | Group: System Enviroment/Base 7 | Source: http://wireless.kernel.org/download/wireless-regdb/wireless-regdb-2009-01-15.tar.bz2 8 | URL: http://wireless.kernel.org/en/developers/Regulatory/ 9 | Packager: Luis R. Rodriguez 10 | BuildRoot : /var/tmp/%{name}-buildroot 11 | Requires: python 12 | BuildArch: noarch 13 | 14 | %define crda_lib /usr/lib/crda 15 | 16 | %description 17 | This package contains the wireless regulatory database used by all 18 | cfg80211 based Linux wireless drivers. The wireless database being 19 | used is maintained by John Linville, the Linux wireless kernel maintainer 20 | http://wireless.kernel.org/en/developers/Regulatory/ 21 | 22 | %prep 23 | %setup -n %name-2009-01-15 24 | %build 25 | %install 26 | install -m 755 -d %buildroot/%crda_lib 27 | install -m 644 regulatory.bin %buildroot/%{crda_lib}/regulatory.bin 28 | %files 29 | %crda_lib/regulatory.bin 30 | %doc README LICENSE 31 | 32 | %changelog 33 | * Fri Jan 23 2009 - mcgrof@gmail.com 34 | - Started wireless-regdb package 35 | 36 | --------------------------------------------------------------------------------