1 #!/usr/bin/perl 2 use strict; 3 4 my $msg_ctr = 0; 5 my %messages; 6 my %devices; 7 8 sub add_message { 9 my $msg = shift; 10 my $val = $messages{$msg}; 11 12 defined($val) or do { 13 $val = $msg_ctr++; 14 $messages{$msg} = $val; 15 }; 16 17 return $val; 18 } 19 20 sub add_device($) { 21 my $id = shift; 22 my $dev = {}; 23 my $match; 24 25 $id =~ /^(\w{4}:\w{4})(:.*)?/ or do { 26 warn "Invalid device ID string $id\n"; 27 return $dev; 28 }; 29 30 $id = $1; 31 $match = $2 or $match = "*"; 32 33 $devices{$id} or $devices{$id} = {}; 34 $devices{$id}->{$match} = $dev; 35 36 return $dev; 37 } 38 39 sub add_hex { 40 $_[0] =~ s/^0x//; 41 return hex($_[0]); 42 } 43 44 sub add_mode { 45 $_[1] =~ s/^(\w+)Mode$/$1/; 46 return $_[1]; 47 } 48 49 sub add_modeval { 50 return unless ($_[1] && $_[1] =~ /^\d+$/); 51 $_[0]->{"ModeValue"} = $_[1]; 52 } 53 54 my $hex_option = [ undef, \&add_hex ]; 55 my $msg_option = [ undef, \&add_message ]; 56 my $mode_option = [ "Mode", \&add_mode ]; 57 my $value_mode_option = [ "Mode", \&add_mode, \&add_modeval ]; 58 my %options = ( 59 TargetVendor => $hex_option, 60 TargetProductList => [ "TargetProduct", sub { return [ map(hex,split(/,/, $_[0])) ]; } ], 61 TargetProduct => [ "TargetProduct", sub { return [ hex($_[0]) ]; } ], 62 TargetClass => $hex_option, 63 MessageContent => $msg_option, 64 MessageContent2 => $msg_option, 65 MessageContent3 => $msg_option, 66 WaitBefore => [ ], 67 DetachStorageOnly => [ ], 68 MBIM => $mode_option, 69 HuaweiMode => $mode_option, 70 HuaweiNewMode => $mode_option, 71 QuantaMode => $mode_option, 72 BlackberryMode => $mode_option, 73 PantechMode => $value_mode_option, 74 OptionMode => $mode_option, 75 SierraMode => $mode_option, 76 SonyMode => $mode_option, 77 QisdaMode => $mode_option, 78 GCTMode => $mode_option, 79 KobilMode => $mode_option, 80 SequansMode => $mode_option, 81 MobileActionMode => $mode_option, 82 CiscoMode => $mode_option, 83 StandardEject => $mode_option, 84 NoDriverLoading => [], 85 MessageEndpoint => $hex_option, 86 ReleaseDelay => [], 87 NeedResponse => [], 88 ResponseEndpoint => $hex_option, 89 ResetUSB => [], 90 InquireDevice => [], 91 CheckSuccess => $hex_option, 92 Interface => $hex_option, 93 Configuration => $hex_option, 94 AltSetting => $hex_option, 95 ); 96 97 sub parse_file($) { 98 my $file = shift; 99 my $id; 100 101 $id = $file; 102 $file =~ /\/?([^\/]+)$/ and $id = $1; 103 104 my $dev = add_device($id); 105 106 open FILE, "<$file" or die "Cannot open file '$file'\n"; 107 while (<FILE>) { 108 chomp; 109 s/^\s*(.+?)\s*$/$1/; 110 s/#.+$//; 111 next unless /\w/; 112 /(\w+)\s*=\s*(.+)\s*/ or do { 113 warn "Invalid Line: $_"; 114 next; 115 }; 116 117 my ($var, $val) = ($1, $2); 118 $val =~ s/^"(.+)"$/$1/; 119 120 my $opt = $options{$var}; 121 $opt or do { 122 warn "Unrecognized option $var in file $file\n"; 123 next; 124 }; 125 126 $opt->[2] and &{$opt->[2]}($dev, $val, $var); 127 $opt->[1] and $val = &{$opt->[1]}($val, $var); 128 $opt->[0] and $var = $opt->[0]; 129 $dev->{$var} = $val; 130 } 131 } 132 133 foreach my $file (@ARGV) { 134 parse_file $file; 135 } 136 137 sub json_chr { 138 my $chr = shift; 139 140 $chr eq "\b" and return "\\b"; 141 $chr eq "\n" and return "\\n"; 142 $chr eq "\r" and return "\\r"; 143 $chr eq "\t" and return "\\t"; 144 $chr eq "\\" and return "\\\\"; 145 $chr eq "\"" and return "\\\""; 146 $chr eq '/' and return "\\/"; 147 return sprintf("\\u%04x", ord($chr)); 148 }; 149 150 sub json_str { 151 $_[0] =~ s/([\x00- \/"\\])/json_chr($1)/eg; 152 return $_[0]; 153 } 154 155 sub json_val($$) { 156 my ($val, $type) = (shift, shift); 157 $type eq 'bool' and $val = $val > 0 ? "true" : "false"; 158 $type eq 'string' and $val = "\"$val\""; 159 return $val; 160 } 161 162 sub dev_opt { 163 my ($val, $name, $type, $sep) = (shift, shift, shift, shift); 164 return unless defined($val); 165 if ($type =~ /array:(.+)/) { 166 $type = $1; 167 my @val = @$val; 168 undef $val; 169 foreach my $elem (@val) { 170 my $json = json_val($elem, $type); 171 next unless defined $json; 172 if (defined $val) { 173 $val = "$val, $json" 174 } else { 175 $val = $json; 176 } 177 } 178 $val = "[ $val ]"; 179 } else { 180 $val = json_val($val, $type); 181 } 182 print "$$sep\t\t\t\t\"".json_str($name)."\": $val"; 183 $$sep = ",\n"; 184 } 185 186 print <<EOF; 187 { 188 "messages" : [ 189 EOF 190 my $suffix = ""; 191 foreach my $msg (sort { $messages{$a} <=> $messages{$b} } keys %messages) { 192 print "$suffix\t\t\"".json_str($msg)."\""; 193 $suffix = ",\n"; 194 } 195 print <<EOF; 196 197 ], 198 199 "devices" : { 200 EOF 201 my $dev_sep = ""; 202 foreach my $devid (sort keys %devices) { 203 my $dev = $devices{$devid}; 204 205 print "$dev_sep\t\t\"".json_str($devid)."\": {\n"; 206 $dev_sep = ",\n"; 207 208 my $match_sep = ""; 209 foreach my $match (sort keys %$dev) { 210 my $cur = $dev->{$match}; 211 my $sep = ""; 212 213 print "$match_sep\t\t\t\"".json_str($match)."\": {\n"; 214 $match_sep = ",\n"; 215 216 dev_opt($cur->{TargetVendor}, "t_vendor", "int", \$sep); 217 dev_opt($cur->{TargetProduct}, "t_product", "array:int", \$sep); 218 dev_opt($cur->{TargetClass}, "t_class", "int", \$sep); 219 dev_opt($cur->{DetachStorageOnly}, "detach_storage", "bool", \$sep); 220 dev_opt($cur->{Mode}, "mode", "string", \$sep); 221 dev_opt($cur->{ModeValue}, "modeval", "int", \$sep); 222 dev_opt($cur->{NoDriverLoading}, "no_driver", "bool", \$sep); 223 dev_opt($cur->{MessageEndpoint}, "msg_endpoint", "int", \$sep); 224 my $msg = [ 225 $cur->{MessageContent}, 226 $cur->{MessageContent2}, 227 $cur->{MessageContent3} 228 ]; 229 dev_opt($msg, "msg", "array:int", \$sep); 230 dev_opt($cur->{WaitBefore}, "wait", "int", \$sep); 231 dev_opt($cur->{ReleaseDelay}, "release_delay", "int", \$sep); 232 dev_opt($cur->{NeedResponse}, "response", "bool", \$sep); 233 dev_opt($cur->{ResponseEndpoint}, "response_endpoint", "int", \$sep); 234 dev_opt($cur->{ResetUSB}, "reset", "bool", \$sep); 235 dev_opt($cur->{InquireDevice}, "inquire", "int", \$sep); 236 dev_opt($cur->{CheckSuccess}, "check", "bool", \$sep); 237 dev_opt($cur->{Interface}, "interface", "int", \$sep); 238 dev_opt($cur->{Configuration}, "config", "int", \$sep); 239 dev_opt($cur->{AltSetting}, "alt", "int", \$sep); 240 print "\n\t\t\t}"; 241 } 242 print "\n\t\t}" 243 } 244 print <<EOF; 245 246 } 247 } 248 EOF
This page was automatically generated by LXR 0.3.1. • OpenWrt