#!/usr/bin/python

"""Utility for controlling WiFi AP and client functionality."""

from __future__ import print_function

import atexit
import glob
import os
import re
import subprocess
import sys
import time

import autochannel
import bandsteering
import configs
import experiment
import iw
import mwifiex
import options
import persist
import qca9880_cal
import quantenna
import utils


_OPTSPEC_FORMAT = """
{bin} set           Enable or modify access points.  Takes all options unless otherwise specified.
{bin} setclient     Enable or modify wifi clients.  Takes -b, -P, -s, --bssid, -S, --wds.
{bin} stop|off      Disable access points and clients.  Takes -b, -P, -S.
{bin} stopap        Disable access points.  Takes -b, -P, -S.
{bin} stopclient    Disable wifi clients.  Takes -b, -P, -S.
{bin} restore       Restore saved client and access point options.  Takes -b, -S.
{bin} show          Print all known parameters.  Takes -b, -S.
{bin} scan          Print 'iw scan' results for a single band.  Takes -b, -S.
--
b,band=                           Wifi band(s) to use (5 GHz and/or 2.4 GHz).  set, setclient, and scan have a default of 2.4 and cannot take multiple-band values.  [2.4 5]
c,channel=                        Channel to use [auto]
a,autotype=                       Autochannel method to use (LOW, HIGH, DFS, NONDFS, ANY,OVERLAP) [NONDFS]
s,ssid=                           SSID to use [{ssid}]
bssid=                            BSSID to use []
e,encryption=                     Encryption type to use (WPA_PSK_AES, WPA2_PSK_AES, WPA12_PSK_AES, WPA_PSK_TKIP, WPA2_PSK_TKIP, WPA12_PSK_TKIP, WEP, or NONE) [WPA2_PSK_AES]
f,force-restart                   Force restart even if already running with these options
C,client-isolation                Enable client isolation, preventing bridging of frames between associated stations.
H,hidden-mode                     Enable hidden mode (disable SSID advertisements)
M,enable-wmm                      Enable wmm extensions (needed for block acks)
G,short-guard-interval            Enable short guard interval
p,protocols=                      802.11 levels to allow, slash-delimited [a/b/g/n/ac]
w,width=                          Channel width to use, in MHz (20, 40, or 80) [20]
B,bridge=                         Bridge device to use [br0]
X,extra-short-timeouts            Use shorter key rotations; 1=rotate PTK, 2=rotate often
Y,yottasecond-timeouts            Don't rotate any keys: PTK, GTK, or GMK
P,persist                         For set commands, persist options so we can restore them with 'wifi restore'.  For stop commands, remove persisted options.
S,interface-suffix=               Interface suffix (defaults to ALL for stop commands; use NONE to specify no suffix) []
W,wds                             Enable WDS mode (nl80211 only)
lock-timeout=                     How long, in seconds, to wait for another /bin/wifi process to finish before giving up. [60]
scan-ap-force                     (Scan only) scan when in AP mode
scan-passive                      (Scan only) do not probe, scan passively
scan-freq=                        (Scan only) limit scan to specific frequencies.
supports-provisioning             Indicate via vendor IE that this AP supports provisioning.  Corresponds to feature ID 01 of OUI f4f5e8 at go/alphabet-ie-registry.
no-band-restriction               For setclient only.  If set, let --band select the wifi radio but do not actually enforce it for multi-band radios.
"""

_FINGERPRINTS_DIRECTORY = '/tmp/wifi/fingerprints'
_LOCKFILE = '/tmp/wifi/wifi'
_PLATFORM_FILE = '/etc/platform'
lockfile_taken = False


# pylint: disable=protected-access
subprocess.call(('mkdir', '-p', utils._CONFIG_DIR))


def _stop_hostapd(interface):
  """Stops hostapd from running on the given interface.

  Also removes the pid file, sets them interface down and deletes the monitor
  interface, if it exists.

  Args:
    interface: The interface on which to stop hostapd.

  Returns:
    Whether hostapd was successfully stopped and cleaned up.
  """
  if not _is_hostapd_running(interface):
    utils.log('hostapd already not running.')
    return True

  config_filename = utils.get_filename(
      'hostapd', utils.FILENAME_KIND.config, interface, tmp=True)
  pid_filename = utils.get_filename(
      'hostapd', utils.FILENAME_KIND.pid, interface, tmp=True)
  if not utils.kill_pid('hostapd .* %s$' % config_filename, pid_filename):
    return False

  # TODO(apenwarr): hostapd doesn't always delete interface mon.$ifc.  Then it
  # gets confused by the fact that it already exists.  Let's help out.  We
  # should really fix this by eliminating the need for hostapd to have a
  # monitor interface at all (which is deprecated anyway) Remove this line when
  # our hostapd no longer needs a monitor interface.
  utils.subprocess_quiet(('iw', 'dev', 'mon.%s' % interface, 'del'))

  subprocess.check_call(('ip', 'link', 'set', interface, 'down'))

  return True


