#!/usr/bin/perl use strict; use warnings; sub addWifiFromNet(); sub clearAllWifi(); sub getExisting(); sub getWifiGconf($$$); sub getGconfCmds($); sub gconfGetCmd($); sub gconfSetCmd($$$;$); sub listInt($); sub listString($); sub ssidListInt($); sub wpaPskListInt($$); sub randHex($); sub randomId(); sub runBT(@); my $usage = "Usage: $0 -g print all wifi networks on the phone $0 remove all wifi networks from the phone and replace with net "; my $rootDir = '/system/osso/connectivity/IAP'; my $noAutoFile = "$ENV{HOME}/Code/n9/wifi-noauto"; my $TRUE = ['true', 'bool']; my $FALSE = ['false', 'bool']; my $wifiAtts = { name => [""], wlan_ssid => listInt [], EAP_wpa_preshared_key => listInt [], EAP_wpa_preshared_passphrase => [""], http_check_status => ["no_login"], proxytype => ["NONE"], wlan_hidden => $FALSE, wlan_security => ["WPA_PSK"], type => ["WLAN_INFRA"], autoconnect => $TRUE, ipv4_type => ["AUTO"], }; my $gprsAtts = { name => [""], gprs_accesspointname => [""], sim_imsi => [""], gprs_username => [""], gprs_password => [""], type => ["GPRS"], autoconnect => $TRUE, ask_password => $FALSE, first_time_dialog_shown => $TRUE, ipv4_autodns => $TRUE, ipv4_type => ["AUTO"], }; sub main(@){ my $get; if(@_ == 1 and $_[0] =~ /^(-g)$/){ $get = shift; } die $usage if @_ > 0; if(defined $get){ my $networks = getExisting(); my $sortByName = sub{$$networks{$a}{name} cmp $$networks{$b}{name}}; for my $id(sort $sortByName keys %$networks){ if($$networks{$id}{type} eq "WLAN_INFRA"){ my $name = $$networks{$id}{name}; my $key = $$networks{$id}{EAP_wpa_preshared_passphrase} || ''; print "$name => $key\n"; } } }else{ print "clearing all wifi networks\n"; clearAllWifi(); print "\n\n"; print "adding wifi networks from net\n"; addWifiFromNet(); } } sub addWifiFromNet(){ my @cmds; my %noAuto = map {chomp; $_ => 1} `cat $noAutoFile 2>/dev/null`; for my $ssidName(sort split /\n/, runBT "winfo", "--list-all"){ my $info = runBT "winfo", $ssidName; my $ssid = $1 if $info =~ /^ssid:(.*)$/m; my $enc = $1 if $info =~ /^enc:(.*)$/m; my $key = $1 if $info =~ /^key:(.*)$/m; my $mode = $1 if $info =~ /^mode:(.*)$/m; my $auto = $1 if $info =~ /^auto:(.*)$/m; my $autoConnect = $auto =~ /^\d+$/ ? 'true' : 'false'; if($enc =~ /WPA/i and $mode =~ /managed/i){ if(defined $noAuto{$ssid}){ print " forcibly disabling autoconnect for $ssid\n"; $autoConnect = 'false'; } my $wifiCmds = getGconfCmds(getWifiGconf $ssid, $key, $autoConnect); push @cmds, "echo adding: SSID='$ssid' WPA='$key' auto='$autoConnect'"; @cmds = (@cmds, @$wifiCmds); } } system "n9", "-s", join "\n", @cmds; } sub clearAllWifi(){ my $networks = getExisting(); my @cmds; for my $id(keys %$networks){ if($$networks{$id}{type} eq "WLAN_INFRA"){ my $name = $$networks{$id}{name}; $name = '' if not defined $name; push @cmds, "echo 'deleting $id => $name'"; push @cmds, "gconftool --recursive-unset $rootDir/$id"; } } system "n9", "-s", join "\n", @cmds if @cmds > 0; } sub getExisting(){ my @iapLines = `n9 -u user -s gconftool -R $rootDir`; my %allAtts = (%$wifiAtts, %$gprsAtts); my $id; my $networks = {}; my $h4Re = "[a-f0-9]{4}"; my $h8Re = "[a-f0-9]{8}"; my $h12Re = "[a-f0-9]{12}"; my $attRe = join "|", keys %allAtts; for my $line(@iapLines){ if($line =~ /^ $rootDir\/($h8Re-$h4Re-$h4Re-$h4Re-$h12Re):$/){ $id = $1; $$networks{$id} = {}; }elsif(defined $id and $line =~ /^ ($attRe) = (.*)$/){ $$networks{$id}{$1} = $2; } } return $networks; } sub getWifiGconf($$$){ my ($ssid, $wpa, $auto) = @_; my $id = randomId; my $dir = "$rootDir/$id"; my $gconf = {}; for my $att(keys %$wifiAtts){ $$gconf{"$dir/$att"} = $$wifiAtts{$att}; } $$gconf{"$dir/name"} = [$ssid]; $$gconf{"$dir/wlan_ssid"} = ssidListInt $ssid; $$gconf{"$dir/EAP_wpa_preshared_key"} = wpaPskListInt $ssid, $wpa; $$gconf{"$dir/EAP_wpa_preshared_passphrase"} = [$wpa]; $$gconf{"$dir/autoconnect"} = $auto =~ /true/i ? $TRUE : $FALSE; return $gconf; } sub getGconfCmds($){ my $gconf = shift; my $cmds = []; for my $key(keys %$gconf){ my @arr = @{$$gconf{$key}}; my $val = shift @arr; my $type = @arr > 0 ? shift @arr : 'string'; my $listType = @arr > 0 ? shift @arr : undef; push @$cmds, gconfSetCmd($key, $val, $type, $listType); } return $cmds; } sub gconfGetCmd($){ return "gconftool-2 --get $_[0]"; } sub gconfSetCmd($$$;$){ my ($key, $val, $type, $listType) = @_; my $cmd = "gconftool-2 --set '$key' '$val' --type=$type"; if(lc $type eq 'list'){ $cmd .= " --list-type=$listType"; } return $cmd; } sub listInt($){ my @list = @{shift()}; my $val = '[' . (join ',', @list) . ']'; return [$val, 'list', 'int']; } sub listString($){ my @list = @{shift()}; my $val = '[' . (join ',', @list) . ']'; return [$val, 'list', 'string']; } sub ssidListInt($){ my ($ssid) = @_; my @dec; for(my $i=0; $i; close FH; return join '', @lines; } &main(@ARGV);