package org.eclipse.kura.linux.net.util; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; import org.eclipse.kura.core.net.WifiAccessPointImpl; import org.eclipse.kura.core.net.util.NetworkUtil; import org.eclipse.kura.net.wifi.WifiAccessPoint; import org.eclipse.kura.net.wifi.WifiMode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Consumes AP property lines from iw scan command. */ class IWAPParser { private static final Logger s_logger = LoggerFactory.getLogger(IWAPParser.class); // Top-level properties we'll be picking up private String ssid = null; private List<Long> bitrate = null; private long frequency = -1; private byte[] hardwareAddress = null; private int strength = -1; private List<String> capabilities = null; // For parsing the security sections private final IWSecuritySectionParser rsn = new IWSecuritySectionParser(); private final IWSecuritySectionParser wpa = new IWSecuritySectionParser(); // Current security section parser, or null if we're currently parsing toplevel things private IWSecuritySectionParser securityParser = null; public IWAPParser(String macAddressString) { this.hardwareAddress = NetworkUtil.macToBytes(macAddressString); } public WifiAccessPoint toWifiAccessPoint() { WifiAccessPointImpl wifiAccessPoint = new WifiAccessPointImpl(this.ssid); wifiAccessPoint.setBitrate(this.bitrate); wifiAccessPoint.setFrequency(this.frequency); wifiAccessPoint.setHardwareAddress(this.hardwareAddress); wifiAccessPoint.setMode(WifiMode.MASTER); // FIME - is this right? - always MASTER - or maybe // AD-HOC too? wifiAccessPoint.setRsnSecurity(this.rsn.getWifiSecurityFlags()); wifiAccessPoint.setStrength(this.strength); wifiAccessPoint.setWpaSecurity(this.wpa.getWifiSecurityFlags()); if (this.capabilities != null && this.capabilities.size() > 0) { wifiAccessPoint.setCapabilities(this.capabilities); } return wifiAccessPoint; } /** * @param propLine * A trimmed line from iw scan. * @throws Exception * Something went wrong for this AP. */ public void parsePropLine(String propLine) throws Exception { if (this.securityParser != null) { // We're parsing a section right now boolean done = this.securityParser.parsePropLine(propLine); if (done) { this.securityParser = null; } } else if (propLine.startsWith("freq:")) { StringTokenizer st = new StringTokenizer(propLine, " "); st.nextToken(); // eat freq: this.frequency = Long.parseLong(st.nextToken()); } else if (propLine.startsWith("SSID: ")) { this.ssid = propLine.substring(5).trim(); } else if (propLine.startsWith("RSN:")) { this.securityParser = this.rsn; parsePropLine(propLine); } else if (propLine.startsWith("WPA:")) { this.securityParser = this.wpa; parsePropLine(propLine); } else if (propLine.startsWith("Supported rates: ")) { // Supported rates: 1.0* 2.0* 5.5* 11.0* 18.0 24.0 36.0 54.0 if (this.bitrate == null) { this.bitrate = new ArrayList<Long>(); } String[] rateStrings = propLine.replaceFirst("Supported rates: ", "").replaceAll("\\*", "").trim() .split(" "); for (String rateString : rateStrings) { this.bitrate.add((long) (Float.parseFloat(rateString) * 1000000)); } } else if (propLine.startsWith("Extended supported rates: ")) { // Extended supported rates: 6.0 9.0 12.0 48.0 if (this.bitrate == null) { this.bitrate = new ArrayList<Long>(); } String[] rateStrings = propLine.replaceFirst("Extended supported rates: ", "").replaceAll("\\*", "").trim() .split(" "); for (String rateString : rateStrings) { this.bitrate.add((long) (Float.parseFloat(rateString) * 1000000)); } } else if (propLine.startsWith("signal:")) { // signal: -56.00 dBm StringTokenizer st = new StringTokenizer(propLine, " "); st.nextToken(); // eat signal: final String strengthRaw = st.nextToken(); if (strengthRaw.contains("/")) { // Could also be of format 39/100 final String[] parts = strengthRaw.split("/"); this.strength = (int) Float.parseFloat(parts[0]); this.strength = SignalStrengthConversion.getRssi(this.strength); } else { this.strength = Math.abs((int) Float.parseFloat(strengthRaw)); } } else if (propLine.startsWith("capability:")) { this.capabilities = new ArrayList<String>(); String newLine = propLine.substring("capability:".length()).trim(); StringTokenizer st = new StringTokenizer(newLine, " "); while (st.hasMoreTokens()) { this.capabilities.add(st.nextToken()); } } else { s_logger.debug("Ignoring line in scan result: {}", propLine); } } }