def _stop_wpa_supplicant(interface):
  """Stops wpa_supplicant from running on the given interface.

  Also removes the pid file and sets the interface down.

  Args:
    interface: The interface on which to stop wpa_supplicant.

  Returns:
    Whether wpa_supplicant was successfully stopped.
  """
  if not _is_wpa_supplicant_running(interface):
    utils.log('wpa_supplicant already not running.')
    return True

  pid_filename = utils.get_filename(
      'wpa_supplicant', utils.FILENAME_KIND.pid, interface, tmp=True)
  config_filename = utils.get_filename(
      'wpa_supplicant', utils.FILENAME_KIND.config, interface, tmp=True)
  if not utils.kill_pid('wpa_supplicant .* %s$' % config_filename,
                        pid_filename):
    return False

  try:
    subprocess.check_call(('ip', 'link', 'set', interface, 'down'))
  except subprocess.CalledProcessError:
    return False

  return True


def _set_wifi_broadcom(opt):
  """Set up wifi using wl, for Broadcom chips.

  Args:
    opt: The OptDict parsed from command line options.

  Raises:
    BinWifiException: On various errors.
  """
  def wl(*args):
    utils.log('wl %s', ' '.join(args))
    subprocess.check_call(('wl') + list(args))

  utils.log('Configuring broadcom wifi.')
  wl('radio', 'on')
  wl('down')
  wl('ssid', '')
  band = opt.band
  if opt.channel != 'auto':
    band = 'auto'
  try:
    wl('band', {'2.4': 'b', '5': 'a', 'auto': 'auto'}[band])
  except KeyError:
    raise utils.BinWifiException('Invalid band %s', band)

  wl('ap', '0')
  wl('up')
  if opt.channel == 'auto':
    # We can only run autochannel when ap=0, but setting ap=1 later will wipe
    # the value.  So we have to capture the autochannel setting, then set it
    # later.  'wl autochannel 2' is thus useless.
    wl('autochannel', '1')
    # enough time to scan all the 2.4 or 5 GHz channels at 100ms each
    time.sleep(3)
    utils.log('wl autochannel')
    channel = subprocess.check_output(('wl', 'autochannel')).split()[0]

  wl('ap', '1')
  wl('chanspec', channel)
  wl('auth', '0')
  wl('infra', '1')
  try:
    wl('wsec', {'_AES': '4',
                'TKIP': '2',
                'WEP': '1',
                'NONE': '0'}[opt.encryption[-4:]])
  except KeyError:
    raise utils.BinWifiException('invalid crypto %s', opt.encryption)
  wl('sup_wpa', '1')
  try:
    wl('wpa_auth',
       {'WPA_': '4',
        'WPA2': '128',
        'WEP': '0',
        'NONE': '0'}[opt.encryption[:4]])
  except KeyError:
    raise utils.BinWifiException('invalid crypto %s', opt.encryption)

  wl('up')
  if '_PSK_' in opt.encryption:
    # WPA keys must be added *before* setting the SSID
    wl('set_pmk', os.environ['WIFI_PSK'])
    wl('ssid', opt.ssid)
  elif opt.encryption == 'WEP':
    # WEP keys must be added *after* setting the SSID
    wl('ssid', opt.ssid)
    wl('set_pmk', os.environ['WIFI_PSK'])
  elif opt.encryption == 'NONE':
    wl('ssid', opt.ssid)
  else:
    raise utils.BinWifiException('invalid crypto %s', opt.encryption)


