1#!/usr/bin/awk -f 2# 3# genregdb.awk -- generate regdb.c from db.txt 4# 5# Actually, it reads from stdin (presumed to be db.txt) and writes 6# to stdout (presumed to be regdb.c), but close enough... 7# 8# Copyright 2009 John W. Linville <linville@tuxdriver.com> 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 22BEGIN { 23 active = 0 24 rules = 0; 25 print "/*" 26 print " * DO NOT EDIT -- file generated from data in db.txt" 27 print " */" 28 print "" 29 print "#include <linux/nl80211.h>" 30 print "#include <net/cfg80211.h>" 31 print "#include \"regdb.h\"" 32 print "" 33 regdb = "const struct ieee80211_regdomain *reg_regdb[] = {\n" 34} 35 36function parse_country_head() { 37 country=$2 38 sub(/:/, "", country) 39 printf "static const struct ieee80211_regdomain regdom_%s = {\n", country 40 printf "\t.alpha2 = \"%s\",\n", country 41 if ($NF ~ /DFS-ETSI/) 42 printf "\t.dfs_region = NL80211_DFS_ETSI,\n" 43 else if ($NF ~ /DFS-FCC/) 44 printf "\t.dfs_region = NL80211_DFS_FCC,\n" 45 else if ($NF ~ /DFS-JP/) 46 printf "\t.dfs_region = NL80211_DFS_JP,\n" 47 printf "\t.reg_rules = {\n" 48 active = 1 49 regdb = regdb "\t®dom_" country ",\n" 50} 51 52function parse_reg_rule() 53{ 54 flag_starts_at = 7 55 56 start = $1 57 sub(/\(/, "", start) 58 end = $3 59 bw = $5 60 sub(/\),/, "", bw) 61 gain = 0 62 power = $6 63 # power might be in mW... 64 units = $7 65 dfs_cac = 0 66 67 sub(/\(/, "", power) 68 sub(/\),/, "", power) 69 sub(/\),/, "", units) 70 sub(/\)/, "", units) 71 72 if (units == "mW") { 73 flag_starts_at = 8 74 power = 10 * log(power)/log(10) 75 if ($8 ~ /[[:digit:]]/) { 76 flag_starts_at = 9 77 dfs_cac = $8 78 } 79 } else { 80 if ($7 ~ /[[:digit:]]/) { 81 flag_starts_at = 8 82 dfs_cac = $7 83 } 84 } 85 sub(/\(/, "", dfs_cac) 86 sub(/\),/, "", dfs_cac) 87 flagstr = "" 88 for (i=flag_starts_at; i<=NF; i++) 89 flagstr = flagstr $i 90 split(flagstr, flagarray, ",") 91 flags = "" 92 for (arg in flagarray) { 93 if (flagarray[arg] == "NO-OFDM") { 94 flags = flags "\n\t\t\tNL80211_RRF_NO_OFDM | " 95 } else if (flagarray[arg] == "NO-CCK") { 96 flags = flags "\n\t\t\tNL80211_RRF_NO_CCK | " 97 } else if (flagarray[arg] == "NO-INDOOR") { 98 flags = flags "\n\t\t\tNL80211_RRF_NO_INDOOR | " 99 } else if (flagarray[arg] == "NO-OUTDOOR") { 100 flags = flags "\n\t\t\tNL80211_RRF_NO_OUTDOOR | " 101 } else if (flagarray[arg] == "DFS") { 102 flags = flags "\n\t\t\tNL80211_RRF_DFS | " 103 } else if (flagarray[arg] == "PTP-ONLY") { 104 flags = flags "\n\t\t\tNL80211_RRF_PTP_ONLY | " 105 } else if (flagarray[arg] == "PTMP-ONLY") { 106 flags = flags "\n\t\t\tNL80211_RRF_PTMP_ONLY | " 107 } else if (flagarray[arg] == "PASSIVE-SCAN") { 108 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 109 } else if (flagarray[arg] == "NO-IBSS") { 110 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 111 } else if (flagarray[arg] == "NO-IR") { 112 flags = flags "\n\t\t\tNL80211_RRF_NO_IR | " 113 } else if (flagarray[arg] == "AUTO-BW") { 114 flags = flags "\n\t\t\tNL80211_RRF_AUTO_BW | " 115 } 116 117 } 118 flags = flags "0" 119 printf "\t\tREG_RULE_EXT(%d, %d, %d, %d, %.0f, %d, %s),\n", start, end, bw, gain, power, dfs_cac, flags 120 rules++ 121} 122 123function print_tail_country() 124{ 125 active = 0 126 printf "\t},\n" 127 printf "\t.n_reg_rules = %d\n", rules 128 printf "};\n\n" 129 rules = 0; 130} 131 132/^[ \t]*#/ { 133 # Ignore 134} 135 136!active && /^[ \t]*$/ { 137 # Ignore 138} 139 140!active && /country/ { 141 parse_country_head() 142} 143 144active && /^[ \t]*\(/ { 145 parse_reg_rule() 146} 147 148active && /^[ \t]*$/ { 149 print_tail_country() 150} 151 152END { 153 if (active) 154 print_tail_country() 155 print regdb "};" 156 print "" 157 print "int reg_regdb_size = ARRAY_SIZE(reg_regdb);" 158} 159