220 likes | 487 Views
Using wifi. This is not about packet formats and other aspects of 802.11, but only how to use wifi on the Android platform. Wifi modes. A 802.11 node can be in one of the following modes Access point (AP) infrastructure mode Your linksys “router” at home is an AP.
E N D
Using wifi This is not about packet formats and other aspects of 802.11, but only how to use wifi on the Android platform
Wifi modes • A 802.11 node can be in one of the following modes • Access point (AP) infrastructure mode • Your linksys “router” at home is an AP. • It is not a router (it does not exchange routing messages with other routers), but is an AP and a NAT • A linux box can be an AP by using hostpad • An Android phone can also be AP • Station infrastructure mode • When you connect your laptop to an AP, your laptop is in station infrastructure mode. • Monitor mode • Promiscuous mode is able to receive frames even if the frame destination MAC address is not this node • This is useful to • spy on networks (bad) • Debugging network (good) • Smart/cognitive wifi (good) • E.g., the node receives frames from other nodes and can determine if other nodes provide a better path • A node receives other frames and determines that the channel is too busy and adjusts, for example, audio compression • Etc. • Maybe chips can sleep once they determine that the frame is not destined for this node. This can save power. However, this requires the node not be in monitor node • Monitor mode is not supported in nexus one or nexus s wifi chips • Some chips can be in station mode and monitor mode at the same time • Ad hoc mode • Nodes can communicate with each other without an AP • This allows peer-to-peer communication, however, it is not wifi-direct • Android does not support ad hoc mode, but a rooted phone can be made to support ad hoc • Wifi-direct • New protocol that allows nodes to communicate directly without an AP • Nodes that use wifi-direct can also simultaneously communicate with an AP (ad mode cannot do this) • There are hints that furture android APIs will support wifi direct • Some phones already have wifi direct • Also known as wifi p2p (this is the name used by the driver developers) • Mesh • Allows nodes to act as routes and access points. • Not widely supported • Not supported by mobile phones
wpa_supplicant Wifi hardware Wifi driver wpa_supplicant Android system Your app • Running wifi • Let android system help • Manually starting on nexus S • Do the following while having root privileges • Load wifi driver • on nexus S • insmod /system/modules/bcm4329.ko • On nexus one • -insmod /system/lib/modules/bcm4329.ko (not sure if this works) • On others, look for driver with find . –name *.ko • Check that driver loaded • lsmod • Should show driver is running • Start wifi • /system/bin/wpa_supplicant –Dext –ieth0 –c/data/misc/wifi_wpa_supplicant.conf • Run dhcp • /system/bin/dhcpcd –c/system/etc/dhcpcd/dhcpcd.conf –b eth0 (does not work) wpa_supplicant.conf
wpa_supplicant.conf • See examples and information at • http://user.uni-frankfurt.de/~testrad/wpa_supplicant/wpa_supplicant.conf.examples • See /data/misc/wifi/wpa-supplicant.conf • ctrl_interface=eth0 • update_config=1 • Network={ • ssid=“something” • psk=“something” • key_mgmt=WPA-PSK • priority=1 • } • More of the same • Note, passwords are stored in the .cof file, so this file can only be accessed via root privileges • Update_config=1 allows the conf to be overwritten when updated, e.g., when a new network is added • ctrl_interface • Interaction with the wpa_supplicant is through “unix sockets.” • The location of this socket is given by the argument to ctrl_interface=. However, eth0 does not really make sense • When wiif is running, see ls /data/misc/wifi/sockets to see the unix sockets • ap_scan • While not given in the example above, ap_scan can be used • ap_scan=1 • Allows the wpa_supplicant to initiate scaning and ap selection by using the wpa_supplicant.conf • This is the default • ap_scan=0 • The driver scans for Aps, and associates with the AP • This mode is best if the driver does not good wpa_supplicant support • ap_scan=2 • Not always supported • Does no scan, just asks driver to connect • This will allow connections to ad hoc networks • Network block • ssid=“something” • Sets the ssid of the ap • scan_ssid • =0 • Do not scan • =1 • Scan with ssid-specific probe request. • This is used to find Aps that do not broadcast ssid • Priority • High numbers means attemp to connect to this network first • Not used when ap_scan=2. in this case, the order that networks appear is used • Mode • =0 inferstructure • =1 IBSS or ad hoc • Requires key_mgmt = NONE or key_mgmt=WPA-NONE
Ad hoc • The wpa_supplicant.conf must be changed • ap_scan=2 • Network = { • ssid = “MyAdHocNetwork” • mode = 1 • key_mgmt = NONE • } • Other networks… • These networks will likely not be used
IP address • If ap_scan=2 and dhcp is used • Connection is attempted to each network in the order they appear • If the network is an infrastructure, then • an association is attempted. • if associate fails, then the a connection to the next network is the list is attempted • If the network is ad hoc, • then dhcp is attempted. • If dhcp fails, then a connection with the next network in the list is attempted • This step is initiated by the android system, not the wpa_supplicant+wifi-driver system • If ap_scan=2 and the ip address is set statically, • Connection is attempted to each network in the order they appear • If the network is an infrastructure, then • an association is attempted. • if associate fails, then the a connection to the next network is the list is attempted • If the network is ad hoc, • Then the static ip is used, and the connection is complete • Conclusions • Assuming that dhcp is not available in the ad hoc network, using a static IP is required for ad hoc, and not setting the ip address will essentially disable the ad hoc mode • That is, if the wpa_supplicant can remain fixed, with ap_scan=2 and ad hoc mode can be enabled by setting a static ip • However, when ad hoc mode is not used (i.e., the ip is not set to be a static ip), then association with a network is delayed by the dhcp attempt on the ad hoc network • This makes the performance a bit sluggish when are connecting to a network • Therefore, the best performance is achieved by using a different wpa_supplicant.conf depending on whether ad hoc mode is to be used. • Just to be safe, we only change the ap_scan=1 or 2 in the wpa_supplicant.conf. That way, the wpa_supplicant.conf will always be able to connect to access points as usual
Connecting to ad hoc network • Initial set up • Make sure that ap_scan=1 conf file includes all networks that are in ap_scan=2 .conf file • Check that conf file with ap_scan=1 is backed up • make sure all conf files are only accessible with root privilege • Turn on ad hoc • Copy conf file with ap_scan = 2 to • /data/misc/wifi/wpa_supplicant.conf • Set permissions of wpa_supplicant.conf • Set owner of wpa_supplicant.conf • Otherwise, when the system reboots, the permission of the wpa_supplicant is incorrectly set • Stop wifi • When wifi is stopped, set static ip • Start wifi • Turn off • Copy conf file with ap_scan = 1 to • /data/misc/wifi/wpa_suplicant.conf • Set permisions of wpa_supplicant.conf • Set owner of wpa_supplicant.conf • Stop wifi • Once stopped • Disable static ip • Start wifi
wpa_supplicant.conf permissions • The conf contains password for access points, and therefore requires super-user privilege to access • On a rooted phone will allow any app get access to AP passwords! • Also, the wpa_supplicant.conf must be owned by the wifi system, otherwise, after boot up, the permissions would be incorrect
Ad hoc mode does not work • Sometime ad hoc mode does not work • This might be a bug in the android wifi system, or maybe a parameter is set incorrectly • Rebooting often fixes the problem
To do • Set IP address • wpa_supplicant.conf stuff • Save current .conf • ap_scan • =2 if we want ad hoc mode • =1 if we want to connect to an access point • Save and set permissions • Set ad hoc mode • Turn off wifi • Wait until it is off • Change settings • Turn on • Check if succeeded • We can only check after a little while, so we need to set a timer (use Handler class) • Call callback function when finished • If failed, then try rebooting the phone • ((PowerManager) getSystemService(Context.POWER_SERVICE)).reboot(); // requires reboot permission • Needs • Permissions • ACCESS_WIFI_STATE • ACCESS_NETWORK_STATE • CHANGE_WIFI_STATE • WRITE_SETTINGS • Root access • cp command in /system/xbin • This can be installed by installing busy box
AdHocConnectionManager • Is the main class for controlling ad hoc connections • Contrustor is AdHocConnectionManager(Context _context, String _baseDirPath, TextView _statusView) • The textview, can be null, or can be a textVeiw object where the wifi state will be written • Public functions • public void startAdHoc(String _ssidOfAdHocNetwork, WifiConnectionResponse _responseObject) • Calls callback when the conenction succeeds or fails • Note, the connection to ad hoc does not occur until several seconds after this function is called • Public void stopAdHoc() • Disables ad hoc and returns wpa_supplicant.conf to original state • public String getWifStatus() • Returns a string that includes the current state of the wifi • public void showWifiStatus() • Shows the wiif status in the log • public void turnWifiOn() • public void turnWifiOff() • public booleanconnectedToDesiredAdHocNetwork() • Returns true if connected To Desired Ad Hoc Network
example • From class web page get classes • WpaSupplicantConfManager • IPAddressManager • AdHocConnectionManager • Note, more details on these classes is on the following slides • Make new app called TurnOnAdHocTest • Go to layout and • Add buttons • StartAdHoc • StopAdHoc • ShowStatus • TurnWifiOn • TurnWifiOff • Add TextView, called textView • Add member variables • TextViewtextView = null; • AdHocConnectionManageradHocConnectionManager; • In onCreate, after setContentView, add • textView = (TextView)findViewById(R.id.Status); • adHocConnectionManager = new AdHocConnectionManager(this, this.getFilesDir().getAbsolutePath(), textView); • Button startAdHocButton = (Button)findViewById(R.id.startAdHoc); • startAdHocButton.setOnClickListener(new View.OnClickListener() { • @Override • public void onClick(View v) { • Log.e("TurnOnWifi","clicked start ad hoc"); • adHocConnectionManager.startAdHoc("MyAdHoc", new AdHocConnectionManager.WifiConnectionResponse(){ • @Override • public void response(booleanconnectionSucceeded) { • if (connectionSucceeded) { • Log.e("debug","Connected to ad hoc network"); • } else { • Log.e("debug","Failed to connected to ad hoc network"); • } • }}); • }}); • Button stopAdHocButton = (Button)findViewById(R.id.stopAdHoc); • stopAdHocButton.setOnClickListener(new View.OnClickListener() { • @Override • public void onClick(View v) { • adHocConnectionManager.stopAdHoc(); • }}); • Button showWifi = (Button)findViewById(R.id.showWifiState); • showWifi.setOnClickListener(new View.OnClickListener() { • @Override • public void onClick(View v) { • Log.e("wifistatus",adHocConnectionManager.getWifStatus()); • }}); • Button wifiOn = (Button)findViewById(R.id.wifiOn); • wifiOn.setOnClickListener(new View.OnClickListener() { • @Override • public void onClick(View v) { • Log.e("debug","turningwifi on"); • adHocConnectionManager.turnWifiOn(); • }}); • Button wifiOff = (Button)findViewById(R.id.wifiOff); • wifiOff.setOnClickListener(new View.OnClickListener() { • @Override • public void onClick(View v) { • Log.e("debug","turningwifi off"); • adHocConnectionManager.turnWifiOff(); • }}); • }
IPAddressManager • Make new class, IPAddressManager • Add member variables • private Context context = null; • public String baseDir = null; • String ip = null; • Constructor • public IPAddressManager(Context _context, WifiManager _wifiManager, String _baseDir) { • context = _context; • baseDir = _baseDir; • WifiInfowifiInfo = _wifiManager.getConnectionInfo(); • Log.e("DEBUG","currentmac: "+wifiInfo.getMacAddress()); • ip = makeIPAddressFromMac(wifiInfo.getMacAddress()); • } • Two public functions: setStaticIP and setDynamicIP • public void setDynmaicIP() { • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_USE_STATIC_IP, "0"); • } • public void setStaticIP() { • // even if dns is not required and there is no default gateway, these parameters must be set. So we set them this like this • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_STATIC_IP, makeIPAddressFromMac(ip)); • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_STATIC_NETMASK, "255.255.0.0"); • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_STATIC_DNS1, "208.67.222.222"); • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_STATIC_DNS2, "208.67.220.220"); • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_STATIC_GATEWAY, "192.168.4.1"); • Settings.System.putString(context.getContentResolver(), Settings.System.WIFI_USE_STATIC_IP, "1"); • Log.e("debug","setting static IP to: "+Settings.System.getString(context.getContentResolver(), Settings.System.WIFI_STATIC_IP) ); • Log.e("debug","use static is set to :"+Settings.System.getString(context.getContentResolver(), Settings.System.WIFI_USE_STATIC_IP) ); • } • // !! These function require write.settings permissions • A private function for setting the ip address from the mac address • Using ipv6 would be better. I’ll add that later • The ip address is in the 192.168.255.255 subnet • Sometimes the mac address cannot be retrived. In this case, we try to read from a file that has saved the ip or, if that fails, generate a random ip
IPAddressManager cont • A private function for setting the ip address from the mac address • Using ipv6 would be better. I’ll add that later • The ip address is in the 192.168.255.255 subnet • Sometimes the mac address cannot be retrived. In this case, we try to read from a file that has saved the ip or, if that fails, generate a random ip • private String makeIPAddressFromMac(String mac) { • File aFile = new File(baseDir+"/savedIpAddress.txt"); • if (mac==null) { • Log.e("debug","could not get mac address. checking is ip is saved in a file"); • FileReaderfr; • try { • fr= new FileReader(aFile); • BufferedReaderinput = new BufferedReader(fr); • String line = null; • while ( (line = input.readLine()) != null) { • String address; • address = line.trim(); • String [] tokens = address.split("."); • if (tokens.length!=4) { • Random generator = new Random(); • address = "192.168."+generator.nextInt(255)+"."+generator.nextInt(255); • return address; • } else { • for (inti=0; i<4; i++) { • if (Integer.valueOf(tokens[i])>254 || Integer.valueOf(tokens[i])<0) { • Random generator = new Random(); • address = "192.168."+generator.nextInt(255)+"."+generator.nextInt(255); • return address; • } • } • } • return address; • } • } catch (FileNotFoundException e) { • Random generator = new Random(); • String address = "192.168."+generator.nextInt(255)+"."+generator.nextInt(255); • return address; • } catch (IOException e) { • //e.printStackTrace(); • } • } else { • // continued next column • // from first column • String delim = "[:]“; • String[] tokens = mac.split(delim); • inti1 = Integer.parseInt(tokens[4].trim(), 16); • inti2 = Integer.parseInt(tokens[5].trim(), 16); • String address = "192.168."+i1+"."+i2; • Log.e("debug","staticip address: "+address); • Writer output;// save this ip address to a file • try { • output = new BufferedWriter(new FileWriter(aFile)); • output.write( address ); • } catch (IOException e) { • Log.e("debug","could not save ip address to: "+aFile.toString()); • } • return address; • } • Random generator = new Random(); • String address = "192.168."+generator.nextInt(255)+"."+generator.nextInt(255); • return address; • }
WpaSupplicantConfManager Reads current .conf, set permissions, sets to connect to ad hoc or not • Disconnect from ad hoc and enable regular infrastructure connection • public void makeConfNonAdHoc() { • Log.e("confManager","making conf without ad hoc network "); • if (initilized==false) { • Log.e("debug","WpaSupplicantConfManager should be initilized before using"); • initialize(); • } • currentConf.saveWithoutAdHocNetworks(currentConfFileName); • moveAndsetPermissionsOfConf(currentConfFileName); • } • This class needs root access. Show a dialog if root access seems to be missing. Also, we need cp (copy command) in /system/xbin. This can be installed by installing BusyBox • public void showRootFailed() { • AlertDialog.Builderalertbox = new AlertDialog.Builder(context); • alertbox.setMessage("Failed to copy current conf. Perhaps missing root or /system/xbin/cp command is missing"); • alertbox.setNeutralButton("Ok", new DialogInterface.OnClickListener() { • public void onClick(DialogInterface arg0, int arg1) { • Toast.makeText(context, "app is disabled", Toast.LENGTH_LONG).show(); • } • }); • alertbox.show(); • } • Add new class WpaSupplicantConfManager • Add member variables • String currentConfFileName = new String(); • String savedConfFileName = new String(); • ConfDetailscurrentConf = null; • booleaninitilized = false; • String baseDir = null; • Context context = null; • Constructor • public WpaSupplicantConfManager(String _baseDir, Context _context) { • baseDir = _baseDir; • context = _context; • } • Connect to ad hoc network • public void makeConfAdHoc(String ssidOfAdHocNetwork) { • Log.e("confManager","making conf for ad hoc network with ssid: "+ssidOfAdHocNetwork); • if (initilized==false) { • Log.e("debug","WpaSupplicantConfManager should be initilized before using"); • initialize(); • } • currentConf.saveWithAdHocNetwork(currentConfFileName,ssidOfAdHocNetwork); • moveAndsetPermissionsOfConf(currentConfFileName); • }
WpaSupplicantConfManager • Move conf from working dir to directory used by wifi system and set permissions • public void moveAndsetPermissionsOfConf(String fileName) { • // this function will not work correctly if the device does not have root access • // However, lack of root access will be caught will be caught somewhere else • Log.e("confManager","moving and setting permissions of: "+fileName); • String copyCommand = "cp “; • copyCommand+= currentConfFileName; • copyCommand+= " /data/misc/wifi/wpa_supplicant.conf“; • final Runtime runtime = Runtime.getRuntime(); • Process qq; • try { • qq= runtime.exec(new String[]{"/system/bin/su", "-c", copyCommand}); • qq.waitFor(); • qq= runtime.exec(new String[]{"/system/bin/su", "-c", "chmod 666 /data/misc/wifi/wpa_supplicant.conf"}); • qq.waitFor(); • qq= runtime.exec(new String[]{"/system/bin/su", "-c", "chownsystem.wifi /data/misc/wifi/wpa_supplicant.conf"}); • qq.waitFor(); • } catch (IOException e) { • //e.printStackTrace(); • } catch (InterruptedException e) { • //e.printStackTrace(); • } • } • Initialize the conf manager • gets current conf and saves it • Return false if failed, which likely means that the device does not have root access • public boolean initialize() { • Log.e("debug","WpaSupplicantConfManager.ini"); • initilized = true; • currentConfFileName = baseDir + "/current_wpa_supplicant.conf"; • savedConfFileName = baseDir + "/saved_wpa_supplicant.conf"; • try { • copyCurrentWpaSupplicant(currentConfFileName); • } catch (IOException e) { • Log.e("AdHocWifi Conf Manager","Failed to copy current conf. Perhaps missing root"); • showRootFailed(); • return false; • } catch (InterruptedException e) { • Log.e("AdHocWifi Conf Manager","Failed to copy current conf. Perhaps missing root"); • showRootFailed(); • return false; • } • Log.e("confManager","getting networks"); • currentConf.getNetworksFromConf(currentConfFileName); • //Log.e("current conf",currentConf.toString()); • if ( currentConf == null) { • } Log.e("Info","currentwpa_supplicant.conf did not exist. Making new one"); • currentConf = new ConfDetails(); • currentConf.header += "ctrl_interface=eth0\nupdate_config=1\nap_scan=1\n\n"; • currentConf.ap_scan = 1;
WpaSupplicantConfManager continued • Initialize continued • Log.e("confManager","getting networks from saved: "+savedConfFileName); • ConfDetailssavedConf = new ConfDetails(); • savedConf.getNetworksFromConf(savedConfFileName); • if (savedConf!=null) { • //Log.e("savedConf",savedConf.toString()); • Log.e("debug","updating saved config"); • // make sure all networks in the saved .conf are also in the current.conf (we will make current into our saved) • for(inti=0; i<savedConf.networks.size(); i++) { • if (savedConf.modes.get(i)==1) • continue; // skip ad hoc networks • booleanfd = false; • for (int j=0; j<currentConf.networks.size(); j++) { • if (savedConf.networks.get(i).equals(currentConf.networks.get(j))) { • fd = true; • break; • } • } • if (fd==false) { • currentConf.networks.add(savedConf.networks.get(i)); • currentConf.ssids.add(savedConf.ssids.get(i)); • currentConf.modes.add(savedConf.modes.get(i)); • } • } • } • currentConf.saveWithoutAdHocNetworks(savedConfFileName); • return true; • } • public void copyCurrentWpaSupplicant(String destFile) throws IOException, InterruptedException { • Log.e("confManager","copying current conf to: "+destFile); • String copyCommand = "cp /data/misc/wifi/wpa_supplicant.conf "; • copyCommand += destFile; • final Runtime runtime = Runtime.getRuntime(); • Process qq; • qq = runtime.exec(new String[]{"/system/bin/su", "-c", copyCommand}); • qq.waitFor(); • qq = runtime.exec(new String[]{"/system/bin/su", "-c", "chmod 777 "+destFile}); • qq.waitFor(); • }
ConfDetails • WpaSupplicantConfManager uses a subclass named ConfDetails that holds the information contained in the .conf file • Public functions include • toString • saveWithoutAdHocNetworks(String fileName) • saveWithAdHocNetwork(String fileName, String ssidOfAdHocNetwork) • getNetworksFromConf(String fileName) • String makeApScanEqual1(String header) • String makeApScanEqual2(String header) • public class ConfDetails { • public String header; • public List<String> ssids; • public List<String> networks; • public List<Integer> modes; • intap_scan; • public ConfDetails() { • header = new String(); • ssids = new ArrayList<String>(); • networks = new ArrayList<String>(); • modes = new ArrayList<Integer>(); • ap_scan = 1; • Log.e("degug","made conf detials"); • } • public String toString() { • String S = new String(); • S += header; • for (inti=0; i<networks.size(); i++ ) { • S += "mode= "+modes.get(i)+"\n"; • S += networks.get(i); • } • return S; • } • public void saveWithoutAdHocNetworks(String fileName) { • Log.e("confManager","saving conf without ad hoc network to: "+fileName); • String newHeader = makeApScanEqual1(header); • //use buffering • Writer output; • try { • output = new BufferedWriter(new FileWriter(fileName)); • try { • output.write( newHeader ); • for (inti=0; i<networks.size(); i++) { • if (modes.get(i)==1) • continue; • output.write(networks.get(i)); • if (i<networks.size()-2) { • output.write("\n"); • } • } • } catch (IOException e) { • // TODO Auto-generated catch block • e.printStackTrace(); • } • finally { • output.close(); • } • } catch (IOException e) { • // TODO Auto-generated catch block • e.printStackTrace(); • } • }
ConfDetailscontiued • public void saveWithAdHocNetwork(String fileName, String ssidOfAdHocNetwork) { • Log.e("confManager","saving conf with ad hoc network to: "+fileName); • String newHeader = makeApScanEqual2(header); • //use buffering • Writer output; • try { • output = new BufferedWriter(new FileWriter(fileName)); • try { • output.write( newHeader ); • String adHocNetwork = new String(); • adHocNetwork += "network={\n"; • adHocNetwork += "ssid="; • adHocNetwork += "\""+ssidOfAdHocNetwork+"\"\n"; • adHocNetwork += "scan_ssid=1\nkey_mgmt=NONE\nmode=1\n}\n\n"; • output.write( adHocNetwork ); • for (inti=0; i<networks.size(); i++) { • if (modes.get(i)==1) • continue; • output.write(networks.get(i)); • if (i<networks.size()-2) { • output.write("\n"); • } • } • } catch (IOException e) { • // TODO Auto-generated catch block • e.printStackTrace(); • } • finally { • output.close(); • } • } catch (IOException e) { • // TODO Auto-generated catch block • e.printStackTrace(); • } • } • public String makeApScanEqual1(String header) { • Log.e("confManager","makingap scan equal to 1"); • if (header==null) { • Log.e("error","header is null"); • } • if (header.contains("ap_scan")) { • String newHeader = new String(); • int index = header.indexOf("ap_scan"); • index = header.indexOf("=",index); • newHeader = header.substring(0,index); • newHeader += "=1\n"; • index = header.indexOf("\n",index); • if (index+1<header.length()) • newHeader += header.substring(index+1,header.length()); • //Log.e("old header",header); • //Log.e("new header",newHeader); • return newHeader; • } else { • String newHeader = header; • newHeader += "ap_scan=1\n"; • return newHeader; • } • } • public String makeApScanEqual2(String header) { • Log.e("confManager","makingap scan equal to 2"); • if (header.contains("ap_scan")) { • String newHeader = new String(); • int index = header.indexOf("ap_scan"); • index = header.indexOf("=",index); • newHeader = header.substring(0,index); • newHeader += "=2\n"; • index = header.indexOf("\n",index); • newHeader += header.substring(index+1,header.length()); • return newHeader; • } else { • String newHeader = header; • newHeader += "ap_scan=2\n"; • return newHeader; • } • }
ConfDetails continued • public ConfDetailsgetNetworksFromConf(String fileName) { • Log.e("confManager","getting list of networks from conf named: "+fileName); • ConfDetailsconfDetails = new ConfDetails(); • File aFile = new File(fileName); • try { • FileReaderfr = new FileReader(aFile); • BufferedReader input = new BufferedReader(fr); • String line = null; • booleannetworkStatementEnded = false; • booleanfoundSSID = false; • booleanreadingHeader = true; • while ( (line = input.readLine()) != null) { • if (line.contains("Network")==false && line.contains("network")==false) { • //Log.e("debug","header line: "+line); • if (readingHeader) { • confDetails.header += line + "\n"; • if (line.contains("ap_scan")) { • String[] tokens = line.split(new String("=")); • if (tokens.length!=2) { • Log.e("ERROR","malformedwpa_supplicant.conf when searching for ap_scan=...: "+fileName); • Log.e("line:",line); • Log.e("error","num tokens: "+tokens.length); • return null; • } • confDetails.ap_scan = Integer.valueOf(tokens[1]); • } • } • } else { • readingHeader = false; • String network = new String(); • network += line + "\n"; • networkStatementEnded = false; • foundSSID = false; • String ssid = null; • booleanfoundMode = false; • int mode = -1; • readingHeader = false; • String network = new String(); • network += line + "\n"; • networkStatementEnded = false; • foundSSID = false; • String ssid = null; • booleanfoundMode = false; • int mode = -1; • // read each line in the network specification • while ( (line = input.readLine()) != null) { • network += line + "\n"; • if (line.contains("ssid") && !line.contains("scan_ssid")) { • String[] tokens = line.split(new String("\"")); • if (tokens.length<2 || tokens.length>3) { • Log.e("ERROR","malformedwpa_supplicant.conf when seaching for ssid=...: "+fileName); • Log.e("line:",line); • Log.e("error","num tokens: "+tokens.length); • return null; • } • ssid = tokens[1]; • //Log.e("debug","ssid: "+ssid); • foundSSID = true; • } • if (line.contains("mode")) { • String[] tokens = line.split(new String("=")); • if (tokens.length!=2) { • Log.e("ERROR","perhaps malformed wpa_supplicant.conf when seaching for mode...: "+fileName); • Log.e("line:",line); • Log.e("error","num tokens: "+tokens.length); • //return null; • } else { • mode = Integer.valueOf(tokens[1]); • foundMode = true; • } • } • if (line.contains("}")) { • networkStatementEnded = true; • break; • } • } • if (networkStatementEnded && foundSSID) { // if false, then something is wrong • confDetails.networks.add(network); • confDetails.ssids.add(ssid); • if (foundMode) { • confDetails.modes.add(mode); • } else { • confDetails.modes.add(new Integer(0)); • } • } else { • Log.e("error","malformed conf. networkStatementEnded="+networkStatementEnded+" foundssid: "+foundSSID); • break; • } • } • }
ConfDetails continued • if (networkStatementEnded && foundSSID){ • return confDetails; • } else { • return null; • } • } catch (FileNotFoundException e) { • // TODO Auto-generated catch block • Log.e("error","file not found: "+fileName); • return null; • } catch (IOException e) { • // TODO Auto-generated catch block • Log.e("error","io error"); • return null; • } • } // ends getNetworksFromConf