nicer comment for DE entry
[platform/upstream/crda.git] / db2bin.py
1 #!/usr/bin/env python
2
3 from cStringIO import StringIO
4 import struct
5 import sha
6 from dbparse import DBParser
7
8 MAGIC = 0x52474442
9 VERSION = 19
10
11 def create_rules(countries):
12     result = {}
13     for c in countries.itervalues():
14         for rule in c.restrictions:
15             result[rule] = 1
16     return result.keys()
17
18 def create_collections(countries):
19     result = {}
20     for c in countries.itervalues():
21         result[c.restrictions] = 1
22     return result.keys()
23
24
25 def be32(output, val):
26     output.write(struct.pack('>I', val))
27
28 class PTR(object):
29     def __init__(self, output):
30         self._output = output
31         self._pos = output.tell()
32         be32(output, 0xFFFFFFFF)
33
34     def set(self, val=None):
35         if val is None:
36             val = self._output.tell()
37         self._offset = val
38         pos = self._output.tell()
39         self._output.seek(self._pos)
40         be32(self._output, val)
41         self._output.seek(pos)
42
43     def get(self):
44         return self._offset
45
46 p = DBParser()
47 countries = p.parse(file('db.txt'))
48 power = {}
49 bands = {}
50 for c in countries.itervalues():
51     for b, p in c.restrictions:
52         bands[b] = b
53         power[p] = p
54 rules = create_rules(countries)
55 rules.sort(cmp=lambda x, y: cmp(bands[x[0]], bands[y[0]]))
56 collections = create_collections(countries)
57 collections.sort(cmp=lambda x, y: cmp(bands[x[0][0]], bands[y[0][0]]))
58
59 output = StringIO()
60
61 # struct regdb_file_header
62 be32(output, MAGIC)
63 be32(output, VERSION)
64 reg_country_ptr = PTR(output)
65 # add number of countries
66 be32(output, len(countries))
67 siglen = PTR(output)
68
69 power_rules = {}
70 pi = [(i, p) for i, p in power.iteritems()]
71 pi.sort(cmp=lambda x, y: cmp(x[1], y[1]))
72 for power_rule_id, pr in pi:
73     environ = pr.environment
74     pr = [int(v * 100) for v in (pr.max_ant_gain, pr.max_ir_ptmp, pr.max_ir_ptp,
75                                  pr.max_eirp_ptmp, pr.max_eirp_ptp)]
76     power_rules[power_rule_id] = output.tell()
77     # struct regdb_file_power_rule
78     output.write(struct.pack('>cxxxIIIII', str(environ), *pr))
79
80 freq_ranges = {}
81 bi = [(f, i) for f, i in bands.iteritems()]
82 bi.sort(cmp=lambda x, y: cmp(x[1], y[1]))
83 for freq_range_id, fr in bands.iteritems():
84     freq_ranges[freq_range_id] = output.tell()
85     fl = fr.flags
86     fr = [int(f * 1000) for f in (fr.start, fr.end, fr.maxbw)]
87     # struct regdb_file_freq_range
88     output.write(struct.pack('>IIIII', fr[0], fr[1], fr[2], fl, 0))
89
90
91 reg_rules = {}
92 for reg_rule in rules:
93     freq_range_id, power_rule_id = reg_rule
94     reg_rules[reg_rule] = output.tell()
95     # struct regdb_file_reg_rule
96     output.write(struct.pack('>II', freq_ranges[freq_range_id], power_rules[power_rule_id]))
97
98
99 reg_rules_collections = {}
100
101 for coll in collections:
102     reg_rules_collections[coll] = output.tell()
103     # struct regdb_file_reg_rules_collection
104     coll = list(coll)
105     be32(output, len(coll))
106     coll.sort(cmp=lambda x, y: cmp(bands[x[0]], bands[y[0]]))
107     for regrule in coll:
108         be32(output, reg_rules[regrule])
109
110 # update country pointer now!
111 reg_country_ptr.set()
112
113 countrynames = countries.keys()
114 countrynames.sort()
115 for alpha2 in countrynames:
116     coll = countries[alpha2]
117     # struct regdb_file_reg_country
118     output.write(struct.pack('>ccxxI', str(alpha2[0]), str(alpha2[1]), reg_rules_collections[coll.restrictions]))
119
120 # Load RSA only now so people can use this script
121 # without having those libraries installed to verify
122 # their SQL changes
123 from M2Crypto import RSA
124
125 # determine signature length
126 key = RSA.load_key('key.priv.pem')
127 hash = sha.new()
128 hash.update(output.getvalue())
129 sig = key.sign(hash.digest())
130 # write it to file
131 siglen.set(len(sig))
132 # sign again
133 hash = sha.new()
134 hash.update(output.getvalue())
135 sig = key.sign(hash.digest())
136
137 output.write(sig)
138
139 outfile = open('regulatory.bin', 'w')
140 outfile.write(output.getvalue())