move RSA import down in dbgen.py
[platform/upstream/crda.git] / dbgen.py
1 #!/usr/bin/env python
2
3 from pysqlite2 import dbapi2 as db
4 from cStringIO import StringIO
5 import struct
6 import sha
7
8 MAGIC = 0x52474442
9 VERSION = 19
10
11 def be32(output, val):
12     output.write(struct.pack('>I', val))
13
14 class PTR(object):
15     def __init__(self, output):
16         self._output = output
17         self._pos = output.tell()
18         be32(output, 0xFFFFFFFF)
19
20     def set(self, val=None):
21         if val is None:
22             val = self._output.tell()
23         self._offset = val
24         pos = self._output.tell()
25         self._output.seek(self._pos)
26         be32(self._output, val)
27         self._output.seek(pos)
28
29     def get(self):
30         return self._offset
31
32 regdb = db.connect('regulatory.sqlite')
33 cursor = regdb.cursor()
34
35 output = StringIO()
36
37 # struct regdb_file_header
38 be32(output, MAGIC)
39 be32(output, VERSION)
40 reg_country_ptr = PTR(output)
41 # add number of countries
42 cursor.execute('SELECT COUNT(*) FROM reg_country;')
43 be32(output, cursor.fetchone()[0])
44 siglen = PTR(output)
45
46 power_rules = {}
47 # just to make sure db scheme isn't bad
48 cursor.execute('''SELECT power_rule_id,
49                          environment_cap,
50                          max_antenna_gain_mbi,
51                          max_ir_ptmp_mbm,
52                          max_ir_ptp_mbm,
53                          max_eirp_pmtp_mbm,
54                          max_eirp_ptp_mbm FROM power_rule;''')
55 for pr in cursor:
56     power_rule_id = pr[0]
57     power_rules[power_rule_id] = output.tell()
58     # struct regdb_file_power_rule
59     output.write(struct.pack('>cxxxIIIII', str(pr[1]), *pr[2:]))
60
61 freq_ranges = {}
62 # just to make sure db scheme isn't bad
63 cursor.execute('''SELECT freq_range_id,
64                          start_freq_khz,
65                          end_freq_khz,
66                          max_bandwidth_khz,
67                          modulation_cap,
68                          misc_restrictions FROM freq_range;''')
69 for fr in cursor:
70     freq_range_id = fr[0]
71     freq_ranges[freq_range_id] = output.tell()
72     # struct regdb_file_freq_range
73     output.write(struct.pack('>IIIII', *fr[1:]))
74
75
76 reg_rules = {}
77 # just to make sure db scheme isn't bad
78 cursor.execute('SELECT reg_rule_id, freq_range_id, power_rule_id FROM reg_rule;')
79 for reg_rule in cursor:
80     reg_rule_id, freq_range_id, power_rule_id = reg_rule
81     reg_rules[reg_rule_id] = output.tell()
82     # struct regdb_file_reg_rule
83     output.write(struct.pack('>II', freq_ranges[freq_range_id], power_rules[power_rule_id]))
84
85
86 collection_data = {}
87 # just to make sure db scheme isn't bad
88 cursor.execute('SELECT entry_id, reg_collection_id, reg_rule_id FROM reg_rules_collection;')
89 for coll in cursor:
90     entry_id, reg_collection_id, reg_rule_id = coll
91     l = collection_data.get(reg_collection_id, [])
92     l.append(reg_rule_id)
93     collection_data[reg_collection_id] = l
94
95 reg_rules_collections = {}
96
97 for rc, l in collection_data.iteritems():
98     reg_rules_collections[rc] = output.tell()
99     # struct regdb_file_reg_rules_collection
100     be32(output, len(l))
101     for regrule in l:
102         be32(output, reg_rules[regrule])
103
104 # update country pointer now!
105 reg_country_ptr.set()
106
107 # just to make sure db scheme isn't bad
108 cursor.execute('SELECT reg_country_id, alpha2, reg_collection_id FROM reg_country;')
109 for country in cursor:
110     reg_country_id, alpha2, reg_collection_id = country
111     # struct regdb_file_reg_country
112     output.write(struct.pack('>ccxxI', str(alpha2[0]), str(alpha2[1]), reg_rules_collections[reg_collection_id]))
113
114 # Load RSA only now so people can use this script
115 # without having those libraries installed to verify
116 # their SQL changes
117 from M2Crypto import RSA
118
119 # determine signature length
120 key = RSA.load_key('key.priv.pem')
121 hash = sha.new()
122 hash.update(output.getvalue())
123 sig = key.sign(hash.digest())
124 # write it to file
125 siglen.set(len(sig))
126 # sign again
127 hash = sha.new()
128 hash.update(output.getvalue())
129 sig = key.sign(hash.digest())
130
131 output.write(sig)
132
133 outfile = open('regulatory.bin', 'w')
134 outfile.write(output.getvalue())