def set_wifi(opt):
  """Set up an access point in response to the 'set' command.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    Whether setting up the AP succeeded.

  Raises:
    BinWifiException: On various errors.
  """
  band = opt.band
  width = opt.width
  channel = opt.channel
  autotype = opt.autotype
  protocols = set(opt.protocols.split('/'))

  utils.validate_set_wifi_options(opt)

  psk = None
  if opt.encryption == 'WEP' or '_PSK_' in opt.encryption:
    psk = os.environ['WIFI_PSK']

  if band == '5' and  quantenna.set_wifi(opt):
    return True

  if iw.RUNNABLE_WL() and not iw.RUNNABLE_IW():
    _set_wifi_broadcom(opt)
    return True

  if not iw.RUNNABLE_IW():
    raise utils.BinWifiException("Can't proceed without iw")

  # If this phy is running client mode, we need to use its width/channel.
  phy = iw.find_phy(band, channel)
  if phy is None:
    raise utils.BinWifiException(
        'no wifi phy for band=%s channel=%s', band, channel)

  # Check for calibration errors on ath10k.
  qca9880_cal.qca8990_calibration()
  mwifiex.set_recovery(experiment.enabled('MwifiexFirmwareRecovery'))

  client_interface = iw.find_interface_from_phy(
      phy, iw.INTERFACE_TYPE.client, opt.interface_suffix)
  if (client_interface is not None and
      _is_wpa_supplicant_running(client_interface)):
    # Wait up to ten seconds for interface width and channel to be available
    # (only relevant if wpa_supplicant was started recently).
    # TODO(rofrankel): Consider shortcutting this loop if wpa_cli shows status
    # is SCANNING (and other values)?
    utils.log('Client running on same band; finding its width and channel.')
    for _ in xrange(50):
      client_band = _get_wpa_band(client_interface)
      client_width, client_channel = iw.find_width_and_channel(client_interface)

      sys.stderr.write('.')
      if None not in (client_band, client_width, client_channel):
        band, width, channel = client_band, client_width, client_channel
        utils.log('Using band=%s, channel=%s, width=%s MHz from client',
                  band, channel, width)
        break
      time.sleep(0.2)
    else:
      utils.log("Couldn't find band, width, and channel used by client "
                "(it may not be connected)")

  interface = iw.find_interface_from_phy(
      phy, iw.INTERFACE_TYPE.ap, opt.interface_suffix)
  if interface is None:
    raise utils.BinWifiException(
        'no wifi interface found for band=%s channel=%s suffix=%s',
        band, channel, opt.interface_suffix)

  for ap_interface in iw.find_all_interfaces_from_phy(phy,
                                                      iw.INTERFACE_TYPE.ap):
    if not _is_hostapd_running(ap_interface):
      continue

    if ap_interface == interface:
      continue

    # TODO(rofrankel):  Figure out what to do about width.  Unlike channel,
    # there's no 'auto' default; we don't know if 20 was requested or just
    # defaulted to.  So it's not clear whether to override the other AP's
    # choice.
    _, other_ap_channel = iw.find_width_and_channel(ap_interface)
    if channel == 'auto':
      channel = other_ap_channel
    else:
      _restart_hostapd(ap_interface, '-c', channel)

  utils.log('interface: %s', interface)
  utils.log('Configuring cfg80211 wifi.')

  pid_filename = utils.get_filename(
      'hostapd', utils.FILENAME_KIND.pid, interface, tmp=True)
  utils.log('pidfile: %s', pid_filename)

  autotype_filename = '/tmp/autotype.%s' % interface
  band_filename = '/tmp/band.%s' % interface
  width_filename = '/tmp/width.%s' % interface
  autochan_filename = '/tmp/autochan.%s' % interface

  old_autotype = utils.read_or_empty(autotype_filename)
  old_band = utils.read_or_empty(band_filename)
  old_width = utils.read_or_empty(width_filename)

  # Special case: if autochannel enabled and we've done it before, just use the
  # old autochannel.  The main reason for this is we may not be able to run the
  # autochannel algorithm without stopping hostapd first, which defeats the code
  # that tries not to restart hostapd unnecessarily.
  if (channel == 'auto'
      and (autotype, band, width) == (old_autotype, old_band, old_width)):
    # ...but only if not forced mode.  If it's forced, don't use the old
    # value, but don't wipe it either.
    if not opt.force_restart:
      autochan = utils.read_or_empty(autochan_filename)
      if autochan and int(autochan) > 0:
        utils.log('Reusing old autochannel=%s', autochan)
        channel = autochan
  else:
    # forget old autochannel setting
    if os.path.exists(autochan_filename):
      try:
        os.remove(autochan_filename)
      except OSError:
        utils.log('Failed to remove autochan file.')

  if channel == 'auto':
    utils.atomic_write(autochan_filename, '')
    try:
      channel = autochannel.scan(interface, band, autotype, width)
    except ValueError as e:
      raise utils.BinWifiException('Autochannel scan failed: %s', e)
    utils.atomic_write(autochan_filename, channel)

  utils.atomic_write(autotype_filename, autotype)
  utils.atomic_write(band_filename, band)
  utils.atomic_write(width_filename, width)

  utils.log('using channel=%s', channel)

  try:
    utils.log('getting phy info...')
    with open(os.devnull, 'w') as devnull:
      try:
        phy_info = subprocess.check_output(('iw', 'phy', phy, 'info'),
                                           stderr=devnull)
      except subprocess.CalledProcessError as e:
        raise utils.BinWifiException(
            'Failed to get phy info for phy %s: %s', phy, e)
    hostapd_config = configs.generate_hostapd_config(
        phy_info, interface, band, channel, width, protocols, psk, opt)
  except ValueError as e:
    raise utils.BinWifiException('Invalid option: %s', e)

  return _maybe_restart_hostapd(interface, hostapd_config, opt)


@iw.requires_iw
def stop_wifi(opt):
  return stop_client_wifi(opt) and stop_ap_wifi(opt)


