From: Felix Fietkau Date: Wed, 29 May 2013 07:29:25 +0000 (+0200) Subject: add usb_modeswitch.d converter X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=3f7b295629aed37ca746dce134f2e2de606a1c82;p=oweals%2Fusbmode.git add usb_modeswitch.d converter --- diff --git a/convert-modeswitch.pl b/convert-modeswitch.pl new file mode 100644 index 0000000..f7ac9ff --- /dev/null +++ b/convert-modeswitch.pl @@ -0,0 +1,229 @@ +#!/usr/bin/perl +use strict; + +my $msg_ctr = 0; +my %messages; +my %devices; + +sub add_message { + my $msg = shift; + my $val = $messages{$msg}; + + $val or do { + $val = $msg_ctr++; + $messages{$msg} = $val; + }; + + return $val; +} + +sub add_device($) { + my $id = shift; + my $dev = {}; + my $match; + + $id =~ /^(\w{4}:\w{4})(:.*)?/ or do { + warn "Invalid device ID string $id\n"; + return $dev; + }; + + $id = $1; + $match = $2 or $match = "*"; + + $devices{$id} or $devices{$id} = {}; + $devices{$id}->{$match} = $dev; + + return $dev; +} + +sub add_hex { + $_[0] =~ s/^0x//; + return hex($_[0]); +} + +sub add_mode { + $_[1] =~ s/^(\w+)Mode$/$1/; + return $_[1]; +} + +my $hex_option = [ undef, \&add_hex ]; +my $msg_option = [ undef, \&add_message ]; +my $mode_option = [ "Mode", \&add_mode ]; +my %options = ( + TargetVendor => $hex_option, + TargetProductList => [ "TargetProduct", sub { return [ map(hex,split(/,/, $_[0])) ]; } ], + TargetProduct => [ "TargetProduct", sub { return [ hex($_[0]) ]; } ], + TargetClass => $hex_option, + MessageContent => $msg_option, + MessageContent2 => $msg_option, + MessageContent3 => $msg_option, + WaitBefore => [ ], + DetachStorageOnly => [ ], + HuaweiMode => $mode_option, + SierraMode => $mode_option, + SonyMode => $mode_option, + QisdaMode => $mode_option, + GCTMode => $mode_option, + KobilMode => $mode_option, + SequansMode => $mode_option, + MobileActionMode => $mode_option, + CiscoMode => $mode_option, + NoDriverLoading => [], + MessageEndpoint => $hex_option, + ReleaseDelay => [], + NeedResponse => [], + ResponseEndpoint => $hex_option, + ResetUSB => [], + InquireDevice => [], + CheckSuccess => $hex_option, + Interface => $hex_option, + Configuration => $hex_option, + AltSetting => $hex_option, +); + +sub parse_file($) { + my $file = shift; + my $id; + + $id = $file; + $file =~ /\/?([^\/]+)$/ and $id = $1; + + my $dev = add_device($id); + + open FILE, "<$file" or die "Cannot open file '$file'\n"; + while () { + chomp; + s/^\s*(.+?)\s*$/$1/; + s/#.+$//; + next unless /\w/; + /(\w+)\s*=\s*(.+)\s*/ or do { + warn "Invalid Line: $_"; + next; + }; + + my ($var, $val) = ($1, $2); + $val =~ s/^"(.+)"$/$1/; + + my $opt = $options{$var}; + $opt or do { + warn "Unrecognized option $var in file $file\n"; + next; + }; + + $opt->[1] and $val = &{$opt->[1]}($val, $var); + $opt->[0] and $var = $opt->[0]; + $dev->{$var} = $val; + } +} + +foreach my $file (@ARGV) { + parse_file $file; +} + +sub json_chr { + my $chr = shift; + + $chr eq "\b" and return "\\b"; + $chr eq "\n" and return "\\n"; + $chr eq "\r" and return "\\r"; + $chr eq "\t" and return "\\t"; + $chr eq "\\" and return "\\\\"; + $chr eq "\"" and return "\\\""; + $chr eq '/' and return "\\/"; + return sprintf("\\u%04x", ord($chr)); +}; + +sub json_str { + $_[0] =~ s/([\x00- \/"\\])/json_chr($1)/eg; + return $_[0]; +} + +sub json_val($$) { + my ($val, $type) = (shift, shift); + $type eq 'bool' and $val = $val > 0 ? "true" : "false"; + $type eq 'string' and $val = "\"$val\""; + return $val; +} + +sub dev_opt { + my ($val, $name, $type, $sep) = (shift, shift, shift, shift); + return unless defined($val); + if ($type =~ /array:(.+)/) { + $type = $1; + my @val = @$val; + undef $val; + foreach my $elem (@val) { + if (defined $val) { + $val = "$val, " + } else { + $val = ""; + } + $val .= json_val($elem, $type); + } + $val = "[ $val ]"; + } else { + $val = json_val($val, $type); + } + print "$$sep\t\t\t\t\"".json_str($name)."\": $val"; + $$sep = ",\n"; +} + +print < $messages{$b} } keys %messages) { + print "$suffix\t\t\"".json_str($msg)."\""; + $suffix = ",\n"; +} +print <{$match}; + my $sep = ""; + + print "$match_sep\t\t\t\"".json_str($match)."\": {\n"; + $match_sep = ",\n"; + + dev_opt($cur->{TargetVendor}, "t_vendor", "int", \$sep); + dev_opt($cur->{TargetProduct}, "t_product", "array:int", \$sep); + dev_opt($cur->{TargetClass}, "t_class", "int", \$sep); + dev_opt($cur->{DetachStorageOnly}, "detach_storage", "bool", \$sep); + dev_opt($cur->{Mode}, "mode", "string", \$sep); + dev_opt($cur->{NoDriverLoading}, "no_driver", "bool", \$sep); + dev_opt($cur->{MessageEndpoint}, "msg_endpoint", "int", \$sep); + dev_opt($cur->{MessageContent}, "msg", "int", \$sep); + dev_opt($cur->{MessageContent2}, "msg2", "int", \$sep); + dev_opt($cur->{MessageContent3}, "msg3", "int", \$sep); + dev_opt($cur->{WaitBefore}, "wait", "int", \$sep); + dev_opt($cur->{ReleaseDelay}, "release_delay", "int", \$sep); + dev_opt($cur->{NeedResponse}, "response", "bool", \$sep); + dev_opt($cur->{ResponseEndpoint}, "response_endpoint", "int", \$sep); + dev_opt($cur->{ResetUSB}, "reset", "bool", \$sep); + dev_opt($cur->{InquireDevice}, "inquire", "int", \$sep); + dev_opt($cur->{CheckSuccess}, "check", "bool", \$sep); + dev_opt($cur->{Interface}, "interface", "int", \$sep); + dev_opt($cur->{Configuration}, "config", "int", \$sep); + dev_opt($cur->{AltSetting}, "alt", "int", \$sep); + print "\n\t\t\t}"; + } + print "\n\t\t}" +} +print <