gt:                     String propLine = line.trim();
context: /*******************************************************************************
   * Copyright (c) 2011, 2016 Eurotech and/or its affiliates
   *
   * All rights reserved. This program and the accompanying materials
   * are made available under the terms of the Eclipse Public License v1.0
   * which accompanies this distribution, and is available at
   * http://www.eclipse.org/legal/epl-v10.html
   *
   * Contributors:
   *     Eurotech
   *******************************************************************************/
  
  package org.eclipse.kura.linux.net.util;
  
  import java.io.BufferedReader;
  import java.io.InputStreamReader;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.StringTokenizer;
  import java.util.concurrent.ExecutorService;
  import java.util.concurrent.Executors;
  import java.util.concurrent.Future;
  import java.util.concurrent.TimeUnit;
  
  import org.eclipse.kura.KuraErrorCode;
  import org.eclipse.kura.KuraException;
  import org.eclipse.kura.core.linux.util.LinuxProcessUtil;
  import org.eclipse.kura.core.util.ProcessUtil;
  import org.eclipse.kura.core.util.SafeProcess;
  import org.eclipse.kura.net.wifi.WifiAccessPoint;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class iwScanTool extends ScanTool implements IScanTool {
  
      private static final Logger s_logger = LoggerFactory.getLogger(iwScanTool.class);
      private static final String SCAN_THREAD_NAME = "iwScanThread";
      private static final Object s_lock = new Object();
      private String m_ifaceName;
      private ExecutorService m_executor;
      private static Future<?> m_task;
  
      private int m_timeout;
  
      // FIXME:MC Is this process always closed?
      private SafeProcess m_process;
      private boolean m_status;
      private String m_errmsg;
  
      protected iwScanTool() {
          this.m_timeout = 20;
      }
  
      protected iwScanTool(String ifaceName) {
          this();
          this.m_ifaceName = ifaceName;
          this.m_errmsg = "";
          this.m_status = false;
      }
  
      protected iwScanTool(String ifaceName, int tout) {
          this(ifaceName);
          this.m_timeout = tout;
      }
  
      @Override
      public List<WifiAccessPoint> scan() throws KuraException {
  
          List<WifiAccessPoint> wifiAccessPoints = new ArrayList<WifiAccessPoint>();
          synchronized (s_lock) {
              StringBuilder sb = new StringBuilder();
  
              SafeProcess prIpLink = null;
              SafeProcess prIpAddr = null;
              try {
                  if (!LinuxNetworkUtil.hasAddress(this.m_ifaceName)) {
                      // activate the interface
                      sb.append("ip link set ").append(this.m_ifaceName).append(" up");
                      prIpLink = ProcessUtil.exec(sb.toString());
                      prIpLink.waitFor();
  
                      // remove the previous ip address (needed on mgw)
                      sb = new StringBuilder();
                      sb.append("ip addr flush dev ").append(this.m_ifaceName);
                      prIpAddr = ProcessUtil.exec(sb.toString());
                      prIpAddr.waitFor();
                  }
              } catch (Exception e) {
                  throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e);
              } finally {
                  if (prIpLink != null) {
                      ProcessUtil.destroy(prIpLink);
                  }
                  if (prIpAddr != null) {
                      ProcessUtil.destroy(prIpAddr);
                  }
              }
  
              long timerStart = System.currentTimeMillis();
  
              this.m_executor = Executors.newSingleThreadExecutor();
              m_task = this.m_executor.submit(new Runnable() {
  
                  @Override
                  public void run() {
                      Thread.currentThread().setName(SCAN_THREAD_NAME);
                      int stat = -1;
                      iwScanTool.this.m_process = null;
                      StringBuilder sb = new StringBuilder();
                      sb.append("iw dev ").append(iwScanTool.this.m_ifaceName).append(" scan");
                      s_logger.info("scan() :: executing: {}", sb.toString());
                      iwScanTool.this.m_status = false;
                      try {
                          iwScanTool.this.m_process = ProcessUtil.exec(sb.toString());
                          stat = iwScanTool.this.m_process.waitFor();
                          s_logger.info("scan() :: {} command returns status={}", sb.toString(), stat);
                          if (stat == 0) {
                              iwScanTool.this.m_status = true;
                          } else {
                              s_logger.error("scan() :: failed to execute {} error code is {}", sb.toString(), stat);
                              s_logger.error("scan() :: STDERR: " + LinuxProcessUtil
                                      .getInputStreamAsString(iwScanTool.this.m_process.getErrorStream()));
                          }
                      } catch (Exception e) {
                          iwScanTool.this.m_errmsg = "exception executing scan command";
                          e.printStackTrace();
                      }
                  }
              });
  
              while (!m_task.isDone()) {
                  if (System.currentTimeMillis() > timerStart + this.m_timeout * 1000) {
                      s_logger.warn("scan() :: scan timeout");
                      sb = new StringBuilder();
                      sb.append("iw dev ").append(this.m_ifaceName).append(" scan");
                      try {
                          int pid = LinuxProcessUtil.getPid(sb.toString());
                          if (pid >= 0) {
                              s_logger.warn("scan() :: scan timeout :: killing pid {}", pid);
                              LinuxProcessUtil.kill(pid);
                          }
                      } catch (Exception e) {
                          e.printStackTrace();
                      }
                      m_task.cancel(true);
                      m_task = null;
                      this.m_errmsg = "timeout executing scan command";
                      break;
                  }
                  try {
                      Thread.sleep(500);
                  } catch (InterruptedException e) {
                  }
              }
  
              if (this.m_status == false || this.m_process == null) {
                  throw new KuraException(KuraErrorCode.INTERNAL_ERROR, this.m_errmsg);
              }
  
              s_logger.info("scan() :: the 'iw scan' command executed successfully, parsing output ...");
              try {
                  wifiAccessPoints = parse();
              } catch (Exception e) {
                  throw new KuraException(KuraErrorCode.INTERNAL_ERROR, e, "error parsing scan results");
              } finally {
                  s_logger.info("scan() :: destroing scan proccess ...");
                  if (this.m_process != null) {
                      ProcessUtil.destroy(this.m_process);
                  }
                  this.m_process = null;
  
                  s_logger.info("scan() :: Terminating {} ...", SCAN_THREAD_NAME);
                  this.m_executor.shutdownNow();
                  try {
                      this.m_executor.awaitTermination(2, TimeUnit.SECONDS);
                  } catch (InterruptedException e) {
                      s_logger.warn("Interrupted", e);
                  }
                  s_logger.info("scan() :: 'iw scan' thread terminated? - {}", this.m_executor.isTerminated());
                  this.m_executor = null;
              }
          }
  
          return wifiAccessPoints;
      }
  
      private List<WifiAccessPoint> parse() throws Exception {
  
          List<IWAPParser> apInfos = new ArrayList<IWAPParser>();
          IWAPParser currentAP = null;
  
          BufferedReader br = new BufferedReader(new InputStreamReader(this.m_process.getInputStream()));
          try {
              String line = null;
              while ((line = br.readLine()) != null) {
  
                  if (line.startsWith("scan aborted!")) {
                      br.close();
                      s_logger.warn("parse() :: scan operation was aborted");
                      throw new KuraException(KuraErrorCode.INTERNAL_ERROR, "iw scan operation was aborted");
                  }
  
                  if (line.startsWith("BSS")) {
                      // new AP - parse out the MAC
                      StringTokenizer st = new StringTokenizer(line, " ");
                      st.nextToken(); // eat BSS
                      String macAddressString = st.nextToken().substring(0, 16);
  
                      if (macAddressString != null) {
                          // Set this AP parser as the current one
                          currentAP = new IWAPParser(macAddressString);
                      }
  
                      // Add it to the list
                      apInfos.add(currentAP);
  
                  } else {
                      // Must be an AP property line
  