Merge "Change power test utilities."
diff --git a/acts/framework/acts/controllers/ap_lib/hostapd_security.py b/acts/framework/acts/controllers/ap_lib/hostapd_security.py
index 4e1ae3a..9733e99 100644
--- a/acts/framework/acts/controllers/ap_lib/hostapd_security.py
+++ b/acts/framework/acts/controllers/ap_lib/hostapd_security.py
@@ -64,14 +64,15 @@
         else:
             security_mode = None
         self.security_mode = security_mode
-        if len(password) < hostapd_constants.MIN_WPA_PSK_LENGTH or len(
-                password) > hostapd_constants.MAX_WPA_PSK_LENGTH:
-            raise ValueError(
-                'Password must be a minumum of %s characters and a maximum of %s'
-                % (hostapd_constants.MIN_WPA_PSK_LENGTH,
-                   hostapd_constants.MAX_WPA_PSK_LENGTH))
-        else:
-            self.password = password
+        if password:
+            if len(password) < hostapd_constants.MIN_WPA_PSK_LENGTH or len(
+                    password) > hostapd_constants.MAX_WPA_PSK_LENGTH:
+                raise ValueError(
+                    'Password must be a minumum of %s characters and a maximum of %s'
+                    % (hostapd_constants.MIN_WPA_PSK_LENGTH,
+                       hostapd_constants.MAX_WPA_PSK_LENGTH))
+            else:
+                self.password = password
 
     def generate_dict(self):
         """Returns: an ordered dictionary of settings"""
diff --git a/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py b/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py
index abc2563..031ef08 100644
--- a/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py
+++ b/acts/framework/acts/test_utils/wifi/wifi_power_test_utils.py
@@ -20,6 +20,7 @@
 from acts import asserts
 from acts import utils
 from acts.controllers import monsoon
+from acts.libs.proc import job
 from acts.test_utils.wifi import wifi_test_utils as wutils
 from bokeh.layouts import layout
 from bokeh.models import CustomJS, ColumnDataSource
@@ -353,10 +354,13 @@
     log = logging.getLogger()
     bss_settings = []
     ssid = network[wutils.WifiEnums.SSID_KEY]
-    password = network["password"]
+    if "password" in network.keys():
+        password = network["password"]
+        security = hostapd_security.Security(
+            security_mode="wpa", password=password)
+    else:
+        security = hostapd_security.Security(security_mode=None, password=None)
     channel = network["channel"]
-    security = hostapd_security.Security(
-        security_mode="wpa", password=password)
     config = hostapd_ap_preset.create_ap_preset(
         channel=channel,
         ssid=ssid,
@@ -497,6 +501,48 @@
     return None
 
 
+@utils.timeout(60)
+def wait_for_dhcp(intf):
+    """Wait the DHCP address assigned to desired interface.
+
+    Getting DHCP address takes time and the wait time isn't constant. Utilizing
+    utils.timeout to keep trying until success
+
+    Args:
+        intf: desired interface name
+    Returns:
+        ip: ip address of the desired interface name
+    Raise:
+        TimeoutError: After timeout, if no DHCP assigned, raise
+    """
+    log = logging.getLogger()
+    reset_host_interface(intf)
+    ip = '0.0.0.0'
+    while ip == '0.0.0.0':
+        ip = scapy.get_if_addr(intf)
+    log.info('DHCP address assigned to {}'.format(intf))
+    return ip
+
+
+def reset_host_interface(intf):
+    """Reset the host interface.
+
+    Args:
+        intf: the desired interface to reset
+    """
+    log = logging.getLogger()
+    intf_down_cmd = 'ifconfig %s down' % intf
+    intf_up_cmd = 'ifconfig %s up' % intf
+    try:
+        job.run(intf_down_cmd)
+        time.sleep(3)
+        job.run(intf_up_cmd)
+        time.sleep(3)
+        log.info('{} has been reset'.format(intf))
+    except job.Error:
+        raise Exception('No such interface')
+
+
 def create_pkt_config(test_class):
     """Creates the config for generating multicast packets