def stop_ap_wifi(opt):
  """Disable an access point in response to the 'setap' command.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    Whether disabling the AP succeeded.

  Raises:
    BinWifiException: If an expected interface is not found.
  """
  success = True
  for band in opt.band.split():
    utils.log('stopping AP for %s GHz...', band)

    if band == '5' and quantenna.stop_ap_wifi(opt):
      continue

    interfaces = []
    if opt.interface_suffix == 'ALL':
      interfaces = iw.find_all_interfaces_from_band(band, iw.INTERFACE_TYPE.ap)
    else:
      interface = iw.find_interface_from_band(
          band, iw.INTERFACE_TYPE.ap, opt.interface_suffix)
      if interface:
        interfaces = [interface]
    if not interfaces:
      utils.log('No AP interfaces for %s GHz; nothing to stop', band)
      continue

    for interface in interfaces:
      if _stop_hostapd(interface):
        if opt.persist:
          persist.delete_options('hostapd', interface)
      else:
        utils.log('Failed to stop hostapd on interface %s', interface)
        success = False

  return success


@iw.requires_iw
def _restore_wifi(interface, program):
  """Restore a program from persisted settings.

  Args:
    interface: The interface on which to restore program.
    program: The program to restore (wpa_supplicant or hostapd).

  Returns:
    Whether restoring succeeded.
  """
  argv = persist.load_options(program, interface, False)
  if argv is None:
    utils.log('No persisted options for %s %s, not restoring',
              interface, program)
    return False

  utils.log('Loaded persisted options for %s %s', interface, program)

  if _run(argv):
    utils.log('Restored %s for %s', program, interface)
    return True

  utils.log('Failed to restore %s for %s', program, interface)
  return False


def restore_wifi(opt):
  """Restore hostapd and wpa_supplicant on both bands from persisted settings.

  Nothing happens if persisted settings are not available.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    True.
  """
  # If both bands are specified, restore 5 GHz first so that STAs are more
  # likely to join it.
  restored = set()
  for band in sorted(opt.band.split(),
                     reverse=not experiment.enabled('WifiReverseBandsteering')):
    client_interface = iw.find_interface_from_band(band,
                                                   iw.INTERFACE_TYPE.client,
                                                   opt.interface_suffix)
    ap_interface = iw.find_interface_from_band(band, iw.INTERFACE_TYPE.ap,
                                               opt.interface_suffix)
    for interface, program in ((client_interface, 'wpa_supplicant'),
                               (ap_interface, 'hostapd')):
      if interface and interface not in restored:
        restored.add(interface)
        _restore_wifi(interface, program)
  return True


# TODO(apenwarr): Extend this to notice actual running settings.
#  Including whether hostapd is up or down, etc.
# TODO(rofrankel): Extend this to show client interface info.
@iw.requires_iw
def show_wifi(opt):
  """Prints information about wifi interfaces on this device.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    True.
  """
  for band in opt.band.split():
    print('Band: %s' % band)
    for tokens in utils.subprocess_line_tokens(('iw', 'reg', 'get')):
      if len(tokens) >= 2 and tokens[0] == 'country':
        print('RegDomain: %s' % tokens[1].strip(':'))
        break

    for prefix, interface_type in (('', iw.INTERFACE_TYPE.ap),
                                   ('Client ', iw.INTERFACE_TYPE.client)):
      interface = iw.find_interface_from_band(
          band, interface_type, opt.interface_suffix)
      if interface is None:
        continue
      print('%sInterface: %s  # %s GHz %s' %
            (prefix, interface, band, 'client' if 'cli' in interface else 'ap'))

      info_parsed = iw.info_parsed(interface)
      for k, label in (('channel', 'Channel'),
                       ('ssid', 'SSID'),
                       ('addr', 'BSSID')):
        v = info_parsed.get(k, None)
        if v is not None:
          print('%s%s: %s' % (prefix, label, v))

      if interface_type == iw.INTERFACE_TYPE.ap:
        print('AutoChannel: %r' %
              os.path.exists('/tmp/autochan.%s' % interface))
        try:
          with open('/tmp/autotype.%s' % interface) as autotype:
            print('AutoType: %s' % autotype.read().strip())
        except IOError:
          pass

        print('Station List for band: %s' % band)
        station_dump = iw.station_dump(interface)
        if station_dump:
          print(station_dump)

      print()

  return True


@iw.requires_iw
def scan_wifi(opt):
  """Prints 'iw scan' results.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    True.

  Raises:
    BinWifiException: If an expected interface is not found.
  """
  band = opt.band.split()[0]

  if band == '5' and quantenna.scan_wifi(opt):
    return True

  interface = iw.find_interface_from_band(
      band, iw.INTERFACE_TYPE.ap, opt.interface_suffix)
  if interface is None:
    raise utils.BinWifiException('No client interface for band %s', band)

  scan_args = []
  if opt.scan_freq:
    scan_args += ['freq', str(opt.scan_freq)]
  if opt.scan_ap_force:
    scan_args += ['ap-force']
  if opt.scan_passive:
    scan_args += ['passive']

  print(iw.scan(interface, scan_args))

  return True


