diff options
author | Felix Fietkau <nbd@openwrt.org> | 2013-06-09 00:56:35 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2013-06-09 00:56:35 +0200 |
commit | a54ab694cdad2a5b50159a27e2f79df4b4a1e8bd (patch) | |
tree | f45895a1fc2d904b9b95a1f467cd396dda6d001b | |
parent | ed0e0e939dbf9cc53ff13d1c4853cdccbd3c4ba2 (diff) |
codegen: work around firmware bug, only accept the first found tlv
-rwxr-xr-x | data/gen-code.pl | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/data/gen-code.pl b/data/gen-code.pl index 71b738d..c903d6b 100755 --- a/data/gen-code.pl +++ b/data/gen-code.pl @@ -132,9 +132,12 @@ sub gen_tlv_parse_field($$$$) { } } -sub gen_tlv_type($$) { +sub gen_tlv_type($$$) { my $cname = shift; my $elem = shift; + my $idx = shift; + my $idx_word = "found[".int($idx / 32)."]"; + my $idx_bit = "(1 << ".($idx % 32).")"; my $type = $elem->{"format"}; my $id = $elem->{"id"}; @@ -146,6 +149,10 @@ sub gen_tlv_type($$) { print <<EOF; case $id: + if ($idx_word & $idx_bit) + break; + + $idx_word |= $idx_bit; EOF my $val = $tlv_get{$type}; @@ -188,9 +195,14 @@ sub gen_parse_func($$) EOF if (gen_has_types($data)) { + my $n_bits = scalar @$data; + my $n_words = int(($n_bits + 31) / 32); + my $i = 0; + print <<EOF; struct tlv *tlv; int i; + uint32_t found[$n_words] = {}; memset(res, 0, sizeof(*res)); @@ -203,7 +215,7 @@ EOF EOF foreach my $field (@$data) { my $cname = gen_cname($field->{name}); - gen_tlv_type($cname, $field); + gen_tlv_type($cname, $field, $i++); } print <<EOF; |