Wi-Fi hotspot timeout setting gone in Nougat 7.0 , 7.1, but timeout has not Just got a new Android 7.0 Nougat phone , and only major gripe so far is 
disappearance of the Wi-Fi-hotspot timeout setting .

This is probably the same issue as
 :
https://android.stackexchange.com/questions/168549/hotspot-timeout-setting-gone-in-7-1-nougat
, but it did start with 7.0, not 7.1 , and since no-one has answered that 
question, I thought I might as well try.

The Hotspot seems to time out after 1-2 mins of inactivity, I think
corresponding to the device going to sleep, requiring me to restart
ISC dhclient &amp; wpa_supplicant manually to re-connect.

The Hotspot goes to sleap due to inactivity much sooner than the DHCP lease
it has given out expires. 

I have WiFi Settings → Advanced 'On during sleep ( ALWAYS )' enabled.
But I do not need to enable WiFi to enable the WiFi-Hotspot (IP Tethering over WiFi, acting as an Access Point for my laptop), so
I do not see many WiFi settings, and do not know if any WiFi setting
would take effect if WiFi is disabled. I thought one enables WiFi only
to connect as terminal of another Access Point, not when providing an AP?

It does work, and used to work reliably &amp; long-term in Android 4.2.2 with 
appropriate timeout settings,  but now with no timeout setting it is highly unreliable and I have to keep waking up the device to use the internet via
Hotspot - or disable sleep mode entirely and drain the battery very quickly. 
Another reason to try and root the phone, which is also made much harder by 7.0. 

It could be something to do with :

/etc/hostapd/hostapd_default.conf :

    # Station inactivity limit
    #
    # If a station does not send anything in ap_max_inactivity seconds, an
    # empty data frame is sent to it in order to verify whether it is
    # still in range. If this frame is not ACKed, the station will be
    # disassociated and then deauthenticated. This feature is used to
    # clear station table of old entries when the STAs move out of the
    # range.
    #
    # The station can associate again with the AP if it is still in range;
    # this inactivity poll is just used as a nicer way of verifying
    # inactivity; i.e., client will not report broken connection because
    # disassociation frame is not sent immediately without first polling
    # the STA with a data frame.
    # default: 300 (i.e., 5 minutes)
    #ap_max_inactivity=300


So I need to root the phone to change this default value. 
Has anyone found any workarounds ?
Yes, it is because of inactivity timeouts. But without rooting the device I cannot determine for sure if it is that specific hostapd ap_max_inactivity=300 default, but I believe it is. I'm not sure if it is
the case that my Linux 4.10 x86_64 iwlwifi driver (recently restructured) is not acting appropriately when it receives the empty data frame.

But, I think it is really not in for Android to decide to prevent users from setting this parameter anymore, when it used to let them in previous versions.

The fix is, of course, to start a 'ping monitor daemon', like this shell script on the AP client host (Linux in my case):

#!/usr/bin/bash
declare -i wpm_should_exit=0;
function wpm_exit()
{ wpm_should_exit=1;
}
function wlan_ping_monitor()
{ trap 'wpm_exit' HUP INT QUIT TERM;
  local the_IF="$1";
  declare -i ok=1 i=0;
  def_router=$(ip route show default  2&gt;/dev/null |\
  sed -rn \
      '/^default[[:space:]]via/{s/^.*via[[:space:]]+'\
      '//;s/[[:space:]].*$//;p}'); # join above lines! 
  if [ x == x"$def_router" ]; then
     echo "$FUNCNAME: default router is not set. Nothing to do." &gt;&amp;2;
     return 1;
  fi
  kernel_org=$(host www.kernel.org | sed -rn \
     '/has[[:space:]]+address/{s/^.*address' \
     '[[:space:]]'//;p}'); # join above lines!
  if [ x = x"$kernel_org" ]; then
     echo "$FUNCNAME: Unable to resolve kernel.org -"\
          " must be able to ping an internet host." &gt;&amp;2;
     return 1;
  fi
  logger -p user.info "$FUNCNAME : started.";
  sleep 60;
  while ((0 == wpm_should_exit)); do
      ((ok=0));
        for (( i=0; i &lt; 3 ; i+=1 )); do
        if /usr/bin/ping -n -q -c 2 -W 8 $kernel_org &gt;/dev/null 2&gt;&amp;1 || \
           /usr/bin/ping -n -q -c 2 -W 4 $def_router &gt;/dev/null 2&gt;&amp;1; \
        then ((ok=1)); break 1 ; fi 
        logger -p daemon.error \
             "$FUNCNAME: ping $def_router or $kernel_org failed.";
        sleep 1;
     done
     if (( ok == 0 )); then
        logger -p daemon.error \
            "$FUNCNAME"': interface '"$the_IF"\
            ' is down. Could not ping '$def_router' or '$kernel_org\
            '. Restarting Network...' ;
        /etc/init.d/network restart || break;
        ((ok=1));
        sleep 60;
    else
        sleep 8;
    fi
 done
 logger -p daemon.error "$FUNCNAME: restarting network failed.";
 rm -vf $PID_FILE;
}
declare -i status=0;
case "$0" in
  (\*${BASH_SOURCE})
      wlan_ping_monitor ;
      status=$?;
  ;;
esac
((status==0));


For completeness, here is daemon.sh, with which the above script
is invoked by '/etc/init.d/network start':

PID_FILE=/run/wlan_ping_monitor.pid \
   daemon /etc/init.d/wlan_ping_monitor.sh


Missing is only the 'setpgid' and 'noctty' bash built-ins, which does:

setpgid( pid = getpid(), pid );


and 

ioctl(0, TIOCSCTTY , 0 );


But, they are not strictly necessary to test - just remove / comment out -
these built-ins are easy to write &amp; available on request. They must be 
built-ins, not programs, because they must effect the current process. 

One weird thing about the ping script is that it must send a packet
out to the WAN internet to reset the inactivity timer - it is not 
enough to simply ping the phone , which can fail to respond to ICMP
packets within 4 seconds while still passing through pings to the WAN. 

#!/usr/bin/bash
. /usr/lib64/bash-${BASH_VERSION}_loadables/load.sh
if [ ! -v N_DAEMONS ]; then
   declare -xi N_DAEMONS=0;
fi
if [ ! -v TMPDIR ]; then
   declare -x TMPDIR=/tmp;
fi
if [ ! -v USER ]; then
   declare -x USER=$(whoami);
fi
declare -i daemon_status=0;
function daemon()
{   export \
      PID_FILE=${PID_FILE:-${TMPDIR}/${USER}- daemon-${N_DAEMONS}.pid};
    declare -xi N_DAEMONS=0;
    if [[ "$PID_FILE" =~ ^(.*)[\.][pP][iI][dD]$ ]]; then
       export PID_FILE="${BASH_REMATCH[1]}";
    fi
    while [ -f "$PID_FILE".pid ]; do
       ((N_DAEMONS+=1));
       export PID_FILE="${PID_FILE%-\*}-${N_DAEMONS}";
    done
    export PID_FILE="${PID_FILE}.pid" LOG_FILE="${PID_FILE}.log";
    echo "daemon: PID_FILE: $PID_FILE LOG_FILE: $LOG_FILE" &gt;&amp;2;
    declare -i checkjobs_enabled=0;
    if shopt -q checkjobs; then
       ((checkjobs_enabled=1));
       shopt -u checkjobs;
    fi
    trap "" CHLD HUP TERM QUIT EXIT ERR;
    { tty=$(ps -o 'tty=' -p $BASHPID 2&gt;/dev/null);
      { trap "-" CHLD HUP TERM QUIT EXIT ERR;
        if [ x != x$tty ] &amp;&amp; [ -e /dev/$tty ]; then 
           noctty &lt; /dev/$tty || :; # another built-in -just comment out
        fi
        setpgid;
        echo "$BASHPID" &gt; "$PID_FILE";
        declare -a ps=($(cat /proc/${BASHPID}/stat));
        if [ x != x"${ps[3]}" ] &amp;&amp; [ "${ps[3]}" != 1 ] &amp;&amp; \
           [ -d /proc/${ps[3]} ] ; then
           echo 'DAEMON: '${ps[3]}' : '$(readlink  \
              /proc/${ps[3]}/exe) &gt;&amp;2;
        fi
        exec "$@" &lt;/dev/null  &gt;${LOG_FILE} 2&gt;&amp;1 ;
      } &amp;
      exit $?; # our child becomes child of init
    }&amp;
    declare -i ok=$?;
    trap "-" CHLD HUP TERM QUIT EXIT ERR;
    if ((checkjobs_enabled)); then
       shopt -s checkjobs;
    fi
    return $ok;
 }
 case "$0" in
   (\*/${BASH_SOURCE}) ;&amp;
   (${BASH_SOURCE})
      daemon "$@";
      ((daemon_status=$?));
   ;;
 esac
 ((daemon_status==0));


This daemon is also killed by /etc/init.d/network stop (which is invoked
by 'network restart').

It is a shame that it is necessary, when simply moving from using an Android 4.2.2 phone Access Point / router to using an Android 7.0 AP, that such methods must be used by clients to maintain an 'always on' WAN internet connection through the AP.