def _is_hostapd_running(interface):
  return utils.subprocess_quiet(
      ('hostapd_cli', '-i', interface, 'quit'), no_stdout=True) == 0


def _wpa_cli(program, interface, command):
  return utils.subprocess_quiet(
      (program, '-i', interface, command), no_stdout=True) == 0


def _is_wpa_supplicant_running(interface):
  return _wpa_cli('wpa_cli', interface, 'status')


def _reconfigure_wpa_supplicant(interface):
  if not _wpa_cli('wpa_cli', interface, 'reconfigure'):
    return False

  return _wait_for_wpa_supplicant_to_associate(interface)


def _hostapd_debug_options():
  if experiment.enabled('WifiHostapdDebug'):
    return ['-d']
  else:
    return []


def _get_hostapd_band(interface):
  for line in utils.subprocess_lines(
      ('hostapd_cli', '-i', interface, 'status')):
    tokens = line.split('=')
    if tokens and tokens[0] == 'freq':
      try:
        return {'5': '5', '2': '2.4'}[tokens[1][0]]
      except (IndexError, KeyError):
        return None


def _is_wind_charger():
  try:
    etc_platform = open(_PLATFORM_FILE).read()
    if etc_platform[:-1] == 'GFMN100':
      return True
    else:
      return False
  except IOError as e:
    print('_is_wind_charger: cant open %s: %s' % (_PLATFORM_FILE, e.strerror))
    return False


def _start_hostapd(interface, config_filename, band, ssid):
  """Starts a babysat hostapd.

  Args:
    interface: The interface on which to start hostapd.
    config_filename: The filename of the hostapd configuration.
    band: The band on which hostapd is being started.
    ssid: The SSID with which hostapd is being started.

  Returns:
    Whether hostapd was started successfully.
  """
  aggfiles = glob.glob('/sys/kernel/debug/ieee80211/phy*/' +
                       'netdev:%s/default_agg_timeout' % interface)
  if not aggfiles:
    # This can happen on non-mac80211 interfaces.
    utils.log('agg_timeout: no default_agg_timeout files for %r', interface)
  else:
    if experiment.enabled('WifiShortAggTimeout'):
      utils.log('Using short agg_timeout.')
      agg = 500
    elif experiment.enabled('WifiNoAggTimeout'):
      utils.log('Disabling agg_timeout.')
      agg = 0
    else:
      utils.log('Using default long agg_timeout.')
      agg = 5000
    for aggfile in aggfiles:
      open(aggfile, 'w').write(str(agg))

  pid_filename = utils.get_filename(
      'hostapd', utils.FILENAME_KIND.pid, interface, tmp=True)
  alivemonitor_filename = utils.get_filename(
      'hostapd', utils.FILENAME_KIND.alive, interface, tmp=True)

  # Don't use alivemonitor on Windcharger since no waveguide. b/32376077
  if _is_wind_charger() or experiment.enabled('WifiNoAliveMonitor'):
    alive_monitor = []
  else:
    alive_monitor = ['alivemonitor', alivemonitor_filename, '30', '2', '65']

  utils.log('Starting hostapd.')
  utils.babysit(alive_monitor +
                ['hostapd',
                 '-A', alivemonitor_filename,
                 '-F', _FINGERPRINTS_DIRECTORY] +
                bandsteering.hostapd_options(band, ssid) +
                _hostapd_debug_options() +
                [config_filename],
                'hostapd-%s' % interface, 10, pid_filename)

  # Wait for hostapd to start, and return False if it doesn't.
  for _ in xrange(40):
    if utils.check_pid(pid_filename):
      break
    sys.stderr.write('.')
    time.sleep(0.1)
  else:
    return False

  # hostapd_cli returns success on command timeouts.  If we time this
  # perfectly and manage to connect but then wpa_supplicant dies right after,
  # we'd think it succeeded.  So sleep a bit to try to give wpa_supplicant a
  # chance to die from its error before we try to connect to it.
  time.sleep(0.5)
  for _ in xrange(10):
    if not utils.check_pid(pid_filename):
      break
    if _is_hostapd_running(interface):
      utils.log('ok')
      return True
    sys.stderr.write('.')
    time.sleep(0.1)

  return False


def _get_wpa_state(interface):
  for line in utils.subprocess_lines(('wpa_cli', '-i', interface, 'status')):
    tokens = line.split('=')
    if tokens and tokens[0] == 'wpa_state':
      return tokens[1]


def _get_wpa_band(interface):
  for line in utils.subprocess_lines(('wpa_cli', '-i', interface, 'status')):
    tokens = line.split('=')
    if tokens and tokens[0] == 'freq':
      try:
        return {'5': '5', '2': '2.4'}[tokens[1][0]]
      except (IndexError, KeyError):
        return None


def _wait_for_wpa_supplicant_to_associate(interface):
  """Wait for wpa_supplicant to associate.

  If it does not associate within a certain period of time, terminate it.

  Args:
    interface: The interface on which wpa_supplicant is running.

  Raises:
    BinWifiException: if wpa_supplicant fails to associate and
    also cannot be stopped to cleanup after the failure.

  Returns:
    Whether wpa_supplicant associated within the timeout.
  """
  utils.log('Waiting for wpa_supplicant to connect')
  for _ in xrange(100):
    if _get_wpa_state(interface) == 'COMPLETED':
      utils.log('ok')
      return True
    sys.stderr.write('.')
    time.sleep(0.1)

  utils.log('wpa_supplicant did not connect.')
  if not _stop_wpa_supplicant(interface):
    raise utils.BinWifiException(
        "Couldn't stop wpa_supplicant after it failed to connect.  "
        "Consider killing it manually.")

  return False


def _start_wpa_supplicant(interface, config_filename):
  """Starts a babysat wpa_supplicant.

  Args:
    interface: The interface on which to start wpa_supplicant.
    config_filename: The filename of the wpa_supplicant configuration.

  Raises:
    BinWifiException: if wpa_supplicant fails to connect and
    also cannot be stopped to cleanup after the failure.

  Returns:
    Whether wpa_supplicant was started successfully.
  """
  pid_filename = utils.get_filename(
      'wpa_supplicant', utils.FILENAME_KIND.pid, interface, tmp=True)

  utils.log('Starting wpa_supplicant.')
  utils.babysit(['wpa_supplicant',
                 '-Dnl80211',
                 '-i', interface,
                 '-c', config_filename] +
                _hostapd_debug_options(),
                'wpa_supplicant-%s' % interface, 10, pid_filename)

  # Wait for wpa_supplicant to start, and return False if it doesn't.
  for _ in xrange(10):
    if utils.check_pid(pid_filename):
      break
    sys.stderr.write('.')
    time.sleep(0.1)
  else:
    return False

  # wpa_supplicant_cli returns success on command timeouts.  If we time this
  # perfectly and manage to connect but then wpa_supplicant dies right after,
  # we'd think it succeeded.  So sleep a bit to try to give wpa_supplicant a
  # chance to die from its error before we try to connect to it.
  time.sleep(0.5)

  for _ in xrange(50):
    if not utils.check_pid(pid_filename):
      utils.log('wpa_supplicant process died.')
      return False
    if _is_wpa_supplicant_running(interface):
      break
    sys.stderr.write('.')
    time.sleep(0.1)
  else:
    return False

  return _wait_for_wpa_supplicant_to_associate(interface)


def _maybe_restart_hostapd(interface, config, opt):
  """Starts or restarts hostapd unless doing so would be a no-op.

  The no-op case (i.e. hostapd is already running with an equivalent config) can
  be overridden with --force-restart.

  Args:
    interface: The interface on which to start hostapd.
    config: A hostapd configuration, as a string.
    opt: The OptDict parsed from command line options.

  Returns:
    Whether hostapd was started successfully.

  Raises:
    BinWifiException: On various errors.
  """
  tmp_config_filename = utils.get_filename(
      'hostapd', utils.FILENAME_KIND.config, interface, tmp=True)
  forced = False
  current_config = None

  try:
    with open(tmp_config_filename) as tmp_config_file:
      current_config = tmp_config_file.read()
  except IOError:
    pass

  if not _is_hostapd_running(interface):
    utils.log('hostapd not running yet, starting.')
  elif current_config != config:
    utils.log('hostapd config changed, restarting.')
  elif opt.force_restart:
    utils.log('Forced restart requested.')
    forced = True
  else:
    utils.log('hostapd-%s already configured and running', interface)
    return True

  if not _stop_hostapd(interface):
    raise utils.BinWifiException("Couldn't stop hostapd")

  # Set or unset 4-address mode.  This has to be done while hostapd is down.
  utils.log('%s 4-address mode', 'Enabling' if opt.wds else 'Disabling')
  iw.set_4address_mode(interface, opt.wds)

  # We don't want to try to rewrite this file if this is just a forced restart.
  if not forced:
    utils.atomic_write(tmp_config_filename, config)

  if not _start_hostapd(interface, tmp_config_filename, opt.band, opt.ssid):
    utils.log('hostapd failed to start.  Look at hostapd logs for details.')
    return False

  return True


def _restart_hostapd(interface, *overrides):
  """Restart hostapd from previous options.

  Only used by _set_wpa_supplicant_config, to restart hostapd after stopping it.

  Args:
    interface: The interface on which to restart hostapd.
    *overrides:  A list of options to override the pre-existing ones.

  Returns:
    Whether hostapd was successfully restarted.

  Raises:
    BinWifiException: If reading previous settings fails.
  """
  argv = persist.load_options('hostapd', interface, True) + list(overrides)

  if argv is None:
    raise utils.BinWifiException('Failed to read previous hostapd config')

  _run(argv)


def _set_wpa_supplicant_config(interface, config, opt):
  """Starts or restarts wpa_supplicant unless doing so would be a no-op.

  The no-op case (i.e. wpa_supplicant is already running with an equivalent
  config) can be overridden with --force-restart.

  Args:
    interface: The interface on which to start wpa_supplicant.
    config: A wpa_supplicant configuration, as a string.
    opt: The OptDict parsed from command line options.

  Returns:
    Whether wpa_supplicant was started successfully.

  Raises:
    BinWifiException: On various errors.
  """
  tmp_config_filename = utils.get_filename(
      'wpa_supplicant', utils.FILENAME_KIND.config, interface, tmp=True)
  forced = False
  current_config = None
  band = opt.band

  try:
    with open(tmp_config_filename) as tmp_config_file:
      current_config = tmp_config_file.read()
  except IOError:
    pass

  already_running = _is_wpa_supplicant_running(interface)
  if not already_running:
    utils.log('wpa_supplicant not running yet, starting.')
  elif current_config != config:
    # TODO(rofrankel): Consider using wpa_cli reconfigure here.
    utils.log('wpa_supplicant config changed, reconfiguring.')
  elif opt.force_restart:
    utils.log('Forced restart requested.')
    forced = True
  else:
    utils.log('wpa_supplicant-%s already configured and running', interface)
    return True

  if not forced:
    utils.atomic_write(tmp_config_filename, config)

  # TODO(rofrankel): Consider removing all the restart hostapd stuff when
  # b/30140131 is resolved.  hostapd seems to keep working without being
  # restarted, at least on Camaro.
  restart_hostapd = False
  ap_interface = iw.find_interface_from_band(band, iw.INTERFACE_TYPE.ap,
                                             opt.interface_suffix)
  if _is_hostapd_running(ap_interface):
    restart_hostapd = True
    opt_without_persist = options.OptDict({})
    opt_without_persist.persist = False
    opt_without_persist.band = opt.band
    opt_without_persist.interface_suffix = opt.interface_suffix
    if not stop_ap_wifi(opt_without_persist):
      raise utils.BinWifiException(
          "Couldn't stop hostapd to start wpa_supplicant.")

  if already_running:
    subprocess.check_call(['ifdown', interface])
    subprocess.check_call(['/etc/ifplugd/ifplugd.action', interface, 'down'])
    if not _reconfigure_wpa_supplicant(interface):
      raise utils.BinWifiException('Failed to reconfigure wpa_supplicant.')
    subprocess.check_call(['ifup', interface])
    subprocess.check_call(['/etc/ifplugd/ifplugd.action', interface, 'up'])
  elif not _start_wpa_supplicant(interface, tmp_config_filename):
    raise utils.BinWifiException(
        'wpa_supplicant failed to start.  Look at wpa_supplicant logs for '
        'details.')

  if restart_hostapd:
    _restart_hostapd(ap_interface)

  return True


@iw.requires_iw
def client_interface_name(phy, interface_suffix):
  ap_interface = iw.find_interface_from_phy(phy, iw.INTERFACE_TYPE.ap,
                                            interface_suffix)
  if ap_interface:
    return 'w%s%s' % (iw.INTERFACE_TYPE.client,
                      re.match(r'[^0-9]+([0-9]+)$', ap_interface).group(1))
  else:
    return None


@iw.requires_iw  # Client mode not supported on Broadcom.
def set_client_wifi(opt):
  """Set up a wifi client in response to the 'setclient' command.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    Whether wpa_supplicant successfully started and associated.

  Raises:
    BinWifiException: On various errors.
  """
  if not opt.ssid:
    raise utils.BinWifiException('You must specify an ssid with --ssid')

  band = opt.band
  if band not in ('2.4', '5'):
    raise utils.BinWifiException('You must specify band with -b2.4 or -b5')

  psk = os.environ.get('WIFI_CLIENT_PSK', None)

  if band == '5' and quantenna.set_client_wifi(opt):
    return True

  mwifiex.set_recovery(experiment.enabled('MwifiexFirmwareRecovery'))

  phy = iw.find_phy(band, 'auto')
  if phy is None:
    utils.log("Couldn't find phy for band %s", band)
    return False

  interface = iw.find_interface_from_phy(phy, iw.INTERFACE_TYPE.client,
                                         opt.interface_suffix)

  if interface is None:
    # Create the client interface if it does not exist, using the same number as
    # an existing AP interface, which is stable across driver reloads.
    interface = client_interface_name(phy, opt.interface_suffix)
    if interface is None:
      raise utils.BinWifiException('AP interface not initialized for %s' % phy)

    if not iw.does_interface_exist(interface):
      utils.log('Creating client interface %s', interface)
      utils.subprocess_quiet(
          ('iw', 'phy', phy, 'interface', 'add', interface, 'type', 'station'),
          no_stdout=True)
      ap_mac_address = utils.get_mac_address_for_interface(
          iw.find_interface_from_phy(
              phy, iw.INTERFACE_TYPE.ap,
              opt.interface_suffix))
      mac_address = utils.increment_mac_address(ap_mac_address)
      subprocess.check_call(
          ('ip', 'link', 'set', interface, 'address', mac_address))

  wpa_config = configs.generate_wpa_supplicant_config(opt.ssid, psk, opt)
  if not _set_wpa_supplicant_config(interface, wpa_config, opt):
    return False

  return True


@iw.requires_iw  # Client mode not supported on Broadcom.
def stop_client_wifi(opt):
  """Disable a wifi client in response to the 'stopclient' command.

  Args:
    opt: The OptDict parsed from command line options.

  Returns:
    Whether wpa_supplicant was successfully stopped on all bands specified by
    opt.band.
  """
  success = True
  for band in opt.band.split():
    utils.log('stopping client for %s GHz...', band)

    if band == '5' and quantenna.stop_client_wifi(opt):
      continue

    interfaces = iw.find_interfaces_from_band_and_suffix(
        band, opt.interface_suffix, iw.INTERFACE_TYPE.client)
    if not interfaces:
      utils.log('No client interfaces for %s GHz; nothing to stop', band)
      continue

    for interface in interfaces:
      if _stop_wpa_supplicant(interface):
        if opt.persist:
          persist.delete_options('wpa_supplicant', interface)
      else:
        utils.log('Failed to stop wpa_supplicant on interface %s', interface)
        success = False

  return success


def stringify_options(optdict):
  for option in ('channel', 'width', 'band', 'ssid'):
    optdict.__setitem__(option, str(optdict.__getitem__(option)))


def _run(argv):
  """Runs a wifi command.

  This is the main entry point of the script, and is called by the main function
  and also by commands which need to run other commands (e.g. restore).

  Args:
    argv: A list containing a command and a series of options, e.g.
    sys.argv[1:].

  Returns:
    Whether the command succeeded.

  Raises:
    BinWifiException: On file write failures.
  """
  global lockfile_taken

  serial = 'UNKNOWN'
  try:
    serial = subprocess.check_output(('serial')).strip()
  except subprocess.CalledProcessError:
    utils.log('Could not get serial number')

  optspec = _OPTSPEC_FORMAT.format(
      bin=__file__.split('/')[-1], ssid='%s_TestWifi' % serial)
  parser = options.Options(optspec)
  opt, _, extra = parser.parse(argv)
  stringify_options(opt)

  if not extra:
    parser.fatal('Must specify a command (see usage for details).')
    return 1

  command = extra[0]

  # set and setclient have a different default for -b.
  if command.startswith('set') and ' ' in opt.band:
    opt.band = '2.4'

  if command == 'off' or command.startswith('stop'):
    if not opt.interface_suffix:
      opt.interface_suffix = 'ALL'
    elif opt.interface_suffix == 'NONE':
      opt.interface_suffix = ''

  try:
    function = {
        'set': set_wifi,
        'stop': stop_wifi,
        'off': stop_wifi,
        'restore': restore_wifi,
        'show': show_wifi,
        'setclient': set_client_wifi,
        'stopclient': stop_client_wifi,
        'stopap': stop_ap_wifi,
        'scan': scan_wifi,
    }[command]
  except KeyError:
    parser.fatal('Unrecognized command %s' % command)

  read_only_commands = ('show',)

  if command not in read_only_commands:
    if not lockfile_taken:
      utils.lock(_LOCKFILE, int(opt.lock_timeout))
      atexit.register(utils.unlock, _LOCKFILE)
      lockfile_taken = True

  success = function(opt)

  if success:
    if command in ('set', 'setclient'):
      if command == 'set':
        program = 'hostapd'
        interface_type = iw.INTERFACE_TYPE.ap
      else:
        program = 'wpa_supplicant'
        interface_type = iw.INTERFACE_TYPE.client
      interface = iw.find_interface_from_band(opt.band, interface_type,
                                              opt.interface_suffix)
      if opt.persist:
        # Save in /fiber/config.
        persist.save_options(program, interface, argv, False)
      # Save in /tmp.
      persist.save_options(program, interface, argv, True)

  return success


def main():
  try:
    return 0 if _run(sys.argv[1:]) else 1
  except iw.RequiresIwException as e:
    utils.log('NOOP: %s', e)
    return 0
  except utils.BinWifiException as e:
    utils.log('FATAL: %s', e)
    return 99
  except subprocess.CalledProcessError as e:
    utils.log('FATAL: subprocess failed unexpectedly: %s', e)
    return 99


if __name__ == '__main__':
  sys.stdout = os.fdopen(1, 'w', 1)  # force line buffering even if redirected
  sys.stderr = os.fdopen(2, 'w', 1)  # force line buffering even if redirected
  sys.exit(main())
