/bin/wifi: various Quantenna improvements.

- Support the --encryption flag in AP mode only. In client mode, the
  AP's encryption setting is used.

- Support the --bssid flag.

- Fix 'stopap' and 'stopclient' failure when run before 'startprod'.

- Use 'get_ssid' instead of 'get_bssid'. The latter can sporadically
  return a nonzero result immediately after associating with a wrong
  passphrase.

Change-Id: Ia67ccf68eefe53423e05ac114552aa49cf7af83a
diff --git a/wifi/quantenna.py b/wifi/quantenna.py
index 4724d88..12a2add 100755
--- a/wifi/quantenna.py
+++ b/wifi/quantenna.py
@@ -78,6 +78,9 @@
   if not interface:
     return False
 
+  if opt.encryption == 'WEP':
+    raise utils.BinWifiException('WEP not supported')
+
   if mode == 'scan':
     mode = 'sta'
     scan = True
@@ -102,7 +105,7 @@
   if int(_qcsapi('is_startprod_done')):
     _qcsapi('reload_in_mode', 'wifi0', mode)
   else:
-    _qcsapi('startprod', 'wifi0')
+    _qcsapi('startprod')
     for _ in xrange(30):
       if int(_qcsapi('is_startprod_done')):
         break
@@ -113,24 +116,27 @@
   if mode == 'ap':
     _set_interface_in_bridge(opt.bridge, interface, True)
     _qcsapi('set_ssid', 'wifi0', opt.ssid)
-    _qcsapi('set_passphrase', 'wifi0', 0, os.environ['WIFI_PSK'])
-    _qcsapi('set_option', 'wifi0', 'ssid_broadcast', int(not opt.hidden_mode))
-    _qcsapi('rfenable', 1)
-  elif mode == 'sta' and not scan:
-    _set_interface_in_bridge(opt.bridge, interface, False)
-    _qcsapi('create_ssid', 'wifi0', opt.ssid)
     if opt.encryption == 'NONE':
-      _qcsapi('ssid_set_authentication_mode', 'wifi0', opt.ssid, 'NONE')
-    elif opt.encryption == 'WEP':
-      raise utils.BinWifiException('WEP not supported')
+      _qcsapi('set_beacon_type', 'wifi0', 'Basic')
     else:
       protocol, authentication, encryption = opt.encryption.split('_')
       protocol = {'WPA': 'WPA', 'WPA2': '11i', 'WPA12': 'WPAand11i'}[protocol]
       authentication += 'Authentication'
       encryption += 'Encryption'
-      _qcsapi('ssid_set_proto', 'wifi0', opt.ssid, protocol)
-      _qcsapi('ssid_set_authentication_mode', 'wifi0', opt.ssid, authentication)
-      _qcsapi('ssid_set_encryption_modes', 'wifi0', opt.ssid, encryption)
+      _qcsapi('set_beacon_type', 'wifi0', protocol)
+      _qcsapi('set_wpa_authentication_mode', 'wifi0', authentication)
+      _qcsapi('set_wpa_encryption_modes', 'wifi0', encryption)
+      _qcsapi('set_passphrase', 'wifi0', 0, os.environ['WIFI_PSK'])
+    _qcsapi('set_option', 'wifi0', 'ssid_broadcast', int(not opt.hidden_mode))
+    _qcsapi('rfenable', 1)
+  elif mode == 'sta' and not scan:
+    _set_interface_in_bridge(opt.bridge, interface, False)
+    _qcsapi('create_ssid', 'wifi0', opt.ssid)
+    if opt.bssid:
+      _qcsapi('set_ssid_bssid', 'wifi0', opt.ssid, opt.bssid)
+    if opt.encryption == 'NONE' or not os.environ.get('WIFI_CLIENT_PSK'):
+      _qcsapi('ssid_set_authentication_mode', 'wifi0', opt.ssid, 'NONE')
+    else:
       _qcsapi('ssid_set_passphrase', 'wifi0', opt.ssid, 0,
               os.environ['WIFI_CLIENT_PSK'])
     # In STA mode, 'rfenable 1' is already done by 'startprod'/'reload_in_mode'.
@@ -138,7 +144,7 @@
     _qcsapi('apply_security_config', 'wifi0')
 
     for _ in xrange(10):
-      if _qcsapi('get_bssid', 'wifi0') != '00:00:00:00:00:00':
+      if _qcsapi('get_ssid', 'wifi0'):
         break
       time.sleep(1)
     else:
@@ -189,7 +195,8 @@
   if not _get_interface():
     return False
 
-  if _qcsapi('get_mode', 'wifi0') == 'Access point':
+  if (int(_qcsapi('is_startprod_done')) and
+      _qcsapi('get_mode', 'wifi0') == 'Access point'):
     _qcsapi('rfenable', 0)
 
   return True
@@ -200,7 +207,8 @@
   if not _get_interface():
     return False
 
-  if _qcsapi('get_mode', 'wifi0') == 'Station':
+  if (int(_qcsapi('is_startprod_done')) and
+      _qcsapi('get_mode', 'wifi0') == 'Station'):
     _qcsapi('rfenable', 0)
 
   return True
diff --git a/wifi/quantenna_test.py b/wifi/quantenna_test.py
index e19c76e..ebef2a0 100755
--- a/wifi/quantenna_test.py
+++ b/wifi/quantenna_test.py
@@ -20,9 +20,9 @@
 def fake_qcsapi(*args):
   calls.append([str(x) for x in args])
   if args[0] == 'is_startprod_done':
-    return '1' if ['startprod', 'wifi0'] in calls else '0'
-  if args[0] == 'get_bssid':
-    return '00:11:22:33:44:55'
+    return '1' if ['startprod'] in calls else '0'
+  if args[0] == 'get_ssid':
+    return calls[matching_calls_indices(['set_ssid', 'create_ssid'])[-1]][1]
   if args[0] == 'get_mode':
     i = [c for c in matching_calls_indices(['update_config_param'])
          if calls[c][2] == 'mode']
@@ -126,7 +126,7 @@
 
   # 'update_config_param' and 'set_mac_addr' must be run before 'startprod',
   # since 'startprod' runs scripts that read these configs.
-  sp = calls.index(['startprod', 'wifi0'])
+  sp = calls.index(['startprod'])
   i = matching_calls_indices(['update_config_param', 'set_mac_addr'])
   wvtest.WVPASSLT(i[-1], sp)
 
@@ -161,7 +161,7 @@
   wvtest.WVPASSEQ(calls[1], ['restore_default_config', 'noreboot'])
 
   # Check that 'startprod' is not run.
-  wvtest.WVPASS(['startprod', 'wifi0'] not in calls)
+  wvtest.WVPASS(['startprod'] not in calls)
 
   # Check that configs are written.
   wvtest.WVPASS(['update_config_param', 'wifi0', 'bw', '80'] in calls)