Introduce support for setting DFS CAC time
in milliseconds.
Eg.
(5250 - 5330 @ AUTO), (20), (60000), DFS
will setup CAC 60 seconds CAC time.
Signed-off-by: Janusz Dziedzic <[email protected]>
---
db2bin.py | 6 +++---
dbparse.py | 17 +++++++++++++----
2 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/db2bin.py b/db2bin.py
index 41d3741..f6c3bc1 100755
--- a/db2bin.py
+++ b/db2bin.py
@@ -7,7 +7,7 @@ from dbparse import DBParser
import sys
MAGIC = 0x52474442
-VERSION = 19
+VERSION = 20
if len(sys.argv) < 3:
print 'Usage: %s output-file input-file [key-file]' % sys.argv[0]
@@ -93,8 +93,8 @@ for reg_rule in rules:
freq_range, power_rule = reg_rule.freqband, reg_rule.power
reg_rules[reg_rule] = output.tell()
# struct regdb_file_reg_rule
- output.write(struct.pack('>III', freq_ranges[freq_range], power_rules[power_rule],
- reg_rule.flags))
+ output.write(struct.pack('>IIII', freq_ranges[freq_range], power_rules[power_rule],
+ reg_rule.flags, reg_rule.cac_time))
reg_rules_collections = {}
diff --git a/dbparse.py b/dbparse.py
index b735b6a..d54311f 100755
--- a/dbparse.py
+++ b/dbparse.py
@@ -77,12 +77,13 @@ class FlagError(Exception):
self.flag = flag
class Permission(object):
- def __init__(self, freqband, power, flags):
+ def __init__(self, freqband, power, flags, cac_time):
assert isinstance(freqband, FreqBand)
assert isinstance(power, PowerRestriction)
self.freqband = freqband
self.power = power
self.flags = 0
+ self.cac_time = cac_time
for flag in flags:
if not flag in flag_definitions:
raise FlagError(flag)
@@ -90,7 +91,7 @@ class Permission(object):
self.textflags = flags
def _as_tuple(self):
- return (self.freqband, self.power, self.flags)
+ return (self.freqband, self.power, self.flags, self.cac_time)
def __cmp__(self, other):
if not isinstance(other, Permission):
@@ -254,6 +255,7 @@ class DBParser(object):
self._comments = []
def _parse_country_item(self, line):
+ cac_time = 0
if line[0] == '(':
try:
band, line = line[1:].split('),', 1)
@@ -282,7 +284,14 @@ class DBParser(object):
flags = []
else:
pname = items[0]
- flags = items[1].split(',')
+ pcac = items[1]
+ if pcac[0] == '(':
+ cac, flags = pcac.split('),', 1)
+ flags = flags.split(',')
+ cac_time = int(cac[1:])
+ else:
+ flags = items[1].split(',')
+
power = pname[1:]
pname = 'UNNAMED %d' % self._lineno
self._parse_power_def(pname, power, dupwarn=False)
@@ -303,7 +312,7 @@ class DBParser(object):
b = self._bands[bname]
p = self._power[pname]
try:
- perm = Permission(b, p, flags)
+ perm = Permission(b, p, flags, cac_time)
except FlagError, e:
self._syntax_error("Invalid flag '%s'" % e.flag)
for cname, c in self._current_countries.iteritems():
--
1.7.9.5
On Tue, May 20, 2014 at 12:33:51AM -0700, Luis R. Rodriguez wrote:
> On Fri, May 9, 2014 at 1:40 AM, Janusz Dziedzic
> <[email protected]> wrote:
> > Introduce support for setting DFS CAC time
> > in milliseconds.
> >
> > Eg.
> > (5250 - 5330 @ AUTO), (20), (60000), DFS
> >
> > will setup CAC 60 seconds CAC time.
>
> Can you elaborate whether or not this will require a bump on CRDA and
> issuing of two new wireless-regdb files for the different versions on
> the commit log?
I would really prefer not to manage two regdb binary releases.
Fear of that is what has kept me from merging this patch.
John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.
On Tue, May 20, 2014 at 08:01:31PM +0200, Janusz Dziedzic wrote:
> On 20 May 2014 16:24, John W. Linville <[email protected]> wrote:
> > On Tue, May 20, 2014 at 12:33:51AM -0700, Luis R. Rodriguez wrote:
> >> On Fri, May 9, 2014 at 1:40 AM, Janusz Dziedzic
> >> <[email protected]> wrote:
> >> > Introduce support for setting DFS CAC time
> >> > in milliseconds.
> >> >
> >> > Eg.
> >> > (5250 - 5330 @ AUTO), (20), (60000), DFS
> >> >
> >> > will setup CAC 60 seconds CAC time.
> >>
> >> Can you elaborate whether or not this will require a bump on CRDA and
> >> issuing of two new wireless-regdb files for the different versions on
> >> the commit log?
> >
> > I would really prefer not to manage two regdb binary releases.
> > Fear of that is what has kept me from merging this patch.
> >
> I can add support for version 19 and 20 in one crda. I am not sure
> this is the best option.
> BTW what about versions < 19? How do we handle this this days?
What about older CRDA with newer wireless-regdb? Do we need to worry about that?
John
--
John W. Linville Someday the world will need a hero, and you
[email protected] might be all we have. Be ready.
On 20 May 2014 16:24, John W. Linville <[email protected]> wrote:
> On Tue, May 20, 2014 at 12:33:51AM -0700, Luis R. Rodriguez wrote:
>> On Fri, May 9, 2014 at 1:40 AM, Janusz Dziedzic
>> <[email protected]> wrote:
>> > Introduce support for setting DFS CAC time
>> > in milliseconds.
>> >
>> > Eg.
>> > (5250 - 5330 @ AUTO), (20), (60000), DFS
>> >
>> > will setup CAC 60 seconds CAC time.
>>
>> Can you elaborate whether or not this will require a bump on CRDA and
>> issuing of two new wireless-regdb files for the different versions on
>> the commit log?
>
> I would really prefer not to manage two regdb binary releases.
> Fear of that is what has kept me from merging this patch.
>
I can add support for version 19 and 20 in one crda. I am not sure
this is the best option.
BTW what about versions < 19? How do we handle this this days?
BR
Janusz
On 20 May 2014 09:33, Luis R. Rodriguez <[email protected]> wrote:
> On Fri, May 9, 2014 at 1:40 AM, Janusz Dziedzic
> <[email protected]> wrote:
>> Introduce support for setting DFS CAC time
>> in milliseconds.
>>
>> Eg.
>> (5250 - 5330 @ AUTO), (20), (60000), DFS
>>
>> will setup CAC 60 seconds CAC time.
>
> Can you elaborate whether or not this will require a bump on CRDA and
> issuing of two new wireless-regdb files for the different versions on
> the commit log?
>
Yes, sure - will add this.
BTW, probably you know, why we decide to split usermode regulatory
code into crda, regdb? This required binary interface between them and
a lot of "not needed" code? Why we don't simply zip/sign db.tx code
and parse this direrctly in crda and use just one user mode project
for that.
What was the reason for have regulatory in binary file?
BR
Janusz
Add DFS CAC time support. Get this
value form regulatory.bin file.
Add parsers required by db2rd.
Change REGDB_VERSION while binary file
format was changed little bit (rule structure).
Signed-off-by: Janusz Dziedzic <[email protected]>
---
crda.c | 3 ++
regdb.h | 5 ++-
reglib.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
reglib.h | 1 +
4 files changed, 150 insertions(+), 8 deletions(-)
diff --git a/crda.c b/crda.c
index 4751a39..0bf83a1 100644
--- a/crda.c
+++ b/crda.c
@@ -131,6 +131,9 @@ static int put_reg_rule(const struct ieee80211_reg_rule *rule, struct nl_msg *ms
NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_ANT_GAIN, power_rule->max_antenna_gain);
NLA_PUT_U32(msg, NL80211_ATTR_POWER_RULE_MAX_EIRP, power_rule->max_eirp);
+ if (rule->dfs_cac_ms)
+ NLA_PUT_U32(msg, NL80211_ATTR_DFS_CAC_TIME, rule->dfs_cac_ms);
+
return 0;
nla_put_failure:
diff --git a/regdb.h b/regdb.h
index 3ffb781..e7b7ab6 100644
--- a/regdb.h
+++ b/regdb.h
@@ -21,7 +21,7 @@
* to have some more magic. We still consider this to be
* "Version 1" of the file.
*/
-#define REGDB_VERSION 19
+#define REGDB_VERSION 20
/*
* The signature at the end of the file is an RSA-signed
@@ -107,6 +107,7 @@ struct regdb_file_reg_rule {
uint32_t power_rule_ptr; /* pointer to a struct regdb_file_power_rule */
/* rule flags using enum reg_rule_flags */
uint32_t flags;
+ uint32_t dfs_cac_ms;
};
struct regdb_file_reg_rules_collection {
@@ -143,7 +144,7 @@ static inline void check_db_binary_structs(void)
CHECK_STRUCT(regdb_file_header, 20);
CHECK_STRUCT(regdb_file_freq_range, 12);
CHECK_STRUCT(regdb_file_power_rule, 8);
- CHECK_STRUCT(regdb_file_reg_rule, 12);
+ CHECK_STRUCT(regdb_file_reg_rule, 16);
CHECK_STRUCT(regdb_file_reg_rules_collection, 4);
CHECK_STRUCT(regdb_file_reg_country, 8);
}
diff --git a/reglib.c b/reglib.c
index 3deca4a..beddecd 100644
--- a/reglib.c
+++ b/reglib.c
@@ -326,6 +326,7 @@ static void reg_rule2rd(uint8_t *db, size_t dblen,
rd_power_rule->max_eirp = ntohl(power->max_eirp);
rd_reg_rule->flags = ntohl(rule->flags);
+ rd_reg_rule->dfs_cac_ms = ntohl(rule->dfs_cac_ms);
if (rd_reg_rule->flags & RRF_NO_IR_ALL)
rd_reg_rule->flags |= RRF_NO_IR_ALL;
@@ -734,6 +735,9 @@ static void print_reg_rule(const struct ieee80211_reg_rule *rule)
else
printf("N/A)");
+ if ((rule->flags & RRF_DFS) && rule->dfs_cac_ms)
+ printf(", (%u)", rule->dfs_cac_ms);
+
if (rule->flags & RRF_NO_OFDM)
printf(", NO-OFDM");
if (rule->flags & RRF_NO_CCK)
@@ -826,6 +830,7 @@ reglib_parse_rule_simple(char *line, struct ieee80211_reg_rule *reg_rule)
REGLIB_DBM_TO_MBM(max_eirp);
reg_rule->flags = 0;
+ reg_rule->dfs_cac_ms = 0;
if (debug)
printf("reglib_parse_rule_simple(): %d line: %s", hits, line);
@@ -861,6 +866,7 @@ reglib_parse_rule_simple_mw(char *line, struct ieee80211_reg_rule *reg_rule)
REGLIB_MW_TO_MBM(max_eirp);
reg_rule->flags = 0;
+ reg_rule->dfs_cac_ms = 0;
if (debug)
printf("reglib_parse_rule_simple_mw(): %d line: %s",
@@ -920,6 +926,8 @@ reglib_parse_rule_args(char *line, struct ieee80211_reg_rule *reg_rule)
for (i = 0; i < 8; i++)
reg_rule->flags |= reglib_parse_rule_flag(flag_list[i]);
+ reg_rule->dfs_cac_ms = 0;
+
if (debug)
printf("reglib_parse_rule_args(): %d flags: %d, line: %s",
hits, reg_rule->flags, line);
@@ -982,6 +990,8 @@ reglib_parse_rule_args_mw(char *line, struct ieee80211_reg_rule *reg_rule)
for (i = 0; i < 8; i++)
reg_rule->flags |= reglib_parse_rule_flag(flag_list[i]);
+ reg_rule->dfs_cac_ms = 0;
+
if (debug)
printf("reglib_parse_rule_args_mw(): %d flags: %d, line: %s",
hits, reg_rule->flags, line);
@@ -989,6 +999,130 @@ reglib_parse_rule_args_mw(char *line, struct ieee80211_reg_rule *reg_rule)
#undef IGNORE_COMMA_OR_SPACE
}
+static int
+reglib_parse_rule_args_mw_cac(char *line, struct ieee80211_reg_rule *reg_rule)
+{
+#define IGNORE_COMMA_OR_SPACE "%*[ ,]"
+ int hits;
+ char flag_list[9][100];
+ unsigned int i = 0, dfs_cac_ms;
+ char mw[3];
+ float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
+
+ for (i = 0; i < 9; i++)
+ memset(flag_list[i], 0, sizeof(flag_list[i]));
+
+ hits = sscanf(line, "\t(%f - %f @ %f), (%f %2[mW]), (%u),"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s",
+ &start_freq_khz,
+ &end_freq_khz,
+ &max_bandwidth_khz,
+ &max_eirp,
+ mw,
+ &dfs_cac_ms,
+ flag_list[0],
+ flag_list[1],
+ flag_list[2],
+ flag_list[3],
+ flag_list[4],
+ flag_list[5],
+ flag_list[6],
+ flag_list[7],
+ flag_list[8]);
+
+ if (hits < 6)
+ return -EINVAL;
+
+ reg_rule->freq_range.start_freq_khz =
+ REGLIB_MHZ_TO_KHZ(start_freq_khz);
+ reg_rule->freq_range.end_freq_khz =
+ REGLIB_MHZ_TO_KHZ(end_freq_khz);
+ reg_rule->freq_range.max_bandwidth_khz =
+ REGLIB_MHZ_TO_KHZ(max_bandwidth_khz);
+ reg_rule->power_rule.max_eirp =
+ REGLIB_MW_TO_MBM(max_eirp);
+
+ for (i = 0; i < 8; i++)
+ reg_rule->flags |= reglib_parse_rule_flag(flag_list[i]);
+
+ reg_rule->dfs_cac_ms = dfs_cac_ms;
+
+ if (debug)
+ printf("reglib_parse_rule_args_mw_cac(): %d flags: %d, line: %s",
+ hits, reg_rule->flags, line);
+ return 0;
+#undef IGNORE_COMMA_OR_SPACE
+}
+
+static int
+reglib_parse_rule_args_cac(char *line, struct ieee80211_reg_rule *reg_rule)
+{
+#define IGNORE_COMMA_OR_SPACE "%*[ ,]"
+ int hits;
+ char flag_list[9][100];
+ unsigned int i = 0, dfs_cac_ms;
+ float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
+
+ for (i = 0; i < 9; i++)
+ memset(flag_list[i], 0, sizeof(flag_list[i]));
+
+ hits = sscanf(line, "\t(%f - %f @ %f), (%f), (%u)"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s"
+ IGNORE_COMMA_OR_SPACE "%s",
+ &start_freq_khz,
+ &end_freq_khz,
+ &max_bandwidth_khz,
+ &max_eirp,
+ &dfs_cac_ms,
+ flag_list[0],
+ flag_list[1],
+ flag_list[2],
+ flag_list[3],
+ flag_list[4],
+ flag_list[5],
+ flag_list[6],
+ flag_list[7],
+ flag_list[8]);
+
+ if (hits < 6)
+ return -EINVAL;
+
+ reg_rule->freq_range.start_freq_khz =
+ REGLIB_MHZ_TO_KHZ(start_freq_khz);
+ reg_rule->freq_range.end_freq_khz =
+ REGLIB_MHZ_TO_KHZ(end_freq_khz);
+ reg_rule->freq_range.max_bandwidth_khz =
+ REGLIB_MHZ_TO_KHZ(max_bandwidth_khz);
+ reg_rule->power_rule.max_eirp =
+ REGLIB_DBM_TO_MBM(max_eirp);
+
+ for (i = 0; i < 8; i++)
+ reg_rule->flags |= reglib_parse_rule_flag(flag_list[i]);
+
+ reg_rule->dfs_cac_ms = dfs_cac_ms;
+
+ if (debug)
+ printf("reglib_parse_rule_args_cac(): %d flags: %d, line: %s",
+ hits, reg_rule->flags, line);
+
+ return 0;
+#undef IGNORE_COMMA_OR_SPACE
+}
static int reglib_parse_rule(FILE *fp, struct ieee80211_reg_rule *reg_rule)
{
char line[1024];
@@ -997,24 +1131,27 @@ static int reglib_parse_rule(FILE *fp, struct ieee80211_reg_rule *reg_rule)
int r = 0;
struct reglib_rule_parse_list *reglib_rule_parsers;
size_t size_parsers = sizeof(struct reglib_rule_parse_list) +
- 4 * sizeof(int (*)(char *, struct ieee80211_reg_rule *));
+ 6 * sizeof(int (*)(char *, struct ieee80211_reg_rule *));
reglib_rule_parsers = malloc(size_parsers);
if (!reglib_rule_parsers)
return -EINVAL;
memset(reglib_rule_parsers, 0, size_parsers);
- reglib_rule_parsers->n_parsers = 4;
+ reglib_rule_parsers->n_parsers = 6;
+
/*
* XXX: sscanf() is a bit odd with picking up mW
* case over the simple one, this order however works,
* gotta figure out how to be more precise.
*/
- reglib_rule_parsers->rule_parsers[0] = reglib_parse_rule_args_mw;
- reglib_rule_parsers->rule_parsers[1] = reglib_parse_rule_args;
- reglib_rule_parsers->rule_parsers[2] = reglib_parse_rule_simple;
- reglib_rule_parsers->rule_parsers[3] = reglib_parse_rule_simple_mw;
+ reglib_rule_parsers->rule_parsers[0] = reglib_parse_rule_args_mw_cac;
+ reglib_rule_parsers->rule_parsers[1] = reglib_parse_rule_args_cac;
+ reglib_rule_parsers->rule_parsers[2] = reglib_parse_rule_args_mw;
+ reglib_rule_parsers->rule_parsers[3] = reglib_parse_rule_args;
+ reglib_rule_parsers->rule_parsers[4] = reglib_parse_rule_simple;
+ reglib_rule_parsers->rule_parsers[5] = reglib_parse_rule_simple_mw;
memset(line, 0, sizeof(line));
line_p = fgets(line, sizeof(line), fp);
diff --git a/reglib.h b/reglib.h
index afd5ef6..77aa42a 100644
--- a/reglib.h
+++ b/reglib.h
@@ -28,6 +28,7 @@ struct ieee80211_reg_rule {
struct ieee80211_freq_range freq_range;
struct ieee80211_power_rule power_rule;
uint32_t flags;
+ uint32_t dfs_cac_ms;
};
struct ieee80211_regdomain {
--
1.7.9.5
On Fri, May 9, 2014 at 1:40 AM, Janusz Dziedzic
<[email protected]> wrote:
> Introduce support for setting DFS CAC time
> in milliseconds.
>
> Eg.
> (5250 - 5330 @ AUTO), (20), (60000), DFS
>
> will setup CAC 60 seconds CAC time.
Can you elaborate whether or not this will require a bump on CRDA and
issuing of two new wireless-regdb files for the different versions on
the commit log?
Luis
On 9 June 2014 12:22, Janusz Dziedzic <[email protected]> wrote:
> On 9 June 2014 10:00, Felix Fietkau <[email protected]> wrote:
>> On 2014-05-21 18:03, Johannes Berg wrote:
>>> On Tue, 2014-05-20 at 11:48 -0700, Luis R. Rodriguez wrote:
>>>
>>>> > I think we should, but if we can't then at least can we cut to an
>>>> > extensible format?
>>>
>>> I don't see any way to extend the format right now.
>>>
>>> There's a wrinkle with making it more extensible too though - if we do
>>> that then we must be extremely careful that future older crda versions
>>> (i.e. the next version that we're about to write) will not parse a newer
>>> extended file more permissively, so our extensions are limited anyway.
>>>
>>> Looks like the format update really is needed, which probably means we
>>> should change the scripts to generate two databases and change the
>>> filename, or so?
>> How about making the format properly extensible by reusing what we're
>> already doing to keep the kernel ABI stable? For example, we could store
>> the database in a netlink-like attribute format, with some changes to
>> make it fixed endian.
>> I'm already doing just that for a few things in OpenWrt, so I have
>> working C code for writing and parsing such a format.
>>
>> Another nice feature would be to indicate in the attributes if crda is
>> required to understand them, or if it can just continue with a warning.
>>
>> If done right, I think we can probably make this the last time we change
>> the format version.
>>
> What kind of benefit we have having binary format between crda <->
> wireless-regd (nl-based or current regulatory.bin)?
> This is additional code/work to do - why we need that?
>
This is example of /sbin/crda script I have - seems works fine (small
crda_tiny also required):
#!/bin/sh
PUBKEY=/usr/lib/crda/pubkeys/regdb_pubring.gpg
REGDB=/usr/lib/crda/db.txt
CRDA_BIN=/sbin/crda_tiny
LOG=/tmp/crda.err
gpg_verify() {
PUBKEY=$1
REGDB=$2
gpg --no-default-keyring --keyring $PUBKEY --verify $REGDB
}
show_country() {
REGDB=$1
COUNTRY=$2
cat $REGDB \
| sed '
s/#.*//
s/^[ \t]*$//
' \
| awk \
-v ctry=$COUNTRY '
/country/{show=0}
/BEGIN PGP SIGNATURE/{show=0}
/country / && $2 == ctry ":" {show=1}
show && !/^$/
'
}
(
/bin/date
echo "$0 called with params:"
echo "COUNTRY: $COUNTRY"
echo "DB: $REGDB"
echo "PUBKEY: $PUBKEY"
echo "CRDA: $CRDA_BIN"
gpg_verify "$PUBKEY" "$REGDB" && show_country "$REGDB" "$COUNTRY" | "$CRDA_BIN"
On Mon, 2014-06-09 at 09:33 +0200, Janusz Dziedzic wrote:
> Why not just skip this binary interface between regdb --> crda and use
> signed db.txt file?
I fail to see how that's any better? If anything, it seems to me that it
would be *harder* to keep the database text format parseable to old CRDA
versions when making changes.
johannes
On 9 June 2014 10:00, Felix Fietkau <[email protected]> wrote:
> On 2014-05-21 18:03, Johannes Berg wrote:
>> On Tue, 2014-05-20 at 11:48 -0700, Luis R. Rodriguez wrote:
>>
>>> > I think we should, but if we can't then at least can we cut to an
>>> > extensible format?
>>
>> I don't see any way to extend the format right now.
>>
>> There's a wrinkle with making it more extensible too though - if we do
>> that then we must be extremely careful that future older crda versions
>> (i.e. the next version that we're about to write) will not parse a newer
>> extended file more permissively, so our extensions are limited anyway.
>>
>> Looks like the format update really is needed, which probably means we
>> should change the scripts to generate two databases and change the
>> filename, or so?
> How about making the format properly extensible by reusing what we're
> already doing to keep the kernel ABI stable? For example, we could store
> the database in a netlink-like attribute format, with some changes to
> make it fixed endian.
> I'm already doing just that for a few things in OpenWrt, so I have
> working C code for writing and parsing such a format.
>
> Another nice feature would be to indicate in the attributes if crda is
> required to understand them, or if it can just continue with a warning.
>
> If done right, I think we can probably make this the last time we change
> the format version.
>
What kind of benefit we have having binary format between crda <->
wireless-regd (nl-based or current regulatory.bin)?
This is additional code/work to do - why we need that?
BR
Janusz