Commit 2019d708 authored by Janusz Dziedzic's avatar Janusz Dziedzic Committed by Luis R. Rodriguez

crda: simplify text parsing for country/rules

Remove strange parsers.
Signed-off-by: 's avatarJanusz Dziedzic <janusz.dziedzic@tieto.com>
Signed-off-by: 's avatarLuis R. Rodriguez <mcgrof@do-not-panic.com>
parent 0091c6eb
......@@ -40,17 +40,6 @@
int debug = 0;
struct reglib_rule_parse_list {
int n_parsers;
int (*rule_parsers[])(char *line, struct ieee80211_reg_rule *reg_rule);
};
struct reglib_country_parse_list {
int n_parsers;
int (*country_parsers[])(char *line, struct ieee80211_regdomain *rd);
};
void *
reglib_get_file_ptr(uint8_t *db, size_t dblen, size_t structlen, uint32_t ptr)
{
......@@ -768,206 +757,63 @@ void reglib_print_regdom(const struct ieee80211_regdomain *rd)
static unsigned int reglib_parse_dfs_region(char *dfs_region)
{
if (strncmp(dfs_region, "DFS-FCC", 7) == 0)
if (!dfs_region)
return REGDB_DFS_UNSET;
if (strstr(dfs_region, "DFS-FCC"))
return REGDB_DFS_FCC;
if (strncmp(dfs_region, "DFS-ETSI", 8) == 0)
if (strstr(dfs_region, "DFS-ETSI"))
return REGDB_DFS_ETSI;
if (strncmp(dfs_region, "DFS-JP", 6) == 0)
if (strstr(dfs_region, "DFS-JP"))
return REGDB_DFS_JP;
return REGDB_DFS_UNSET;
}
static uint32_t reglib_parse_rule_flag(char *flag_s)
{
if (strncmp(flag_s, "NO-OFDM", 7) == 0)
return RRF_NO_OFDM;
if (strncmp(flag_s, "NO-CCK", 6) == 0)
return RRF_NO_CCK;
if (strncmp(flag_s, "NO-INDOOR", 9) == 0)
return RRF_NO_INDOOR;
if (strncmp(flag_s, "NO-OUTDOOR", 10) == 0)
return RRF_NO_OUTDOOR;
if (strncmp(flag_s, "DFS", 3) == 0)
return RRF_DFS;
if (strncmp(flag_s, "PTP-ONLY", 8) == 0)
return RRF_PTP_ONLY;
if (strncmp(flag_s, "PTMP-ONLY", 9) == 0)
return RRF_PTMP_ONLY;
if (strncmp(flag_s, "NO-IR", 5) == 0)
return RRF_NO_IR;
if (strncmp(flag_s, "AUTO-BW", 7) == 0)
return RRF_AUTO_BW;
return 0;
}
static int
reglib_parse_rule_simple(char *line, struct ieee80211_reg_rule *reg_rule)
{
int hits;
float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
hits = sscanf(line, "\t(%f - %f @ %f), (%f)\n",
&start_freq_khz,
&end_freq_khz,
&max_bandwidth_khz,
&max_eirp);
if (hits != 4)
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);
reg_rule->flags = 0;
if (debug)
printf("reglib_parse_rule_simple(): %d line: %s", hits, line);
return 0;
uint32_t flags = 0;
if (strstr(flag_s, "NO-OFDM"))
flags |= RRF_NO_OFDM;
if (strstr(flag_s, "NO-CCK"))
flags |= RRF_NO_CCK;
if (strstr(flag_s, "NO-INDOOR"))
flags |= RRF_NO_INDOOR;
if (strstr(flag_s, "NO-OUTDOOR"))
flags |= RRF_NO_OUTDOOR;
if (strstr(flag_s, "DFS"))
flags |= RRF_DFS;
if (strstr(flag_s, "PTP-ONLY"))
flags |= RRF_PTP_ONLY;
if (strstr(flag_s, "PTMP-ONLY"))
flags |= RRF_PTMP_ONLY;
if (strstr(flag_s, "NO-IR"))
flags |= RRF_NO_IR;
if (strstr(flag_s, "AUTO-BW"))
flags |= RRF_AUTO_BW;
return flags;
}
static int
reglib_parse_rule_simple_mw(char *line, struct ieee80211_reg_rule *reg_rule)
static int reglib_parse_rule(FILE *fp, struct ieee80211_reg_rule *reg_rule)
{
int hits;
char line[1024];
char *line_p;
int hits, r = 0;
float start_freq_khz, end_freq_khz, max_bandwidth_khz, max_eirp;
char mw[3];
hits = sscanf(line, "\t(%f - %f @ %f), (%f %2[mW])\n",
&start_freq_khz,
&end_freq_khz,
&max_bandwidth_khz,
&max_eirp, mw);
if (hits != 4)
memset(line, 0, sizeof(line));
line_p = fgets(line, sizeof(line), fp);
if (line_p != line)
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);
reg_rule->flags = 0;
if (debug)
printf("reglib_parse_rule_simple_mw(): %d line: %s",
hits, line);
return 0;
}
static int
reglib_parse_rule_args(char *line, struct ieee80211_reg_rule *reg_rule)
{
#define IGNORE_COMMA_OR_SPACE "%*[ ,]"
int hits;
char flag_list[9][100];
unsigned int i = 0;
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)"
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",
/* First get start, end and bandwidth */
hits = sscanf(line_p, "\t(%f - %f @ %f),",
&start_freq_khz,
&end_freq_khz,
&max_bandwidth_khz,
&max_eirp,
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 < 5)
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]);
if (debug)
printf("reglib_parse_rule_args(): %d flags: %d, line: %s",
hits, reg_rule->flags, line);
return 0;
#undef IGNORE_COMMA_OR_SPACE
}
&max_bandwidth_khz);
static int
reglib_parse_rule_args_mw(char *line, struct ieee80211_reg_rule *reg_rule)
{
#define IGNORE_COMMA_OR_SPACE "%*[ ,]"
int hits;
char flag_list[9][100];
unsigned int i = 0;
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])"
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,
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 < 5)
if (hits != 3)
return -EINVAL;
reg_rule->freq_range.start_freq_khz =
......@@ -976,60 +822,32 @@ reglib_parse_rule_args_mw(char *line, struct ieee80211_reg_rule *reg_rule)
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]);
if (debug)
printf("reglib_parse_rule_args_mw(): %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];
char *line_p;
unsigned int i;
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 *));
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;
/*
* 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;
memset(line, 0, sizeof(line));
line_p = fgets(line, sizeof(line), fp);
if (line_p != line) {
free(reglib_rule_parsers);
/* Next get eirp */
strsep(&line_p, ",");
if (!line_p) {
fprintf(stderr, "not found eirp in line: %s\n", line);
return -EINVAL;
}
for (i = 0; i < reglib_rule_parsers->n_parsers; i++) {
r = reglib_rule_parsers->rule_parsers[i](line, reg_rule);
if (r == 0)
break;
if (strstr(line_p, "mW")) {
hits = sscanf(line_p, " (%f mW)", &max_eirp);
if (hits != 1)
return -EINVAL;
reg_rule->power_rule.max_eirp =
REGLIB_MW_TO_MBM(max_eirp);
} else {
hits = sscanf(line_p, " (%f)", &max_eirp);
if (hits != 1)
return -EINVAL;
reg_rule->power_rule.max_eirp =
REGLIB_DBM_TO_MBM(max_eirp);
}
free(reglib_rule_parsers);
/* Next get optional arguments (flags ...) */
strsep(&line_p, ",");
if (line_p)
reg_rule->flags = reglib_parse_rule_flag(line_p);
return r;
}
......@@ -1124,29 +942,6 @@ reglib_parse_rules(FILE *fp, struct ieee80211_regdomain *trd)
return rd;
}
static int
reglib_parse_country_simple(char *line, struct ieee80211_regdomain *rd)
{
char dfs_region_alpha[9];
char alpha2[2];
int hits;
memset(rd, 0, sizeof(*rd));
memset(alpha2, 0, sizeof(alpha2));
memset(dfs_region_alpha, 0, sizeof(dfs_region_alpha));
hits = sscanf(line, "country %2[a-zA-Z0-9]:",
alpha2);
if (hits != 1)
return -EINVAL;
rd->alpha2[0] = alpha2[0];
rd->alpha2[1] = alpha2[1];
return 0;
}
static int reglib_parse_country_dfs(char *line, struct ieee80211_regdomain *rd)
{
char dfs_region_alpha[9];
......@@ -1163,10 +958,6 @@ static int reglib_parse_country_dfs(char *line, struct ieee80211_regdomain *rd)
if (hits <= 0)
return -EINVAL;
if (hits != 2)
return -EINVAL;
rd->alpha2[0] = alpha2[0];
rd->alpha2[1] = alpha2[1];
rd->dfs_region = reglib_parse_dfs_region(dfs_region_alpha);
......@@ -1180,22 +971,7 @@ struct ieee80211_regdomain *__reglib_parse_country(FILE *fp)
struct ieee80211_regdomain tmp_rd;
char line[1024];
char *line_p;
unsigned int i;
int r = 0;
struct reglib_country_parse_list *reglib_country_parsers;
size_t size_of_parsers = sizeof(struct reglib_country_parse_list) +
2 * sizeof(int (*)(char *, struct ieee80211_regdomain *));
reglib_country_parsers = malloc(size_of_parsers);
if (!reglib_country_parsers)
return NULL;
memset(reglib_country_parsers, 0, size_of_parsers);
reglib_country_parsers->n_parsers = 2;
reglib_country_parsers->country_parsers[0] =
reglib_parse_country_dfs;
reglib_country_parsers->country_parsers[1] =
reglib_parse_country_simple;
memset(&tmp_rd, 0, sizeof(tmp_rd));
memset(line, 0, sizeof(line));
......@@ -1203,26 +979,19 @@ struct ieee80211_regdomain *__reglib_parse_country(FILE *fp)
line_p = fgets(line, sizeof(line), fp);
if (line_p != line) {
free(reglib_country_parsers);
return NULL;
}
for (i = 0; i < reglib_country_parsers->n_parsers; i++) {
r = reglib_country_parsers->country_parsers[i](line, &tmp_rd);
if (r == 0)
break;
}
/* Country */
r = reglib_parse_country_dfs(line_p, &tmp_rd);
if (r != 0) {
fprintf(stderr, "Invalid country line: %s", line);
free(reglib_country_parsers);
return NULL;
}
/* Rules */
rd = reglib_parse_rules(fp, &tmp_rd);
free(reglib_country_parsers);
return rd;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment