add script to generate binary database
authorJohannes Berg <johannes@sipsolutions.net>
Thu, 22 May 2008 12:12:40 +0000 (14:12 +0200)
committerJohannes Berg <johannes@sipsolutions.net>
Thu, 22 May 2008 12:12:40 +0000 (14:12 +0200)
.gitignore
Makefile
daemon/regdb.h
dbgen.py [new file with mode: 0755]

index 2d7668a..a8be90a 100644 (file)
@@ -1,2 +1,3 @@
 *~
 regulatory.sqlite
+regulatory.bin
index 275df04..766bb7e 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,5 +1,12 @@
+all:   regulatory.bin
 
 
+regulatory.bin:        regulatory.sqlite dbgen.py
+       @./dbgen.py
+
+clean:
+       @rm -f regulatory.sqlite regulatory.bin *~
+
 regulatory.sqlite: db/*.sql
        @rm -f requlatory.sqlite
        @for i in db/*.sql ; do \
index f9f9823..ada6bea 100644 (file)
@@ -1,5 +1,11 @@
 #include <linux/types.h>
 
+/*
+ * WARNING: This file needs to be kept in sync with
+ *  - the database scheme
+ *  - the generator code (dbgen.py)
+ */
+
 /* spells "RGDB" */
 #define REGDB_MAGIC    0x52474442
 
diff --git a/dbgen.py b/dbgen.py
new file mode 100755 (executable)
index 0000000..d6741a4
--- /dev/null
+++ b/dbgen.py
@@ -0,0 +1,114 @@
+#!/usr/bin/env python
+
+from pysqlite2 import dbapi2 as db
+from cStringIO import StringIO
+import struct
+
+MAGIC = 0x52474442
+VERSION = 19
+
+def be32(output, val):
+    output.write(struct.pack('>I', val))
+
+class PTR(object):
+    def __init__(self, output):
+        self._output = output
+        self._pos = output.tell()
+        be32(output, 0xFFFFFFFF)
+
+    def set(self, val=None):
+        if val is None:
+            val = self._output.tell()
+        self._offset = val
+        pos = self._output.tell()
+        self._output.seek(self._pos)
+        be32(self._output, val)
+        self._output.seek(pos)
+
+    def get(self):
+        return self._offset
+
+regdb = db.connect('regulatory.sqlite')
+cursor = regdb.cursor()
+
+output = StringIO()
+
+# struct regdb_file_header
+be32(output, MAGIC)
+be32(output, VERSION)
+reg_country_ptr = PTR(output)
+
+# add number of countries
+cursor.execute('SELECT COUNT(*) FROM reg_country;')
+be32(output, cursor.fetchone()[0])
+
+power_rules = {}
+# just to make sure db scheme isn't bad
+cursor.execute('''SELECT power_rule_id,
+                         environment_cap,
+                         max_antenna_gain_mbi,
+                         max_ir_ptmp_mbm,
+                         max_ir_ptp_mbm,
+                         max_eirp_pmtp_mbm,
+                         max_eirp_ptp_mbm FROM power_rule;''')
+for pr in cursor:
+    power_rule_id = pr[0]
+    power_rules[power_rule_id] = output.tell()
+    # struct regdb_file_power_rule
+    output.write(struct.pack('>cxxxIIIII', str(pr[1]), *pr[2:]))
+
+freq_ranges = {}
+# just to make sure db scheme isn't bad
+cursor.execute('''SELECT freq_range_id,
+                         start_freq_khz,
+                         end_freq_khz,
+                         max_bandwidth_khz,
+                         modulation_cap,
+                         misc_restrictions FROM freq_range;''')
+for fr in cursor:
+    freq_range_id = fr[0]
+    freq_ranges[freq_range_id] = output.tell()
+    # struct regdb_file_freq_range
+    output.write(struct.pack('>IIIII', *fr[1:]))
+
+
+reg_rules = {}
+# just to make sure db scheme isn't bad
+cursor.execute('SELECT reg_rule_id, freq_range_id, power_rule_id FROM reg_rule;')
+for reg_rule in cursor:
+    reg_rule_id, freq_range_id, power_rule_id = reg_rule
+    reg_rules[reg_rule_id] = output.tell()
+    # struct regdb_file_reg_rule
+    output.write(struct.pack('>II', freq_ranges[freq_range_id], power_rules[power_rule_id]))
+
+
+collection_data = {}
+# just to make sure db scheme isn't bad
+cursor.execute('SELECT entry_id, reg_collection_id, reg_rule_id FROM reg_rules_collection;')
+for coll in cursor:
+    entry_id, reg_collection_id, reg_rule_id = coll
+    l = collection_data.get(reg_collection_id, [])
+    l.append(reg_rule_id)
+    collection_data[reg_collection_id] = l
+
+reg_rules_collections = {}
+
+for rc, l in collection_data.iteritems():
+    reg_rules_collections[rc] = output.tell()
+    # struct regdb_file_reg_rules_collection
+    be32(output, len(l))
+    for regrule in l:
+        be32(output, reg_rules[regrule])
+
+# update country pointer now!
+reg_country_ptr.set()
+
+# just to make sure db scheme isn't bad
+cursor.execute('SELECT reg_country_id, alpha2, reg_collection_id FROM reg_country;')
+for country in cursor:
+    reg_country_id, alpha2, reg_collection_id = country
+    # struct regdb_file_reg_country
+    output.write(struct.pack('>ccxxI', str(alpha2[0]), str(alpha2[1]), reg_rules_collections[reg_collection_id]))
+
+outfile = open('regulatory.bin', 'w')
+outfile.write(output.getvalue())