def get_all_route():
    result = {}
    route = dev.adb_shell(ROUTE_CMD, out=True, quiet=True)
    for iface in (WLAN, RMNET):
        addr = get_route(iface, route)
        if addr:
            result[iface] = addr
    return result
def get_route(iface, route=False):
    if not route:
        route = dev.adb_shell(ROUTE_CMD, out=True, quiet=True)
    if route:
        for line in route:
            if iface in line and not '/' in line:
                return line.split()[0]
    return False
def get_ipv4(iface):
    ip = dev.adb_shell('ip addr show ' + iface, out=True, quiet=True)
    if ip and len(ip) > 2:
        try: # 3th line: '    inet 37.62.66.XXX/29 scope global rmnet0'
            return ip[2].split()[1][:-3]
        except:
            return False
    return False
def get_ipv4(iface):
    ip = dev.adb_shell('ip addr show ' + iface, out=True, quiet=True)
    if ip and len(ip) > 2:
        try:  # 3th line: '    inet 37.62.66.XXX/29 scope global rmnet0'
            return ip[2].split()[1][:-3]
        except:
            return False
    return False
def get_all_route():
    result = {}
    route = dev.adb_shell(ROUTE_CMD, out=True, quiet=True)
    for iface in (WLAN, RMNET):
        addr = get_route(iface, route)
        if addr:
            result[iface] = addr
    return result
def get_route(iface, route=False):
    if not route:
        route = dev.adb_shell(ROUTE_CMD, out=True, quiet=True)
    if route:
        for line in route:
            if iface in line and not '/' in line:
                return line.split()[0]
    return False
def get_default_route():
    route = dev.adb_shell('ip route list 0/0', out=True, quiet=True)
    if route:
        try:  # default via 192.168.0.1 dev wlan0
            route_split = route[0].split()
            return (route_split[4], route_split[2])
        except:
            return False
    return route
def get_default_route():
    route = dev.adb_shell('ip route list 0/0', out=True, quiet=True)
    if route:
        try: # default via 192.168.0.1 dev wlan0
            route_split = route[0].split()
            return (route_split[4], route_split[2])
        except:
            return False
    return route
def sysctl(key, value=False):
    if value:
        arg = '-w ' + key + '=' + str(value)
        my_print("Sysctl: write: " + key + ' = ' + str(value))
        return dev.adb_shell_root("sysctl " + arg)
    else:
        my_print("Sysctl: read: " + key)
        out = dev.adb_shell("sysctl " + key, out=True)
        if not out:
            return out
        return out[0][len(key) + 3:]
def sysctl(key, value=False):
    if value:
        arg = '-w ' + key + '=' + str(value)
        my_print("Sysctl: write: " + key + ' = ' + str(value))
        return dev.adb_shell_root("sysctl " + arg)
    else:
        my_print("Sysctl: read: " + key)
        out = dev.adb_shell("sysctl " + key, out=True)
        if not out:
            return out
        return out[0][len(key)+3:]
def multipath_control(action='enable', path_mgr='default', rr=False):
    dev.stop_proxy() ## prevent error when enabling mptcp
    my_print("Multipath Control: " + action)
    for i in range(5):
        rc = dev.adb_shell(False, uiautomator='multipath_control', args='action ' + action)
        if rc:
            break
        else:
            my_print_err("Error with multipath control, wait 5 sec and retry")
            time.sleep(5)
    rc &= mptcp_path_manager(path_mgr)
    rc &= mptcp_round_robin(rr)
    return rc
def multipath_control(action='enable', path_mgr='default', rr=False):
    dev.stop_proxy()  ## prevent error when enabling mptcp
    my_print("Multipath Control: " + action)
    for i in range(5):
        rc = dev.adb_shell(False,
                           uiautomator='multipath_control',
                           args='action ' + action)
        if rc:
            break
        else:
            my_print_err("Error with multipath control, wait 5 sec and retry")
            time.sleep(5)
    rc &= mptcp_path_manager(path_mgr)
    rc &= mptcp_round_robin(rr)
    return rc
def connect_to_proxy():
    for i in range(5):
        if s.WITH_SHADOWSOCKS:
            my_print("Using ShadowSocks:")
            if s.SSH_TUNNEL_INSTALLED:
                my_print("stop + kill SSHTunnel")
                # Stop + kill ssh_tunnel
                dev.adb_shell(False, uiautomator='ssh_tunnel', args='action stopnotautoconnect')
                dev.adb_shell_root("am force-stop org.sshtunnel")
            my_print("start + autoconnect ShadowSocks")
            # Start shadown socks with autoconnect (in case of random reboot)
            if not dev.adb_shell(False, uiautomator='shadow_socks', args='action startautoconnect'):
                my_print_err('Not able to start shadowsocks...')
                time.sleep(5)
            else:
                break
        elif s.WITH_SSH_TUNNEL:
            if s.SHADOWSOCKS_INSTALLED:
                my_print("Using SSHTunnel: stop + kill ShadowSocks")
                # Stop + kill ShadowSocks
                dev.adb_shell(False, uiautomator='shadow_socks', args='action stopnotautoconnect')
                dev.adb_shell_root("am force-stop com.github.shadowsocks")
            my_print("start + autoconnect sshtunnel")
            # Start shadown socks with autoconnect (in case of random reboot)
            if not dev.adb_shell(False, uiautomator='ssh_tunnel', args='action startautoconnect'):
                my_print_err('Not able to start sshtunnel...')
                time.sleep(5)
            else:
                break
        else:
            break

        if i == 2:
            my_print_err('Not able to start proxy client: reboot')
            dev.adb_reboot()

        elif i == 4:
            my_print_err('Not able to start proxy client: exit')
            sys.exit(1)
    dev.adb_check_reboot()
    if g.LAST_UPTIME:
        break
    if i == 2:
        my_print_err('Not able to contact the device: reboot')
        dev.adb_reboot()
    else:
        time.sleep(6)

if not g.LAST_UPTIME:
    my_print_err("Not able to contact the device... Stop")
    sys.exit(1)

if s.PURGE_TRACES_SMARTPHONE:
    my_print("Remove previous traces located on the phone")
    dev.adb_shell("rm -rf " + s.ANDROID_TRACE_OUT + "*")

# remove sim if any to launch the first UiTest
dev.adb_check_reboot_sim()

def connect_to_proxy():
    for i in range(5):
        if s.WITH_SHADOWSOCKS:
            my_print("Using ShadowSocks:")
            if s.SSH_TUNNEL_INSTALLED:
                my_print("stop + kill SSHTunnel")
                # Stop + kill ssh_tunnel
                dev.adb_shell(False, uiautomator='ssh_tunnel', args='action stopnotautoconnect')
                dev.adb_shell_root("am force-stop org.sshtunnel")
            my_print("start + autoconnect ShadowSocks")
            # Start shadown socks with autoconnect (in case of random reboot)
def avoid_poor_connections(enable):
    my_print("Settings: avoid poor connections: " + str(enable))
    arg = "avoid-poor-conn " + ("on" if enable else "off")
    return dev.adb_shell(False, uiautomator='preference_network', args=arg)
def change_pref_net(version):
    my_print("Settings: prefer " + str(version) + "G")
    arg = "network-status " + str(version) + "G"
    return dev.adb_shell(False, uiautomator='preference_network', args=arg)
def avoid_poor_connections(enable):
    my_print("Settings: avoid poor connections: " + str(enable))
    arg = "avoid-poor-conn " + ("on" if enable else "off")
    return dev.adb_shell(False, uiautomator='preference_network', args=arg)
def change_pref_net(version):
    my_print("Settings: prefer " + str(version) + "G")
    arg = "network-status " + str(version) + "G"
    return dev.adb_shell(False, uiautomator='preference_network', args=arg)